Skip to content

Commit 90bac2a

Browse files
feat: demo list context to prefetch all demos (#64)
* chore: data, types, functions, modular components * feat:demolist context; readme, contributing.md * Update CONTRIBUTING.md * Update README.md * Update README.md * prettier fix
1 parent d914ecd commit 90bac2a

10 files changed

Lines changed: 298 additions & 99 deletions

File tree

CONTRIBUTING.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Contributing to Mifos Gazelle Demo Runtime
2+
3+
First off, thank you for considering contributing to the Mifos Gazelle Demo Runtime! It's people like you that make the open-source community such a great place. We welcome any form of contribution, from reporting bugs and requesting features to submitting code changes.
4+
5+
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open-source project. In return, they should reciprocate that respect in addressing your issue, assessing changes, and helping you finalize your pull requests.
6+
7+
## How Can I Contribute?
8+
9+
### Reporting Bugs
10+
11+
This is one of the most helpful ways to contribute. If you find a bug, please ensure the bug was not already reported by searching on jira under [gax-27](<[https://github.com/openMF/mifos-gazelle-demo-runtime/issues](https://mifosforge.jira.com/browse/GAZ-27)>).
12+
13+
If you're unable to find an open issue addressing the problem, [open a new ticket](https://mifosforge.jira.com/browse/GAZ-27). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample or an executable test case** demonstrating the expected behavior that is not occurring.
14+
15+
### Suggesting Enhancements
16+
17+
If you have an idea for an enhancement or a new feature, please open an issue to discuss it. This allows us to coordinate our efforts and prevent duplication of work.
18+
19+
When creating an enhancement suggestion, please:
20+
21+
- **Use a clear and descriptive title** to identify the suggestion.
22+
- **Provide a step-by-step description of the suggested enhancement** in as many details as possible.
23+
- **Explain why this enhancement would be useful** to most users.
24+
25+
### Pull Requests
26+
27+
The process described here has several goals:
28+
29+
- Maintain project quality
30+
- Fix problems that are important to users
31+
- Engage the community in working toward the best possible solution
32+
- Enable a sustainable system for maintainers to review contributions
33+
34+
## Development Workflow
35+
36+
1. **Fork the repo** on GitHub.
37+
2. **Clone your fork** locally:
38+
```sh
39+
git clone [https://github.com/your_username/mifos-gazelle-demo-runtime.git](https://github.com/your_username/mifos-gazelle-demo-runtime.git)
40+
```
41+
3. **Create a feature branch** for your local development:
42+
```sh
43+
git checkout -b name-of-your-bugfix-or-feature
44+
```
45+
Now you can make your changes locally.
46+
4. **Commit your changes** using a descriptive commit message:
47+
```sh
48+
git commit -m "feat: Add some feature"
49+
```
50+
5. **Push your branch** to your fork on GitHub:
51+
```sh
52+
git push origin name-of-your-bugfix-or-feature
53+
```
54+
6. **Open a Pull Request** from your fork to the original `main` branch. Provide a clear title and description for your pull request, explaining the "what" and "why" of your changes.
55+
56+
## Coding Standards
57+
58+
- Follow the existing code style.
59+
- Write clear, commented code where necessary.
60+
- Ensure your code is readable and maintainable.
61+
62+
We look forward to your contributions!

README.md

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,92 @@
1-
# mifos-gazelle-demo-runtime
1+
# Mifos Gazelle Demo Runtime
22

3-
[![CI](https://github.com/openMF/mifos-gazelle-demo-runtime/actions/workflows/ci.yml/badge.svg)](https://github.com/openMF/mifos-gazelle-demo-runtime/actions/workflows/ci.yml)
3+
## Overview
44

5-
This repo contains the runtime environment for Mifo Gazelle Demos. This is currently WIP.
5+
The Mifos Gazelle Demo Runtime is an open-source, web-based tool designed to perform interactive demos using Gazelle-deployed Digital Public Goods (DPGs). It provides an intuitive and user-friendly interface to showcase complex functionalities and workflows in a step-by-step manner.
66

7-
branch main - is release/stable code
7+
Demos are created using the companion tool, [Mifos Gazelle Demo Creator](https://github.com/openMF/mifos-gazelle-demo-creator), and are stored in a jFrog repository.
88

9-
branch dev - is current development branch
9+
The Demo Runtime UI allows users to navigate to their desired demo. The interface is split into two panels:
1010

11-
All PR's must be to dev. dev-->Main will be undertaken at release points
11+
- **Left Panel:** Displays a clear, step-by-step explanation of the demo, guiding the user through the process.
12+
- **Right Panel:** Renders the live, deployed DPGs within iframes, allowing for direct and interactive engagement.
13+
14+
This side-by-side layout makes it incredibly easy to follow complex flows, as users can read the instructions and perform the actions in the live application simultaneously. Navigation between steps and different DPGs is seamless, making it the most intuitive way to understand the system's capabilities.
15+
16+
## Features
17+
18+
- **Interactive Live Demos:** Engage directly with deployed DPGs in real-time.
19+
- **Side-by-Side View:** Follow guided steps on one side while interacting with the application on the other.
20+
- **Step-by-Step Guidance:** Break down complex workflows into easy-to-understand steps.
21+
- **Seamless Navigation:** Effortlessly move between different stages of a demo and between different DPGs.
22+
- **Centralized Demo Repository:** Loads demos created with the Demo Creator from a centralized jFrog repository.
23+
24+
## Getting Started
25+
26+
Follow these instructions to get a copy of the project up and running on your local machine for development and testing purposes.
27+
28+
### Prerequisites
29+
30+
Make sure you have the following software installed on your system:
31+
32+
- [Node.js](https://nodejs.org/) (which includes npm)
33+
- [Git](https://git-scm.com/)
34+
35+
### Installation Guide
36+
37+
1. **Clone the repository:**
38+
Open your terminal and run the following command to clone the project:
39+
40+
```sh
41+
git clone https://github.com/openMF/mifos-gazelle-demo-runtime.git
42+
```
43+
44+
2. **Navigate to the project directory:**
45+
46+
```sh
47+
cd mifos-gazelle-demo-runtime
48+
```
49+
50+
3. **Install dependencies:**
51+
Install the required npm packages.
52+
53+
```sh
54+
npm install
55+
```
56+
57+
_or if you use yarn:_
58+
59+
```sh
60+
yarn install
61+
```
62+
63+
4. **Run the application:**
64+
Start the development server.
65+
66+
```sh
67+
npm start
68+
```
69+
70+
_or if you use yarn:_
71+
72+
```sh
73+
yarn start
74+
```
75+
76+
5. **View in browser:**
77+
Open your web browser and navigate to `http://localhost:3000` to see the application in action.
78+
79+
## Related Links
80+
81+
- **Jira Story:** [GAZ-27](https://mifosforge.jira.com/browse/GAZ-27) - The original story for this project.
82+
- **Demo Creator Tool:** [Mifos Gazelle Demo Creator](https://github.com/openMF/mifos-gazelle-demo-creator) - The tool used to create the demos that this runtime consumes.
83+
84+
## Contributing
85+
86+
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
87+
88+
Please see the `CONTRIBUTING.md` file for details on our code of conduct, and the process for submitting pull requests to us.
89+
90+
## License
91+
92+
This project is licensed under the Mozilla Public License Version 2.0

src/context/DemosListContext.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { fetchDemoListData } from '@/lib/api/fetchDemoListData';
2+
import { createContext, useContext, useEffect, useState } from 'react';
3+
4+
const DemosListContext = createContext([]);
5+
6+
export function DemoListProvider({ children }: { children: React.ReactNode }) {
7+
const [demosList, setDemosList] = useState([]);
8+
9+
useEffect(() => {
10+
fetchDemoListData().then(fetchedData => {
11+
setDemosList(fetchedData);
12+
});
13+
}, []);
14+
15+
return (
16+
<DemosListContext.Provider value={demosList}>
17+
{children}
18+
</DemosListContext.Provider>
19+
);
20+
}
21+
22+
export function useDemosList() {
23+
const context = useContext(DemosListContext);
24+
if (context === undefined) {
25+
throw new Error('useDemosList must be used within a DemoListProvider');
26+
}
27+
return context;
28+
}

src/lib/api/fetchDemoData.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import axios from 'axios';
22

3-
export const fetchDemoData = async () => {
4-
const response = await axios.get(`${import.meta.env.VITE_API_URL}/demoData`);
3+
export const fetchDemoData = async (demotitle: string) => {
4+
const response = await axios.get(`${import.meta.env.VITE_API_URL}/demoData`, {
5+
params: { demotitle },
6+
});
57
return response.data;
68
};

src/lib/api/fetchDemoListData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import axios from 'axios';
22

33
export const fetchDemoListData = async () => {
44
const response = await axios.get(`${import.meta.env.VITE_API_URL}/demoList`);
5-
return response.data;
5+
return response.data.demos;
66
};

src/main.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,28 @@ import { SideNav } from './components/Navigation/SideNav.tsx';
66
import { TopNav } from './components/Navigation/TopNav.tsx';
77
import { ThemeProvider } from './context/ThemeContext';
88
import { BrowserRouter } from 'react-router-dom';
9+
import { DemoListProvider } from './context/DemosListContext.tsx';
910

1011
createRoot(document.getElementById('root')!).render(
1112
<StrictMode>
1213
<BrowserRouter>
13-
<ThemeProvider>
14-
<div className=" h-screen w-screen overflow-hidden dark:bg-gray-900">
15-
<div className="fixed top-0 left-12 right-0 h-14 bg-[#1579EB] z-10">
16-
<TopNav title="Mifos Product Demo" />
17-
</div>
18-
<div className="fixed top-0 left-0 w-12 h-screen bg-white dark:bg-gray-900 z-10">
19-
<SideNav />
20-
</div>
21-
<div className="think-blue-scrollbar ml-12 mt-14 h-[calc(100vh-3.5rem)] overflow-auto flex flex-col">
22-
<div className="flex-grow">
23-
<App />
14+
<DemoListProvider>
15+
<ThemeProvider>
16+
<div className=" h-screen w-screen overflow-hidden dark:bg-gray-900">
17+
<div className="fixed top-0 left-12 right-0 h-14 bg-[#1579EB] z-10">
18+
<TopNav title="Mifos Product Demo" />
19+
</div>
20+
<div className="fixed top-0 left-0 w-12 h-screen bg-white dark:bg-gray-900 z-10">
21+
<SideNav />
22+
</div>
23+
<div className="think-blue-scrollbar ml-12 mt-14 h-[calc(100vh-3.5rem)] overflow-auto flex flex-col">
24+
<div className="flex-grow">
25+
<App />
26+
</div>
2427
</div>
2528
</div>
26-
</div>
27-
</ThemeProvider>
29+
</ThemeProvider>
30+
</DemoListProvider>
2831
</BrowserRouter>
2932
</StrictMode>
3033
);

src/pages/demo-list/platform-demos.tsx

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import {
3030
DropdownMenuCheckboxItem,
3131
} from '@/components/ui/dropdown-menu';
3232
// import { fetchDemoListData } from '@/lib/api/fetchDemoListData';
33-
import { SamplePlatformDemoData } from '@/data/sample-platform-demos';
3433
import type { PlatformDemoData as DemoData } from '@/types/demodata';
3534
import { allPlatforms } from '@/types/demodata';
35+
import { useDemosList } from '@/context/DemosListContext';
3636

3737
const columnHelper = createColumnHelper<DemoData>();
3838

@@ -43,36 +43,51 @@ export default function PlatformDemos() {
4343
navigate(`/demo/${id}/${demoSlug}`);
4444
};
4545
const [globalFilter, setGlobalFilter] = useState('');
46-
// const [data, setData] = useState<DemoData[]>([]);
47-
const [loading, setLoading] = useState(true);
46+
const [data, setData] = useState<DemoData[]>([]);
47+
const [loading, setLoading] = useState(false);
4848
const [selectedPlatforms, setSelectedPlatforms] = useState<string[]>([]);
49-
49+
const demosList = useDemosList();
50+
const productdemodata = useMemo(() => {
51+
return demosList.filter((demo: DemoData) => {
52+
return demo.tags.length > 1;
53+
});
54+
}, [demosList]);
5055
useEffect(() => {
5156
setLoading(true);
52-
// setData(SamplePlatformDemoData);
57+
setData(productdemodata);
5358
setLoading(false);
54-
// fetchDemoListData()
55-
// .then(setData)
56-
// .finally(() => setLoading(false));
57-
}, []);
59+
}, [demosList, productdemodata]);
60+
61+
// useEffect(() => {
62+
// setLoading(true);
63+
// // setData(SamplePlatformDemoData);
64+
// setLoading(false);
65+
// // fetchDemoListData()
66+
// // .then(setData)
67+
// // .finally(() => setLoading(false));
68+
// }, []);
5869

5970
const filteredData = useMemo(() => {
60-
return SamplePlatformDemoData.filter(demo => {
61-
const matchesSearch =
62-
demo.demoName.toLowerCase().includes(globalFilter.toLowerCase()) ||
63-
demo.demoDescription.toLowerCase().includes(globalFilter.toLowerCase());
71+
const search = globalFilter.toLowerCase();
72+
73+
return data.filter(demo => {
74+
const name = demo.name?.toLowerCase() ?? '';
75+
const desc = demo.description?.toLowerCase() ?? '';
76+
const tags = demo.tags?.map(t => t.toLowerCase()) ?? [];
77+
78+
const matchesSearch = name.includes(search) || desc.includes(search);
6479

6580
const matchesPlatforms =
6681
selectedPlatforms.length === 0 ||
67-
selectedPlatforms.every(p => demo.platforms.includes(p));
82+
selectedPlatforms.some(p => tags.includes(p.toLowerCase()));
6883

6984
return matchesSearch && matchesPlatforms;
7085
});
71-
}, [globalFilter, selectedPlatforms]);
86+
}, [globalFilter, selectedPlatforms, data]);
7287

7388
const columns = useMemo(
7489
() => [
75-
columnHelper.accessor('demoName', {
90+
columnHelper.accessor('name', {
7691
header: 'Demo Name',
7792
enableGlobalFilter: true,
7893
cell: info => (
@@ -81,7 +96,7 @@ export default function PlatformDemos() {
8196
</div>
8297
),
8398
}),
84-
columnHelper.accessor('demoDescription', {
99+
columnHelper.accessor('description', {
85100
header: 'Description',
86101
enableGlobalFilter: true,
87102
cell: info => (
@@ -90,7 +105,7 @@ export default function PlatformDemos() {
90105
</div>
91106
),
92107
}),
93-
columnHelper.accessor('platforms', {
108+
columnHelper.accessor('tags', {
94109
header: 'Deployments needed',
95110
enableGlobalFilter: false,
96111
cell: info => (
@@ -108,8 +123,8 @@ export default function PlatformDemos() {
108123
id: 'action',
109124
header: 'Action',
110125
cell: (info: CellContext<DemoData, unknown>) => {
111-
const demoName = info.row.original.demoName;
112-
const id = info.row.original.demoID;
126+
const demoName = info.row.original.name;
127+
const id = info.row.original.demoId;
113128
return (
114129
<Button
115130
onClick={() => NavigateToDemo(id, demoName)}
@@ -124,7 +139,7 @@ export default function PlatformDemos() {
124139
},
125140
},
126141
],
127-
[]
142+
[NavigateToDemo]
128143
);
129144

130145
const table = useReactTable({

0 commit comments

Comments
 (0)