import React, { useContext } from 'react'; import { CollectionFieldInterface, Cron, css, interfacesProperties, SchemaComponent, SchemaComponentOptions, useCompile, useToken, } from '@tachybase/client'; import { ArrayTable, FormButtonGroup, FormDrawer, FormLayout, Submit } from '@tachybase/components'; import { ISchema, onFieldValueChange, SchemaOptionsContext, useForm, useFormEffects } from '@tachybase/schema'; import { error } from '@tachybase/utils/client'; import { Button, Select } from 'antd'; import { useTranslation } from 'react-i18next'; import { lang, NAMESPACE } from './locale'; function RuleTypeSelect(props) { const compile = useCompile(); const { setValuesIn } = useForm(); const index = ArrayTable.useIndex(); useFormEffects(() => { onFieldValueChange(`patterns.${index}.type`, (field) => { setValuesIn(`patterns.${index}.options`, {}); }); }); return ( ); } function RuleOptions() { const compile = useCompile(); const { values } = useForm(); const index = ArrayTable.useIndex(); const { type, options } = values.patterns[index]; const ruleType = RuleTypes[type]; return (
{Object.keys(options) .filter((key) => typeof options[key] !== 'undefined' && ruleType.optionRenders[key]) .map((key) => { const Component = ruleType.optionRenders[key]; const { title } = ruleType.fieldset[key]; return Component ? (
{compile(title)}
) : null; })}
); } const RuleTypes = { string: { title: `{{t("Fixed text", { ns: "${NAMESPACE}" })}}`, optionRenders: { value(options = { value: '' }) { return {options.value}; }, }, fieldset: { value: { type: 'string', title: `{{t("Text content", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'Input', }, }, }, integer: { title: `{{t("Autoincrement", { ns: "${NAMESPACE}" })}}`, optionRenders: { digits: function Digits({ value }) { return {value}; }, start: function Start({ value }) { return {value}; }, cycle: Cron.ReadPretty, }, fieldset: { digits: { type: 'number', title: `{{t("Digits", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'InputNumber', 'x-component-props': { min: 1, max: 10, }, required: true, default: 1, 'x-reactions': { target: 'start', fulfill: { schema: { 'x-component-props.max': '{{ 10 ** $self.value - 1 }}', }, }, }, }, start: { type: 'number', title: `{{t("Start from", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'InputNumber', 'x-component-props': { min: 0, }, required: true, default: 0, // 'x-reactions': { // dependencies: ['.start', '.base'], // fulfill: { // schema: { // 'x-component-props.max': '{{ ($deps[1] ?? 10) ** ($deps[0] ?? 1) - 1 }}' // } // } // } }, cycle: { type: 'string', title: `{{t("Reset cycle", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', ['x-component']({ value, onChange }) { const shortValues = [ { label: 'No reset', value: 0 }, { label: 'Daily', value: 1, cron: '0 0 * * *' }, { label: 'Every Monday', value: 2, cron: '0 0 * * 1' }, { label: 'Monthly', value: 3, cron: '0 0 1 * *' }, { label: 'Yearly', value: 4, cron: '0 0 1 1 *' }, { label: 'Customize', value: 5, cron: '* * * * *' }, ]; const option = typeof value === 'undefined' ? shortValues[0] : shortValues.find((item) => { return item.cron == value; }) || shortValues[5]; return (
{option.value === 5 ? : null}
); }, default: null, }, }, }, date: { title: `{{t("Date", { ns: "${NAMESPACE}" })}}`, optionRenders: { format(options = { value: 'YYYYMMDD' }) { return {options.value}; }, }, }, }; export function RuleConfigForm() { const { t } = useTranslation(); const compile = useCompile(); const schemaOptions = useContext(SchemaOptionsContext); const { values, setValuesIn } = useForm(); const index = ArrayTable.useIndex(); const { type, options } = values.patterns[index]; const ruleType = RuleTypes[type]; const { token } = useToken(); return ruleType?.fieldset ? ( ) : null; } export class SequenceFieldInterface extends CollectionFieldInterface { name = 'sequence'; type = 'object'; group = 'advanced'; order = 3; title = `{{t("Sequence", { ns: "${NAMESPACE}" })}}`; description = `{{t("Automatically generate codes based on configured rules, supporting combinations of dates, numbers, and text.", { ns: "${NAMESPACE}" })}}`; sortable = true; default = { type: 'sequence', uiSchema: { type: 'string', 'x-component': 'Input', 'x-component-props': {}, }, }; availableTypes = ['string']; hasDefaultValue = false; filterable = { operators: interfacesProperties.operators.string, }; titleUsable = true; schemaInitialize(schema: ISchema, { block, field }) { if (block === 'Form') { Object.assign(schema['x-component-props'], { disabled: !field.inputable, }); } return schema; } properties = { ...interfacesProperties.defaultProps, unique: interfacesProperties.unique, patterns: { type: 'array', title: `{{t("Sequence rules", { ns: "${NAMESPACE}" })}}`, required: true, 'x-decorator': 'FormItem', 'x-component': 'ArrayTable', items: { type: 'object', properties: { sort: { type: 'void', 'x-component': 'ArrayTable.Column', 'x-component-props': { width: 50, title: '', align: 'center' }, properties: { sort: { type: 'void', 'x-component': 'ArrayTable.SortHandle', }, }, }, type: { type: 'void', 'x-component': 'ArrayTable.Column', 'x-component-props': { title: `{{t("Type", { ns: "${NAMESPACE}" })}}` }, // 'x-hidden': true, properties: { type: { type: 'string', name: 'type', required: true, 'x-decorator': 'FormItem', 'x-component': RuleTypeSelect, }, }, }, options: { type: 'void', 'x-component': 'ArrayTable.Column', 'x-component-props': { title: `{{t("Rule content", { ns: "${NAMESPACE}" })}}` }, properties: { options: { type: 'object', name: 'options', 'x-component': RuleOptions, }, }, }, operations: { type: 'void', 'x-component': 'ArrayTable.Column', 'x-component-props': { title: `{{t("Operations", { ns: "${NAMESPACE}" })}}`, dataIndex: 'operations', fixed: 'right', className: css` > *:not(:last-child) { margin-right: 0.5em; } button { padding: 0; } `, }, properties: { config: { type: 'void', properties: { options: { type: 'object', 'x-component': RuleConfigForm, }, }, }, remove: { type: 'void', 'x-component': 'ArrayTable.Remove', }, }, }, }, }, properties: { add: { type: 'void', 'x-component': 'ArrayTable.Addition', 'x-component-props': { defaultValue: { type: 'integer', options: { digits: 1, start: 0 } }, }, title: `{{t("Add rule", { ns: "${NAMESPACE}" })}}`, }, }, }, inputable: { type: 'boolean', title: `{{t("Inputable", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'Checkbox', }, match: { type: 'boolean', title: `{{t("Match rules", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'Checkbox', 'x-reactions': { dependencies: ['inputable'], fulfill: { state: { value: '{{$deps[0] && $self.value}}', visible: '{{$deps[0] === true}}', }, }, }, }, }; }