import { Component } from 'vue';
import { AnTableContext } from '../components/Table';
import { TableUseOptions } from './useTable';
import { TableColumn } from './useTableColumn';
import { useTableRefresh } from '../plugins/useTableRefresh';
import { useColumnConfig } from '../plugins/useTableConfig';
import { useRowFormat } from '../plugins/useRowFormat';
import { useRowDelete } from '../plugins/useRowDelete';
import { useRowModify } from '../plugins/useRowModify';
export interface AnTablePlugin {
/**
* 插件ID(唯一)
* @example
* ```ts
* 'refresh'
* ```
*/
id: string;
/**
* 提供给其他插件使用的变量
* @example
* ```ts
* { isOk: true }
* ```
*/
provide?: Recordable;
/**
* 在表格组件的 `setup` 函数中调用
*/
onSetup?: (context: AnTableContext) => void;
/**
* 钩子
*/
options?: (options: TableUseOptions) => TableUseOptions | null | undefined | void;
/**
* 解析参数之前调用
*/
parse?: (options: TableUseOptions) => TableUseOptions | null | undefined | void;
/**
* 解析参数之后调用
*/
parsed?: (options: any) => any;
/**
* 表格列
*/
column?: (column: TableColumn) => TableColumn;
/**
* 添加部件栏组件
* @example
* ```tsx
* () =>
* ```
*/
widget?: () => (props: any) => any | Component;
/**
* 添加操作栏组件
* @example
* ```tsx
* () =>
* ```
*/
action?: () => (props: any) => any | Component;
onSearch?: (search: Recordable) => any[] | { data: any[]; total: number };
onLoad?: (search: Recordable) => void;
onLoaded?: (res: any) => void;
onLoadOk?: (res: any) => void;
onLoadFail?: (e: any) => void;
}
const callHookWithData = async (name: string, plugins: AnTablePlugin[], data?: any) => {
for (const plugin of plugins) {
data = (await (plugin as any)[name]?.(data)) ?? data;
}
return data;
};
const callHookFirst = async (name: string, plugins: AnTablePlugin[], ...args: any[]) => {
for (const plugin of plugins) {
const data = await (plugin as any)[name]?.(...args);
if (data) {
return data;
}
}
return null;
};
export class PluginContainer {
actions: any[] = [];
widgets: any[] = [];
constructor(private plugins: AnTablePlugin[]) {
this.plugins.unshift(useTableRefresh(), useRowFormat(), useRowDelete(), useRowModify());
for (const plugin of plugins) {
const action = plugin.action?.();
if (action) {
this.actions.push(action);
}
const widget = plugin.widget?.();
if (widget) {
this.widgets.push(widget);
}
}
}
callSetupHook(context: AnTableContext) {
for (const plugin of this.plugins) {
plugin.onSetup?.(context);
}
}
callOptionsHook(options: any) {
for (const plugin of this.plugins) {
options = plugin.options?.(options) ?? options;
}
return options;
}
callActionHook(options: any) {
for (const plugin of this.plugins) {
options = plugin.options?.(options) ?? options;
}
return options;
}
callWidgetHook(options: any) {
for (const plugin of this.plugins) {
options = plugin.options?.(options) ?? options;
}
return options;
}
callLoadHook(data: any[] | ((...args: any[]) => Promise | any), params: Recordable) {
return callHookFirst('onLoad', this.plugins, data, params);
}
callLoadedHook(res: any) {
return callHookWithData('onLoaded', this.plugins, res);
}
callLoadOkHook(res: any) {
return callHookWithData('onLoadOk', this.plugins, res);
}
callLoadFailHook(res: any) {
return callHookWithData('onLoadFail', this.plugins, res);
}
}