Skip to content

Commit

Permalink
Merge pull request #207 from EyeSeeTea/fix/react-router-fix
Browse files Browse the repository at this point in the history
remove react-router as peerDependency
  • Loading branch information
adrianq authored Jan 15, 2025
2 parents 0eea0f2 + c1aae64 commit a8d9fd1
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 43 deletions.
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ yarn add @eyeseetea/training-component
```

```tsx
import { TraininigModule } from "@eyeseetea/training-component";
import { TutorialModule } from "@eyeseetea/training-component";

function MyComponent() {
const { api } = useAppContext();
Expand All @@ -121,7 +121,7 @@ function MyComponent() {
Tutorials were build for being executed in the whole page so it's a good idea to use them inside a full screen component like Dialog.

```tsx
import { TraininigModule } from "training-component";
import { TutorialModule } from "@eyeseetea/training-component";

function MyComponent() {
const { api } = useAppContext();
Expand All @@ -132,15 +132,18 @@ function MyComponent() {
}, []);

return (
<Dialog open fullScreen>
<TutorialModule
moduleId="data-entry"
onExit={() => setShowTutorial(false)}
onHome={() => setShowTutorial(false)}
locale="en"
baseUrl={api.baseUrl}
/>
</Dialog>
<>
<button onClick={openTutorial}>Open Tutorial</button>
<Dialog open={showTutorial} fullScreen>
<TutorialModule
moduleId="data-entry"
onExit={() => setShowTutorial(false)}
onHome={() => setShowTutorial(false)}
locale="en"
baseUrl={api.baseUrl}
/>
</Dialog>
</>
);
}
```
Expand Down
8 changes: 3 additions & 5 deletions build-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,9 @@ function removeDependenciesFromPackage() {
const packageJsonPath = path.join(__dirname, "package.json");
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
const packageJson2 = { ...packageJson, name: packageJson.name.replace(/-app$/, "-component") };
if (packageJson.dependencies && packageJson.dependencies["react-scripts"]) {
delete packageJson.dependencies["react-scripts"];
delete packageJson.dependencies["react-router"];
delete packageJson.dependencies["react-router-dom"];
}

delete packageJson2.dependencies["react-router"];
delete packageJson2.dependencies["react-router-dom"];
const destinationPath = path.join(distPath, "package.json");
fs.writeFileSync(destinationPath, JSON.stringify(packageJson2, null, 2));
console.log("package.json copied");
Expand Down
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
"url": "git+https://github.com/eyeseetea/training-app.git"
},
"peerDependencies": {
"react": "17",
"react-dom": "17",
"react-router": ">=5",
"react-router-dom": ">=5"
"react": ">=17",
"react-dom": ">=17"
},
"dependencies": {
"@dhis2/app-runtime": "3.2.4",
Expand All @@ -33,13 +31,11 @@
"@material-ui/icons": "4.11.2",
"@material-ui/lab": "4.0.0-alpha.60",
"@material-ui/styles": "4.11.4",
"@types/file-saver": "2.0.3",
"axios": "0.24.0",
"btoa": "1.2.1",
"classnames": "2.3.1",
"d2": "31.10.0",
"d2-manifest": "1.0.0",
"date-fns": "2.25.0",
"file-saver": "2.0.5",
"file-type": "16.5.3",
"font-awesome": "4.7.0",
Expand Down Expand Up @@ -93,6 +89,7 @@
"@babel/preset-typescript": "7.15.0",
"@testing-library/jest-dom": "5.14.1",
"@testing-library/react": "12.1.2",
"@types/file-saver": "2.0.3",
"@types/axios-mock-adapter": "1.10.0",
"@types/btoa": "1.2.3",
"@types/classnames": "2.3.1",
Expand Down
19 changes: 14 additions & 5 deletions src/data/repositories/TrainingModuleDefaultRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TranslatableText } from "../../domain/entities/TranslatableText";
import { UserProgress } from "../../domain/entities/UserProgress";
import { ConfigRepository } from "../../domain/repositories/ConfigRepository";
import { InstanceRepository } from "../../domain/repositories/InstanceRepository";
import { TrainingModuleRepository } from "../../domain/repositories/TrainingModuleRepository";
import { GetModuleOptions, TrainingModuleRepository } from "../../domain/repositories/TrainingModuleRepository";
import { swapById } from "../../utils/array";
import { cache } from "../../utils/cache";
import { promiseMap } from "../../utils/promises";
Expand Down Expand Up @@ -96,8 +96,8 @@ export class TrainingModuleDefaultRepository implements TrainingModuleRepository
}
}

