Browse Source

docs: Improve ui extensions docs to better align with CLI use

Michael Bromley 1 year ago
parent
commit
a126cc0583

+ 62 - 32
docs/docs/guides/extending-the-admin-ui/defining-routes/index.md

@@ -13,7 +13,38 @@ Routes can be defined natively using either **Angular** or **React**. It is also
 
 
 ## Example: Creating a "Greeter" route
 ## Example: Creating a "Greeter" route
 
 
-### 1. Create the route component
+### 1. Create a plugin
+
+We will first quickly scaffold a new plugin to house our UI extensions:
+
+- Run `npx vendure add` from your project root
+- Select `Create a new Vendure plugin` and when prompted for a name, name it **"greeter"**
+- After the plugin is created, you will be prompted to add features to the plugin. Select `[Plugin: UI] Set up Admin UI extensions`
+
+You should now have a new plugin scaffolded at `./src/plugins/greeter`, with some empty UI extension files in the `ui` 
+directory. If you check your `vendure-config.ts` file you should also see that your `AdminUiPlugin.init()` call has been modified
+to compile the UI extensions:
+
+```ts
+AdminUiPlugin.init({
+    route: 'admin',
+    port: serverPort + 2,
+    adminUiConfig: {
+        apiPort: serverPort,
+    },
+    // highlight-start
+    app: compileUiExtensions({
+        outputPath: path.join(__dirname, '../admin-ui'),
+        extensions: [
+            GreeterPlugin.ui,
+        ],
+        devMode: true,
+    }),
+    // highlight-end
+}),
+```
+
+### 2. Create the route component
 
 
 First we need to create the component which will be mounted at the route. This component can be either an Angular component or a React component.
 First we need to create the component which will be mounted at the route. This component can be either an Angular component or a React component.
 
 
