feat: 添加mobile的级联组件 (#1221)
Reviewed-on: daoyoucloud/tachybase#1221 Reviewed-by: sealday <zhanglin@daoyoucloud.com> Co-authored-by: wjh <wwwjh0710@163.com> Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
		
							parent
							
								
									f651f460d2
								
							
						
					
					
						commit
						05cc91c6fc
					
				@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
  ImageSearchItemView,
 | 
					  ImageSearchItemView,
 | 
				
			||||||
  ImageSearchProvider,
 | 
					  ImageSearchProvider,
 | 
				
			||||||
  ImageSearchView,
 | 
					  ImageSearchView,
 | 
				
			||||||
 | 
					  MCascader,
 | 
				
			||||||
  MCheckbox,
 | 
					  MCheckbox,
 | 
				
			||||||
  MContainer,
 | 
					  MContainer,
 | 
				
			||||||
  MDatePicker,
 | 
					  MDatePicker,
 | 
				
			||||||
@ -87,6 +88,7 @@ export const MobileCore: React.FC<PropsWithChildren> = (props) => {
 | 
				
			|||||||
        MDatePicker,
 | 
					        MDatePicker,
 | 
				
			||||||
        MRadio,
 | 
					        MRadio,
 | 
				
			||||||
        MImageUploader,
 | 
					        MImageUploader,
 | 
				
			||||||
 | 
					        MCascader,
 | 
				
			||||||
        CollectionField: CollectionField,
 | 
					        CollectionField: CollectionField,
 | 
				
			||||||
        MSelect,
 | 
					        MSelect,
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@ const customComponent = {
 | 
				
			|||||||
  'Upload.Attachment': 'MImageUploader',
 | 
					  'Upload.Attachment': 'MImageUploader',
 | 
				
			||||||
  DatePicker: 'MDatePicker',
 | 
					  DatePicker: 'MDatePicker',
 | 
				
			||||||
  Select: 'MSelect',
 | 
					  Select: 'MSelect',
 | 
				
			||||||
 | 
					  Cascader: 'MCascader',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const canMobileField = (componentName: string) => customComponent[componentName];
 | 
					export const canMobileField = (componentName: string) => customComponent[componentName];
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,282 @@
 | 
				
			|||||||
 | 
					import React, { useEffect, useState } from 'react';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  BlockItem,
 | 
				
			||||||
 | 
					  CollectionProvider,
 | 
				
			||||||
 | 
					  useCollectionManager,
 | 
				
			||||||
 | 
					  useFieldServiceFilter,
 | 
				
			||||||
 | 
					  useRequest,
 | 
				
			||||||
 | 
					} from '@tachybase/client';
 | 
				
			||||||
 | 
					import { observer, useFieldSchema, useForm } from '@tachybase/schema';
 | 
				
			||||||
 | 
					import { isArray } from '@tachybase/utils/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Button, CascaderView, Divider, Popup, SearchBar, Space } from 'antd-mobile';
 | 
				
			||||||
 | 
					import { CloseOutline } from 'antd-mobile-icons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { useTranslation } from '../../../../../locale';
 | 
				
			||||||
 | 
					import { MobileProvider } from '../../../provider';
 | 
				
			||||||
 | 
					import { MInput } from '../Input';
 | 
				
			||||||
 | 
					import { useStyles } from './style';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const AntdCascader = observer((props) => {
 | 
				
			||||||
 | 
					  const { service, fieldNames, disabled, multiple, onChange, value, formCascaderValues, index } = props as any;
 | 
				
			||||||
 | 
					  const fieldSchema = useFieldSchema();
 | 
				
			||||||
 | 
					  const cm = useCollectionManager();
 | 
				
			||||||
 | 
					  const { styles } = useStyles();
 | 
				
			||||||
 | 
					  const collectionField = cm.getCollectionField(fieldSchema['x-collection-field']);
 | 
				
			||||||
 | 
					  const changOnSelect = fieldSchema['x-component-props']?.changOnSelect || false;
 | 
				
			||||||
 | 
					  const collection = cm.getCollection(fieldSchema['x-collection-field']);
 | 
				
			||||||
 | 
					  const isChinaRegion = collectionField.interface === 'chinaRegion';
 | 
				
			||||||
 | 
					  const [options, setOptions] = useState([]);
 | 
				
			||||||
 | 
					  const [popupVisible, setPopupVisible] = useState(false);
 | 
				
			||||||
 | 
					  const [fieldServiceFilter] = useFieldServiceFilter(service?.params);
 | 
				
			||||||
 | 
					  const [filter, setFilter] = useState(fieldServiceFilter);
 | 
				
			||||||
 | 
					  const [searchValue, setSearchValue] = useState('');
 | 
				
			||||||
 | 
					  const [cascaderValue, setCascaderValue] = useState(value);
 | 
				
			||||||
 | 
					  const [valueText, setValueText] = useState('');
 | 
				
			||||||
 | 
					  const [flatOption, setFlatOption] = useState([]);
 | 
				
			||||||
 | 
					  const { run } = useRequest(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      resource: collection?.name,
 | 
				
			||||||
 | 
					      action: 'list',
 | 
				
			||||||
 | 
					      params: {
 | 
				
			||||||
 | 
					        filter,
 | 
				
			||||||
 | 
					        tree: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      manual: true,
 | 
				
			||||||
 | 
					      onSuccess({ data }) {
 | 
				
			||||||
 | 
					        if (data) {
 | 
				
			||||||
 | 
					          setOptions(cascadeOption(data));
 | 
				
			||||||
 | 
					          const valueOption = flatOptions(data);
 | 
				
			||||||
 | 
					          setFlatOption(valueOption);
 | 
				
			||||||
 | 
					          if (value) {
 | 
				
			||||||
 | 
					            setValueText(getValueText(valueOption, value, '', fieldNames['label']));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const cascadeOption = (option) => {
 | 
				
			||||||
 | 
					    option.forEach((item) => {
 | 
				
			||||||
 | 
					      item['value'] = item[fieldNames.value];
 | 
				
			||||||
 | 
					      item['label'] = item[fieldNames.label];
 | 
				
			||||||
 | 
					      if (item.children) {
 | 
				
			||||||
 | 
					        item.children = cascadeOption(item.children);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return option;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (!isChinaRegion && collection?.name) {
 | 
				
			||||||
 | 
					      checkedPopup();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [filter]);
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    if (options.length) {
 | 
				
			||||||
 | 
					      cascadeOption(options);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [fieldSchema['x-component-props']?.['fieldNames']]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleSelect = async (option) => {
 | 
				
			||||||
 | 
					    if (option) {
 | 
				
			||||||
 | 
					      setCascaderValue(option[option.length - 1]);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      setCascaderValue({});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const checkedPopup = () => {
 | 
				
			||||||
 | 
					    if (collection && collection.name) {
 | 
				
			||||||
 | 
					      run();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <CollectionProvider name={collectionField.collectionName}>
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        onClick={() => {
 | 
				
			||||||
 | 
					          if (disabled) return;
 | 
				
			||||||
 | 
					          setPopupVisible(true);
 | 
				
			||||||
 | 
					          checkedPopup();
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					        style={{ display: 'flex', alignItems: 'center' }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {value && Object.keys(value).length ? (
 | 
				
			||||||
 | 
					          <MInput style={{ '--color': '#1e8bf1' }} value={valueText} disabled={disabled} clearable={false} />
 | 
				
			||||||
 | 
					        ) : (
 | 
				
			||||||
 | 
					          <MInput value={valueText ? '' : '请选择'} style={{ '--color': '#c5c5c5' }} />
 | 
				
			||||||
 | 
					        )}
 | 
				
			||||||
 | 
					        {(value && Object.keys(value).length) || (formCascaderValues && index !== 0) ? (
 | 
				
			||||||
 | 
					          <CloseOutline
 | 
				
			||||||
 | 
					            style={{ margin: '5px 10px 5px 20px' }}
 | 
				
			||||||
 | 
					            onClick={() => {
 | 
				
			||||||
 | 
					              if (index) {
 | 
				
			||||||
 | 
					                const formValue = [...formCascaderValues];
 | 
				
			||||||
 | 
					                if (formCascaderValues.length === 1 && index === 0) {
 | 
				
			||||||
 | 
					                  formValue[index] = {};
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  formValue.splice(index, 1);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                onChange(formValue);
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                onChange({});
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        ) : null}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <Popup
 | 
				
			||||||
 | 
					        visible={popupVisible}
 | 
				
			||||||
 | 
					        className={`${styles['PopupStyle']}`}
 | 
				
			||||||
 | 
					        onMaskClick={() => {
 | 
				
			||||||
 | 
					          setPopupVisible(false);
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <MobileProvider>
 | 
				
			||||||
 | 
					          <SearchBar
 | 
				
			||||||
 | 
					            placeholder="请输入内容"
 | 
				
			||||||
 | 
					            value={searchValue}
 | 
				
			||||||
 | 
					            onChange={(value) => {
 | 
				
			||||||
 | 
					              const paramsFilter = { ...filter };
 | 
				
			||||||
 | 
					              paramsFilter[fieldNames['label']] = { $includes: value };
 | 
				
			||||||
 | 
					              setFilter(paramsFilter);
 | 
				
			||||||
 | 
					              setSearchValue(value);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					          <Divider />
 | 
				
			||||||
 | 
					          <CascaderView options={options} onChange={(value, extend) => handleSelect(extend['items'])} />
 | 
				
			||||||
 | 
					          <Space justify="evenly" align="center">
 | 
				
			||||||
 | 
					            <Button
 | 
				
			||||||
 | 
					              color="primary"
 | 
				
			||||||
 | 
					              onClick={() => {
 | 
				
			||||||
 | 
					                setPopupVisible(false);
 | 
				
			||||||
 | 
					                const paramsFilter = { ...filter };
 | 
				
			||||||
 | 
					                if (paramsFilter[fieldNames['label']]) delete paramsFilter[fieldNames['label']];
 | 
				
			||||||
 | 
					                setSearchValue('');
 | 
				
			||||||
 | 
					                setFilter(paramsFilter);
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              取消
 | 
				
			||||||
 | 
					            </Button>
 | 
				
			||||||
 | 
					            <Button
 | 
				
			||||||
 | 
					              color="primary"
 | 
				
			||||||
 | 
					              onClick={() => {
 | 
				
			||||||
 | 
					                const changevalue = ['m2m', 'o2m'].includes(collectionField.interface)
 | 
				
			||||||
 | 
					                  ? getChangValue(formCascaderValues, cascaderValue, index)
 | 
				
			||||||
 | 
					                  : cascaderValue;
 | 
				
			||||||
 | 
					                onChange(changevalue);
 | 
				
			||||||
 | 
					                setValueText(getValueText(flatOption, cascaderValue, '', fieldNames['label']));
 | 
				
			||||||
 | 
					                setPopupVisible(false);
 | 
				
			||||||
 | 
					                const paramsFilter = { ...filter };
 | 
				
			||||||
 | 
					                if (paramsFilter[fieldNames['label']]) delete paramsFilter[fieldNames['label']];
 | 
				
			||||||
 | 
					                setSearchValue('');
 | 
				
			||||||
 | 
					                setFilter(paramsFilter);
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					              disabled={
 | 
				
			||||||
 | 
					                !changOnSelect
 | 
				
			||||||
 | 
					                  ? cascaderValue && cascaderValue !== '{}' && !cascaderValue?.children
 | 
				
			||||||
 | 
					                    ? false
 | 
				
			||||||
 | 
					                    : true
 | 
				
			||||||
 | 
					                  : cascaderValue && cascaderValue !== '{}'
 | 
				
			||||||
 | 
					                    ? false
 | 
				
			||||||
 | 
					                    : true
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              确定
 | 
				
			||||||
 | 
					            </Button>
 | 
				
			||||||
 | 
					          </Space>
 | 
				
			||||||
 | 
					        </MobileProvider>
 | 
				
			||||||
 | 
					      </Popup>
 | 
				
			||||||
 | 
					    </CollectionProvider>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getValueText = (option, item, value, label) => {
 | 
				
			||||||
 | 
					  const text = `${item?.[label] || ''}${value}`;
 | 
				
			||||||
 | 
					  if (item?.parentId) {
 | 
				
			||||||
 | 
					    const filterItem = option.find((optionsItem) => optionsItem.id === item.parentId);
 | 
				
			||||||
 | 
					    const itemText = `/${text}`;
 | 
				
			||||||
 | 
					    return getValueText(option, filterItem, itemText, label);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return text;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const flatOptions = (options) => {
 | 
				
			||||||
 | 
					  const flatChildren = (item, option) => {
 | 
				
			||||||
 | 
					    option.push(item);
 | 
				
			||||||
 | 
					    if (item?.children) {
 | 
				
			||||||
 | 
					      item.children.forEach((childrenItem) => {
 | 
				
			||||||
 | 
					        return flatChildren(childrenItem, option);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return option;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  const optionflat = [];
 | 
				
			||||||
 | 
					  options.forEach((value) => {
 | 
				
			||||||
 | 
					    const flatValue = flatChildren(value, []);
 | 
				
			||||||
 | 
					    optionflat.push(...flatValue);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  return optionflat;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getChangValue = (formCascaderValues, cascaderValue, index) => {
 | 
				
			||||||
 | 
					  const value = [];
 | 
				
			||||||
 | 
					  if (formCascaderValues && (index || index === 0)) {
 | 
				
			||||||
 | 
					    formCascaderValues[index] = cascaderValue;
 | 
				
			||||||
 | 
					    value.push(...formCascaderValues);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    value.push(cascaderValue);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return value;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const InternalCascader = observer((props) => {
 | 
				
			||||||
 | 
					  const { value, onChange } = props as any;
 | 
				
			||||||
 | 
					  const fieldSchema = useFieldSchema();
 | 
				
			||||||
 | 
					  const cm = useCollectionManager();
 | 
				
			||||||
 | 
					  const collectionField = cm.getCollectionField(fieldSchema['x-collection-field']);
 | 
				
			||||||
 | 
					  const form = useForm();
 | 
				
			||||||
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <>
 | 
				
			||||||
 | 
					      {isArray(value) ? (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					          {value.map((item, index) => {
 | 
				
			||||||
 | 
					            const filterProps = {
 | 
				
			||||||
 | 
					              ...props,
 | 
				
			||||||
 | 
					              value: item,
 | 
				
			||||||
 | 
					              formCascaderValues: value || [],
 | 
				
			||||||
 | 
					              index,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return <AntdCascader {...filterProps} key={index} />;
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					      ) : (
 | 
				
			||||||
 | 
					        <AntdCascader {...props} />
 | 
				
			||||||
 | 
					      )}
 | 
				
			||||||
 | 
					      {['m2m', 'o2m'].includes(collectionField.interface) ? (
 | 
				
			||||||
 | 
					        <>
 | 
				
			||||||
 | 
					          <Button
 | 
				
			||||||
 | 
					            style={{
 | 
				
			||||||
 | 
					              textAlign: 'center',
 | 
				
			||||||
 | 
					              width: '100%',
 | 
				
			||||||
 | 
					              border: '1px dashed #c5c5c5',
 | 
				
			||||||
 | 
					              color: '#c5c5c5',
 | 
				
			||||||
 | 
					              fontSize: '12px',
 | 
				
			||||||
 | 
					              height: '5vh',
 | 
				
			||||||
 | 
					              lineHeight: '2vh',
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					            onClick={() => {
 | 
				
			||||||
 | 
					              const pushValue = value ? [...value, {}] : [{}, {}];
 | 
				
			||||||
 | 
					              onChange(pushValue);
 | 
				
			||||||
 | 
					            }}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            + {t('Add new')}
 | 
				
			||||||
 | 
					          </Button>
 | 
				
			||||||
 | 
					        </>
 | 
				
			||||||
 | 
					      ) : null}
 | 
				
			||||||
 | 
					    </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { connect, mapProps, mapReadPretty, useFieldSchema } from '@tachybase/schema';
 | 
				
			||||||
 | 
					import { isArray } from '@tachybase/utils/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { InternalCascader } from './AntdCadcader';
 | 
				
			||||||
 | 
					import { ReadPretty } from './ReadPretty';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const MCascader = connect(
 | 
				
			||||||
 | 
					  InternalCascader,
 | 
				
			||||||
 | 
					  mapProps((props) => {
 | 
				
			||||||
 | 
					    return { ...props };
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					  mapReadPretty(ReadPretty),
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import { ArrayField, toArr, useField } from '@tachybase/schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { defaultFieldNames } from './defaultFieldNames';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const ReadPretty: React.FC<unknown> = (props: any) => {
 | 
				
			||||||
 | 
					  const { fieldNames = defaultFieldNames } = props;
 | 
				
			||||||
 | 
					  const values = toArr(props.value);
 | 
				
			||||||
 | 
					  const len = values.length;
 | 
				
			||||||
 | 
					  const field = useField<ArrayField>();
 | 
				
			||||||
 | 
					  let dataSource = field.dataSource;
 | 
				
			||||||
 | 
					  const data = [];
 | 
				
			||||||
 | 
					  for (const item of values) {
 | 
				
			||||||
 | 
					    if (typeof item === 'object') {
 | 
				
			||||||
 | 
					      data.push(item);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      const curr = dataSource?.find((v) => v[fieldNames.value] === item);
 | 
				
			||||||
 | 
					      dataSource = curr?.[fieldNames.children] || [];
 | 
				
			||||||
 | 
					      data.push(curr || { label: item, value: item });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div>
 | 
				
			||||||
 | 
					      {data.map((item, index) => {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					          <span key={index}>
 | 
				
			||||||
 | 
					            {typeof item === 'object' ? item[fieldNames.label] : item}
 | 
				
			||||||
 | 
					            {len > index + 1 && ' / '}
 | 
				
			||||||
 | 
					          </span>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      })}
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					export const defaultFieldNames = {
 | 
				
			||||||
 | 
					  label: 'label',
 | 
				
			||||||
 | 
					  value: 'value',
 | 
				
			||||||
 | 
					  children: 'children',
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					export * from './Cadcader';
 | 
				
			||||||
@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					import { createStyles } from '@tachybase/client';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useStyles = createStyles(({ css }) => ({
 | 
				
			||||||
 | 
					  PopupStyle: css`
 | 
				
			||||||
 | 
					    .adm-popup-body {
 | 
				
			||||||
 | 
					      padding: 10px;
 | 
				
			||||||
 | 
					      .adm-space {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        margin: 10px 0 10px 0;
 | 
				
			||||||
 | 
					        color: #4592ff;
 | 
				
			||||||
 | 
					        button {
 | 
				
			||||||
 | 
					          width: 23vw;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .adm-divider {
 | 
				
			||||||
 | 
					        margin: 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .adm-list-body {
 | 
				
			||||||
 | 
					        height: 30vh;
 | 
				
			||||||
 | 
					        overflow: auto;
 | 
				
			||||||
 | 
					        text-align: center;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  `,
 | 
				
			||||||
 | 
					}));
 | 
				
			||||||
@ -226,7 +226,6 @@ export const AntdSelect = observer((props) => {
 | 
				
			|||||||
                  if (paramsFilter[fieldNamesLabel]) delete paramsFilter[fieldNamesLabel];
 | 
					                  if (paramsFilter[fieldNamesLabel]) delete paramsFilter[fieldNamesLabel];
 | 
				
			||||||
                  setSearchValue('');
 | 
					                  setSearchValue('');
 | 
				
			||||||
                  setFilter(paramsFilter);
 | 
					                  setFilter(paramsFilter);
 | 
				
			||||||
                  setSearchValue('');
 | 
					 | 
				
			||||||
                }}
 | 
					                }}
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
                确定
 | 
					                确定
 | 
				
			||||||
 | 
				
			|||||||
@ -1,131 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  Nester: {
 | 
					 | 
				
			||||||
    type: 'void',
 | 
					 | 
				
			||||||
    'x-component': 'AssociationField.Nester',
 | 
					 | 
				
			||||||
    properties: {
 | 
					 | 
				
			||||||
      grid: {
 | 
					 | 
				
			||||||
        type: 'void',
 | 
					 | 
				
			||||||
        'x-component': 'Grid',
 | 
					 | 
				
			||||||
        'x-initializer': 'form:configureFields',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  AddNewer: {
 | 
					 | 
				
			||||||
    type: 'void',
 | 
					 | 
				
			||||||
    'x-component': 'AssociationField.AddNewer',
 | 
					 | 
				
			||||||
    'x-action': 'create',
 | 
					 | 
				
			||||||
    title: '{{ t("Add record") }}',
 | 
					 | 
				
			||||||
    'x-component-props': {
 | 
					 | 
				
			||||||
      className: 'nb-action-popup',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    properties: {
 | 
					 | 
				
			||||||
      tabs: {
 | 
					 | 
				
			||||||
        type: 'void',
 | 
					 | 
				
			||||||
        'x-component': 'Tabs',
 | 
					 | 
				
			||||||
        'x-component-props': {},
 | 
					 | 
				
			||||||
        'x-initializer': 'TabPaneInitializersForCreateFormBlock',
 | 
					 | 
				
			||||||
        properties: {
 | 
					 | 
				
			||||||
          tab1: {
 | 
					 | 
				
			||||||
            type: 'void',
 | 
					 | 
				
			||||||
            title: '{{t("Add new")}}',
 | 
					 | 
				
			||||||
            'x-component': 'Tabs.TabPane',
 | 
					 | 
				
			||||||
            'x-designer': 'Tabs.Designer',
 | 
					 | 
				
			||||||
            'x-component-props': {},
 | 
					 | 
				
			||||||
            properties: {
 | 
					 | 
				
			||||||
              grid: {
 | 
					 | 
				
			||||||
                type: 'void',
 | 
					 | 
				
			||||||
                'x-component': 'Grid',
 | 
					 | 
				
			||||||
                'x-initializer': 'popup:addNew:addBlock',
 | 
					 | 
				
			||||||
                properties: {},
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  Selector: {
 | 
					 | 
				
			||||||
    type: 'void',
 | 
					 | 
				
			||||||
    'x-component': 'AssociationField.Selector',
 | 
					 | 
				
			||||||
    title: '{{ t("Select record") }}',
 | 
					 | 
				
			||||||
    'x-component-props': {
 | 
					 | 
				
			||||||
      className: 'nb-record-picker-selector',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    properties: {
 | 
					 | 
				
			||||||
      grid: {
 | 
					 | 
				
			||||||
        type: 'void',
 | 
					 | 
				
			||||||
        'x-component': 'Grid',
 | 
					 | 
				
			||||||
        'x-initializer': 'popup:tableSelector:addBlock',
 | 
					 | 
				
			||||||
        properties: {},
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      footer: {
 | 
					 | 
				
			||||||
        'x-component': 'Action.Container.Footer',
 | 
					 | 
				
			||||||
        'x-component-props': {},
 | 
					 | 
				
			||||||
        properties: {
 | 
					 | 
				
			||||||
          actions: {
 | 
					 | 
				
			||||||
            type: 'void',
 | 
					 | 
				
			||||||
            'x-component': 'ActionBar',
 | 
					 | 
				
			||||||
            'x-component-props': {},
 | 
					 | 
				
			||||||
            properties: {
 | 
					 | 
				
			||||||
              submit: {
 | 
					 | 
				
			||||||
                title: '{{ t("Submit") }}',
 | 
					 | 
				
			||||||
                'x-action': 'submit',
 | 
					 | 
				
			||||||
                'x-component': 'Action',
 | 
					 | 
				
			||||||
                'x-use-component-props': 'usePickActionProps',
 | 
					 | 
				
			||||||
                // 'x-designer': 'Action.Designer',
 | 
					 | 
				
			||||||
                'x-toolbar': 'ActionSchemaToolbar',
 | 
					 | 
				
			||||||
                'x-settings': 'actionSettings:submit',
 | 
					 | 
				
			||||||
                'x-component-props': {
 | 
					 | 
				
			||||||
                  type: 'primary',
 | 
					 | 
				
			||||||
                  htmlType: 'submit',
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  Viewer: {
 | 
					 | 
				
			||||||
    type: 'void',
 | 
					 | 
				
			||||||
    title: '{{ t("View record") }}',
 | 
					 | 
				
			||||||
    'x-component': 'AssociationField.Viewer',
 | 
					 | 
				
			||||||
    'x-component-props': {
 | 
					 | 
				
			||||||
      className: 'nb-action-popup',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    properties: {
 | 
					 | 
				
			||||||
      tabs: {
 | 
					 | 
				
			||||||
        type: 'void',
 | 
					 | 
				
			||||||
        'x-component': 'Tabs',
 | 
					 | 
				
			||||||
        'x-component-props': {},
 | 
					 | 
				
			||||||
        'x-initializer': 'TabPaneInitializers',
 | 
					 | 
				
			||||||
        properties: {
 | 
					 | 
				
			||||||
          tab1: {
 | 
					 | 
				
			||||||
            type: 'void',
 | 
					 | 
				
			||||||
            title: '{{t("Details")}}',
 | 
					 | 
				
			||||||
            'x-component': 'Tabs.TabPane',
 | 
					 | 
				
			||||||
            'x-designer': 'Tabs.Designer',
 | 
					 | 
				
			||||||
            'x-component-props': {},
 | 
					 | 
				
			||||||
            properties: {
 | 
					 | 
				
			||||||
              grid: {
 | 
					 | 
				
			||||||
                type: 'void',
 | 
					 | 
				
			||||||
                'x-component': 'Grid',
 | 
					 | 
				
			||||||
                'x-initializer': 'popup:common:addBlock',
 | 
					 | 
				
			||||||
                properties: {},
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  SubTable: {
 | 
					 | 
				
			||||||
    type: 'void',
 | 
					 | 
				
			||||||
    'x-component': 'AssociationField.SubTable',
 | 
					 | 
				
			||||||
    'x-initializer': 'table:configureColumns',
 | 
					 | 
				
			||||||
    'x-initializer-props': {
 | 
					 | 
				
			||||||
      action: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    properties: {},
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -4,3 +4,4 @@ export * from './DatePicker';
 | 
				
			|||||||
export * from './ImageUploader';
 | 
					export * from './ImageUploader';
 | 
				
			||||||
export * from './Radio';
 | 
					export * from './Radio';
 | 
				
			||||||
export * from './Select';
 | 
					export * from './Select';
 | 
				
			||||||
 | 
					export * from './Cascader';
 | 
				
			||||||
 | 
				
			|||||||
@ -45,5 +45,6 @@
 | 
				
			|||||||
  "Add block": "Add block",
 | 
					  "Add block": "Add block",
 | 
				
			||||||
  "all": "all",
 | 
					  "all": "all",
 | 
				
			||||||
  "AllProducts": "AllProducts",
 | 
					  "AllProducts": "AllProducts",
 | 
				
			||||||
  "sort":"sort"
 | 
					  "sort":"sort",
 | 
				
			||||||
 | 
					  "Add new":"Add new"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -48,5 +48,6 @@
 | 
				
			|||||||
  "sort": "排序",
 | 
					  "sort": "排序",
 | 
				
			||||||
  "Swiper":"轮播图",
 | 
					  "Swiper":"轮播图",
 | 
				
			||||||
  "TabSearch":"表格搜索",
 | 
					  "TabSearch":"表格搜索",
 | 
				
			||||||
  "ImageSearch":"图片搜索"
 | 
					  "ImageSearch":"图片搜索",
 | 
				
			||||||
 | 
					  "Add new":"添加"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user