public async get(key: string): Promise<TrainingModule | undefined> {
const defaultModules = await this.listDefaultModules();
public async get(key: string, options: GetModuleOptions): Promise<TrainingModule | undefined> {
const defaultModules = await this.listDefaultModules(options);
const dataStoreModel = await this.storageClient.getObjectInCollection<PersistedTrainingModule>(
Namespaces.TRAINING_MODULES,
key
Expand Down Expand Up @@ -252,7 +252,9 @@ export class TrainingModuleDefaultRepository implements TrainingModuleRepository
}

@cache()
private async listDefaultModules(): Promise<DefaultModule[]> {
private async listDefaultModules(options: GetModuleOptions = defaultModuleOptions): Promise<DefaultModule[]> {
if (!options.autoInstallDefaultModules) return [];

try {
const blob = await this.assetClient.request<Blob>({ method: "get", url: `/modules/config.json` }).getData();
const text = await blob.text();
Expand All @@ -265,7 +267,12 @@ export class TrainingModuleDefaultRepository implements TrainingModuleRepository
}
}

private async importDefaultModule(id: string): Promise<PersistedTrainingModule | undefined> {
private async importDefaultModule(
id: string,
options: GetModuleOptions = defaultModuleOptions
): Promise<PersistedTrainingModule | undefined> {
if (!options.autoInstallDefaultModules) return undefined;

const defaultModules = await this.listDefaultModules();
const defaultModule = defaultModules.find(item => item.id === id);
if (!defaultModule) return undefined;
Expand Down Expand Up @@ -376,3 +383,5 @@ interface DefaultModule {
id: string;
revision: number;
}

const defaultModuleOptions = { autoInstallDefaultModules: true };
4 changes: 3 additions & 1 deletion src/domain/repositories/TrainingModuleRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TrainingModule } from "../entities/TrainingModule";

export interface TrainingModuleRepository {
list(): Promise<TrainingModule[]>;
get(moduleKey: string): Promise<TrainingModule | undefined>;
get(moduleKey: string, options: GetModuleOptions): Promise<TrainingModule | undefined>;
update(module: Pick<TrainingModule, "id" | "name"> & Partial<TrainingModule>): Promise<void>;
delete(ids: string[]): Promise<void>;
swapOrder(id1: string, id2: string): Promise<void>;
Expand All @@ -14,3 +14,5 @@ export interface TrainingModuleRepository {
export(ids: string[]): Promise<void>;
import(files: File[]): Promise<PersistedTrainingModule[]>;
}

export type GetModuleOptions = { autoInstallDefaultModules: boolean };
6 changes: 3 additions & 3 deletions src/domain/usecases/GetModuleUseCase.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { UseCase } from "../../webapp/CompositionRoot";
import { TrainingModule } from "../entities/TrainingModule";
import { TrainingModuleRepository } from "../repositories/TrainingModuleRepository";
import { GetModuleOptions, TrainingModuleRepository } from "../repositories/TrainingModuleRepository";

export class GetModuleUseCase implements UseCase {
constructor(private trainingModuleRepository: TrainingModuleRepository) {}

public async execute(id: string): Promise<TrainingModule | undefined> {
return this.trainingModuleRepository.get(id);
public async execute(id: string, options: GetModuleOptions): Promise<TrainingModule | undefined> {
return this.trainingModuleRepository.get(id, options);
}
}
2 changes: 1 addition & 1 deletion src/domain/usecases/InstallAppUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class InstallAppUseCase implements UseCase {
) {}

public async execute(moduleId: string): Promise<boolean> {
const module = await this.trainingModuleRepository.get(moduleId);
const module = await this.trainingModuleRepository.get(moduleId, { autoInstallDefaultModules: true });
if (!module?.name) return false;

// TODO: We should store app hub id on model instead of using display name
Expand Down
8 changes: 4 additions & 4 deletions src/tutorial-module/TutorialRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { LoadingProvider, SnackbarProvider } from "@eyeseetea/d2-ui-components";
import { useUpdateModuleStep } from "./useTutorial";

export type HeaderButtonsProps = { onExit: () => void; onMinimize?: () => void; onHome: () => void };
export type TutorialModuleProps = { baseUrl?: string; locale: string; moduleId: string } & HeaderButtonsProps;
export type TutorialModuleProps = { baseUrl?: string; locale?: string; moduleId: string } & HeaderButtonsProps;
export type UseTutorialModuleProps = { baseUrl: string; moduleId: string };

function useTrainingModule(props: UseTutorialModuleProps) {
Expand All @@ -25,7 +25,7 @@ function useTrainingModule(props: UseTutorialModuleProps) {

React.useEffect(() => {
compositionRoot.usecases.modules
.get(moduleId)
.get(moduleId, { autoInstallDefaultModules: false })
.then(setModule)
.catch(() => {
throw new Error(`Module not found: ${moduleId}`);
Expand All @@ -36,7 +36,7 @@ function useTrainingModule(props: UseTutorialModuleProps) {
}

export const TutorialModule = (props: TutorialModuleProps) => {
const { baseUrl, locale, onExit, onHome, onMinimize } = props;
const { baseUrl, locale = "en", onExit, onHome, onMinimize } = props;
const [moduleState, setModuleState] = React.useState<"default" | "minimized">("default");
const module = useTrainingModule({ baseUrl: props.baseUrl || "", moduleId: props.moduleId });
const { moduleStep, setModuleStep, setTutorialProgress, tutorialProgress, updateModuleStep } = useUpdateModuleStep({
Expand All @@ -59,7 +59,7 @@ export const TutorialModule = (props: TutorialModuleProps) => {
return (
<LoadingProvider>
<SnackbarProvider>
<IFrame src={`${baseUrl}${module?.dhisLaunchUrl}`} />
<IFrame src={`${baseUrl}${module.dhisLaunchUrl}`} />
{showBackDrop && <Backdrop />}

{moduleStep === "welcome" && (
Expand Down
21 changes: 14 additions & 7 deletions src/webapp/pages/settings/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ export const SettingsPage: React.FC = () => {
await reload();
}, [showAllModules, reload, usecases]);

const getModule = React.useCallback(
(id: string) => {
return usecases.modules.get(id, { autoInstallDefaultModules: true });
},
[usecases.modules]
);

const tableActions: ComponentParameter<typeof ModuleListTable, "tableActions"> = useMemo(
() => ({
openEditModulePage: ({ id }) => {
Expand All @@ -116,7 +123,7 @@ export const SettingsPage: React.FC = () => {
setAppState({ type: "CLONE_MODULE", module: id });
},
editContents: async ({ id, text, value }) => {
const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(updateTranslation(module, text.key, value));
else snackbar.error(i18n.t("Unable to update module contents"));
},
Expand All @@ -128,34 +135,34 @@ export const SettingsPage: React.FC = () => {
return;
}

const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(updateOrder(module, from, to));
else snackbar.error(i18n.t("Unable to move item"));
},
uploadFile: ({ data, name }) => usecases.instance.uploadFile(data, name),
installApp: ({ id }) => usecases.instance.installApp(id),
addStep: async ({ id, title }) => {
const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(addStep(module, title));
else snackbar.error(i18n.t("Unable to add step"));
},
addPage: async ({ id, step, value }) => {
const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(addPage(module, step, value));
else snackbar.error(i18n.t("Unable to add page"));
},
deleteStep: async ({ id, step }) => {
const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(removeStep(module, step));
else snackbar.error(i18n.t("Unable to remove step"));
},
deletePage: async ({ id, step, page }) => {
const module = await usecases.modules.get(id);
const module = await getModule(id);
if (module) await usecases.modules.update(removePage(module, step, page));
else snackbar.error(i18n.t("Unable to remove page"));
},
}),
[usecases, setAppState, snackbar]
[usecases, setAppState, snackbar, getModule]
);

useEffect(() => {
Expand Down

0 comments on commit a8d9fd1

Please sign in to comment.