@@ -42,7 +73,7 @@ export class GreeterComponent {
 </TabItem>
 </TabItem>
 <TabItem value="React" label="React">
 <TabItem value="React" label="React">
 
 
-```ts title="src/plugins/greeter/ui/components/Greeter.tsx"
+```ts title="src/plugins/greeter/ui/components/greeter/Greeter.tsx"
 import React from 'react';
 import React from 'react';
 
 
 export function Greeter() {
 export function Greeter() {
@@ -63,7 +94,7 @@ The `<vdr-page-block>` (Angular) and `<div className="page-block">` (React) is a
 :::
 :::
 
 
 
 
-### 2. Define the route
+### 3. Define the route
 
 
 Next we need to define a route in our `routes.ts` file. Note that this file can have any name, but "routes.ts" is a convention.
 Next we need to define a route in our `routes.ts` file. Note that this file can have any name, but "routes.ts" is a convention.
 
 
@@ -110,39 +141,34 @@ export default [
 
 
 The `path: ''` is actually optional, since `''` is the default value. But this is included here to show that you can mount different components at different paths. See the section on route parameters below.
 The `path: ''` is actually optional, since `''` is the default value. But this is included here to show that you can mount different components at different paths. See the section on route parameters below.
 
 
-### 3. Add the route to the extension config
+### 4. Add the route to the extension config
 
 
-Now we need to add this routes file to our extension definition:
+Since you have used the CLI to scaffold your plugin, this part has already been done for you. But for the sake of completeness
+this is the part of your plugin which is configured to point to your routes file:
 
 
-```ts title="src/vendure-config.ts"
-import { VendureConfig } from '@vendure/core';
-import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
-import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
-import * as path from 'path';
+```ts title="src/plugins/greeter/greeter.plugin.ts"
+// ...
+export class GreeterPlugin {
+    static options: PluginInitOptions;
+
+    static init(options: PluginInitOptions): Type<GreeterPlugin> {
+        this.options = options;
+        return GreeterPlugin;
+    }
+
+    // highlight-start
+    static ui: AdminUiExtension = {
+        id: 'greeter-ui',
+        extensionPath: path.join(__dirname, 'ui'),
+        routes: [{ route: 'greeter', filePath: 'routes.ts' }],
+        providers: ['providers.ts'],
+    };
+    // highlight-end
+}
 
 
-export const config: VendureConfig = {
-    // ...
-    plugins: [
-        AdminUiPlugin.init({
-            port: 3002,
-            app: compileUiExtensions({
-                outputPath: path.join(__dirname, '../admin-ui'),
-                extensions: [
-                    {
-                        id: 'greeter',
-                        extensionPath: path.join(__dirname, 'plugins/greeter/ui'),
-                        // highlight-start
-                        routes: [{ route: 'greet', filePath: 'routes.ts' }],
-                        // highlight-end
-                    },
-                ],
-            }),
-        }),
-    ],
-};
 ```
 ```
 
 
-Note that by specifying `route: 'greet'`, we are "mounting" the routes at the `/extensions/greet` path.
+Note that by specifying `route: 'greeter'`, we are "mounting" the routes at the `/extensions/greeter` path.
 
 
 :::info
 :::info
 
 
@@ -154,7 +180,11 @@ more information.
 
 
 The `filePath` property is relative to the directory specified in the `extensionPath` property. In this case, the `routes.ts` file is located at `src/plugins/greeter/ui/routes.ts`.
 The `filePath` property is relative to the directory specified in the `extensionPath` property. In this case, the `routes.ts` file is located at `src/plugins/greeter/ui/routes.ts`.
 
 
-Now go to the Admin UI app in your browser and log in. You should now be able to manually enter the URL `http://localhost:3000/admin/extensions/greet` and you should see the component with the "Hello!" header:
+### 5. Test it out
+
+Now run your app with `npm run dev`. Wait for it to compile the Admin UI extensions.
+
+Now go to the Admin UI app in your browser and log in. You should now be able to manually enter the URL `http://localhost:3000/admin/extensions/greeter` and you should see the component with the "Hello!" header:
 
 
 ![./ui-extensions-greeter.webp](./ui-extensions-greeter.webp)
 ![./ui-extensions-greeter.webp](./ui-extensions-greeter.webp)
 
 

+ 46 - 10
docs/docs/guides/extending-the-admin-ui/getting-started/index.md

@@ -21,6 +21,13 @@ UI extensions fall into two categories:
 :::cli
 :::cli
 Use `npx vendure add` and select "Set up Admin UI extensions".
 Use `npx vendure add` and select "Set up Admin UI extensions".
 
 
+If you don't already have any plugins in your project, first create a plugin to house your
+UI extensions. Then select:
+
+```sh
+[Plugin: UI] Set up Admin UI extensions
+```
+
 Then follow the prompts, which will guide you through the process of 
 Then follow the prompts, which will guide you through the process of 
 setting up the necessary files and folders for your UI extensions.
 setting up the necessary files and folders for your UI extensions.
 :::
 :::
@@ -28,7 +35,7 @@ setting up the necessary files and folders for your UI extensions.
 ### Manual setup
 ### Manual setup
 
 
 It is recommended to use the `vendure add` command as described above, but if you prefer to set up the 
 It is recommended to use the `vendure add` command as described above, but if you prefer to set up the 
-Admin UI extensions manually, follow these steps:
+Admin UI extensions manually, or just want to get a better understanding of what the CLI is doing, follow these steps:
 
 
 First, install the [`@vendure/ui-devkit` package](https://www.npmjs.com/package/@vendure/ui-devkit) as a dev dependency:
 First, install the [`@vendure/ui-devkit` package](https://www.npmjs.com/package/@vendure/ui-devkit) as a dev dependency:
 
 
@@ -99,6 +106,32 @@ export default [
 ];
 ];
 ```
 ```
 
 
+Now we can configure the paths to your UI extension files. By convention, we will add this config object as a 
+static property on your plugin class:
+
+```ts title="src/plugins/my-plugin/my.plugin.ts"
+import * as path from 'path';
+import { PluginCommonModule, Type, VendurePlugin } from '@vendure/core';
+// highlight-next-line
+import { AdminUiExtension } from '@vendure/ui-devkit/compiler';
+
+@VendurePlugin({
+    imports: [PluginCommonModule],
+    compatibility: '^3.0.0',
+})
+export class MyPlugin {
+
+    // highlight-start
+    static ui: AdminUiExtension = {
+        id: 'my-plugin-ui',
+        extensionPath: path.join(__dirname, 'ui'),
+        routes: [{ route: 'my-plugin', filePath: 'routes.ts' }],
+        providers: ['providers.ts'],
+    };
+    // highlight-end
+}
+```
+
 You can then use the [`compileUiExtensions` function](/reference/admin-ui-api/ui-devkit/compile-ui-extensions/) to compile your UI extensions and add them to the Admin UI app bundle.
 You can then use the [`compileUiExtensions` function](/reference/admin-ui-api/ui-devkit/compile-ui-extensions/) to compile your UI extensions and add them to the Admin UI app bundle.
 
 
 ```ts title="src/vendure-config.ts"
 ```ts title="src/vendure-config.ts"
@@ -106,7 +139,7 @@ import { VendureConfig } from '@vendure/core';
 import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
 import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
 // highlight-next-line
 // highlight-next-line
 import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
 import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
-import * as path from 'path';
+import { MyPlugin } from './plugins/greeter/my.plugin'
 
 
 export const config: VendureConfig = {
 export const config: VendureConfig = {
     // ...
     // ...
@@ -117,11 +150,7 @@ export const config: VendureConfig = {
             app: compileUiExtensions({
             app: compileUiExtensions({
                 outputPath: path.join(__dirname, '../admin-ui'),
                 outputPath: path.join(__dirname, '../admin-ui'),
                 extensions: [
                 extensions: [
-                    {
-                        id: 'test-extension',
-                        extensionPath: path.join(__dirname, 'plugins/my-plugin/ui'),
-                        providers: ['providers.ts'],
-                    },
+                    MyPlugin.ui,
                 ],
                 ],
                 devMode: true,
                 devMode: true,
             }),
             }),
@@ -134,15 +163,18 @@ export const config: VendureConfig = {
 };
 };
 ```
 ```
 
 
+Everything above will be automatically done for you when you use the CLI.
+
 Now when you start the server, the following will happen:
 Now when you start the server, the following will happen:
 
 
 1. A new folder called `admin-ui` will be created in the root of your project (as specified by the `outputPath` option). This is a temporary directory (it should not be added to version control) which will contain the source files of your custom Admin UI app.
 1. A new folder called `admin-ui` will be created in the root of your project (as specified by the `outputPath` option). This is a temporary directory (it should not be added to version control) which will contain the source files of your custom Admin UI app.
 2. During bootstrap, the `compileUiExtensions` function will be called, which will compile the Admin UI app and serve it in development mode. The dev server will be listening on port `4200` but this port will also be proxied to port `3000` (as specified by `apiOptions.port`). This step can take up to a minute or two, depending on the speed of your machine.
 2. During bootstrap, the `compileUiExtensions` function will be called, which will compile the Admin UI app and serve it in development mode. The dev server will be listening on port `4200` but this port will also be proxied to port `3000` (as specified by `apiOptions.port`). This step can take up to a minute or two, depending on the speed of your machine.
 
 
 :::caution
 :::caution
-**Note:** the TypeScript source files of your UI extensions **must not** be compiled by your regular TypeScript build task. This is because they will instead be compiled by the Angular compiler when you run `compileUiExtensions()`.
+**Note:** the TypeScript source files of your UI extensions **must not** be compiled by your regular TypeScript build task. 
+This is because they will instead be compiled by the Angular compiler when you run `compileUiExtensions()`.
 
 
-You can exclude them in your main `tsconfig.json` by adding a line to the "exclude" array:
+You can exclude them in your main `tsconfig.json` by adding a line to the "exclude" array (this is already defined on a default Vendure project):
 
 
 ```json title="tsconfig.json"
 ```json title="tsconfig.json"
 {
 {
@@ -196,7 +228,8 @@ export default [
 
 
 ### Specifying providers
 ### Specifying providers
 
 
-When defining UI extensions in the `compileUiExtensions()` function, you must specify at least one providers file. This is done by passing an array of file paths, where each file path is relative to the directory specified by the `extensionPath` option.
+When defining UI extensions in the `compileUiExtensions()` function, you must specify at least one providers file. 
+This is done by passing an array of file paths, where each file path is relative to the directory specified by the `extensionPath` option.
 
 
 ```ts title="src/vendure-config.ts"
 ```ts title="src/vendure-config.ts"
 import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
 import { compileUiExtensions } from '@vendure/ui-devkit/compiler';
@@ -207,6 +240,9 @@ import * as path from 'path';
 compileUiExtensions({
 compileUiExtensions({
     outputPath: path.join(__dirname, '../admin-ui'),
     outputPath: path.join(__dirname, '../admin-ui'),
     extensions: [
     extensions: [
+        // Note: this object will usually be 
+        // found in the `ui` static property
+        // of a plugin like `MyPlugin.ui`.
         {
         {
             id: 'test-extension',
             id: 'test-extension',
             extensionPath: path.join(__dirname, 'plugins/my-plugin/ui'),
             extensionPath: path.join(__dirname, 'plugins/my-plugin/ui'),