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 |
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 |
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 |
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 |
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 |
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 |
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 |
StyledMultiDropdownListFilter = styled(TreeSelect)`
width: 100%;
`
Example #8
Source File: edit.tsx From jetlinks-ui-antd with MIT License | 5 votes |
{TreeNode} = TreeSelect
Example #9
Source File: copy.tsx From jetlinks-ui-antd with MIT License | 5 votes |
{ TreeNode } = TreeSelect
Example #10
Source File: save.tsx From jetlinks-ui-antd with MIT License | 5 votes |
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 |
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 |
{TreeNode} = TreeSelect
Example #13
Source File: UpdateForm.tsx From anew-server with MIT License | 5 votes |
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 |
{ TreeNode } = TreeSelect
Example #15
Source File: UpdateForm.tsx From anew-server with MIT License | 5 votes |
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 |
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 |
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 |
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 |
{ TreeNode } = TreeSelect
Example #20
Source File: select-version.tsx From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
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 |
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 |
{ TreeNode } = TreeSelect
Example #23
Source File: UpdateForm.tsx From anew-server with MIT License | 4 votes |
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 |
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 |
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 |
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 |
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 |
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 |
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>
);
}