mirror of https://github.com/rancher/dashboard.git
115 lines
4.8 KiB
Markdown
115 lines
4.8 KiB
Markdown
# Create a page in an existing product
|
|
|
|
Given that you have covered all of the topics in [Extensions API](../api/overview.md), especially the [Navigation & Pages](../api/nav/products.md) area, we will show an example of how you can create an extension that adds a new page to an existing product `Fleet`. This doesn't need any product registration.
|
|
|
|
> To do this in other areas/products of the Rancher UI, simply take a look at the routing structure in the browser url and don't forget to follow the same structure.
|
|
|
|
> **CAVEAT:** In our docs we recommend following the routes pattern of `product-c-cluster-resource` for top-level products and `c-cluster-product-resource` for cluster-level products, but you may find that some top-level products like `Fleet` do follow a `c-cluster-product-resource`. While the route structure is not mandatory right now, it's a guideline that has proven to be important for developers when following the documentation so that they associate different products with different route structures.
|
|
|
|
Taking `Fleet` as an example, let's dive into the code for `index.ts` entry for an extension:
|
|
|
|
```ts
|
|
// ./index.ts
|
|
import { importTypes } from '@rancher/auto-import';
|
|
import { IPlugin } from '@shell/core/types';
|
|
import extensionRouting from './routing/extension-routing';
|
|
|
|
// Init the package
|
|
export default function(plugin: IPlugin) {
|
|
// Auto-import model, detail, edit from the folders
|
|
importTypes(plugin);
|
|
|
|
// Provide extension metadata from package.json
|
|
// it will grab information such as `name` and `description`
|
|
plugin.metadata = require('./package.json');
|
|
|
|
// Load a product
|
|
plugin.addProduct(require('./product'));
|
|
|
|
// Add Vue Routes
|
|
plugin.addRoutes(extensionRouting);
|
|
}
|
|
```
|
|
|
|
The following `product.ts` config is expanding on the product definition in [shell/config/product/fleet](https://github.com/rancher/dashboard/blob/master/shell/config/product/fleet.js) and is where we define the "pages/views" we want to add taking into account the route structure of `Fleet`:
|
|
|
|
```ts
|
|
// ./product.ts
|
|
import { IPlugin } from '@shell/core/types';
|
|
|
|
// this is the definition of a "blank cluster" for Rancher Dashboard
|
|
// definition of a "blank cluster" in Rancher Dashboard
|
|
const BLANK_CLUSTER = '_';
|
|
|
|
|
|
export function init($plugin: IPlugin, store: any) {
|
|
const FLEET_PROD_NAME = 'fleet';
|
|
const YOUR_K8S_RESOURCE_NAME = 'provisioning.cattle.io.cluster';
|
|
const CUSTOM_PAGE_NAME = 'page1';
|
|
|
|
const {
|
|
configureType,
|
|
virtualType,
|
|
basicType
|
|
} = $plugin.DSL(store, FLEET_PROD_NAME);
|
|
|
|
// creating a custom page
|
|
virtualType({
|
|
labelKey: 'some.translation.key',
|
|
name: CUSTOM_PAGE_NAME,
|
|
route: {
|
|
name: `c-cluster-${ FLEET_PROD_NAME }-${ CUSTOM_PAGE_NAME }`,
|
|
params: {
|
|
product: FLEET_PROD_NAME,
|
|
cluster: BLANK_CLUSTER
|
|
}
|
|
}
|
|
});
|
|
|
|
// registering the defined pages as side-menu entries
|
|
basicType([YOUR_K8S_RESOURCE_NAME, CUSTOM_PAGE_NAME]);
|
|
}
|
|
```
|
|
|
|
If the routes follow the same rules for a top-level product like `Fleet` (`c-cluster-product-resource`), then you just need to follow the same route name notation and replace the product name for `fleet`.
|
|
|
|
The `/routing/extension-routing.ts` needs to follow the same route name principle, such as:
|
|
|
|
```ts
|
|
// ./routing/extension-routing.ts
|
|
// definition of a "blank cluster" in Rancher Dashboard
|
|
const BLANK_CLUSTER = '_';
|
|
|
|
import MyCustomPage from '../pages/myCustomPage.vue';
|
|
import ListResource from '@shell/pages/c/_cluster/_product/_resource/index.vue';
|
|
import CreateResource from '@shell/pages/c/_cluster/_product/_resource/create.vue';
|
|
import ViewResource from '@shell/pages/c/_cluster/_product/_resource/_id.vue';
|
|
import ViewNamespacedResource from '@shell/pages/c/_cluster/_product/_resource/_namespace/_id.vue';
|
|
|
|
// to achieve naming consistency throughout the extension
|
|
// we recommend this to be defined on a config file and exported
|
|
// so that the developer can import it wherever it needs to be used
|
|
const FLEET_PROD_NAME = 'fleet';
|
|
const CUSTOM_PAGE_NAME = 'page1';
|
|
|
|
const routes = [
|
|
// this covers the "custom page"
|
|
{
|
|
name: `c-cluster-${ FLEET_PROD_NAME }-${ CUSTOM_PAGE_NAME }`,
|
|
path: `/c/:cluster/${ FLEET_PROD_NAME }/${ CUSTOM_PAGE_NAME }`,
|
|
component: MyCustomPage,
|
|
meta: {
|
|
product: FLEET_PROD_NAME,
|
|
cluster: BLANK_CLUSTER
|
|
},
|
|
}
|
|
];
|
|
|
|
export default routes;
|
|
```
|
|
|
|
And with the above routing, you have successfully registered a new custom and route inside the `Fleet` product.
|
|
|
|
This will also work for `Cluster-level products` like `apps`, but remember that to change that product name and follow the correct notation for a cluster-level product `c-cluster-product-resource` like these [examples](../api/nav/routing.md#cluster-level-product---adding-your-defined-routes-to-vue-router).
|
|
|
|
With this tool, you can extend a lot of the Rancher UI and tailor it to suit your needs. |