Skip to content

Commit c32ffbc

Browse files
authored
fix: Worker plugin definitions, optional panel wrapper for Dashboards (#1329)
- Fix up some types for plugins - Fix up some packaging - Add an optional panel wrapper to Dashboard
1 parent cbe8f72 commit c32ffbc

4 files changed

Lines changed: 34 additions & 8 deletions

File tree

packages/app-utils/src/plugins/PluginUtils.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ export interface PluginModule {}
1616

1717
export type PluginModuleMap = Map<string, PluginModule>;
1818

19+
export type PluginManifestPluginInfo = {
20+
name: string;
21+
main: string;
22+
version: string;
23+
};
24+
25+
export type PluginManifest = { plugins: PluginManifestPluginInfo[] };
26+
1927
/**
2028
* Load a component plugin from the server.
2129
* @param baseURL Base URL of the plugin server
@@ -53,7 +61,9 @@ export function loadComponentPlugin(
5361
* @param pluginUrl The URL of the plugin to load
5462
* @returns The loaded module
5563
*/
56-
export async function loadModulePlugin(pluginUrl: string): Promise<unknown> {
64+
export async function loadModulePlugin(
65+
pluginUrl: string
66+
): Promise<PluginModule> {
5767
const myModule = await loadRemoteModule(pluginUrl);
5868
return myModule;
5969
}
@@ -63,9 +73,7 @@ export async function loadModulePlugin(pluginUrl: string): Promise<unknown> {
6373
* @param jsonUrl The URL of the JSON file to load
6474
* @returns The JSON object of the manifest file
6575
*/
66-
export async function loadJson(
67-
jsonUrl: string
68-
): Promise<{ plugins: { name: string; main: string }[] }> {
76+
export async function loadJson(jsonUrl: string): Promise<PluginManifest> {
6977
const res = await fetch(jsonUrl);
7078
if (!res.ok) {
7179
throw new Error(res.statusText);
@@ -94,7 +102,7 @@ export async function loadModulePlugins(
94102
}
95103

96104
log.debug('Plugin manifest loaded:', manifest);
97-
const pluginPromises: Promise<unknown>[] = [];
105+
const pluginPromises: Promise<PluginModule>[] = [];
98106
for (let i = 0; i < manifest.plugins.length; i += 1) {
99107
const { name, main } = manifest.plugins[i];
100108
const pluginMainUrl = `${modulePluginsUrl}/${name}/${main}`;
@@ -107,7 +115,7 @@ export async function loadModulePlugins(
107115
const module = pluginModules[i];
108116
const { name } = manifest.plugins[i];
109117
if (module.status === 'fulfilled') {
110-
pluginMap.set(name, module.value as PluginModule);
118+
pluginMap.set(name, module.value);
111119
} else {
112120
log.error(`Unable to load plugin ${name}`, module.reason);
113121
}

packages/code-studio/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"],
1010
"exclude": ["node_modules", "src/**/*.test.*", "src/**/__mocks__/*"],
1111
"references": [
12+
{ "path": "../app-utils" },
1213
{ "path": "../auth-plugins" },
1314
{ "path": "../chart" },
1415
{ "path": "../components" },

packages/dashboard/src/Dashboard.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, {
2+
ComponentType,
23
ForwardRefExoticComponent,
34
RefAttributes,
45
useEffect,
@@ -40,6 +41,9 @@ export type DashboardProps = {
4041
>;
4142
hydrate?: PanelHydrateFunction;
4243
dehydrate?: PanelDehydrateFunction;
44+
45+
/** Component to wrap each panel with */
46+
panelWrapper?: ComponentType;
4347
};
4448

4549
export function Dashboard({
@@ -54,6 +58,7 @@ export function Dashboard({
5458
fallbackComponent = PanelPlaceholder,
5559
hydrate,
5660
dehydrate,
61+
panelWrapper,
5762
}: DashboardProps): JSX.Element {
5863
const layoutElement = useRef<HTMLDivElement>(null);
5964
const [isInitialized, setIsInitialized] = useState(false);
@@ -140,6 +145,7 @@ export function Dashboard({
140145
onLayoutInitialized={onLayoutInitialized}
141146
hydrate={hydrate}
142147
dehydrate={dehydrate}
148+
panelWrapper={panelWrapper}
143149
>
144150
{children}
145151
</DashboardLayout>

packages/dashboard/src/DashboardLayout.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, {
2+
ComponentType,
23
ReactElement,
34
useCallback,
45
useEffect,
@@ -63,6 +64,9 @@ interface DashboardLayoutProps {
6364
data?: DashboardData;
6465
children?: React.ReactNode | React.ReactNode[];
6566
emptyDashboard?: React.ReactNode;
67+
68+
/** Component to wrap each panel with */
69+
panelWrapper?: ComponentType;
6670
}
6771

6872
/**
@@ -78,6 +82,8 @@ export function DashboardLayout({
7882
onLayoutInitialized = DEFAULT_CALLBACK,
7983
hydrate = hydrateDefault,
8084
dehydrate = dehydrateDefault,
85+
// eslint-disable-next-line react/jsx-no-useless-fragment
86+
panelWrapper = ({ children: panelChildren }) => <>{panelChildren}</>,
8187
}: DashboardLayoutProps): JSX.Element {
8288
const dispatch = useDispatch();
8389
const data =
@@ -117,14 +123,19 @@ export function DashboardLayout({
117123
// ComponentType doesn't seem to work right, ReactNode is also incorrect
118124
// eslint-disable-next-line @typescript-eslint/no-explicit-any
119125
const CType = componentType as any;
126+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
127+
const PanelWrapperType = panelWrapper as any;
120128

121129
// Props supplied by GoldenLayout
122130
// eslint-disable-next-line react/prop-types
123131
const { glContainer, glEventHub } = props;
124132
return (
125133
<PanelErrorBoundary glContainer={glContainer} glEventHub={glEventHub}>
126134
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
127-
<CType {...props} ref={ref} />
135+
<PanelWrapperType {...props}>
136+
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
137+
<CType {...props} ref={ref} />
138+
</PanelWrapperType>
128139
</PanelErrorBoundary>
129140
);
130141
}
@@ -135,7 +146,7 @@ export function DashboardLayout({
135146
dehydrateMap.set(name, componentDehydrate);
136147
return cleanup;
137148
},
138-
[hydrate, dehydrate, hydrateMap, dehydrateMap, layout]
149+
[hydrate, dehydrate, hydrateMap, dehydrateMap, layout, panelWrapper]
139150
);
140151
const hydrateComponent = useCallback(
141152
(name, props) => (hydrateMap.get(name) ?? FALLBACK_CALLBACK)(props, id),

0 commit comments

Comments
 (0)