@cainiaofe/cn-ui-lowcode
Version:
749 lines (733 loc) • 21.2 kB
JavaScript
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;
}