diff --git a/docs/content/deployment/deploying-admin-ui.md b/docs/content/deployment/deploying-admin-ui.md index a6ab44dece..751fc0d150 100644 --- a/docs/content/deployment/deploying-admin-ui.md +++ b/docs/content/deployment/deploying-admin-ui.md @@ -11,6 +11,23 @@ If you have customized the Admin UI with extensions, you should [compile your ex Usually, the Admin UI is served from the Vendure server via the AdminUiPlugin. However, you may wish to deploy the Admin UI app elsewhere. Since it is just a static Angular app, it can be deployed to any static hosting service such as Vercel or Netlify. +#### Metrics + +The AdminUiPlugin not only serves the Admin UI app, but also provides a `metricSummary` query which is used to display the order metrics on the dashboard. If you wish to deploy the Admin UI app stand-alone (not served by the AdminUiPlugin), but still want to display the metrics on the dashboard, you'll need to include the AdminUiPlugin in your server's plugins array, but do not call `init()`: + +```TypeScript +import { AdminUiPlugin } from '\@vendure/admin-ui-plugin'; + +const config: VendureConfig = { + plugins: [ + AdminUiPlugin, // <== include the plugin, but don't call init() + ], + // ... +}; +``` + +#### Example Script + Here's an example script that can be run as part of your host's `build` command, which will generate a stand-alone app bundle and configure it to point to your remote server API. This example is for Vercel, and assumes: diff --git a/packages/admin-ui-plugin/src/plugin.ts b/packages/admin-ui-plugin/src/plugin.ts index f8d1dd3d87..ec948e19ac 100644 --- a/packages/admin-ui-plugin/src/plugin.ts +++ b/packages/admin-ui-plugin/src/plugin.ts @@ -101,6 +101,25 @@ export interface AdminUiPluginOptions { * }; * ``` * + * ## Metrics + * + * This plugin also defines a `metricSummary` query which is used by the Admin UI to display the order metrics on the dashboard. + * + * If you are building a stand-alone version of the Admin UI app, and therefore don't need this plugin to server the Admin UI, + * you can still use the `metricSummary` query by adding the `AdminUiPlugin` to the `plugins` array, but without calling the `init()` method: + * + * @example + * ```TypeScript + * import { AdminUiPlugin } from '\@vendure/admin-ui-plugin'; + * + * const config: VendureConfig = { + * plugins: [ + * AdminUiPlugin, // <-- no call to .init() + * ], + * // ... + * }; + * ``` + * * @docsCategory core plugins/AdminUiPlugin */ @VendurePlugin({ @@ -113,7 +132,7 @@ export interface AdminUiPluginOptions { compatibility: '^2.0.0', }) export class AdminUiPlugin implements NestModule { - private static options: AdminUiPluginOptions; + private static options: AdminUiPluginOptions | undefined; constructor(private configService: ConfigService, private processContext: ProcessContext) {} @@ -130,6 +149,13 @@ export class AdminUiPlugin implements NestModule { if (this.processContext.isWorker) { return; } + if (!AdminUiPlugin.options) { + Logger.info( + `AdminUiPlugin's init() method was not called. The Admin UI will not be served.`, + loggerCtx, + ); + return; + } const { app, hostname, route, adminUiConfig } = AdminUiPlugin.options; const adminUiAppPath = AdminUiPlugin.isDevModeApp(app) ? path.join(app.sourcePath, 'src') @@ -226,7 +252,8 @@ export class AdminUiPlugin implements NestModule { */ private getAdminUiConfig(partialConfig?: Partial): AdminUiConfig { const { authOptions } = this.configService; - + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const options = AdminUiPlugin.options!; const propOrDefault = ( prop: Prop, defaultVal: AdminUiConfig[Prop], @@ -248,17 +275,14 @@ export class AdminUiPlugin implements NestModule { defaultLanguage: propOrDefault('defaultLanguage', defaultLanguage), defaultLocale: propOrDefault('defaultLocale', defaultLocale), availableLanguages: propOrDefault('availableLanguages', defaultAvailableLanguages), - loginUrl: AdminUiPlugin.options.adminUiConfig?.loginUrl, - brand: AdminUiPlugin.options.adminUiConfig?.brand, + loginUrl: options.adminUiConfig?.loginUrl, + brand: options.adminUiConfig?.brand, hideVendureBranding: propOrDefault( 'hideVendureBranding', - AdminUiPlugin.options.adminUiConfig?.hideVendureBranding || false, - ), - hideVersion: propOrDefault( - 'hideVersion', - AdminUiPlugin.options.adminUiConfig?.hideVersion || false, + options.adminUiConfig?.hideVendureBranding || false, ), - loginImageUrl: AdminUiPlugin.options.adminUiConfig?.loginImageUrl, + hideVersion: propOrDefault('hideVersion', options.adminUiConfig?.hideVersion || false), + loginImageUrl: options.adminUiConfig?.loginImageUrl, cancellationReasons: propOrDefault('cancellationReasons', undefined), }; }