UNPKG

@cainiaofe/cn-ui-lowcode

Version:
749 lines (733 loc) 21.2 kB
import { CnBatchInput, CnInput, CnTimePicker2, CnRangeTimePicker2, componentMap as formComponentMap, } from '@cainiaofe/cn-ui'; import AddressSelect from './address-select'; import DepartmentSelect from './department-select'; import CheckboxGroup from './checkbox-group'; import EmployeeSelect from './employee-select'; import RadioGroup from './radio-group'; import RangePicker from './rangepicker'; import DatePicker from './datepicker'; import Select from './select'; import CnCard from './cn-card'; import CnCardSubCard from './cn-card-sub-card'; // import Table from './table' import CnArrayTable from './cn-array-table'; import { condition, executeObjectExpr, generateIndex, getBizComponent, getBizComponentNameList, getRealizeValue, getRunTimeBizComponent, handlePrototypeCondition, setAdvancedConfigToProps, getItem as getCommonItem, } from '../../util/util'; import { getStyleListByPosition } from '../common-style'; import { DisplayPosition } from '../position/display-position'; import './index.scss'; import Message from './message'; import NumberPicker from './numberpicker'; import RangeNumberPicker from './rangenumberpicker'; import Upload from './upload'; import CnArrayTableIndex from './cn-array-table-index'; import ArrayTableOptButton from './array-table-opt-button'; import TreeSelect from './tree-select'; import CascaderSelect from './cascader-select'; import uniq from 'lodash/uniq'; import { __dataSource__, __filterValue__, __formValue__, } from '@/common/util/expr-const'; import ImageViewer from './image-viewer'; import { componentMap as validatorComponentMap } from '@/common/manager/validator'; import Rating from './rating'; import Range from './range'; import CnFormStepItem from './cn-form-step-item'; // import CnFormGrid from './cn-form-grid' import Compose from './compose'; import AutoComplete from './autocomplete'; import CnArraySubAreaCard from './cn-array-sub-area-card'; import CnFormTabItem from './cn-form-tab-item'; import FormItemSlot from './form-item-slot'; import { ValidatorPosition } from '@/common/manager/position/validator-position'; import { __advancedConfig__ } from '@/common/util/const'; import NumberPickerSetter from '@/common/setter/number-picker-setter'; import Transfer from './transfer'; import ReadOnly from './read-only'; import TimeLine from './timeline'; import set from 'lodash/set'; import { getBizExtendPrototype, handleBizExtendComponentProps, } from '@/common/manager/plugin'; import { getObjectSetterSnippet } from '@/common/manager/setter-snippet'; export const componentMap = { Input: { position: [ DisplayPosition.form, DisplayPosition.formDialog, DisplayPosition.filter, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i1/O1CN01kl2UTl1cx4pqr9W0u_!!6000000003666-2-tps-240-144.png', title: '文本输入框', componentName: 'Input', component: CnInput, formComponent: formComponentMap.CnInput, getFormItemDefaultProps: () => { return { placeholder: '请输入', }; }, getPrototypeList: () => { return [ { name: 'maxLength', title: '文本最大长度', display: 'inline', setter: ( <NumberPickerSetter style={{ width: '100%' }} placeholder={'请输入最大英文字符数'} /> ), }, { name: 'trim', title: '自动去除头尾空格', display: 'inline', setter: 'BoolSetter', }, { name: 'addonAfter', title: '输入框后附加内容', display: 'inline', setter: 'CnI18nSetter', }, ...getBizExtendPrototype({ componentName: 'CnInput', }), // { // title: '高级配置', // name: __advancedConfig__, // display: 'accordion', // extraProps: { // defaultCollapsed: true, // }, // setter: { // componentName: 'ObjectSetter', // props: { // config: { // items: [ // ] // } // } // } // }, ]; }, formItemBeforeHandler: (formItem, config) => { if (formItem) { const componentProps = formItem['x-component-props']; if (componentProps) { componentProps.showLimitHint = true; } handleBizExtendComponentProps(componentProps, 'CnInput'); setAdvancedConfigToProps(componentProps); } }, filterItemBeforeHandler: (filterItemProps, config) => { const { componentProps } = config || {}; if (componentProps) { componentProps.showLimitHint = true; } }, }, CnBatchInput: { position: [ DisplayPosition.form, DisplayPosition.formDialog, DisplayPosition.filter, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i2/O1CN01XvGVZt1g6BYxIf8b9_!!6000000004092-2-tps-240-144.png', title: '批量输入框', componentName: 'CnBatchInput', component: CnBatchInput, formComponent: formComponentMap.CnBatchInput, getFormItemDefaultProps: () => { return { placeholder: '请输入', }; }, getPrototypeList: () => { return [ { name: 'inputProps', title: 'inputProps', display: 'plain', setter: getObjectSetterSnippet({ items: [ { name: 'maxLength', title: '文本最大长度', display: 'inline', setter: ( <NumberPickerSetter style={{ width: '100%' }} placeholder={'请输入最大英文字符数'} /> ), }, ], }), }, ]; }, formItemBeforeHandler: (formItem, config) => { if (formItem) { const componentProps = formItem['x-component-props']; const { hasClear, placeholder } = componentProps || {}; if (hasClear) { set(componentProps, 'inputProps.hasClear', hasClear); } if (placeholder) { set(componentProps, 'inputProps.placeholder', placeholder); } handleBizExtendComponentProps(componentProps, 'CnBatchInput'); setAdvancedConfigToProps(componentProps); } }, filterItemBeforeHandler: (filterItemProps, config) => { const { componentProps } = config || {}; }, }, CnArrayTableIndex, NumberPicker, RangeNumberPicker, Select, RadioGroup, CheckboxGroup, DatePicker, TimePicker: { position: [ DisplayPosition.form, DisplayPosition.filter, DisplayPosition.formDialog, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i1/O1CN01vdQXPP1f4476XeMkj_!!6000000003952-2-tps-240-144.png', title: '时间选择器', componentName: 'TimePicker', component: CnTimePicker2, formComponent: formComponentMap.CnTimePicker2, formItemBeforeHandler: (formItem, config) => { if (formItem) { const componentProps = formItem['x-component-props']; handleBizExtendComponentProps(componentProps, 'CnTimePickerPro'); setAdvancedConfigToProps(componentProps); } }, getPrototypeList: () => { return [ { name: 'outputFormat', title: '输出格式', display: 'inline', setter: { componentName: 'SelectSetter', props: { options: [ { label: '时间戳', value: '', }, { label: '字符串(HH:mm:ss)', value: 'HH:mm:ss', }, ], }, }, }, { name: 'format', title: '前端显示格式', display: 'inline', setter: { componentName: 'SelectSetter', props: { options: [ { label: 'HH', value: 'HH', }, { label: 'HH:mm', value: 'HH:mm', }, { label: 'HH:mm:ss', value: 'HH:mm:ss', }, { label: 'mm:ss', value: 'mm:ss', }, { label: 'ss', value: 'ss', }, ], }, }, }, ...getBizExtendPrototype({ componentName: 'CnTimePickerPro', }), ]; }, }, RangePicker, RangeTimePicker: { position: [ DisplayPosition.form, DisplayPosition.formDialog, DisplayPosition.filter, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i4/O1CN01Yyk6CY1cPBWqMLztD_!!6000000003592-2-tps-240-144.png', title: '时间区间选择器', componentName: 'RangeTimePicker', component: CnRangeTimePicker2, formComponent: formComponentMap.CnRangeTimePicker2, getPrototypeList: () => { return [ { name: 'outputFormat', title: '输出格式', display: 'inline', setter: { componentName: 'SelectSetter', props: { options: [ { label: '时间戳', value: '', }, { label: '字符串(HH:mm:ss)', value: 'HH:mm:ss', }, ], }, }, }, ]; }, }, EmployeeSelect, AddressSelect, DepartmentSelect, TextArea: { position: [ DisplayPosition.form, DisplayPosition.formDialog, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i4/O1CN015bBoNA20LZBBmMTkc_!!6000000006833-2-tps-240-144.png', title: '多行纯文本输入框', componentName: 'TextArea', formComponent: formComponentMap.CnInputTextArea, getPrototypeList: () => { return [ { name: 'maxLength', title: '文本最大长度', display: 'inline', setter: ( <NumberPickerSetter style={{ width: '100%' }} placeholder={'请输入最大英文字符数'} /> ), }, { name: 'rows', title: '文本框有几行', display: 'inline', setter: 'NumberSetter', }, ]; }, formItemBeforeHandler: (formItem, config) => { if (formItem) { const componentProps = formItem['x-component-props']; if (componentProps) { componentProps.showLimitHint = true; } } }, filterItemBeforeHandler: (filterItemProps, config) => { const { componentProps } = config || {}; if (componentProps) { componentProps.showLimitHint = true; } }, }, Switch: { position: [ DisplayPosition.form, DisplayPosition.formDialog, DisplayPosition.cnArrayTable, DisplayPosition.cnArraySubAreaCard, ], thumbUrl: 'https://img.alicdn.com/imgextra/i4/O1CN01Cal4dv1xCuqq6ZuGv_!!6000000006408-0-tps-240-144.jpg', title: '开关', componentName: 'Switch', formComponent: formComponentMap.CnSwitch, }, CnCard, CnCardSubCard, // Table, Message, Upload, CnArrayTable, ArrayTableOptButton, TreeSelect, CascaderSelect, ImageViewer, Rating, Range, CnFormStepItem, // CnFormGrid, Compose, AutoComplete, CnArraySubAreaCard, CnFormTabItem, Transfer, FormItemSlot, TimeLine, ReadOnly, }; const formItemComponentMap = {}; Object.keys(componentMap).forEach((name) => { const item = componentMap[name]; if (item && item.formComponent) { formItemComponentMap[name] = item.formComponent; } }); export function getItemDefaultProps(position, componentName) { const func = getItem(position, componentName, 'getDefaultProps'); if (typeof func === 'function') { return func(); } } export function getFormItemDefaultProps(position, componentName) { const func = getItem(position, componentName, 'getFormItemDefaultProps'); if (typeof func === 'function') { return func(); } } export function getItemInitialValue({ position, prop, componentName }) { const initialValue = { label: '名称', name: 'field', componentName: 'Input', placeholder: '请输入', hasClear: true, }; if (prop) { const existFields = prop.getValue() || []; const defaultLabel = '字段名'; const defaultName = 'field'; const newNameIndex = generateIndex(existFields, defaultName, 'name'); initialValue.label = `${defaultLabel}${newNameIndex}`; initialValue.name = `${defaultName}${newNameIndex}`; if (componentName) { initialValue.componentName = componentName; } } if (position === DisplayPosition.filter) { initialValue.span = 1; } else if ( position === DisplayPosition.form || position === DisplayPosition.formDialog ) { // initialValue.rules = [ // { // name: 'required', // options: { // "required": true // } // }, // ]; } return initialValue; } export function getItemPrototypeListByPosition(config) { const { position } = config; const defaultList = Object.keys(componentMap); const bizComponentNameList = getBizComponentNameList(); let prototypeList = []; const allComponentList = uniq([...defaultList, ...bizComponentNameList]); allComponentList.forEach((name) => { const item = getItem(position, name) || {}; const { getPrototypeList, configure = [] } = item; if (typeof getPrototypeList === 'function') { const temp = getPrototypeList(position); if (temp && temp.length > 0) { prototypeList = [ ...prototypeList, ...handlePrototypeCondition(temp, name, 'componentName'), ]; } } else if (configure?.length > 0) { prototypeList = [ ...prototypeList, ...handlePrototypeCondition(configure, name, 'componentName'), ]; } }); return prototypeList; } export function getItemListByPosition(config) { const { position } = config; const result = []; const defaultList = Object.keys(componentMap); const bizComponentNameList = getBizComponentNameList(); const allComponentList = uniq([...defaultList, ...bizComponentNameList]); allComponentList.forEach((name) => { const component = getItem(position, name); if (component) { const { bizInfo = [] } = component; if (bizInfo.length > 0) { bizInfo.forEach((item) => { const { label, value } = item; const existGroup = result.find((item2) => item2.value === value); if (existGroup) { existGroup?.children.push(component); } else { result.push({ title: label, label, value, children: [component], }); } }); return; } result.push(component); } }); return result; } // export function getRunTimeBizComponentListByPosition(config) { // const { position } = config; // const result = []; // const bizComponentNameList = getBizComponentNameList(); // bizComponentNameList.forEach((name) => { // const component = getItem(position, name); // if (component) { // const { title, value, label, componentName } = component; // const runTimeComponent = getRunTimeItem(componentName); // if(runTimeComponent){ // result.push(runTimeComponent); // } // } // }); // return result; // } export function getItem(position, componentName, propKey) { let result; if (componentName) { let item = componentMap[componentName]; if (!item) { item = getBizComponent(componentName, position); } if (item && item.position && item.position.includes(position)) { if (!item.label) { item.label = item.title; } if (!item.value) { item.value = item.componentName; } if (propKey) { result = item[propKey]; } else { result = item; } } } return result; } export function getRunTimeItem(componentName) { let result; if (componentName) { result = componentMap[componentName]; if (!result) { result = getRunTimeBizComponent(componentName); } } return result; } export function getItemStylePrototype(config) { const { position } = config; const styleList = getStyleListByPosition(position); if (styleList && styleList.length > 0) { return [ { title: '配置字段的展示样式', type: 'group', display: 'accordion', extraProps: { defaultCollapsed: true, }, items: styleList, }, ]; } return []; } export function getFormExtraComponents(usedComponentList = []) { const result = { ...formItemComponentMap }; usedComponentList.forEach((name) => { if (!result[name] && !formComponentMap[name]) { const component = getRunTimeBizComponent(name); if (component && component.component) { result[name] = getRealizeValue(component.component); } } }); return result; } export function transRulesToValidator(rules, config) { const { formValue, state, position, isInCnFilterPro } = config || {}; const result = []; if (Array.isArray(rules) && rules.length > 0) { rules.forEach((item) => { const { name, active, options = {}, message, triggerType, ...rest } = item; const isActive = executeObjectExpr( active, { [__formValue__]: formValue || {}, [__filterValue__]: formValue || {}, [__dataSource__]: state, }, formValue || {}, state, ); if (isActive && name) { const action = getCommonItem( validatorComponentMap, position, name, 'action', ); let temp; if (action) { temp = action({ validateItemConfig: item, position, }); } else { temp = { ...options, }; const { pattern } = options; if (pattern?.length > 2) { if (pattern.startsWith('/') && pattern.endsWith('/')) { temp.pattern = new RegExp(pattern.slice(1, -1)); } } if (message) { temp.message = message; } } if (triggerType) { if (ValidatorPosition.filter === position) { if (temp) { temp.trigger = triggerType; } } else if (temp) { temp.triggerType = triggerType; } } if (ValidatorPosition.form === position) { if (isInCnFilterPro && name === 'custom') { const originalValidator = temp.validator; temp.validator = (value, rules, context) => { const firstParam = { field: context?.field?.props?.name, message: rules?.message, }; const secondParam = value; let errorMsg; const thirdParam = (temMsg) => { if (temMsg) { errorMsg = temMsg; } }; const forthParam = context?.form?.values || {}; const fifthParam = state; originalValidator( firstParam, secondParam, thirdParam, forthParam, fifthParam, ); if (errorMsg) { return errorMsg; } }; } else if (typeof temp?.validator === 'function') { const originalValidator = temp.validator; temp.validator = (value, rules, context) => { return originalValidator(value, rules, context, state); }; } } if (ValidatorPosition.filter === position) { if (typeof temp?.validator === 'function') { const originalValidator = temp.validator; temp.validator = (rule, value, callback) => { originalValidator(rule, value, callback, formValue, state); }; } } if (temp) { result.push(temp); } } }); } return result; }