diff --git a/frontend/src/framework/Module.tsx b/frontend/src/framework/Module.tsx index f9eb9dc96..9d825f3b1 100644 --- a/frontend/src/framework/Module.tsx +++ b/frontend/src/framework/Module.tsx @@ -36,7 +36,7 @@ export class Module { private _defaultTitle: string; public viewFC: ModuleFC; public settingsFC: ModuleFC; - private _importState: ImportState; + protected _importState: ImportState; private _moduleInstances: ModuleInstance[]; private _defaultState: StateType | null; private _stateOptions: StateOptions | undefined; diff --git a/frontend/src/framework/ModuleRegistry.ts b/frontend/src/framework/ModuleRegistry.ts index 34064da6f..92e3edc22 100644 --- a/frontend/src/framework/ModuleRegistry.ts +++ b/frontend/src/framework/ModuleRegistry.ts @@ -3,6 +3,7 @@ import { Module } from "./Module"; import { DrawPreviewFunc } from "./Preview"; import { StateBaseType, StateOptions } from "./StateStore"; import { SyncSettingKey } from "./SyncSettings"; +import { ModuleNotFoundPlaceholder } from "./internal/ModuleNotFoundPlaceholder"; export type RegisterModuleOptions = { moduleName: string; @@ -13,8 +14,19 @@ export type RegisterModuleOptions = { description?: string; }; +export class ModuleNotFoundError extends Error { + readonly moduleName: string; + constructor(moduleName: string) { + super( + `Module '${moduleName}' not found. Did you forget to register your module in 'src/modules/registerAllModules.ts'?` + ); + this.moduleName = moduleName; + } +} + export class ModuleRegistry { private static _registeredModules: Record> = {}; + private static _moduleNotFoundPlaceholders: Record> = {}; /* eslint-disable-next-line @typescript-eslint/no-empty-function */ private constructor() {} @@ -44,7 +56,7 @@ export class ModuleRegistry { module.setDefaultState(defaultState, options); return module as Module; } - throw "Did you forget to register your module in 'src/modules/registerAllModules.ts'?"; + throw new ModuleNotFoundError(moduleName); } static getModule(moduleName: string): Module { @@ -52,7 +64,12 @@ export class ModuleRegistry { if (module) { return module as Module; } - throw "Did you forget to register your module in 'src/modules/registerAllModules.ts'?"; + const placeholder = this._moduleNotFoundPlaceholders[moduleName]; + if (placeholder) { + return placeholder as Module; + } + this._moduleNotFoundPlaceholders[moduleName] = new ModuleNotFoundPlaceholder(moduleName); + return this._moduleNotFoundPlaceholders[moduleName] as Module; } static getRegisteredModules(): Record> { diff --git a/frontend/src/framework/internal/ModuleNotFoundPlaceholder.tsx b/frontend/src/framework/internal/ModuleNotFoundPlaceholder.tsx new file mode 100644 index 000000000..a79251ba8 --- /dev/null +++ b/frontend/src/framework/internal/ModuleNotFoundPlaceholder.tsx @@ -0,0 +1,61 @@ +import { ImportState, Module } from "@framework/Module"; +import { ModuleInstance } from "@framework/ModuleInstance"; +import { Button } from "@lib/components/Button"; +import { Tag } from "@lib/components/Tag"; +import { BugReport, Forum, WebAssetOff } from "@mui/icons-material"; + +export class ModuleNotFoundPlaceholder extends Module> { + constructor(moduleName: string) { + super(moduleName, moduleName, [], {}, null); + this._importState = ImportState.Imported; + } + + makeInstance(instanceNumber: number): ModuleInstance> { + const instance = super.makeInstance(instanceNumber); + instance.setDefaultState({}); + return instance; + } + + viewFC = () => { + function reportIssue() { + window.open("https://github.com/equinor/webviz/issues/new", "_blank"); + } + + function startDiscussion() { + window.open( + "https://github.com/equinor/webviz/discussions/new?category=announcements&welcome_text=true", + "_blank" + ); + } + + return ( +
+ + + Module not found. + + + The module is no longer available and might have been removed from the application. You can safely + remove the module instance by clicking on the cross in its header. If you are wondering why this + module has been removed, please get in touch with us on GitHub. + +
+ + +
+
+ ); + }; + + settingsFC = () => { + return ( +
+ Module not found. +
+ ); + }; +}