docs/docs/en/plugin-samples/schema-initializer/action-simple.md
NocoBase has many Configure actions buttons for adding action buttons to the interface.
If the existing action buttons do not meet our requirements, we need to add sub-items to the existing Configure actions to create new action buttons.
Simple Action in the title refers to Actions that do not require a modal. You can refer to Adding Action with Modal.
This example will create a button that opens the corresponding block's documentation when clicked, and add this button to the Configure actions in Table, Details, and Form blocks.
The complete example code for this document can be found in plugin-samples.
<video width="100%" controls=""> <source src="https://static-docs.nocobase.com/20240522-185359.mp4" type="video/mp4" /> </video>Following the Write Your First Plugin documentation, if you don't have a project yet, you can create one first. If you already have one or have cloned the source code, you can skip this step.
yarn create nocobase-app my-nocobase-app -d postgres
cd my-nocobase-app
yarn install
yarn nocobase install
Then initialize a plugin and add it to the system:
yarn pm create @nocobase-sample/plugin-initializer-action-simple
yarn pm enable @nocobase-sample/plugin-initializer-action-simple
Then start the project:
yarn dev
After logging in, visit http://localhost:13000/admin/pm/list/local/ to see that the plugin has been installed and enabled.
Before implementing this example, we need to understand some basic knowledge:
.
├── client # Client plugin
│ ├── initializer # Initializer
│ ├── index.tsx # Client plugin entry
│ ├── locale.ts # Multi-language utility function
│ ├── constants.ts # Constants
│ ├── schema # Schema
│ └── settings # Schema Settings
├── locale # Multi-language files
│ ├── en-US.json # English
│ └── zh-CN.json # Chinese
├── index.ts # Server plugin entry
└── server # Server plugin
First, we need to define the action name, which will be used in various places.
We create packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/constants.ts:
export const ActionName = 'Document';
export const ActionNameLowercase = ActionName.toLowerCase();
NocoBase's dynamic pages are all rendered through Schema, so we need to define a Schema, which will be used later to add to the interface. Before implementing this section, we need to understand some basic knowledge:
We create packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/schema/index.ts file with the following content:
import { useFieldSchema } from '@formily/react';
import { ISchema } from "@nocobase/client"
import { useT } from '../locale';
import { ActionName } from '../constants';
export function useDocumentActionProps() {
const fieldSchema = useFieldSchema();
const t = useT();
return {
title: t(ActionName),
type: 'primary',
onClick() {
window.open(fieldSchema['x-doc-url'])
}
}
}
export const createDocumentActionSchema = (blockComponent: string): ISchema & { 'x-doc-url': string } => {
return {
type: 'void',
'x-component': 'Action',
'x-doc-url': `https://client.docs.nocobase.com/components/${blockComponent}`,
'x-use-component-props': 'useDocumentActionProps',
}
}
The createDocumentActionSchema component accepts a blockComponent parameter and returns a Schema, which is used to add a button to the interface that opens the corresponding block's documentation when clicked.
createDocumentActionSchema:
type: Type, here it is void, indicating a pure UI componentx-component: 'Action': Action component used to generate a buttontitle: 'Document': Button titlex-doc-url: Custom Schema property representing the documentation addressx-use-component-props: 'useDocumentActionProps': Dynamic properties, for more information refer to the documentationuseDocumentActionProps():
type: 'primary': Button typeonClick: Click event to open the corresponding block's documentationFor more information about Schema, please refer to the UI Schema documentation.
We need to register useDocumentActionProps to the system, so that x-use-component-props can find the corresponding scope.
import { useDocumentActionProps } from './schema';
import { Plugin } from '@nocobase/client';
export class PluginInitializerActionSimpleClient extends Plugin {
async load() {
this.app.addScopes({ useDocumentActionProps });
}
}
export default PluginInitializerActionSimpleClient;
There are 2 ways to verify Schema:
yarn doc plugins/@nocobase-sample/plugin-initializer-action-modal, and verify if it meets the requirements by writing documentation examples (TODO)We use temporary page verification as an example. We create a new page and add one or more examples according to property parameters to check if they meet the requirements.
import { Plugin, SchemaComponent } from '@nocobase/client';
import { createDocumentActionSchema, useDocumentActionProps } from './schema';
import React from 'react';
export class PluginInitializerActionSimpleClient extends Plugin {
async load() {
this.app.addScopes({ useDocumentActionProps });
this.app.router.add('admin.document-action-schema', {
path: '/admin/document-action-schema',
Component: () => {
return <>
<div style={{ marginTop: 20, marginBottom: 20 }}>
<SchemaComponent schema={{ properties: { test1: createDocumentActionSchema('table-v2') } }} />
</div>
<div style={{ marginTop: 20, marginBottom: 20 }}>
<SchemaComponent schema={{ properties: { test2: createDocumentActionSchema('details') } }} />
</div>
</>
}
})
}
}
export default PluginInitializerActionSimpleClient;
Then we visit http://localhost:13000/admin/document-action-schema to see the temporary page we added.
For detailed explanation of SchemaComponent, please refer to the SchemaComponent documentation.
<video controls width='100%' src="https://static-docs.nocobase.com/20240526171318_rec_.mp4"></video>
After verification, the test page needs to be deleted.
We create packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/initializer/index.ts file:
import { SchemaInitializerItemType, useSchemaInitializer } from "@nocobase/client"
import { createDocumentActionSchema } from '../schema';
import { ActionNameLowercase, ActionName } from "../constants";
import { useT } from "../locale";
export const createDocumentActionInitializerItem = (blockComponent: string): SchemaInitializerItemType => ({
type: 'item',
name: ActionNameLowercase,
useComponentProps() {
const { insert } = useSchemaInitializer();
const t = useT();
return {
title: t(ActionName),
onClick: () => {
insert(createDocumentActionSchema(blockComponent));
},
};
},
})
Because we need to generate different DocumentAction based on different blockComponent, we defined a createDocumentActionInitializerItem function to generate the corresponding Schema Initializer Item.
type: Type, here it is item, indicating a text with a click event that can insert a new Schema when clickedname: Unique identifier used to distinguish different Schema Items and CRUD operationsuseComponentProps: Returns an object containing title and onClick properties, title is the displayed text, onClick is the callback function after clickingSchemaInitializerContext context, which contains some operation methodsFor more information about Schema Item definitions, please refer to the Schema Initializer Item documentation.
Currently, after adding through createDocumentActionInitializerItem(), it cannot be deleted. We can use Schema Settings to set it.
We create packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/settings/index.ts file:
import { SchemaSettings } from "@nocobase/client";
import { ActionNameLowercase } from "../constants";
export const documentActionSettings = new SchemaSettings({
name: `actionSettings:${ActionNameLowercase}`,
items: [
{
name: 'remove',
type: 'remove',
}
]
});
import { Plugin } from '@nocobase/client';
import { useDocumentActionProps } from './schema';
+ import { documentActionSettings } from './settings';
export class PluginInitializerActionSimpleClient extends Plugin {
async load() {
this.app.addScopes({ useDocumentActionProps });
+ this.app.schemaSettingsManager.add(documentActionSettings);
}
}
export default PluginInitializerActionSimpleClient;
We modify the createDocumentActionSchema in packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/schema/index.ts file:
+ import { documentActionSettings } from '../settings';
export const createDocumentActionSchema = (blockComponent: string): ISchema & { 'x-doc-url': string } => {
return {
type: 'void',
'x-component': 'Action',
+ 'x-settings': documentActionSettings.name,
// ...
}
}
There are many Configure actions buttons in the system, but their names are different. We need to add it to the Configure actions in Table, Details, and Form blocks according to our needs.
First, let's find the corresponding name:
TODO
Then we modify packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/client/index.tsx file:
import { Plugin } from '@nocobase/client';
import { useDocumentActionProps } from './schema';
import { documentActionSettings } from './settings';
+ import { createDocumentActionInitializerItem } from './initializer';
export class PluginInitializerActionSimpleClient extends Plugin {
async load() {
this.app.addScopes({ useDocumentActionProps });
this.app.schemaSettingsManager.add(documentActionSettings);
+ this.app.schemaInitializerManager.addItem('table:configureActions', 'document', createDocumentActionInitializerItem('table-v2'));
+ this.app.schemaInitializerManager.addItem('details:configureActions', 'document', createDocumentActionInitializerItem('details'));
+ this.app.schemaInitializerManager.addItem('createForm:configureActions', 'document', createDocumentActionInitializerItem('form-v2'));
}
}
export default PluginInitializerActionSimpleClient;
:::warning After multi-language files are changed, you need to restart the service for them to take effect :::
We edit packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/locale/en-US.json with the following content:
{
"Document": "Document"
}
We edit packages/plugins/@nocobase-sample/plugin-initializer-action-simple/src/locale/zh-CN.json with the following content:
{
"Document": "文档"
}
If you need more multi-language support, you can continue to add them.
We can add multiple languages through http://localhost:13000/admin/settings/system-settings, and switch languages in the upper right corner.
According to the Build and Package Plugin documentation, we can package the plugin and upload it to the production environment.
If you cloned the source code, you need to execute a full build first to build the plugin's dependencies as well.
yarn build
If you used create-nocobase-app to create the project, you can directly execute:
yarn build @nocobase-sample/plugin-initializer-action-simple --tar
This way you can see the storage/tar/@nocobase-sample/plugin-initializer-action-simple.tar.gz file, and then install it by uploading.