カスタム操作ボタンを作る

NocoBase では、操作(Action)はブロック内のボタンで、ビジネスロジックをトリガーします。例えば「新規作成」「編集」「削除」などです。この例では ActionModel を使ってカスタム操作ボタンを作り、ActionSceneEnum でボタンの表示シーンを制御する方法を示します。

前提知識

以下の内容を事前に理解しておくと、開発がスムーズになります:

最終的な効果

3つのカスタム操作ボタンを作ります。それぞれ3つの操作シーンに対応します:

  • データテーブルレベル操作collection)— ブロック上部の操作バーに表示(「新規作成」ボタンの横など)
  • レコードレベル操作record)— テーブル各行の操作列に表示(「編集」「削除」の横など)
  • 両方に対応both)— 両方のシーンに表示

完全なソースコードは @nocobase-example/plugin-simple-action を参照してください。ローカルで動作確認したい場合:

yarn pm enable @nocobase-example/plugin-simple-action

以下、ゼロからこのプラグインを構築していきます。

ステップ1:プラグインスケルトンの作成

リポジトリのルートで実行します:

yarn pm create @my-project/plugin-simple-action

詳しくははじめてのプラグインを書くをご覧ください。

ステップ2:操作モデルの作成

各操作は表示シーンの宣言が必要で、static scene プロパティで指定します:

シーン説明
collectionActionSceneEnum.collectionデータテーブルに対する操作(「新規作成」ボタンなど)
recordActionSceneEnum.record単一レコードに対する操作(「編集」「削除」ボタンなど)
bothActionSceneEnum.both両方のシーンで使用可能

データテーブルレベル操作

src/client-v2/models/SimpleCollectionActionModel.tsx を新規作成:

// src/client-v2/models/SimpleCollectionActionModel.tsx
import { ActionModel, ActionSceneEnum } from '@nocobase/client-v2';
import { ButtonProps } from 'antd';
import { tExpr } from '../locale';

export class SimpleCollectionActionModel extends ActionModel {
  static scene = ActionSceneEnum.collection;

  defaultProps: ButtonProps = {
    children: tExpr('Simple collection action'),
  };
}

SimpleCollectionActionModel.define({
  label: tExpr('Simple collection action'),
});

// registerFlow でクリックイベントをリッスンし、ctx.message でユーザーにフィードバック
SimpleCollectionActionModel.registerFlow({
  key: 'clickFlow',
  title: tExpr('Simple collection action'),
  on: 'click',
  steps: {
    showMessage: {
      async handler(ctx) {
        ctx.message.success(ctx.t('Collection action clicked'));
      },
    },
  },
});

レコードレベル操作

src/client-v2/models/SimpleRecordActionModel.tsx を新規作成:

// src/client-v2/models/SimpleRecordActionModel.tsx
import { ActionModel, ActionSceneEnum } from '@nocobase/client-v2';
import { ButtonProps } from 'antd';
import { tExpr } from '../locale';

export class SimpleRecordActionModel extends ActionModel {
  static scene = ActionSceneEnum.record;

  defaultProps: ButtonProps = {
    children: tExpr('Simple record action'),
  };
}

SimpleRecordActionModel.define({
  label: tExpr('Simple record action'),
});

// レコードレベル操作では ctx.model.context から現在の行のデータとインデックスを取得可能
SimpleRecordActionModel.registerFlow({
  key: 'clickFlow',
  title: tExpr('Simple record action'),
  on: 'click',
  steps: {
    showMessage: {
      async handler(ctx) {
        const index = ctx.model.context.recordIndex;
        const record = ctx.model.context.record;
        const id = record?.id;
        ctx.message.info(ctx.t('Record action clicked, record ID: {{id}}, row index: {{index}}', { id, index }));
      },
    },
  },
});

両方のシーンに対応

src/client-v2/models/SimpleBothActionModel.tsx を新規作成:

// src/client-v2/models/SimpleBothActionModel.tsx
import { ActionModel, ActionSceneEnum } from '@nocobase/client-v2';
import { ButtonProps } from 'antd';
import { tExpr } from '../locale';

export class SimpleBothActionModel extends ActionModel {
  static scene = ActionSceneEnum.both;

  defaultProps: ButtonProps = {
    children: tExpr('Simple both action'),
  };
}

SimpleBothActionModel.define({
  label: tExpr('Simple both action'),
});

SimpleBothActionModel.registerFlow({
  key: 'clickFlow',
  title: tExpr('Simple both action'),
  on: 'click',
  steps: {
    showMessage: {
      async handler(ctx) {
        ctx.message.info(ctx.t('Both action clicked'));
      },
    },
  },
});

3つの書き方の構造は同じです。違いは static scene の値とボタンのテキストだけです。各ボタンは registerFlow({ on: 'click' }) でクリックイベントをリッスンし、ctx.message でメッセージを表示して、ボタンが正しく動作していることをユーザーが確認できるようにしています。

ステップ3:多言語ファイルの追加

プラグインの src/locale/ 配下の翻訳ファイルを編集します:

// src/locale/zh-CN.json
{
  "Simple collection action": "简单数据表操作",
  "Simple record action": "简单记录操作",
  "Simple both action": "简单通用操作",
  "Collection action clicked": "数据表操作被点击了",
  "Record action clicked, record ID: {{id}}, row index: {{index}}": "记录操作被点击了,记录 ID:{{id}},行索引:{{index}}",
  "Both action clicked": "通用操作被点击了"
}
// src/locale/en-US.json
{
  "Simple collection action": "Simple collection action",
  "Simple record action": "Simple record action",
  "Simple both action": "Simple both action",
  "Collection action clicked": "Collection action clicked",
  "Record action clicked, record ID: {{id}}, row index: {{index}}": "Record action clicked, record ID: {{id}}, row index: {{index}}",
  "Both action clicked": "Both action clicked"
}
注意

初めて言語ファイルを追加した場合、アプリの再起動が必要です。

翻訳ファイルの書き方と tExpr() のその他の使い方については、i18n 国際化をご覧ください。

ステップ4:プラグインへの登録

src/client-v2/plugin.tsx を編集し、registerModelLoaders で遅延読み込み登録します:

// src/client-v2/plugin.tsx
import { Plugin } from '@nocobase/client-v2';

export class PluginSimpleActionClient extends Plugin {
  async load() {
    this.flowEngine.registerModelLoaders({
      SimpleCollectionActionModel: {
        loader: () => import('./models/SimpleCollectionActionModel'),
      },
      SimpleRecordActionModel: {
        loader: () => import('./models/SimpleRecordActionModel'),
      },
      SimpleBothActionModel: {
        loader: () => import('./models/SimpleBothActionModel'),
      },
    });
  }
}

export default PluginSimpleActionClient;

ステップ5:プラグインの有効化

yarn pm enable @my-project/plugin-simple-action

有効化すると、テーブルブロックの「操作の設定」からこれらのカスタム操作ボタンを追加できます。

完全なソースコード

まとめ

この例で使用した機能:

機能使い方ドキュメント
操作ボタンActionModel + static sceneFlowEngine → 操作拡張
操作シーンActionSceneEnum.collection / record / both / allFlowEngine → 操作拡張
メニュー登録define({ label })FlowEngine 概要
モデル登録this.flowEngine.registerModelLoaders()Plugin プラグイン
遅延翻訳tExpr()i18n 国際化

関連リンク