Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 0 additions & 107 deletions lib/static/components/extension-point.jsx

This file was deleted.

136 changes: 136 additions & 0 deletions lib/static/components/extension-point.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React, {Component, FC, ReactNode} from 'react';
import * as plugins from '../modules/plugins';
import {PLUGIN_COMPONENT_POSITIONS, PluginComponentPosition, PluginDescription} from '@/types';
import ErrorBoundary from './error-boundary';

interface ExtensionPointProps {
name: string;
children?: React.ReactNode;
}

interface ExtensionPointComponent {
PluginComponent: FC;
name: string;
point: string;
position: PluginComponentPosition;
config: PluginDescription;
}

type ExtensionPointComponentUnchecked =
Omit<ExtensionPointComponent, 'point' | 'position'>
& Partial<Pick<ExtensionPointComponent, 'point' | 'position'>>

export default class ExtensionPoint<T extends ExtensionPointProps> extends Component<T> {
render(): ReactNode {
const loadedPluginConfigs = plugins.getLoadedConfigs();

if (loadedPluginConfigs.length) {
const {name: pointName, children: reportComponent, ...componentProps} = this.props;
const pluginComponents = getExtensionPointComponents(loadedPluginConfigs, pointName);
return getComponentsComposition(pluginComponents, reportComponent, componentProps);
}

return this.props.children;
}
}

function getComponentsComposition(pluginComponents: ExtensionPointComponent[], reportComponent: ReactNode, componentProps: any): ReactNode {

Check warning on line 37 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

Unexpected any. Specify a different type

Check warning on line 37 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 37 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (22.6)

Unexpected any. Specify a different type
let currentComponent = reportComponent;

for (const {PluginComponent, position, config} of pluginComponents) {
currentComponent = composeComponents(PluginComponent, componentProps, currentComponent, position, config);
}

return currentComponent;
}

function composeComponents(PluginComponent: FC, pluginProps: any, currentComponent: ReactNode, position: PluginComponentPosition, config: PluginDescription): ReactNode {

Check warning on line 47 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

Unexpected any. Specify a different type

Check warning on line 47 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 47 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (22.6)

Unexpected any. Specify a different type
switch (position) {
case 'wrap':
return <ErrorBoundary fallback={currentComponent}>
<PluginComponent {...pluginProps}>
{currentComponent}
</PluginComponent>
</ErrorBoundary>;
case 'before':
return <>
<ErrorBoundary>
<PluginComponent {...pluginProps}/>
</ErrorBoundary>
{currentComponent}
</>;
case 'after':
return <>
{currentComponent}
<ErrorBoundary>
<PluginComponent {...pluginProps}/>
</ErrorBoundary>
</>;
default:
console.error(`${getComponentSpec(config)} unexpected position "${position}" specified.`);
return currentComponent;
}
}

function getExtensionPointComponents(loadedPluginConfigs: PluginDescription[], pointName: string): ExtensionPointComponent[] {
return loadedPluginConfigs
.map<ExtensionPointComponentUnchecked>(pluginDescription => {
try {
const PluginComponent = plugins.getPluginField<FC>(pluginDescription.name, pluginDescription.component);

return {
PluginComponent,
name: pluginDescription.name,
point: getComponentPoint(PluginComponent, pluginDescription),
position: getComponentPosition(PluginComponent, pluginDescription),
config: pluginDescription
};
} catch (err) {
console.error(err);
return {} as ExtensionPointComponentUnchecked;
}
})
.filter((component: ExtensionPointComponentUnchecked): component is ExtensionPointComponent => {
return Boolean(component.point && component.position && component.point === pointName);
});
}

function getComponentPoint(component: FC, config: PluginDescription): string | undefined {
const result = getComponentConfigField(component, config, 'point');

if (typeof result !== 'string') {
return;
}

return result as string;
}

function getComponentPosition(component: FC, config: PluginDescription): PluginComponentPosition | undefined {
const result = getComponentConfigField(component, config, 'position');

if (typeof result !== 'string') {
return;
}

if (!PLUGIN_COMPONENT_POSITIONS.includes(result as PluginComponentPosition)) {
return;
}

return result as PluginComponentPosition;
}

function getComponentConfigField(component: any, config: any, field: string): unknown | null {

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

Unexpected any. Specify a different type

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (18.x)

Unexpected any. Specify a different type

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (20.x)

Unexpected any. Specify a different type

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (22.6)

Unexpected any. Specify a different type

Check warning on line 122 in lib/static/components/extension-point.tsx

View workflow job for this annotation

GitHub Actions / build (22.6)

Unexpected any. Specify a different type
if (component[field] && config[field] && component[field] !== config[field]) {
console.error(`${getComponentSpec(config)} "${field}" field does not match the one from the config: "${component[field]}" vs "${config[field]}".`);
return null;
} else if (!component[field] && !config[field]) {
console.error(`${getComponentSpec(config)} "${field}" field is not set.`);
return null;
}

return component[field] || config[field];
}

function getComponentSpec(pluginDescription: PluginDescription): string {
return `Component "${pluginDescription.component}" of "${pluginDescription.name}" plugin`;
}
Loading