/* eslint-disable-next-line @typescript-eslint/no-unused-vars */ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { isJSExpression, getDataSourceItemSetter, mockProTableRow, mockId, uuid, } from '../utils/index'; import { actionColumnField, buttonGroupConfigureProp } from './actionColumn'; const showFixedHeight = (target) => { const { autoHeight } = target.parent.getPropValue('scroll'); return autoHeight; }; const showScrollToFirstRowOnChange = (target) => { const { scrollAuto } = target.parent.getPropValue('scroll'); return scrollAuto; }; const positiveIntegerSetter = { componentName: 'NumberSetter', props: { max: 200, min: 1, }, }; const scrollSetValue = (field, value, type) => { const { node } = field; node.setPropValue('scroll', { ...node.getPropValue('scroll'), [type]: value, }); }; const ProTableMeta: IPublicTypeComponentMetadata = { componentName: 'ProTable', group: '精选组件', category: '表格类', title: 'ProTable', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: 'yl-ssa-lowcode-antd-comps', version: '0.1.1', exportName: 'ProTable', main: 'src\\index.tsx', destructuring: true, subName: '', }, configure: { props: [ { name: 'tableStyle', title: '表格样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'tableStyle', title: { label: '样式设置', tip: 'tableStyle | 表格样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { title: { label: { type: 'i18n', 'en-US': 'columns', 'zh-CN': '表格列', }, }, name: 'columns', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { title: { label: { type: 'i18n', 'en-US': 'title', 'zh-CN': 'title', }, }, name: 'title', setter: { componentName: 'StringSetter', isRequired: true, initialValue: '', }, }, { name: 'formatType', title: '数据类型', display: 'inline', initialValue: 'text', isRequired: true, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'text', title: '文本' }, { value: 'dateTime', title: '时间' }, { value: 'percent', title: '百分比' }, { value: 'progress', title: '进度条' }, { value: 'tag', title: '标签' }, { value: 'link', title: '链接' }, { value: 'selete', title: '下拉选' }, ], }, }, }, { name: 'formatOptions', title: '时间格式', display: 'inline', defaultValue: 'YYYY-MM-DD HH:mm:ss', condition: (target) => { return target.parent.getPropValue('formatType') === 'dateTime'; }, getValue: (target, value) => { return value; }, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'YYYY-MM-DD HH:mm:ss', title: '年-月-日 时:分:秒' }, { value: 'YYYY-MM-DD HH:mm', title: '年-月-日 时:分' }, { value: 'YYYY-MM-DD', title: '年-月-日' }, { value: 'YYYY-MM', title: '年-月' }, { value: 'YYYY', title: '年' }, ], }, }, }, { name: 'progressColor', title: '进度条配色', display: 'inline', defaultValue: '', condition: (target) => { return target.parent.getPropValue('formatType') === 'progress'; }, getValue: (target, value) => { return value; }, setter: { componentName: 'ColorSetter', }, }, { name: 'tagsColor', title: '标签配色', display: 'inline', defaultValue: 'magenta', condition: (target) => { return target.parent.getPropValue('formatType') === 'tag'; }, getValue: (target, value) => { return value; }, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'magenta', title: 'magenta' }, { value: 'red', title: 'red' }, { value: 'volcano', title: 'volcano' }, { value: 'orange', title: 'orange' }, { value: 'gold', title: 'gold' }, { value: 'lime', title: 'lime' }, { value: 'green', title: 'green' }, { value: 'cyan', title: 'cyan' }, { value: 'blue', title: 'blue' }, { value: 'geekblue', title: 'geekblue' }, { value: 'purple', title: 'purple' }, ], }, }, }, { name: 'dataIndex', title: '数据字段', display: 'inline', initialValue: (currentValue, defaultValue) => currentValue || defaultValue || `data-${uuid()}`, setter: 'StringSetter', }, { title: { label: { type: 'i18n', 'en-US': 'state', 'zh-CN': '自定义节点配置', }, }, name: 'fieldNames', extraProps: { display: 'accordion', defaultCollapsed: false, }, condition: (target) => { return target.parent.getPropValue('formatType') === 'selete'; }, getValue: (target, value) => { return value; }, setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'treeData', title: { label: '数据源', tip: '数据源' }, setter: { componentName: 'JsonSetter', isRequired: true, initialValue: [ { label: 'parent 0', value: '0-0', children: [ { label: 'leaf 0-0', value: '0-0-0', isLeaf: true }, { label: 'leaf 0-1', value: '0-0-1', isLeaf: true }, ], }, { label: 'parent 1', value: '0-1', children: [ { label: 'leaf 1-0', value: '0-1-0', isLeaf: true }, { label: 'leaf 1-1', value: '0-1-1', isLeaf: true }, ], }, ], }, }, { title: { label: { type: 'i18n', 'en-US': 'label', 'zh-CN': 'label', }, }, name: 'label', setter: { componentName: 'StringSetter', isRequired: true, initialValue: 'label', }, }, { title: { label: { type: 'i18n', 'en-US': 'value', 'zh-CN': 'value', }, }, name: 'value', setter: { componentName: 'StringSetter', isRequired: true, initialValue: 'value', }, }, { title: { label: { type: 'i18n', 'en-US': 'children', 'zh-CN': 'children', }, }, name: 'children', setter: { componentName: 'StringSetter', isRequired: true, initialValue: 'children', }, }, ], }, }, }, }, { name: 'align', title: '对齐方式', display: 'inline', initialValue: 'left', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'left', title: '居左', }, { value: 'center', title: '居中', }, { value: 'right', title: '居右', }, ], }, }, }, { name: 'fixed', title: '锁列', display: 'inline', initialValue: 'none', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左侧', value: 'left', tip: 'left', }, { title: '不锁', value: 'none', tip: 'none', }, { title: '右侧', value: 'right', tip: 'right', }, ], // compact: false, }, }, }, { type: 'field', name: 'width', title: '宽度', extraProps: { display: 'inline', defaultValue: 120, }, setter: { componentName: 'NumberSetter', props: { units: 'px', }, }, }, { name: 'render', title: { label: '自定义渲染', tip: 'render | 插槽内的物料表达式可通过this.record获取当前行数据,this.index获取索引', }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '单元格插槽', initialValue: { type: 'JSSlot', params: ['text', 'record', 'index'], value: [], }, }, 'VariableSetter', ], }, { name: 'sorter', title: { label: 'sorter', tip: '排序函数', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'onTableChange(a,b){\n\n}', }, }, ], }, { name: 'ellipsis', title: '超出自动省略', setter: 'BoolSetter', }, { name: 'copyShow', title: '是否复制', setter: 'BoolSetter', }, ], extraSetter: { componentName: 'MixedSetter', isRequired: false, props: {}, }, }, }, initialValue: () => { return { title: '列标题', formatType: 'text', dataIndex: `data-${uuid()}`, width: 200, hidden: false, key: `key-${uuid()}`, }; }, }, }, isRequired: true, initialValue: [], }, }, { title: { label: '表格列数据导入', }, display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'columnsJson', title: { label: '表格数据', tip: '第一次导入后,后续就不要修改了,否则会继续添加,可以清空', }, setter: 'TextAreaSetter', }, { name: 'columnsJsonShow', title: { label: '是否导入', tip: 'true导入columnsJson数据到columns,false清除columnsJson数据', }, setter: 'BoolSetter', getValue: (target, value) => { return value; }, setValue: (field, value) => { const { node } = field; if (value) { // 确定导入数据到columns中 const stringJson = node.getPropValue('columnsJson'); // 目标值: // 【 // const json =`{ // "appId": "", // 配置appid // "applicationName": "", // 应用名称` // 】 // 期望值 // 【 // [ // { name: "appId", title: "配置appid" }, // { name: "applicationName", title: "应用名称" }, // ] // 】 if (stringJson.replace(/\s+/g, '')) { // 提取字段和注释的正则表达式 const fieldRegex = /"(\w+)":\s*[^,}]+(?:,\s*\/\/\s*(.*))?/g; let match; const result: any = []; // 遍历所有匹配的字段和注释 /* eslint-disable no-cond-assign */ while ((match = fieldRegex.exec(stringJson)) !== null) { const key = match[1]; const title = match[2] ? match[2].trim() : ''; result.push({ dataIndex: key, title, formatType: 'text', width: 200, hidden: false, key: `key-${uuid()}`, }); } if (result.length > 0) { node.setPropValue('columns', [...node.getPropValue('columns'), ...result]); } } } else { // 清除 node.setPropValue('columnsJson', ''); } }, }, ], }, { name: 'dataSource', title: '表格数据源', display: 'accordion', setter: (target) => { const columns = target.getProps().getPropValue('columns'); if (!columns || isJSExpression(columns)) { return { componentName: 'ExpressionSetter', }; } const mockRow = mockProTableRow(columns); const primaryKey = target.getProps().getPropValue('primaryKey') || 'id'; const items = columns.map((column, index) => { return { title: { label: { type: 'i18n', 'en-US': column.dataIndex, 'zh-CN': column.title, }, }, name: column.dataIndex, important: index < 2, setter: getDataSourceItemSetter(column.formatType), defaultValue: mockRow[column.dataIndex], }; }); return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items, }, }, initialValue: () => { return { ...mockRow, [primaryKey]: mockId(), }; }, }, }, }, 'ExpressionSetter', ], }, }; }, }, { ...actionColumnField, name: 'actionColumnProps', title: '操作列', }, { ...buttonGroupConfigureProp, name: 'actionBarButtons', title: '操作栏按钮', }, { name: 'paginationProps', title: '分页器', extraProps: { display: 'accordion', defaultCollapsed: true, }, setter: { componentName: 'ObjectSetter', display: 'inline', props: { config: { items: [ { name: 'hidden', title: '关闭分页', setter: 'BoolSetter', }, { name: 'showTotal', title: { label: '数量总数', tip: 'showTotal | 数量总数' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'showTotal(total,range){\n// 设置数量总数\nreturn `${range[0]}-${range[1]} of ${total}`;\n}', }, }, 'VariableSetter', ], }, { name: 'showQuickJumper', title: '跳转设置', setter: 'BoolSetter', }, { name: 'textAlign', title: '对齐方式', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左侧', value: 'bottomLeft ', tip: 'bottomLeft ', }, { title: '居中', value: 'bottomCenter ', tip: 'bottomCenter', }, { title: '右侧', value: 'bottomRight', tip: 'bottomRight', }, ], }, }, }, { name: 'total', title: '总数', setter: [ { componentName: 'NumberSetter', props: { min: 0, }, }, 'StringSetter', ], hidden() { return !this.parent.getParam('hidden').getValue(); }, }, { name: 'current', title: '当前页', setter: [positiveIntegerSetter, 'StringSetter'], }, { name: 'pageSize', title: '每页行数', setter: [ { componentName: 'SelectSetter', initialValue: 10, props: { options: [ { title: '5', value: 5, }, { title: '10', value: 10, }, { title: '20', value: 20, }, { title: '50', value: 50, }, ], }, }, positiveIntegerSetter, ], }, ], }, }, }, }, { title: '滚动', display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'scrollAuto', title: { label: '自动滚动', tip: 'scrollAuto | 是否自动滚动到表格顶部', }, propType: 'bool', setter: 'BoolSetter', getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.scrollAuto; }, setValue: (field, value) => { scrollSetValue(field, value, 'scrollAuto'); }, }, { name: 'scrollbarWidth', title: '滚动条高度', condition: (target) => { return showScrollToFirstRowOnChange(target); }, setter: { componentName: 'NumberSetter', props: {}, }, getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.scrollbarWidth || undefined; }, setValue: (field, value) => { scrollSetValue(field, value, 'scrollbarWidth'); }, }, { name: 'autoWidth', title: '宽度自适应', condition: (target) => { return showScrollToFirstRowOnChange(target); }, setter: 'BoolSetter', getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.autoWidth; }, setValue: (field, value) => { scrollSetValue(field, value, 'autoWidth'); }, }, { name: 'autoHeight', title: '高度自适应', setter: 'BoolSetter', condition: (target) => { return showScrollToFirstRowOnChange(target); }, getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.autoHeight; }, setValue: (field, value) => { scrollSetValue(field, value, 'autoHeight'); }, }, { type: 'field', name: 'footHeight', title: { label: { type: 'i18n', zh_CN: '额外滚动补偿', }, tip: { type: 'i18n', zh_CN: '当高度自适应的时候,依旧出现滚动条时,再减去的距离', }, }, condition: (target) => { return showScrollToFirstRowOnChange(target) && showFixedHeight(target); }, setter: { componentName: 'NumberSetter', props: {}, }, getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.footHeight; }, setValue: (field, value) => { scrollSetValue(field, value, 'footHeight'); }, }, { type: 'field', name: 'fixedHeight', title: '高度', condition: (target) => { return !!showScrollToFirstRowOnChange(target) && !showFixedHeight(target); }, setter: { componentName: 'NumberSetter', props: { units: 'px', }, }, getValue: (target) => { const advanced = target.parent.getPropValue('scroll'); return advanced?.fixedHeight || undefined; }, setValue: (field, value) => { scrollSetValue(field, value, 'fixedHeight'); }, }, ], }, { title: '外观', display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'outline.settingButtons', title: '设置按钮', setter: 'BoolSetter', }, { name: 'outline.showHeader', title: { label: '显示表头', tip: 'showHeader | 是否显示表头' }, propType: 'bool', setter: 'BoolSetter', }, { title: '头部插槽', name: 'outline.headerSlot', setter: { componentName: 'SlotSetter', isRequired: true, initialValue: { type: 'JSSlot', value: [], }, }, }, { title: '头部右侧插槽', name: 'outline.rightSlot', setter: { componentName: 'SlotSetter', isRequired: true, initialValue: { type: 'JSSlot', value: [], }, }, }, { name: 'outline.bordered', title: { label: '显示边框', tip: 'bordered | 是否展示外边框和列边框', }, propType: 'bool', setter: 'BoolSetter', }, { name: 'outline.size', title: { label: '表格大小', tip: 'size | 表格大小' }, propType: { type: 'oneOf', value: ['default', 'middle', 'small'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], }, ], }, { title: { label: '自定义样式', tip: '注意:表格头的自定义样式' }, display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'customStyle.titleColor', title: { label: 'body文字颜色', tip: '设置表格文字颜色信息', }, propType: 'string', setter: 'ColorSetter', }, { name: 'customStyle.headerBorderRadius', title: { label: '圆角', tip: '设置表格头圆角信息,类似10px 10px 0 0', }, display: 'inline', setter: { componentName: 'StringSetter', props: {}, }, }, { name: 'customStyle.headerBackgroundColor', title: { label: '背景颜色', tip: '设置表格头背景颜色信息', }, propType: 'string', setter: 'ColorSetter', }, { name: 'customStyle.headerColor', title: { label: '文字颜色', tip: '设置表格头文字颜色信息', }, propType: 'string', setter: 'ColorSetter', }, ], }, { title: '高级', display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: false, }, items: [ { name: 'advanced.loading', title: '加载动画', setter: 'BoolSetter', }, { name: 'advanced.type', title: '选择模式', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '无', value: 'none', tip: 'none', }, { title: '多选', value: 'checkbox', tip: 'checkbox', }, { title: '单选', value: 'radio', tip: 'radio', }, ], }, }, }, { name: 'advanced.align', title: '列对齐', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左对齐', value: 'left', tip: 'left', }, { title: '居中', value: 'center', tip: 'center', }, { title: '右侧对齐', value: 'right', tip: 'right', }, ], }, }, }, ], }, { title: '表格行是否可选择', display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'rowSelection.rowKey', title: { label: '选中行Key', tip: '表格行 key 的取值,可以是字符串或一个函数', }, display: 'inline', setter: { componentName: 'StringSetter', props: {}, }, }, { name: 'rowSelection.selectedRowKeys', title: { label: '选中行Key', tip: 'rowSelection.selectedRowKeys | 指定选中项的 key 数组', }, display: 'inline', setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter'], }, }, }, ], }, { title: '行展开', display: 'block', type: 'group', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'expandable.expandedRowRender', title: { label: '展开行渲染', tip: 'expandable.expandedRowRender | 额外的展开行', }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '展开行插槽', initialValue: { type: 'JSSlot', params: ['record', 'index', 'indent', 'expanded'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'expandedRowRender(record,index,indent,expanded,${extParams}){\n// 展开行渲染\nreturn `${record.id}`}', }, }, 'VariableSetter', ], }, { name: 'expandable.iconShow', title: '图标显示', setter: 'BoolSetter', }, { name: 'expandable.expandRowByClick', title: '点击行来展开', setter: 'BoolSetter', }, { name: 'expandable.rowExpandable', title: { label: '是否可展开', tip: 'expandable.rowExpandable | 行是否可展开', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'rowExpandable(record,${extParams}){\n// 行是否可展开\nreturn true;\n}', }, }, 'VariableSetter', ], }, ], }, { title: '行扩展', display: 'block', type: 'group', items: [ { name: 'extend.title', title: { label: '表格标题', tip: 'title | 表格标题' }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '表格标题插槽', initialValue: { type: 'JSSlot', params: ['currentPageData'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'renderTitle(currentPageData,${extParams}){\n// 自定义渲染表格顶部\nreturn "表格顶部";\n}', }, }, 'VariableSetter', ], }, { name: 'extend.footer', title: { label: '表格尾部', tip: 'footer | 表格尾部' }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '表格尾部插槽', initialValue: { type: 'JSSlot', params: ['currentPageData'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'renderFooter(currentPageData,${extParams}){\n// 自定义渲染表格尾部\nreturn "表格尾部";\n}', }, }, 'VariableSetter', ], }, { name: 'extend.onHeaderRow', title: { label: '头部行属性', tip: 'onHeaderRow | 设置头部行属性' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'onHeaderRow(columns,index,${extParams}){\n// 设置头部行属性\nreturn {onClick:()=>{}};\n}', }, }, 'VariableSetter', ], }, { name: 'extend.onRow', title: { label: '行属性', tip: 'onRow | 设置行属性' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'onRow(record,index,${extParams}){\n// 设置行属性\nreturn {onClick:event=>{}};\n}', }, }, 'VariableSetter', ], }, { name: 'extend.rowClassName', title: { label: '行类名', tip: 'rowClassName | 表格行的类名' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'rowClassName(record,index,${extParams}){\n// 表格行的类名\nreturn `className-line`;\n}', }, }, 'VariableSetter', ], }, { name: 'extend.lineClassNameColor', title: { label: '行背景色', tip: '设置行背景颜色信息', }, propType: 'string', setter: 'ColorSetter', }, ], }, ], supports: { events: ['onChange', 'rowSelectionChange'], style: true, }, component: {}, }, }; const snippets: IPublicTypeSnippet[] = [ { title: '基础表格', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01R1OdLV1GgCXW0rjop_!!6000000000651-2-tps-112-112.png', schema: { componentName: 'ProTable', props: { columns: [ { title: '公司', dataIndex: 'title', formatType: 'text', width: 200, hidden: false, key: 'title', }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', width: 200, hidden: false, key: 'percent', }, { title: '日期', dataIndex: 'dateTime', formatType: 'dateTime', width: 200, hidden: false, key: 'dateTime', }, ], actionBarButtons: { buttonSource: [ { children: '查看', type: 'text', }, { children: '编辑', type: 'text', disabled: true, }, { children: '删除', type: 'text', popconfirm: true, }, ], textModel: true, }, actionColumnProps: { key: 'action', field: false, width: 140, title: '操作', fixed: 'none', }, paginationProps: { hidden: false, showQuickJumper: false, textAlign: 'bottomRight', }, advanced: { type: 'none', // fixedHeight: 400, // footHeight: 0, // align: 'left', // autoHeight: false, // autoWidth: true, }, scroll: { scrollAuto: true, autoHeight: true, autoWidth: true, fixedHeight: 400, footHeight: 0, scrollbarWidth: 5, }, rowSelection: { rowKey: 'id', }, outline: { settingButtons: false, size: 'middle', showHeader: true, }, customStyle: { titleColor: '#848688', headerBorderRadius: '10px 10px 0 0', headerBackgroundColor: '#2d7cff', headerColor: ' #fff', }, expandable: { iconShow: true, expandRowByClick: true, }, extend: { lineClassNameColor: '#ddf5ff', }, }, children: [ { componentName: 'Icon', props: { type: 'MinusCircleTwoTone', size: 12, }, }, { componentName: 'Icon', props: { type: 'PlusCircleTwoTone', size: 12, }, }, ], }, }, ]; export default { ...ProTableMeta, snippets, };