132 lines
3.7 KiB
TypeScript

import { i18n as i18next } from 'i18next';
import React from 'react';
import { I18nextProvider } from 'react-i18next';
import { Link, NavLink } from 'react-router-dom';
import { ACLProvider, ACLShortcut } from '../acl';
import { AntdConfigProvider } from '../antd-config-provider';
import { APIClient, APIClientProvider } from '../api-client';
import { BlockSchemaComponentProvider } from '../block-provider';
import { CollectionManagerShortcut } from '../collection-manager';
import { RemoteDocumentTitleProvider } from '../document-title';
import { FileStorageShortcut } from '../file-manager';
import { i18n } from '../i18n';
import { PluginManagerProvider } from '../plugin-manager';
import {
AdminLayout,
AuthLayout,
RemoteRouteSwitchProvider,
RouteSchemaComponent,
RouteSwitch,
useRoutes
} from '../route-switch';
import {
AntdSchemaComponentProvider,
DesignableSwitch,
MenuItemInitializers,
SchemaComponentProvider
} from '../schema-component';
import { SchemaInitializerProvider } from '../schema-initializer';
import { BlockTemplateDetails, BlockTemplatePage, SchemaTemplateShortcut } from '../schema-templates';
import { SystemSettingsProvider, SystemSettingsShortcut } from '../system-settings';
import { SigninPage, SignupPage } from '../user';
import { compose } from './compose';
export interface ApplicationOptions {
apiClient?: any;
i18n?: any;
plugins?: any[];
}
export type PluginCallback = () => Promise<any>;
export class Application {
providers = [];
mainComponent = null;
apiClient: APIClient;
i18n: i18next;
plugins: PluginCallback[] = [];
constructor(options: ApplicationOptions) {
const { WorkflowPage, WorkflowRouteProvider, WorkflowShortcut } = require('../workflow');
this.apiClient = new APIClient({
baseURL: process.env.API_BASE_URL,
headers: {
'X-Hostname': window?.location?.hostname,
},
...options.apiClient,
});
this.i18n = options.i18n || i18n;
this.use(APIClientProvider, { apiClient: this.apiClient });
this.use(I18nextProvider, { i18n: this.i18n });
this.use(AntdConfigProvider, { remoteLocale: true });
this.use(RemoteRouteSwitchProvider, {
components: {
AuthLayout,
AdminLayout,
RouteSchemaComponent,
SigninPage,
SignupPage,
WorkflowPage,
BlockTemplatePage,
BlockTemplateDetails,
},
});
this.use(SystemSettingsProvider);
this.use(PluginManagerProvider, {
components: {
ACLShortcut,
DesignableSwitch,
CollectionManagerShortcut,
WorkflowShortcut,
SystemSettingsShortcut,
SchemaTemplateShortcut,
FileStorageShortcut,
},
});
this.use(SchemaComponentProvider, { components: { Link, NavLink } });
this.use(SchemaInitializerProvider, {
initializers: {
MenuItemInitializers,
},
});
this.use(BlockSchemaComponentProvider);
this.use(AntdSchemaComponentProvider);
this.use(ACLProvider);
this.use(RemoteDocumentTitleProvider);
this.use(WorkflowRouteProvider);
for (const plugin of options.plugins) {
const [component, props] = Array.isArray(plugin) ? plugin : [plugin];
this.use(component, props);
}
}
use(component, props?: any) {
this.providers.push(props ? [component, props] : component);
}
main(mainComponent: any) {
this.mainComponent = mainComponent;
}
/**
* TODO
*/
plugin(plugin: PluginCallback) {
this.plugins.push(plugin);
}
render() {
return compose(...this.providers)(
this.mainComponent ||
(() => {
const routes = useRoutes();
return (
<div>
<RouteSwitch routes={routes} />
</div>
);
}),
);
}
}