antd#TreeSelect TypeScript Examples

The following examples show how to use antd#TreeSelect. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.tsx    From antdp with MIT License 6 votes vote down vote up
getItem = ({ attr, type, inputNode }: {
  attr?: Partial<ItemChildAttr<any, any>>;
  type?: ItemChildType;
  inputNode?: ((...arg: any[]) => React.ReactNode) | React.ReactNode;
}) => {
  let renderItem = undefined;
  if (type === 'Input') {
    const inputAttr = attr as InputProps;
    renderItem = <Input {...inputAttr} />;
  } else if (type === 'TextArea') {
    const inputAttr = attr as TextAreaProps;
    renderItem = <Input.TextArea {...inputAttr} />;
  } else if (type === 'InputNumber') {
    const inputAttr = attr as InputNumberProps;
    renderItem = <InputNumber {...inputAttr} />;
  } else if (type === 'AutoComplete') {
    const inputAttr = attr as AutoCompleteProps;
    renderItem = <AutoComplete {...inputAttr} />;
  } else if (type === 'Cascader') {
    const inputAttr = attr as CascaderProps;
    renderItem = <Cascader {...inputAttr} />;
  } else if (type === 'DatePicker') {
    const inputAttr = attr as DatePickerProps;
    renderItem = <DatePicker {...inputAttr} />;
  } else if (type === 'Rate') {
    const inputAttr = attr as RateProps;
    renderItem = <Rate {...inputAttr} />;
  } else if (type === 'Slider') {
    const inputAttr = attr as SliderSingleProps;
    renderItem = <Slider {...inputAttr} />;
  } else if (type === 'TreeSelect') {
    const inputAttr = attr as TreeSelectProps<any>;
    renderItem = <TreeSelect {...inputAttr} />;
  } else if (type === 'Select') {
    const inputAttr = attr as SelectProps<any>;
    renderItem = <Select {...inputAttr} />;
  } else if (type === 'Checkbox') {
    const inputAttr = attr as CheckboxGroupProps;
    renderItem = <Checkbox.Group {...inputAttr} />;
  } else if (type === 'Mentions') {
    const inputAttr = attr as MentionProps;
    renderItem = <Mentions {...inputAttr} />;
  } else if (type === 'Radio') {
    const inputAttr = attr as RadioProps;
    renderItem = <Radio.Group {...inputAttr} />;
  } else if (type === 'Switch') {
    const inputAttr = attr as SwitchProps;
    renderItem = <Switch {...inputAttr} />;
  } else if (type === 'TimePicker') {
    const inputAttr = attr as TimePickerProps;
    renderItem = <TimePicker {...inputAttr} />;
  } else if (type === 'Upload') {
    const inputAttr = attr as UploadProps;
    renderItem = <Upload {...inputAttr} />;
  } else if (type === 'RangePicker') {
    const inputAttr = attr as RangePickerProps;
    renderItem = <RangePicker {...inputAttr} />;
  } else if (type === 'Custom') {
    renderItem = inputNode;
  }
  return renderItem;
}
Example #2
Source File: index.tsx    From ii-admin-base with MIT License 6 votes vote down vote up
ITreeSelect: FC<ITreeSelectProps> = props => {
  const {
    treeData,
    titleField,
    keyField,
    childrenField,
    ...extraProps
  } = props;

  const computeTree = (
    treeData: DataNode[],
    titleField: string,
    keyField: string,
    childrenField: string,
  ): DataNode[] => {
    return treeData.map((item: any) => ({
      title: item[`${titleField}`],
      key: item[keyField],
      value: item[keyField],
      children: item[`${childrenField}`]
        ? computeTree(
            item[`${childrenField}`],
            titleField,
            keyField,
            childrenField,
          )
        : [],
    }));
  };

  const memoTreeData = useMemo(() => {
    return computeTree(treeData, titleField, keyField, childrenField);
  }, [treeData, titleField, keyField]);

  return <TreeSelect treeData={memoTreeData} {...extraProps} />;
}
Example #3
Source File: index.tsx    From brick-design with MIT License 6 votes vote down vote up
function Animate(props: AnimatePropsType, ref: any) {
	const { value, onChange } = props
	const [dropdownVisible, setDropdownVisible] = useState(false)

	function handleChange(val: any) {
		let animatedClass = val ? `${val} animated` : undefined
		onChange && onChange(animatedClass)
	}

	function renderAnimateBox(animateName: string) {
		const animateClass = animateName ? `${animateName} animated` : ''

		return (
			<div className={styles['animate-wrap']}>
				{/* //这里一定要加上key
            //className是animate.css中的类名,显示不同动画 */}
				<div
					key="amache"
					className={classNames(styles['animate-box'], animateClass)}
				>
					Animate
				</div>
			</div>
		)
	}

	return (
		<Row gutter={10} className={styles['animate-component-warp']}>
			<Col style={{ lineHeight: 0 }} span={14}>
				<TreeSelect
					showSearch
					value={value ? value.split(' ')[0] : ''}
					style={{ width: '100%' }}
					dropdownStyle={{ maxHeight: 300, overflow: 'auto' }}
					placeholder="请选择"
					allowClear
					treeDefaultExpandAll
					dropdownMatchSelectWidth
					className={styles['select-box']}
					onChange={handleChange}
				>
					{map(options, (optGroup) => (
						<TreeNode
							value={optGroup.title}
							title={optGroup.title}
							key={optGroup.title}
							disabled
						>
							{map(optGroup.data, (option) => (
								<TreeNode value={option} title={option} key={option} />
							))}
						</TreeNode>
					))}
				</TreeSelect>
			</Col>
			<Col
				style={{ lineHeight: 0, position: 'relative' }}
				span={10}
				id="drop-down"
			>
				<Dropdown
					visible={dropdownVisible}
					getPopupContainer={(triggerNode: any) => triggerNode}
					overlay={renderAnimateBox(value ? value.split(' ')[0] : '')}
					placement="bottomRight"
				>
					<Button
						size={'small'}
						className={styles['animate-btn']}
						onClick={() => setDropdownVisible(!dropdownVisible)}
					>
						Animate It
					</Button>
				</Dropdown>
			</Col>
		</Row>
	)
}
Example #4
Source File: CreateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
CreateForm: React.FC<CreateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange } = props;
    const [treeData, setTreeData] = useState<API.DeptList[]>([]);

    useEffect(() => {
        queryDepts().then((res) => {
            const top: API.DeptList = { id: 0, name: '暂无所属' };
            res.data.unshift(top)
            const depts = loopTreeItem(res.data);
            setTreeData(depts);
        });
    }, []);

    return (
        <ModalForm
            title="新建部门"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                createDept(v as API.DeptParams).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="name" label="名称" width="md" rules={[{ required: true }]} />
                <ProFormDigit name="sort" label="排序" width="md" fieldProps={{ precision: 0 }} />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级部门" name="parent_id" >
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择部门"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #5
Source File: TargetTreeSelect.tsx    From datart with Apache License 2.0 5 votes vote down vote up
TargetTreeSelect: FC<TargetTreeSelectProps> = ({
  treeData,
  filterBoardId,
  value,
  onChange,
  ...restProps
}) => {
  const t = useI18NPrefix(`viz.jump`);
  const _treeData = useMemo(() => {
    return disabledTreeData(treeData || [], filterBoardId);
  }, [treeData, filterBoardId]);
  const _onChange = useCallback(
    (value, label, extra) => {
      const allCheckednodes = extra?.allCheckedNodes,
        checkNode =
          allCheckednodes?.length > 0
            ? allCheckednodes[allCheckednodes?.length - 1]
            : null;
      const relType = checkNode?.node?.props?.relType,
        relId = checkNode?.node?.props?.relId;
      if (relId && relType) {
        onChange?.({ id: value, relId, relType });
      } else {
        onChange?.(undefined);
      }
    },
    [onChange],
  );
  const _value = useMemo(() => {
    return value?.id;
  }, [value]);
  return (
    <TreeSelect
      placeholder={t('target')}
      treeData={_treeData}
      treeDefaultExpandAll
      treeIcon
      showSearch
      value={_value}
      onChange={_onChange}
      {...restProps}
    />
  );
}
Example #6
Source File: MultiDropdownListFilter.tsx    From datart with Apache License 2.0 5 votes vote down vote up
MultiDropdownListFilter: FC<PresentControllerFilterProps> = memo(
  ({ viewId, view, condition, onConditionChange }) => {
    const [originalNodes, setOriginalNodes] = useState<RelationFilterValue[]>(
      condition?.value as RelationFilterValue[],
    );

    useFetchFilterDataByCondition(viewId, condition, setOriginalNodes, view);

    const handleSelectedChange = (keys: any) => {
      const newCondition = updateBy(condition!, draft => {
        draft.value = keys;
      });
      onConditionChange(newCondition);
    };
    const selectedNodes = useMemo(() => {
      if (Array.isArray(condition?.value)) {
        const item = condition?.value?.[0];
        if (typeof item === 'object') {
          const firstValues =
            (condition?.value as [])?.filter(n => {
              if (IsKeyIn(n as RelationFilterValue, 'key')) {
                return (n as RelationFilterValue).isSelected;
              }
              return false;
            }) || [];
          return firstValues?.map((n: RelationFilterValue) => n.key);
        } else {
          return condition?.value || [];
        }
      }
      return [];
    }, [condition]);
    return (
      <StyledMultiDropdownListFilter
        showSearch
        allowClear
        multiple
        treeCheckable
        treeDefaultExpandAll
        value={selectedNodes as any}
        onChange={handleSelectedChange}
      >
        {originalNodes?.map((n: RelationFilterValue) => {
          return (
            <TreeSelect.TreeNode key={n.key} value={n.key} title={n.label} />
          );
        })}
      </StyledMultiDropdownListFilter>
    );
  },
)
Example #7
Source File: MultiDropdownListFilter.tsx    From datart with Apache License 2.0 5 votes vote down vote up
StyledMultiDropdownListFilter = styled(TreeSelect)`
  width: 100%;
`
Example #8
Source File: edit.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
{TreeNode} = TreeSelect
Example #9
Source File: copy.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
{ TreeNode } = TreeSelect
Example #10
Source File: save.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
Save = (props: Props) => {
  const { form, form: { getFieldDecorator } } = props;
  const [categoryList, setCategoryList] = useState([]);
  const token = getAccessToken();

  const save = () => {
    form.validateFields((err, fileValue) => {
      if (err) return;

      fileValue.type = 'big_screen';
      fileValue.target="";
      fileValue.state = {
        text: "启用",
        value: "enabled"
      };

      api.screen.save(fileValue).then(res => {
        if (res.status === 200) {
          props.save();
          props.data != '' ? window.open(props.data+'#/build/'+res.result.id+'?token=' + token,'_blank') : message.error('配置错误,请联系管理员')
        }
      })
    })
  };

  useEffect(() => {
    api.categoty.queryNoPaging({}).then(res => {
      if (res.status === 200) {
        let list: any = [];
        res.result.map((item: any) => {
          list.push({ id: item.id, pId: item.parentId, value: item.id, title: item.name })
        });
        setCategoryList(list);
      }
    })
  }, []);
  return (
    <Modal
      visible
      title="新增大屏"
      onCancel={() => props.close()}
      onOk={() => {
        save()
      }}
    >
      <Form labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
        <Form.Item key="id" label="大屏ID">
          {getFieldDecorator('id', {
            rules: [{ required: true, message: '请输入大屏ID' }]
          })(<Input placeholder="请输入大屏ID" />)}
        </Form.Item>
        <Form.Item key="name" label="大屏名称">
          {getFieldDecorator('name', {
            rules: [{ required: true, message: '请输入大屏名称' }]
          })(<Input placeholder="请输入大屏名称" />)}
        </Form.Item>
        <Form.Item key="catalogId" label="分类">
          {getFieldDecorator('catalogId', {
            rules: [{required: true, message: '请选择分类'}],
          })(<TreeSelect
            allowClear treeDataSimpleMode showSearch
            placeholder="选择分类" treeData={categoryList}
            treeNodeFilterProp='title' searchPlaceholder='根据分类名称模糊查询'
          />)}
        </Form.Item>
        <Form.Item key="description" label="说明">
          {getFieldDecorator('description', {
            rules: [{ required: false, message: '请输入说明' }]
          })(<Input placeholder="请输入说明" />)}
        </Form.Item>
      </Form>
    </Modal>
  )
}
Example #11
Source File: CreateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
CreateForm: React.FC<CreateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange } = props;
    const [treeData, setTreeData] = useState<API.ApiList[]>([]);

    useEffect(() => {
        queryApis().then((res) => {
            const top: API.ApiList = { id: 0, name: '暂无所属' };
            res.data.unshift(top)
            const menus = loopTreeItem(res.data);
            setTreeData(menus);
        });
    }, []);

    return (
        <ModalForm
            title="新建接口"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                createApi(v as API.ApiParams).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="name" label="名称" width="md" rules={[{ required: true }]} />
                <ProFormText name="perms_tag" label="权限标识" width="md" rules={[{ required: true }]} />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText name="method" label="请求方式" width="md" />
                <ProFormText name="path" label="路径" width="md" />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText name="desc" label="说明" width="md" />
                <Form.Item label="上级接口" name="parent_id">
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择接口"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #12
Source File: edit.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
{TreeNode} = TreeSelect
Example #13
Source File: UpdateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
UpdateForm: React.FC<UpdateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange, values } = props;
    const [treeData, setTreeData] = useState<API.ApiList[]>([]);
    useEffect(() => {
        queryApis().then((res) => {
            const top: API.ApiList = { id: 0, name: '暂无所属' };
            res.data.unshift(top)
            const menus = loopTreeItem(res.data);
            setTreeData(menus);
        });
    }, []);

    return (
        <ModalForm
            title="更新接口"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                updateApi(v as API.ApiParams, values?.id).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText
                    name="name"
                    label="名称"
                    width="md"
                    rules={[{ required: true }]}
                    initialValue={values?.name}
                />
                <ProFormText
                    name="perms_tag"
                    label="权限标识"
                    width="md"
                    rules={[{ required: true }]}
                    initialValue={values?.perms_tag}
                />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText
                    name="path"
                    label="路径"
                    width="md"
                    initialValue={values?.path}
                />
                <ProFormText
                    name="method"
                    label="请求方式"
                    width="md"
                    initialValue={values?.method}
                />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText name="desc" label="说明" width="md" initialValue={values?.desc} />
                <Form.Item label="上级接口" name="parent_id" initialValue={values?.parent_id}>
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择接口"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #14
Source File: copy.tsx    From jetlinks-ui-antd with MIT License 5 votes vote down vote up
{ TreeNode } = TreeSelect
Example #15
Source File: UpdateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
UpdateForm: React.FC<UpdateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange, values } = props;
    const [treeData, setTreeData] = useState<API.DeptList[]>([]);
    useEffect(() => {
        queryDepts().then((res) => {
            const top: API.DeptList = { id: 0, name: '暂无所属' };
            res.data.unshift(top)
            const depts = loopTreeItem(res.data);
            setTreeData(depts);
        });
    }, []);

    return (
        <ModalForm
            title="更新部门"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                updateDept(v as API.DeptParams, values?.id).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText
                    name="name"
                    label="名称"
                    width="md"
                    initialValue={values?.name}
                    rules={[{ required: true }]}
                />
                <ProFormDigit
                    name="sort"
                    label="排序"
                    width="md"
                    initialValue={values?.sort}
                    fieldProps={{ precision: 0 }}
                />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级部门" name="parent_id" initialValue={values?.parent_id}>
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择部门"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #16
Source File: CreateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
CreateForm: React.FC<CreateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange } = props;
    const [treeData, setTreeData] = useState<API.DictList[]>([]);
    const { initialState, setInitialState } = useModel('@@initialState');

    useEffect(() => {
        queryDicts().then((res) => {
            const top: API.DictList = { id: 0, dict_value: '暂无所属', dict_key: '' };
            res.data.unshift(top)
            const dicts = loopTreeItem(res.data);
            setTreeData(dicts);
        });
    }, []);

    return (
        <ModalForm
            title="新建字典"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                createDict(v as API.DictParams).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        queryDictsByAllType().then((res) => setInitialState({ ...initialState, DictObj: res.data }));
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="dict_key" label="字典标签" width="md" rules={[{ required: true }]} />
                <ProFormText name="dict_value" label="字典键值" width="md" rules={[{ required: true }]} />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormDigit name="sort" label="排序" width="md" fieldProps={{ precision: 0 }} />
                <ProFormText name="desc" label="说明" width="md" />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级字典" name="parent_id">
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择字典"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm >
    );
}
Example #17
Source File: UpdateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
UpdateForm: React.FC<UpdateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange, values } = props;
    const [treeData, setTreeData] = useState<API.DictList[]>([]);
    const { initialState, setInitialState } = useModel('@@initialState');

    useEffect(() => {
        queryDicts().then((res) => {
            const top: API.DictList = { id: 0, dict_value: '暂无所属', dict_key: '' };
            res.data.unshift(top)
            const dicts = loopTreeItem(res.data);
            setTreeData(dicts);
        });
    }, []);

    return (
        <ModalForm
            title="更新字典"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                updateDict(v as API.DictParams, values?.id).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        queryDictsByAllType().then((res) => setInitialState({ ...initialState, DictObj: res.data }));
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText
                    name="dict_key"
                    label="字典标签"
                    width="md"
                    rules={[{ required: true }]}
                    initialValue={values?.dict_key}
                />
                <ProFormText
                    name="dict_value"
                    label="字典键值"
                    width="md"
                    rules={[{ required: true }]}
                    initialValue={values?.dict_value}
                />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormDigit name="sort" label="排序" width="md" initialValue={values?.sort} fieldProps={{ precision: 0 }} />
                <ProFormText name="desc" label="说明" initialValue={values?.desc} width="md" />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级字典" name="parent_id" initialValue={values?.parent_id}>
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择字典"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #18
Source File: CreateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
CreateForm: React.FC<CreateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange } = props;
    const [treeData, setTreeData] = useState<API.MenuList[]>([]);

    useEffect(() => {
        queryMenus().then((res) => {
            const top: API.MenuList = { id: 0, name: '顶级菜单'};
            res.data.unshift(top)
            const menus = loopTreeItem(res.data);
            setTreeData(menus);
        });
    }, []);

    return (
        <ModalForm
            title="新建菜单"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                createMenu(v as API.MenuParams).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="name" label="名称" width="md" rules={[{ required: true }]} />
                <ProFormText name="icon" label="图标" width="md" />
                <ProFormText name="path" label="路径" width="md" />
                <ProFormDigit name="sort" label="排序" width="md" fieldProps={{ precision: 0 }} />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级菜单" name="parent_id">
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择菜单"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #19
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
{ TreeNode } = TreeSelect
Example #20
Source File: select-version.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
SelectVersion = ({ onChangeVersion }: IProps) => {
  const [versionList, setVersionList] = React.useState<API_MARKET.VersionTreeItem[]>([]);
  const [selectVersionID, setSelectVersionID] = React.useState<number | undefined>();
  const { assetID, versionID } = routeInfoStore.useStore((s) => s.params);
  const getVersionList = React.useCallback(() => {
    if (assetID) {
      getVersionTree<Promise<API_MARKET.CommonResList<API_MARKET.VersionTreeItem[]>>>({
        assetID,
        patch: false,
        instantiation: false,
        access: false,
      }).then((res) => {
        if (res.success) {
          const list = res.data.list || [];
          setVersionList(list);
        }
      });
    }
  }, [assetID]);
  React.useEffect(() => {
    getVersionList();
  }, [getVersionList]);
  const handleChange = (id: number) => {
    setSelectVersionID(id);
    onChangeVersion(id);
  };
  const treeData = React.useMemo(() => {
    const [tree, id] = formatVersion(versionList, +versionID);
    setSelectVersionID(id);
    return tree;
  }, [versionList, versionID]);
  return (
    <TreeSelect
      value={selectVersionID}
      treeData={treeData}
      placeholder={i18n.t('default:please select version')}
      style={{ width: '100%' }}
      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
      treeDefaultExpandAll
      onSelect={handleChange}
      onFocus={getVersionList}
    />
  );
}
Example #21
Source File: UpdateForm.tsx    From anew-server with MIT License 5 votes vote down vote up
UpdateForm: React.FC<UpdateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange, values } = props;
    const [treeData, setTreeData] = useState<API.MenuList[]>([]);
    useEffect(() => {
        queryMenus().then((res) => {
            const top: API.MenuList = { id: 0, name: '顶级菜单' };
            res.data.unshift(top)
            const menus = loopTreeItem(res.data);
            setTreeData(menus);
        });
    }, []);

    return (
        <ModalForm
            title="更新菜单"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                updateMenu(v as API.MenuParams, values?.id).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText
                    name="name"
                    label="名称"
                    width="md"
                    initialValue={values?.name}
                    rules={[{ required: true }]}
                />
                <ProFormText name="icon" label="图标" width="md" initialValue={values?.icon} />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText name="path" label="路径" width="md" initialValue={values?.path} />
                <ProFormDigit
                    name="sort"
                    label="排序"
                    width="md"
                    initialValue={values?.sort}
                    fieldProps={{ precision: 0 }}
                />
            </ProForm.Group>
            <ProForm.Group>
                <Form.Item label="上级菜单" name="parent_id" initialValue={values?.parent_id}>
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择菜单"
                    />
                </Form.Item>
            </ProForm.Group>
        </ModalForm>
    );
}
Example #22
Source File: index.tsx    From brick-design with MIT License 5 votes vote down vote up
{ TreeNode } = TreeSelect
Example #23
Source File: UpdateForm.tsx    From anew-server with MIT License 4 votes vote down vote up
UpdateForm: React.FC<UpdateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange, values } = props;
    const [treeData, setTreeData] = useState<API.DeptList[]>([]);
    useEffect(() => {
        queryDepts().then((res) => {
            const top: API.DeptList = { id: 0, name: '暂无所属'};
            res.data.unshift(top)
            const depts = loopTreeItem(res.data);
            setTreeData(depts);
        });
    }, []);

    return (
        <ModalForm
            title="更新用户"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                updateUser(v as API.UserParams, values?.id).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="username" label="用户名" width="md" initialValue={values?.username} rules={[{ required: true }]} />
                <ProFormText name="name" label="姓名" width="md" initialValue={values?.name} rules={[{ required: true }]} />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText
                    name="mobile"
                    label="手机"
                    width="md"
                    initialValue={values?.mobile}
                    rules={[
                        {
                            pattern: /^1(?:70\d|(?:9[89]|8[0-24-9]|7[135-8]|66|5[0-35-9])\d|3(?:4[0-8]|[0-35-9]\d))\d{7}$/,
                            message: '请输入正确的手机号码',
                        },
                    ]}
                />
                <ProFormText
                    name="email"
                    label="邮箱"
                    width="md"
                    initialValue={values?.email}
                    rules={[
                        {
                            type: 'email',
                            message: '请输入正确的邮箱地址',
                        },
                    ]}
                />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormSelect
                    name="role_id"
                    label="角色"
                    width="md"
                    hasFeedback
                    initialValue={values?.role.id}
                    request={() =>
                        queryRoles().then((res) =>
                            res.data.data.map((item: any) => ({
                                label: item.name,
                                value: item.id,
                            })),
                        )
                    }
                    rules={[{ required: true, message: '请选择角色' }]}
                />
                <Form.Item label="部门" name="dept_id" initialValue={values?.dept.id}>
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择部门"
                    />
                </Form.Item>

            </ProForm.Group>
            <ProForm.Group>
                <ProFormSelect
                    name="status"
                    label="状态"
                    width="md"
                    hasFeedback
                    initialValue={values?.status}
                    options={[
                        {
                            value: true as any,
                            label: '激活',
                        },
                        {
                            value: false as any,
                            label: '禁用',
                        },
                    ]}
                    rules={[{ required: true, message: '请选择状态' }]}
                />
                <ProFormText.Password label="重置密码" name="password" width="md" placeholder="输入则修改密码" />
            </ProForm.Group>

        </ModalForm>
    );
}
Example #24
Source File: SaveForm.tsx    From datart with Apache License 2.0 4 votes vote down vote up
export function SaveForm({ formProps, ...modalProps }: SaveFormProps) {
  const {
    vizType,
    type,
    visible,
    initialValues,
    onSave,
    onCancel,
    onAfterClose,
  } = useContext(SaveFormContext);
  const selectVizFolderTree = useMemo(makeSelectVizFolderTree, []);
  const saveFolderLoading = useSelector(selectSaveFolderLoading);
  const saveStoryboardLoading = useSelector(selectSaveStoryboardLoading);
  const orgId = useSelector(selectOrgId);
  const isOwner = useSelector(selectIsOrgOwner);
  const permissionMap = useSelector(selectPermissionMap);
  const formRef = useRef<FormInstance>();
  const t = useI18NPrefix('viz.saveForm');
  const tg = useI18NPrefix('global');

  const getDisabled = useCallback(
    (_, path: string[]) =>
      !getCascadeAccess(
        isOwner,
        permissionMap,
        ResourceTypes.Viz,
        path,
        PermissionLevels.Create,
      ),
    [isOwner, permissionMap],
  );

  const treeData = useSelector(state =>
    selectVizFolderTree(state, { id: initialValues?.id, getDisabled }),
  );

  const save = useCallback(
    values => {
      onSave(values, onCancel);
    },
    [onSave, onCancel],
  );

  const afterClose = useCallback(() => {
    formRef.current?.resetFields();
    onAfterClose && onAfterClose();
  }, [onAfterClose]);

  useEffect(() => {
    if (initialValues) {
      formRef.current?.setFieldsValue(initialValues);
    }
  }, [initialValues]);

  const boardTips = () => {
    return (
      <>
        <span>{t('boardType.autoTips')}</span>
        <br />
        <span>{t('boardType.freeTips')}</span>
      </>
    );
  };

  return (
    <ModalForm
      formProps={formProps}
      {...modalProps}
      title={t(`vizType.${vizType.toLowerCase()}`)}
      type={type}
      visible={visible}
      confirmLoading={saveFolderLoading || saveStoryboardLoading}
      onSave={save}
      onCancel={onCancel}
      afterClose={afterClose}
      ref={formRef}
    >
      <IdField name="id" hidden={type === CommonFormTypes.Add}>
        <Input />
      </IdField>
      <Form.Item
        name="name"
        label={t('name')}
        rules={[
          {
            required: true,
            message: `${t('name')}${tg('validation.required')}`,
          },
          {
            validator: debounce((_, value) => {
              if (!value || initialValues?.name === value) {
                return Promise.resolve();
              }
              if (!value.trim()) {
                return Promise.reject(
                  `${t('name')}${tg('validation.required')}`,
                );
              }
              const parentId = formRef.current?.getFieldValue('parentId');
              const data = {
                name: value,
                orgId,
                vizType,
                parentId: parentId || null,
              };
              return fetchCheckName('viz', data);
            }, DEFAULT_DEBOUNCE_WAIT),
          },
        ]}
      >
        <Input />
      </Form.Item>
      {vizType === 'DATACHART' && !(type === CommonFormTypes.SaveAs) && (
        <Form.Item name="description" label={t('description')}>
          <Input.TextArea />
        </Form.Item>
      )}
      {vizType === 'DASHBOARD' && type === CommonFormTypes.Add && (
        <Form.Item
          rules={[
            {
              required: true,
              message: t('boardType.requiredMessage'),
            },
          ]}
          name="boardType"
          label={t('boardType.label')}
          tooltip={boardTips()}
        >
          <Radio.Group>
            <Radio.Button value={BoardTypes[0]}>
              {t('boardType.auto')}
            </Radio.Button>
            <Radio.Button value={BoardTypes[1]}>
              {t('boardType.free')}
            </Radio.Button>
          </Radio.Group>
        </Form.Item>
      )}
      {vizType !== 'STORYBOARD' && (
        <Form.Item name="parentId" label={t('parent')}>
          <TreeSelect
            placeholder={t('root')}
            treeData={treeData}
            allowClear
            onChange={() => {
              formRef.current?.validateFields();
            }}
          />
        </Form.Item>
      )}
    </ModalForm>
  );
}
Example #25
Source File: CreateForm.tsx    From anew-server with MIT License 4 votes vote down vote up
CreateForm: React.FC<CreateFormProps> = (props) => {
    const { actionRef, modalVisible, handleChange } = props;
    const [treeData, setTreeData] = useState<API.DeptList[]>([]);

    useEffect(() => {    
        queryDepts().then((res) => {
            const top: API.DeptList = { id: 0, name: '暂无所属' };
            res.data.unshift(top)
            const depts = loopTreeItem(res.data);
            setTreeData(depts);
        });
    }, []);

    return (
        <ModalForm
            title="新建用户"
            visible={modalVisible}
            onVisibleChange={handleChange}
            onFinish={async (v) => {
                createUser(v as API.UserParams).then((res) => {
                    if (res.code === 200 && res.status === true) {
                        message.success(res.message);
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                    }
                });
                return true;
            }}
        >
            <ProForm.Group>
                <ProFormText name="username" label="用户名" width="md" rules={[{ required: true }]} />
                <ProFormText name="name" label="姓名" width="md" rules={[{ required: true }]} />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormText
                    name="mobile"
                    label="手机"
                    width="md"
                    rules={[
                        {
                            pattern: /^1(?:70\d|(?:9[89]|8[0-24-9]|7[135-8]|66|5[0-35-9])\d|3(?:4[0-8]|[0-35-9]\d))\d{7}$/,
                            message: '请输入正确的手机号码',
                        },
                    ]}
                />
                <ProFormText
                    name="email"
                    label="邮箱"
                    width="md"
                    rules={[
                        {
                            type: 'email',
                            message: '请输入正确的邮箱地址',
                        },
                    ]}
                />
            </ProForm.Group>
            <ProForm.Group>
                <ProFormSelect
                    name="role_id"
                    label="角色"
                    width="md"
                    hasFeedback
                    request={() =>
                        queryRoles().then((res) =>
                            res.data.data.map((item: any) => ({
                                label: item.name,
                                value: item.id,
                            })),
                        )
                    }
                    rules={[{ required: true, message: '请选择角色' }]}
                />
                {/* <Form.Item label="部门" name="dept_id" width="md"> */}
                <Form.Item label="部门" name="dept_id">
                    <TreeSelect
                        style={{ width: 330 }}
                        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                        treeData={treeData}
                        placeholder="请选择部门"
                    />
                </Form.Item>
                <ProFormText.Password label="密码" name="password" width="md" rules={[{ required: true }]} />
            </ProForm.Group>
        </ModalForm>
    );
}
Example #26
Source File: SaveForm.tsx    From datart with Apache License 2.0 4 votes vote down vote up
export function SaveForm({ formProps, ...modalProps }: SaveFormProps) {
  const [advancedVisible, setAdvancedVisible] = useState(false);
  const [concurrencyControl, setConcurrencyControl] = useState(true);
  const [cache, setCache] = useState(false);
  const selectViewFolderTree = useMemo(makeSelectViewFolderTree, []);
  const [expensiveQuery, setExpensiveQuery] = useState(false); // beta.2 add expensiveQuery
  const {
    type,
    visible,
    simple,
    parentIdLabel,
    initialValues,
    onSave,
    onCancel,
    onAfterClose,
  } = useContext(SaveFormContext);
  const isOwner = useSelector(selectIsOrgOwner);
  const permissionMap = useSelector(selectPermissionMap);

  const getDisabled = useCallback(
    (_, path: string[]) =>
      !getCascadeAccess(
        isOwner,
        permissionMap,
        ResourceTypes.View,
        path,
        PermissionLevels.Create,
      ),
    [isOwner, permissionMap],
  );

  const folderTree = useSelector(state =>
    selectViewFolderTree(state, { id: initialValues?.id, getDisabled }),
  );
  const currentEditingView = useSelector(selectCurrentEditingView);
  const orgId = useSelector(selectOrgId);
  const formRef = useRef<FormInstance>();
  const t = useI18NPrefix('view.saveForm');
  const tg = useI18NPrefix('global');

  useEffect(() => {
    if (initialValues) {
      formRef.current?.setFieldsValue({
        ...initialValues,
        parentId: initialValues.parentId || void 0,
      });
    }
  }, [initialValues]);

  const toggleAdvanced = useCallback(() => {
    setAdvancedVisible(!advancedVisible);
  }, [advancedVisible]);

  const save = useCallback(
    values => {
      onSave(
        {
          ...values,
          config: { version: APP_CURRENT_VERSION, ...values.config },
        },
        onCancel,
      );
    },
    [onSave, onCancel],
  );

  const afterClose = useCallback(() => {
    formRef.current?.resetFields();
    setAdvancedVisible(false);
    setConcurrencyControl(true);
    setCache(false);
    onAfterClose && onAfterClose();
    setExpensiveQuery(false);
  }, [onAfterClose]);

  return (
    <ModalForm
      formProps={formProps}
      {...modalProps}
      title={t(simple ? 'folder' : 'title')}
      type={type}
      visible={visible}
      confirmLoading={currentEditingView?.stage === ViewViewModelStages.Saving}
      onSave={save}
      onCancel={onCancel}
      afterClose={afterClose}
      ref={formRef}
    >
      <Form.Item
        name="name"
        label={t('name')}
        rules={[
          {
            required: true,
            message: `${t('name')}${tg('validation.required')}`,
          },
          {
            validator: debounce((_, value) => {
              if (!value || initialValues?.name === value) {
                return Promise.resolve();
              }
              if (!value.trim()) {
                return Promise.reject(
                  `${t('name')}${tg('validation.required')}`,
                );
              }
              const parentId = formRef.current?.getFieldValue('parentId');
              const data = {
                name: value,
                orgId,
                parentId: parentId || null,
              };
              return fetchCheckName('views', data);
            }, DEFAULT_DEBOUNCE_WAIT),
          },
        ]}
      >
        <Input />
      </Form.Item>
      <Form.Item name="parentId" label={parentIdLabel}>
        <TreeSelect
          placeholder={t('root')}
          treeData={folderTree || []}
          allowClear
          onChange={() => {
            formRef.current?.validateFields();
          }}
        />
      </Form.Item>
      {!simple && initialValues?.config && (
        <>
          <AdvancedToggle
            type="link"
            icon={<DoubleRightOutlined rotate={advancedVisible ? -90 : 90} />}
            onClick={toggleAdvanced}
          >
            {t('advanced')}
          </AdvancedToggle>
          <AdvancedWrapper show={advancedVisible}>
            <Form.Item
              name={['config', 'concurrencyControl']}
              label={t('concurrencyControl')}
              valuePropName="checked"
              initialValue={concurrencyControl}
            >
              <Switch onChange={setConcurrencyControl} />
            </Form.Item>
            <Form.Item
              name={['config', 'concurrencyControlMode']}
              label={t('concurrencyControlMode')}
              initialValue={ConcurrencyControlModes.DirtyRead}
            >
              <Radio.Group disabled={!concurrencyControl}>
                {Object.values(ConcurrencyControlModes).map(value => (
                  <Radio key={value} value={value}>
                    {t(value.toLowerCase())}
                  </Radio>
                ))}
              </Radio.Group>
            </Form.Item>
            <Form.Item
              name={['config', 'cache']}
              label={t('cache')}
              valuePropName="checked"
              initialValue={cache}
            >
              <Switch onChange={setCache} />
            </Form.Item>
            <Form.Item
              name={['config', 'cacheExpires']}
              label={t('cacheExpires')}
              initialValue={0}
            >
              <InputNumber disabled={!cache} />
            </Form.Item>
            <Form.Item
              wrapperCol={{ span: 13, offset: 9 }}
              name={['config', 'expensiveQuery']}
              initialValue={expensiveQuery}
              valuePropName="checked"
            >
              <Checkbox>{t('expensiveQuery')}</Checkbox>
            </Form.Item>
          </AdvancedWrapper>
        </>
      )}
    </ModalForm>
  );
}
Example #27
Source File: ChartDataViewPanel.tsx    From datart with Apache License 2.0 4 votes vote down vote up
ChartDataViewPanel: FC<{
  dataView?: ChartDataView;
  defaultViewId?: string;
  chartConfig?: ChartConfig;
  onDataViewChange?: () => void;
}> = memo(({ dataView, defaultViewId, chartConfig, onDataViewChange }) => {
  const t = useI18NPrefix(`viz.workbench.dataview`);
  const dispatch = useDispatch();
  const dataviewTreeSelector = useMemo(makeDataviewTreeSelector, []);
  const getSelectable = useCallback(v => !v.isFolder, []);
  const dataviewTreeData = useSelector(state =>
    dataviewTreeSelector(state, getSelectable),
  );
  const [showModal, modalContextHolder] = useStateModal({});
  const [isDisplayAddNewModal, setIsDisplayAddNewModal] = useToggle();
  const views = useSelector(dataviewsSelector);

  const path = useMemo(() => {
    return views?.length && dataView
      ? getPath(
          views as Array<{ id: string; parentId: string }>,
          { id: dataView.id, parentId: dataView.parentId },
          ResourceTypes.View,
        )
      : [];
  }, [views, dataView]);

  const managePermission = useCascadeAccess({
    module: ResourceTypes.View,
    path,
    level: PermissionLevels.Manage,
  });
  const allowManage = managePermission(true);
  const allowEnableView = useAccess({
    type: 'module',
    module: ResourceTypes.View,
    id: '',
    level: PermissionLevels.Enable,
  })(true);
  const history = useHistory();

  const handleDataViewChange = useCallback(
    value => {
      if (dataView?.id === value) {
        return false;
      }
      let Data = chartConfig?.datas?.filter(v => v.rows && v.rows.length);
      if (Data?.length) {
        (showModal as Function)({
          title: '',
          modalSize: StateModalSize.XSMALL,
          content: () => t('toggleViewTip'),
          onOk: () => {
            onDataViewChange?.();
            dispatch(fetchViewDetailAction(value));
          },
        });
      } else {
        onDataViewChange?.();
        dispatch(fetchViewDetailAction(value));
      }
    },
    [
      chartConfig?.datas,
      dataView?.id,
      dispatch,
      onDataViewChange,
      showModal,
      t,
    ],
  );

  const filterDateViewTreeNode = useCallback(
    (inputValue, node) =>
      node.title.toLowerCase().includes(inputValue.toLowerCase()),
    [],
  );

  const handleAddNewOrUpdateComputedField = async (
    field?: ChartDataViewMeta,
    originId?: string,
  ) => {
    if (!field) {
      return Promise.reject('field is empty');
    }

    let validComputedField = true;
    try {
      validComputedField = await checkComputedFieldAsync(
        dataView?.sourceId,
        field.expression,
      );
    } catch (error) {
      validComputedField = false;
    }

    if (!validComputedField) {
      message.error('validate function computed field failed');
      return Promise.reject('validate function computed field failed');
    }
    const otherComputedFields = dataView?.computedFields?.filter(
      f => f.id !== originId,
    );
    const isNameConflict = !!otherComputedFields?.find(f => f.id === field?.id);
    if (isNameConflict) {
      message.error(
        'The computed field has already been exist, please choose anohter one!',
      );
      return Promise.reject(
        'The computed field has already been exist, please choose anohter one!',
      );
    }

    const currentFieldIndex = (dataView?.computedFields || []).findIndex(
      f => f.id === originId,
    );

    if (currentFieldIndex >= 0) {
      const newComputedFields = updateByKey(
        dataView?.computedFields,
        currentFieldIndex,
        field,
      );
      dispatch(
        workbenchSlice.actions.updateCurrentDataViewComputedFields(
          newComputedFields!,
        ),
      );
      return;
    }
    const newComputedFields = (dataView?.computedFields || []).concat([field]);
    dispatch(
      workbenchSlice.actions.updateCurrentDataViewComputedFields(
        newComputedFields,
      ),
    );
  };

  const handleDeleteComputedField = fieldId => {
    const newComputedFields = (dataView?.computedFields || []).filter(
      f => f.id !== fieldId,
    );
    dispatch(
      workbenchSlice.actions.updateCurrentDataViewComputedFields(
        newComputedFields,
      ),
    );
  };

  const handleEditComputedField = fieldId => {
    const editField = (dataView?.computedFields || []).find(
      f => f.id === fieldId,
    );
    handleAddOrEditComputedField(editField);
  };

  const handleAddOrEditComputedField = field => {
    (showModal as Function)({
      title: t('createComputedFields'),
      modalSize: StateModalSize.MIDDLE,
      content: onChange => (
        <ChartComputedFieldSettingPanel
          computedField={field}
          sourceId={dataView?.sourceId}
          fields={dataView?.meta}
          variables={dataView?.meta?.filter(
            c => c.category === ChartDataViewFieldCategory.Variable,
          )}
          allComputedFields={dataView?.computedFields}
          onChange={onChange}
        />
      ),
      onOk: newField => handleAddNewOrUpdateComputedField(newField, field?.id),
    });
  };

  const sortedMetaFields = useMemo(() => {
    const computedFields = dataView?.computedFields?.filter(
      v => v.category !== ChartDataViewFieldCategory.DateLevelComputedField,
    );
    const allFields = (dataView?.meta || []).concat(computedFields || []);
    const hierarchyFields = allFields.filter(
      f => f.role === ColumnRole.Hierarchy,
    );
    const allNonHierarchyFields = allFields.filter(
      f => f.role !== ColumnRole.Hierarchy,
    );
    const stringFields = allNonHierarchyFields.filter(
      f => f.type === DataViewFieldType.STRING,
    );
    const numericFields = allNonHierarchyFields.filter(
      f => f.type === DataViewFieldType.NUMERIC,
    );
    const dateFields = allNonHierarchyFields.filter(
      f => f.type === DataViewFieldType.DATE,
    );
    return [
      ...hierarchyFields,
      ...dateFields,
      ...stringFields,
      ...numericFields,
    ];
  }, [dataView?.meta, dataView?.computedFields]);

  const editView = useCallback(() => {
    let orgId = dataView?.orgId as string;
    let viewId = dataView?.id as string;
    history.push(`/organizations/${orgId}/views/${viewId}`);
  }, [dataView?.id, dataView?.orgId, history]);

  const handleConfirmVisible = useCallback(() => {
    (showModal as Function)({
      title: '',
      modalSize: StateModalSize.XSMALL,
      content: () => t('editViewTip'),
      onOk: editView,
    });
  }, [editView, showModal, t]);

  useMount(() => {
    if (defaultViewId) {
      handleDataViewChange(defaultViewId);
    }
  });

  return (
    <StyledChartDataViewPanel>
      <Header>
        <Tooltip placement="topLeft" title={t('editView')}>
          <ToolbarButton
            disabled={!(allowEnableView && allowManage && dataView)}
            iconSize={14}
            icon={<FormOutlined />}
            size="small"
            onClick={handleConfirmVisible}
          />
        </Tooltip>
        <TreeSelect
          showSearch
          placeholder={t('plsSelectDataView')}
          className="view-selector"
          treeData={dataviewTreeData}
          value={dataView?.id}
          onChange={handleDataViewChange}
          filterTreeNode={filterDateViewTreeNode}
          bordered={false}
        />
        <Popover
          placement="bottomRight"
          visible={isDisplayAddNewModal}
          onVisibleChange={() => setIsDisplayAddNewModal()}
          trigger="click"
          content={
            <ul>
              <li
                onClick={() => {
                  setIsDisplayAddNewModal();
                  handleAddOrEditComputedField(null);
                }}
              >
                {t('createComputedFields')}
              </li>
              {/* <li>{t('createVariableFields')}</li> */}
            </ul>
          }
        >
          <ToolbarButton icon={<PlusOutlined />} size="small" />
        </Popover>
        {modalContextHolder}
      </Header>
      <ChartDraggableSourceGroupContainer
        meta={sortedMetaFields}
        onDeleteComputedField={handleDeleteComputedField}
        onEditComputedField={handleEditComputedField}
      />
    </StyledChartDataViewPanel>
  );
})
Example #28
Source File: copy.tsx    From jetlinks-ui-antd with MIT License 4 votes vote down vote up
Save = (props: Props) => {
  const { form, form: { getFieldDecorator } } = props;
  const [categoryList, setCategoryList] = useState([]);
  const token = getAccessToken();

  const save = () => {
    form.validateFields((err, fileValue) => {
      if (err) return;
      let param = {
        description: fileValue.description,
        id: fileValue.id,
        name: fileValue.name,
        type: "big_screen",
        target: "",
        metadata: props.data.metadata || "",
        catalogId: fileValue.categoryId,
        state:{
            text: "启用",
            value: "enabled"
        }
      }
      api.screen.save(param).then(res => {
        if (res.status === 200) {
          props.save()
          props.data.url != '' ? window.open(props.data.url+'#/build/'+res.result.id+'?token=' + token,'_blank') : message.error('配置错误,请联系管理员')
        }
      })
    })
  };
  let getView = (view: any) => {
    return (
      <TreeNode title={view.name} value={view.id} key={view.id}>
        {
          view.children && view.children.length > 0 ? view.children.map((v: any) => {
            return getView(v)
          }) : ''
        }
      </TreeNode>
    )
  };
  useEffect(() => {
    api.categoty.query_tree({}).then(res => {
      if (res.status === 200) {
        setCategoryList(res.result)
      }
    })
  }, []);
  return (
    <Modal
      visible
      title="复制大屏"
      onCancel={() => props.close()}
      onOk={() => {
        save()
      }}
    >
      <Form labelCol={{ span: 4 }} wrapperCol={{ span: 20 }}>
        <Form.Item key="id" label="大屏ID">
          {getFieldDecorator('id', {
            rules: [{ required: true, message: '请输入大屏ID' }]
          })(<Input placeholder="请输入大屏ID" />)}
        </Form.Item>
        <Form.Item key="name" label="大屏名称">
          {getFieldDecorator('name', {
            rules: [{ required: true, message: '请输入大屏名称' }]
          })(<Input placeholder="请输入大屏名称" />)}
        </Form.Item>
        <Form.Item key="categoryId" label="分类">
          {getFieldDecorator('categoryId', {
            rules: [{ required: true, message: '请选择分类' }]
          })(<TreeSelect
            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
            placeholder="请选择分类"
            allowClear
          >
            {
              categoryList.map((v: any) => {
                return getView(v)
              })
            }
          </TreeSelect>)}
        </Form.Item>
        <Form.Item key="description" label="说明">
          {getFieldDecorator('description', {
            rules: [{ required: false, message: '请输入说明' }]
          })(<Input placeholder="请输入说明" />)}
        </Form.Item>
      </Form>
    </Modal>
  )
}
Example #29
Source File: index.tsx    From antdp with MIT License 4 votes vote down vote up
QuickForm: QuickFormComponent = (props, ref) => {
  const {
    collapseAttributes,
    panelAttributes,
    visible = false,
    type = 'cardform',
    extra,
    formDatas,
    colspan = 3,
    header,
    defaultFormLayout = 'vertical',
    defaultFormItemLayout = formDefaultFormItemLayout,
    size = 'default',
    formHide,
    initialHide,
    ...otherProps
  } = props;

  const [hide] = useFormItemHide(formHide)
  hide.setInitialValues(initialHide || {}, true)

  const HideFormItemDoM = []; // 隐藏的表单
  const FormItemDoM = [];
  let rowcolspan: string | any; // col 里的布局
  let formitemlayout: string | any; // formitem 的布局

  for (var i = 0; i < formDatas.length; i++) {
    if (formDatas[i].hideInForm) {
      HideFormItemDoM.push(formDatas[i]);
    } else {
      FormItemDoM.push(formDatas[i]);
    }
  }
  // 计算一个row里排几个表单;
  const result = [];
  for (let i = 0, j = FormItemDoM.length; i < j; i++) {
    if (FormItemDoM[i].full) {
      result.push(FormItemDoM.slice(i, i + 1));
    } else {
      if (FormItemDoM[i + 1] && FormItemDoM[i + 1].full) {
        result.push(FormItemDoM.slice(i, i + 1));
      } else if (FormItemDoM[i].defaultcolspan) {
        result.push(FormItemDoM.slice(i, i + FormItemDoM[i].defaultcolspan));
        i = i + FormItemDoM[i].defaultcolspan - 1;
      } else {
        result.push(FormItemDoM.slice(i, i + colspan));
        i = i + colspan - 1;
      }
    }
  }
  // 渲染成表单;
  const CollapseFormDoM = (item: any, idx: React.Key | null | undefined) => {
    const {
      label,
      name,
      attributes,
      type,
      options,
      onlyimg,
      defaultFormItemLayout,
      full,
      defaultRowColspan,
      hideInForm,
      descItem,
      render,
      // 用于判断是否需要进行隐藏显示 (在组件外层包裹一层组件用于控制item显示和隐藏)
      isHide,
      ...otherts
    } = item;
    const dataList = options || [];
    const optionDatas =
      dataList &&
      dataList.length > 0 &&
      dataList.map(
        (
          { value, label, ...others }: any,
          _idx: React.Key | null | undefined,
        ) => {
          if (type === 'select' || type === 'Select') {
            return (
              <Option value={value} key={_idx} {...others}>
                {label}
              </Option>
            );
          } else if (type === 'radio' || type === 'Radio') {
            return (
              <Radio.Button value={value} key={_idx} {...others}>
                {label}
              </Radio.Button>
            );
          }
        },
      );
    const selectOption = optionDatas ? optionDatas : [];
    const rowcolspan_num = [
      colLayout_one,
      colLayout_two,
      colLayout_third,
      colLayout_fourth,
    ];
    const formitemlayout_num = [
      fromItemLayout_conspan_one,
      fromItemLayout_conspan_two,
      fromItemLayout_conspan_third,
      fromItemLayout_conspan_fourth,
    ];
    if (colspan && full) {
      rowcolspan = colLayout_one;
      if (colspan === 3 || colspan === 4) {
        if (props.defaultFormItemLayout) {
          // 如果FormCollapse组件上带有defaulFormItemLayout参数
          formitemlayout = props.defaultFormItemLayout;
          // eslint-disable-next-line max-depth
          if (item.defaultFormItemLayout || item.defaultRowColspan) {
            // 如果FormCollapse组件内部的某个小组件带有defaulFormItemLayout参数
            formitemlayout = item.defaultFormItemLayout;
            rowcolspan = item.defaultRowColspan; // 单独的表单col 布局
          }
        } else if (item.defaultFormItemLayout || item.defaultRowColspan) {
          //FormCollapse组件内部只有某个小组件带了defaulFormItemLayout参数
          formitemlayout = item.defaultFormItemLayout;
          rowcolspan = item.defaultRowColspan; // 单独的表单col 布局
        } else {
          formitemlayout = fromItemLayout_third_row;
        }
      } else {
        formitemlayout = fromItemLayout_two_row;
      }
    } else {
      rowcolspan = rowcolspan_num[colspan - 1];
      if (props.defaultFormItemLayout) {
        formitemlayout = props.defaultFormItemLayout;
        if (item.defaultFormItemLayout || item.defaultRowColspan) {
          // 如果FormCollapse组件内部的某个小组件带有defaultFormItemLayout参数
          formitemlayout = item.defaultFormItemLayout;
          rowcolspan = item.defaultRowColspan; // 单独的表单col 布局
        }
      } else if (item.defaultFormItemLayout || item.defaultRowColspan) {
        formitemlayout =
          item.defaultFormItemLayout || formitemlayout_num[colspan - 1];
        rowcolspan = item.defaultRowColspan; // 单独的表单col 布局
      } else {
        formitemlayout = formitemlayout_num[colspan - 1];
      }
    }

    // 上传图片的按钮展示
    const uploadButtonDom = () => {
      if (item.attributes.listType === 'picture-card') {
        if (item.attributes.imageUrl && item.attributes.imageUrl !== '') {
          return (
            <img
              src={item.attributes.imageUrl}
              alt="avatar"
              style={{ width: '100%' }}
            />
          );
        } else if (item.attributes.fileList) {
          // 上传的图片大于或等于8张时 并且 没有onlyimg参数,显示icon上传按钮
          if (item.attributes.fileList.length >= 8 && !onlyimg) {
            return (
              <div>
                {item.attributes.loading === 'loading' ? (
                  <LoadingOutlined />
                ) : (
                  <PlusOutlined />
                )}
                <div className="ant-upload-text">上传</div>
              </div>
            );
            // 上传的图片大于或等于maxCount张时 并且 有onlyimg参数,不显示上传按钮
          } else if (item.attributes.maxCount && item.attributes.fileList.length >= item.attributes.maxCount && onlyimg) {
            return null;
          }
          return (
            <div>
              {item.attributes.loading === 'loading' ? (
                <LoadingOutlined />
              ) : (
                <PlusOutlined />
              )}
              <div className="ant-upload-text">上传</div>
            </div>
          );
        }
      } else {
        return (
          <div>
            <Button>
              <UploadOutlined />
              上传
            </Button>
          </div>
        );
      }
    };
    let renderItem = (
      <Col
        key={idx}
        style={{
          display: item.hideInForm ? 'none' : 'block',
          padding:
            defaultFormLayout && defaultFormLayout === 'vertical'
              ? '0px 12px 8px 12px'
              : '0',
        }}
        className={
          defaultFormLayout && defaultFormLayout === 'vertical'
            ? 'antdp-FormCol'
            : ''
        }
        {...rowcolspan}
      >
        <FormItem
          className="antdp-FormItem"
          colon={false}
          label={label}
          name={name}
          {...(defaultFormLayout && defaultFormLayout === 'vertical'
            ? null
            : formitemlayout)}
          {...otherts}
        >
          {name ? (
            (() => {
              // 组件基础参数
              const componentprams = {
                size: size ? size : 'small',
                ...attributes,
              };
              if (type === 'select' || type === 'Select') {
                return (
                  <Select
                    dropdownMatchSelectWidth={false}
                    allowClear
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  >
                    {selectOption}
                  </Select>
                );
              } else if (type === 'radio' || type === 'Radio') {
                return (
                  <Radio.Group size={size ? size : 'small'} {...attributes}>
                    {selectOption}
                  </Radio.Group>
                );
              } else if (type === 'datePicker' || type === 'DatePicker') {
                return (
                  <DatePicker
                    locale={locale}
                    style={{ width: '100%' }}
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'monthPicker' || type === 'MonthPicker') {
                return (
                  <MonthPicker
                    locale={locale}
                    style={{ width: '100%' }}
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'rangePicker' || type === 'RangePicker') {
                return (
                  <RangePicker
                    locale={locale}
                    style={{ width: '100%' }}
                    {...componentprams}
                  />
                );
              } else if (
                type === 'timepicker' ||
                type === 'timePicker' ||
                type === 'TimePicker'
              ) {
                return (
                  <TimePicker
                    locale={locale}
                    style={{ width: '100%' }}
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'cascader' || type === 'Cascader') {
                return (
                  <Cascader
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'textarea' || type === 'TextArea') {
                return (
                  <Input.TextArea
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'inputNumber' || type === 'InputNumber') {
                return (
                  <InputNumber
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    style={{ width: '100%' }}
                    {...componentprams}
                  />
                );
              } else if (type === 'treeSelect' || type === 'TreeSelect') {
                return (
                  <TreeSelect
                    placeholder={
                      attributes && attributes.disabled ? '' : `请选择${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'checkbox' || type === 'Checkbox') {
                if (
                  (item.options && item.options.length > 0) ||
                  (item.option && item.option.length > 0)
                ) {
                  return (
                    <Checkbox.Group
                      options={item.options || item.option}
                      {...attributes}
                    />
                  );
                }
                return (
                  <Checkbox {...attributes}>
                    {label || item.checkboxLable}
                  </Checkbox>
                );
              } else if (type === 'UploadGrid' || type === 'uploadGrid') {
                return (
                  <UploadGrid {...attributes}>{uploadButtonDom()}</UploadGrid>
                );
              } else if (type === 'autoComplete' || type === 'AutoComplete') {
                return (
                  <AutoComplete
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'Password') {
                return (
                  <Input.Password
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    {...componentprams}
                  />
                );
              } else if (type === 'inputCount' || type === 'InputCount') {
                return (
                  <InputCount
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    {...attributes}
                  />
                );
              } else if (type === 'render') {
                return render && render
              } else {
                if (
                  (attributes && attributes.type === 'Search') ||
                  type === 'InputSearch'
                ) {
                  const suffix = (
                    <AudioOutlined
                      style={{
                        fontSize: 16,
                        color: '#fff',
                      }}
                    />
                  );
                  return (
                    <Search
                      suffix={suffix}
                      placeholder={
                        attributes && attributes.disabled
                          ? ''
                          : `请输入${label} `
                      }
                      {...componentprams}
                    />
                  );
                }
                return (
                  <Input
                    placeholder={
                      attributes && attributes.disabled ? '' : `请输入${label} `
                    }
                    {...componentprams}
                  />
                );
              }
            })()
          ) : (
            <Input
              placeholder={
                attributes && attributes.disabled ? '' : `请输入${label} `
              }
              size={size}
              {...attributes}
            />
          )}
        </FormItem>
      </Col>
    )

    if (isHide && name) {
      return (
        <Hide key={idx} name={name}>
          {renderItem}
        </Hide>
      );
    }


    return renderItem;
  };
  // 隐藏的表单集合
  const hideCollapseForm = HideFormItemDoM.map((item, idx) =>
    CollapseFormDoM(item, idx),
  );
  // 表单集合
  const CollapseForm = result.map((it, indix) => {
    return (
      <Row key={indix}>
        {it.map((item, idx) => {
          return CollapseFormDoM(item, idx);
        })}
      </Row>
    );
  });
  // Form+表单集合
  const FormDom = (
    <HideContext.Provider value={hide} >
      <ConfigProvider locale={zhCN}>
        <Form
          layout={defaultFormLayout ? defaultFormLayout : 'horizontal'}
          ref={ref}
          {...(defaultFormLayout && defaultFormLayout === 'vertical'
            ? null
            : formitemlayout)}
          {...otherProps}
        >
          <Row>{hideCollapseForm}</Row>
          <div>{CollapseForm}</div>
        </Form>
      </ConfigProvider>
    </HideContext.Provider>
  );
  // type 为 modal时没有折叠,没有标题,直接显示form表单内容
  if (type === 'modal') {
    return <div style={{ margin: -10 }}>{FormDom}</div>
  }
  // type 为CardPro  带标题
  if (type === 'CardPro') {
    return (
      <CardPro title={header}>
        <div className="antdp-FormBox">{FormDom}</div>
      </CardPro>
    );
  }
  // type 为cardform 时 显示表单,分割线 分离每个表单
  if (type === 'cardform') {
    return (
      <div>
        <h3 className="antdp-FormTitle">{header}</h3>
        {FormDom}
        <Divider type="horizontal" className="antdp-FormDivider" />
      </div>
    );
  }
  return (
    <Collapse
      defaultActiveKey={!visible ? ['1'] : ''}
      {...collapseAttributes}
      className="antdp-mb10"
    >
      <Panel header={header} key="1" {...panelAttributes} extra={extra}>
        {FormDom}
      </Panel>
    </Collapse>
  );
}