@ant-design/icons#UploadOutlined TypeScript Examples
The following examples show how to use
@ant-design/icons#UploadOutlined.
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: FileUpload.tsx From jmix-frontend with Apache License 2.0 | 6 votes |
function FileUploadDropArea(props: FileUploadDropAreaProps) {
return props.fileRef
? (
<div className={styles.fileDropArea}>
<UploadOutlined className={styles.replaceIcon} />
<span className={styles.replaceText}>
<FormattedMessage id='jmix.fileUpload.replace'/>
</span>
</div>
)
: (
<div className={styles.fileDropArea}>
<UploadOutlined className={styles.uploadIcon} />
<div className={styles.uploadText}>
<FormattedMessage id='jmix.fileUpload.upload'/>
</div>
</div>
);
}
Example #2
Source File: UploadField.tsx From posthog-foss with MIT License | 6 votes |
export function UploadField({
value,
onChange,
}: {
value?: UploadFile | null
onChange?: (file?: UploadFile | null) => void
}): JSX.Element {
return (
<Upload
multiple={false}
fileList={value?.size ? [value] : []}
beforeUpload={(file) => {
onChange?.(file)
return false
}}
onRemove={() => {
onChange?.(null)
return false
}}
className="ph-ignore-input"
>
<Button icon={<UploadOutlined />}>Click to upload</Button>
</Upload>
)
}
Example #3
Source File: MultipleFilesForm.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
export function LegacyMultipleFilesForm(
{ fieldList, onFinish, onFinishFailed }: MultipleFilesFormProps,
ref: React.Ref<FormInstance>
): React.ReactElement {
const [form] = Form.useForm();
useImperativeHandle(ref, () => form);
const handleFinish = (data: UploadFormData): void => {
const formData = processFileData(data);
onFinish?.(formData);
};
return (
<Form
form={form}
name="filesForm"
data-testid="files-form"
onFinish={handleFinish}
onFinishFailed={onFinishFailed}
>
{fieldList?.map((item) => (
<Form.Item key={item.name} name={item.name} label={item.name}>
<Upload
maxCount={isMultipleFiles(item.type) ? null : 1}
beforeUpload={() => false}
>
<Button icon={<UploadOutlined />}>upload</Button>
</Upload>
</Form.Item>
))}
</Form>
);
}
Example #4
Source File: index.tsx From scorpio-h5-design with MIT License | 6 votes |
export default function() {
useEffect(()=>{
//
}, []);
const props = {
name: 'file',
async onChange(info: any) {
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
const uploadResult = await ossClient.put(`design/${info.file.name}`, info.file.originFileObj);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
};
return (
<Upload {...props} className="aliyun-upload">
<Button icon={<UploadOutlined />}>上传</Button>
</Upload>
);
}
Example #5
Source File: InputWithUpload.tsx From jitsu with MIT License | 6 votes |
InputWithUpload: React.FC<InputWithUploadProps> = ({ value, onChange }) => {
const triggerChange = e => {
onChange?.(e.target.value)
}
const beforeUpload = file => {
const reader = new FileReader()
reader.onload = e => {
const content: string = e.target.result as string
onChange?.(content)
}
reader.readAsText(file)
// Prevent upload
return false
}
return value === "" ? (
<Upload showUploadList={true} beforeUpload={beforeUpload}>
<Button icon={<UploadOutlined />}>Click to Upload</Button>
</Upload>
) : (
<Input.TextArea autoSize={{ minRows: 1, maxRows: 5 }} value={value} autoComplete="off" onChange={triggerChange} />
)
}
Example #6
Source File: index.tsx From ii-admin-base with MIT License | 5 votes |
export default function IUpload(props: IUpload) {
const {
multiple = true,
iconFontSize = 28,
iconFontStyle,
describe,
extra,
icon,
uploadType = 'dragger',
children,
...restProps
} = props;
if (!restProps.beforeUpload) {
restProps.beforeUpload = beforeUpload;
}
if (uploadType === 'dragger') {
return (
<Dragger multiple={multiple} {...restProps}>
{children}
<p className="myupload-iconpart">
{!icon && (
<UploadOutlined
style={{
fontSize: `${iconFontSize}px`,
color: '#3079FF',
...iconFontStyle,
}}
/>
)}
{icon}
</p>
<p className="myupload-describe">
{describe instanceof Array
? describe.map((item, index: number) => (
<div key={`index${index}`}>{item}</div>
))
: describe}
</p>
<p className="myupload-extra">
{extra instanceof Array
? extra.map((item, index: number) => (
<div key={`index${index}`}>{item}</div>
))
: extra}
</p>
</Dragger>
);
}
return (
<Upload multiple={multiple} {...restProps}>
{children}
</Upload>
);
}
Example #7
Source File: FileUpload.tsx From datart with Apache License 2.0 | 5 votes |
export function FileUpload({
form,
sourceId,
loading,
onTest,
}: FileUploadProps) {
const [uploadFileLoading, setUploadFileLoading] = useState(false);
const t = useI18NPrefix('source');
const normFile = useCallback(e => {
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
}, []);
const uploadChange = useCallback(
async ({ file }) => {
if (file.status === 'done') {
const format = file.name
.substr(file.name.lastIndexOf('.') + 1)
.toUpperCase();
const response = file.response as APIResponse<string>;
if (response.success) {
form &&
form.setFieldsValue({ config: { path: response.data, format } });
onTest && onTest();
}
setUploadFileLoading(false);
} else {
setUploadFileLoading(true);
}
},
[form, onTest],
);
return (
<>
<Form.Item
label={t('form.file')}
valuePropName="fileList"
getValueFromEvent={normFile}
>
<Upload
accept=".xlsx,.xls,.csv"
method="post"
action={`${BASE_API_URL}/files/datasource/?sourceId=${sourceId}`}
headers={{ authorization: getToken()! }}
showUploadList={false}
onChange={uploadChange}
>
<Button
icon={<UploadOutlined />}
loading={uploadFileLoading || loading}
>
{t('form.selectFile')}
</Button>
</Upload>
</Form.Item>
<Form.Item
name={['config', 'path']}
css={`
display: none;
`}
>
<Input />
</Form.Item>
<Form.Item
name={['config', 'format']}
css={`
display: none;
`}
>
<Input />
</Form.Item>
</>
);
}
Example #8
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
Save: React.FC<Props> = props => {
const { form: { getFieldsValue, getFieldDecorator }, data } = props;
const [photoUrl, setPhotoUrl] = useState(data?.photoUrl);
const uploadProps: UploadProps = {
action: '/jetlinks/file/static',
headers: {
'X-Access-Token': getAccessToken(),
},
showUploadList: false,
onChange(info) {
if (info.file.status === 'done') {
setPhotoUrl(info.file.response.result);
message.success('上传成功');
}
},
};
return (
<Modal
title={data.id ? `编辑` : '新增'}
visible
onCancel={() => { props.close() }}
onOk={() => {
const formData = getFieldsValue();
if (props.data.id) {
apis.edgeProduct.update({...formData, photoUrl}).then(res => {
if (res.status === 200) {
props.save();
message.success('更新成功');
}
})
} else {
apis.edgeProduct.save({...formData, photoUrl}).then(res => {
if (res.status === 200) {
props.save();
message.success('新增成功');
}
})
}
}}
>
<Form
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
>
<Form.Item label="ID">
{getFieldDecorator('id', {
rules: [{ required: true }],
initialValue: data?.id,
})(
<Input readOnly={!!data.id} />
)}
</Form.Item>
<Form.Item label="名称">
{getFieldDecorator('name', {
rules: [{ required: true }],
initialValue: data?.name,
})(
<Input />
)}
</Form.Item>
<Form.Item label="厂家">
{getFieldDecorator('manufacturer', {
rules: [{ required: true }],
initialValue: data?.manufacturer,
})(
<Input />
)}
</Form.Item>
<Form.Item label="型号">
{getFieldDecorator('model', {
rules: [{ required: true }],
initialValue: data?.model,
})(
<Input />
)}
</Form.Item>
<Form.Item label='图标'>
<>
<div>
<Avatar size={80} src={photoUrl || data?.photoUrl} />
</div>
<Upload {...uploadProps} showUploadList={false}>
<Button>
<UploadOutlined />
更换图片
</Button>
</Upload>
</>
</Form.Item>
<Form.Item label="说明">
{getFieldDecorator('description', {
initialValue: data?.description,
})(
<Input.TextArea rows={3} placeholder="请输入" />
)}
</Form.Item>
</Form>
</Modal>
)
}
Example #9
Source File: FileManager.tsx From anew-server with MIT License | 4 votes |
FileManager: React.FC<FileManagerProps> = (props) => {
const { modalVisible, handleChange, connectId } = props;
const [columnData, setColumnData] = useState<API.SSHFileList[]>([]);
const [showHidden, setShowHidden] = useState<boolean>(false);
const [childrenDrawer, setChildrenDrawer] = useState<boolean>(false);
const [currentPathArr, setCurrentPathArr] = useState<string[]>([]);
const [initPath, setInitPath] = useState<string>('');
const _dirSort = (item: API.SSHFileList) => {
return item.isDir;
};
const getFileData = (key: string, path: string) => {
querySSHFile(key, path).then((res) => {
const obj = lds.orderBy(res.data, [_dirSort, 'name'], ['desc', 'asc']);
showHidden ? setColumnData(obj) : setColumnData(obj.filter((x) => !x.name.startsWith('.')));
try {
// 获取服务器的当前路径
let pathb = obj[0].path;
const index = pathb.lastIndexOf('/');
pathb = pathb.substring(0, index + 1);
setCurrentPathArr(pathb.split('/').filter((x: any) => x !== ''));
setInitPath(pathb); // 保存当前路径,刷新用
} catch (exception) {
setCurrentPathArr(path.split('/').filter((x) => x !== ''));
setInitPath(path);
}
});
};
const getChdirDirData = (key: string, path: string) => {
const index = currentPathArr.indexOf(path);
const currentDir = '/' + currentPathArr.splice(0, index + 1).join('/');
getFileData(key, currentDir);
};
const handleDelete = (key: string, path: string) => {
if (!path) return;
const index = path.lastIndexOf('/');
const currentDir = path.substring(0, index + 1);
const currentFile = path.substring(index + 1, path.length);
const content = `您是否要删除 ${currentFile}?`;
Modal.confirm({
title: '注意',
content,
onOk: () => {
deleteSSHFile(key, path).then((res) => {
if (res.code === 200 && res.status === true) {
message.success(res.message);
getFileData(key, currentDir);
}
});
},
onCancel() { },
});
};
const handleDownload = (key: string, path: string) => {
if (!path) return;
const index = path.lastIndexOf('/');
const currentFile = path.substring(index + 1, path.length);
const content = `您是否要下载 ${currentFile}?`;
Modal.confirm({
title: '注意',
content,
onOk: () => {
const token = localStorage.getItem('token');
const link = document.createElement('a');
link.href = `/api/v1/host/ssh/download?key=${key}&path=${path}&token=${token}`;
document.body.appendChild(link);
const evt = document.createEvent('MouseEvents');
evt.initEvent('click', false, false);
link.dispatchEvent(evt);
document.body.removeChild(link);
},
onCancel() { },
});
};
const uploadProps = {
name: 'file',
action: `/api/v1/host/ssh/upload?key=${connectId}&path=${initPath}`,
multiple: true,
headers: {
Authorization: `Bearer ${localStorage.getItem('token')}`,
},
// showUploadList: {
// removeIcon: false,
// showRemoveIcon: false,
// },
onChange(info: any) {
// if (info.file.status !== 'uploading') {
// console.log(info.file, info.fileList);
// }
//console.log(info);
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
getFileData(connectId, initPath as string); // 刷新数据
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
progress: {
strokeColor: {
'0%': '#108ee9',
'100%': '#87d068',
},
strokeWidth: 3,
format: (percent: any) => `${parseFloat(percent.toFixed(2))}%`,
},
};
const columns: ProColumns<API.SSHFileList>[] = [
{
title: '名称',
dataIndex: 'name',
render: (_, record) =>
record.isDir ? (
<div onClick={() => getFileData(connectId, record.path)} style={{ cursor: 'pointer' }}>
<FolderTwoTone />
<span style={{ color: '#1890ff', paddingLeft: 5 }}>{record.name}</span>
</div>
) : (
<React.Fragment>
{record.isLink ? (
<div>
<LinkOutlined />
<Tooltip title="Is Link">
<span style={{ color: '#3cb371', paddingLeft: 5 }}>{record.name}</span>
</Tooltip>
</div>
) : (
<div>
<FileOutlined />
<span style={{ paddingLeft: 5 }}>{record.name}</span>
</div>
)}
</React.Fragment>
),
},
{
title: '大小',
dataIndex: 'size',
},
{
title: '修改时间',
dataIndex: 'mtime',
},
{
title: '属性',
dataIndex: 'mode',
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) =>
!record.isDir && !record.isLink ? (
<>
<Tooltip title="下载文件">
<DownloadOutlined
style={{ fontSize: '17px', color: 'blue' }}
onClick={() => handleDownload(connectId, record.path)}
/>
</Tooltip>
<Divider type="vertical" />
<Tooltip title="删除文件">
<DeleteOutlined
style={{ fontSize: '17px', color: 'red' }}
onClick={() => handleDelete(connectId, record.path)}
/>
</Tooltip>
</>
) : null,
},
];
useEffect(() => {
// 是否显示隐藏文件
getFileData(connectId, initPath as string); // 刷新数据
}, [showHidden]);
const { Dragger } = Upload;
return (
<Drawer
title="文件管理器"
placement="right"
width={800}
visible={modalVisible}
onClose={()=>handleChange(false)}
getContainer={false}
>
{/* <input style={{ display: 'none' }} type="file" ref={(ref) => (this.input = ref)} /> */}
<div className={styles.drawerHeader}>
<Breadcrumb>
<Breadcrumb.Item href="#" onClick={() => getFileData(connectId, '/')}>
<ApartmentOutlined />
</Breadcrumb.Item>
<Breadcrumb.Item href="#" onClick={() => getFileData(connectId, '')}>
<HomeOutlined />
</Breadcrumb.Item>
{currentPathArr.map((item) => (
<Breadcrumb.Item key={item} href="#" onClick={() => getChdirDirData(connectId, item)}>
<span>{item}</span>
</Breadcrumb.Item>
))}
</Breadcrumb>
<div style={{ display: 'flex', alignItems: 'center' }}>
<span>显示隐藏文件:</span>
<Switch
checked={showHidden}
checkedChildren="开启"
unCheckedChildren="关闭"
onChange={(v) => {
setShowHidden(v);
}}
/>
<Button
style={{ marginLeft: 10 }}
size="small"
type="primary"
icon={<UploadOutlined />}
onClick={() => setChildrenDrawer(true)}
>
上传文件
</Button>
</div>
</div>
<Drawer
title="上传文件"
width={320}
closable={false}
onClose={() => setChildrenDrawer(false)}
visible={childrenDrawer}
>
<div style={{ height: 150 }}>
<Dragger {...uploadProps}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">单击或拖入上传</p>
<p className="ant-upload-hint">支持多文件</p>
</Dragger>
</div>
</Drawer>
<ProTable
pagination={false}
search={false}
toolBarRender={false}
rowKey="name"
dataSource={columnData}
columns={columns}
/>
</Drawer>
);
}
Example #10
Source File: index.tsx From anew-server with MIT License | 4 votes |
Settings: React.FC = () => {
const { initialState, setInitialState } = useModel('@@initialState');
if (!initialState || !initialState.currentUser) {
return null;
}
const { currentUser } = initialState;
const beforeUpload = (file: RcFile) => {
const isJpgOrPng =
file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif';
if (!isJpgOrPng) {
message.error('只可以上传JPG/PNG/GIF图片!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片必须小于2MB!');
}
return isJpgOrPng && isLt2M;
};
const handleChange = (info: UploadChangeParam) => {
if (info.file.status === 'uploading') {
//setUploadLoading(true);
return;
}
if (info.file.status === 'done') {
message.success('上传成功');
let userInfo = {};
Object.assign(userInfo, initialState?.currentUser);
(userInfo as API.UserInfo).avatar = info.file.response.data.url;
setInitialState({ ...initialState, currentUser: userInfo as API.UserInfo });
}
};
const tokenHeaders = {
Authorization: 'Bearer ' + localStorage.getItem('token'),
};
return (
<GridContent>
{currentUser.username && (
<Row gutter={24}>
<Col span={10}>
<Card
title="关于我"
bordered={false}
style={{
marginBottom: 14,
}}
>
<div>
<div className={styles.avatarHolder}>
<img alt="" src={currentUser.avatar} />
<Upload
name="avatar"
headers={tokenHeaders}
accept=".jpg,.jpeg,.png,.gif"
className="avatar-uploader"
showUploadList={false}
action="/api/v1/user/info/uploadImg"
beforeUpload={beforeUpload}
onChange={handleChange}
>
<div className={styles.button_view}>
<Button>
<UploadOutlined /> 更换头像
</Button>
</div>
</Upload>
</div>
<div className={styles.detail}>
<div>
<p style={{ marginRight: '15px' }}>
<IconFont
type="icon-yonghuming"
style={{ fontSize: '16px', marginRight: 8 }}
/>
用户名
</p>
{currentUser.username}
</div>
<div>
<p style={{ marginRight: '29px' }}>
<IconFont
type="icon-xingming"
style={{ fontSize: '16px', marginRight: 8 }}
/>
姓名
</p>
{currentUser.name}
</div>
<div>
<p style={{ marginRight: '29px' }}>
<IconFont
type="icon-youxiang"
style={{ fontSize: '16px', marginRight: 8 }}
/>
邮箱
</p>
{currentUser.email}
</div>
<div>
<p style={{ marginRight: '29px' }}>
<IconFont
type="icon-shouji54"
style={{ fontSize: '16px', marginRight: 8 }}
/>
手机
</p>
{currentUser.mobile}
</div>
<div>
<p style={{ marginRight: '29px' }}>
<IconFont
type="icon-jiaose"
style={{ fontSize: '16px', marginRight: 8 }}
/>
角色
</p>
{currentUser.role?.name}
</div>
<div>
<p style={{ marginRight: '29px' }}>
<IconFont
type="icon-bumen"
style={{ fontSize: '16px', marginRight: 8 }}
/>
部门
</p>
{currentUser.dept?.name}
</div>
</div>
</div>
</Card>
</Col>
<Col span={14}>
<Card title="个人设置" bordered={false} >
<Tabs tabPosition="right" onChange={() => { }}>
<Tabs.TabPane tab="基本信息" key="baseInfo">
<BaseForm values={currentUser} />
</Tabs.TabPane>
<Tabs.TabPane tab="修改密码" key="changePwd">
<ChangePasswordFrom />
</Tabs.TabPane>
</Tabs>
</Card>
</Col>
</Row>
)}
</GridContent>
);
}
Example #11
Source File: SettingsPage.tsx From office-hours with GNU General Public License v3.0 | 4 votes |
export default function SettingsPage({
defaultPage,
}: SettingsPageProps): ReactElement {
const {
data: profile,
error,
mutate,
} = useSWR(`api/v1/profile`, async () => API.profile.index());
const router = useRouter();
const { cid } = router.query;
const role = useRoleInCourse(Number(cid));
const isTAOrProfessor = role === Role.TA || role === Role.PROFESSOR;
const [currentSettings, setCurrentSettings] = useState(
defaultPage || SettingsOptions.PROFILE
);
const [uploading, setUploading] = useState(false);
const isMobile = useIsMobile();
const windowWidth = useWindowWidth();
const [avatarSize, setAvatarSize] = useState(windowWidth / 2);
useEffect(() => {
const widthDivider = isMobile ? 6 : 10;
setAvatarSize(windowWidth / widthDivider);
});
const beforeUpload = (file) => {
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
message.error("You can only upload JPGs or PNGs!");
}
const isLt1M = file.size / 1024 / 1024 < 1;
if (!isLt1M) {
message.error("Image must smaller than 1MB!");
}
return isJpgOrPng && isLt1M;
};
if (error) {
message.error(error);
}
const AvatarSettings = () => (
<Col>
{avatarSize ? (
<Row
style={{
marginTop: avatarSize / 6,
justifyContent: `${isMobile ? "left" : "center"}`,
}}
>
{uploading ? (
<Skeleton.Avatar
active={true}
size={avatarSize}
shape="circle"
style={{
marginTop: avatarSize / 6,
marginBottom: avatarSize / 12,
marginLeft: avatarSize / 6,
marginRight: avatarSize / 6,
}}
/>
) : (
<SettingsPanelAvatar avatarSize={avatarSize} />
)}
<Col>
{profile && (
<h2>
{profile.firstName} {profile.lastName}
</h2>
)}
<Upload
action={"/api/v1/profile/upload_picture"}
beforeUpload={beforeUpload}
showUploadList={false}
onChange={(info) => {
setUploading(info.file.status === "uploading");
mutate();
}}
>
<ProfilePicButton icon={<UploadOutlined />}>
Edit photo
</ProfilePicButton>
</Upload>
{profile?.photoURL && (
<ProfilePicButton
icon={<DeleteOutlined />}
style={{ marginTop: "10px" }}
onClick={async () => {
try {
await API.profile.deleteProfilePicture();
message.success(
"You've successfully deleted your profile picture"
);
mutate();
} catch (e) {
message.error(
"There was an error with deleting your profile picture, please contact the Khoury Office Hours team for assistance"
);
throw e;
}
}}
>
Delete my Profile Picture
</ProfilePicButton>
)}
</Col>
</Row>
) : null}
</Col>
);
const SettingsMenu = () => (
<>
{isMobile ? (
<Collapse accordion style={{ marginTop: "10px" }}>
<Panel header="Personal Information" key="profile">
<ProfileSettings />
</Panel>
{isTAOrProfessor && (
<Panel header="Teams Settings" key="teams_settings">
<TeamsSettings />
</Panel>
)}
<Panel header="Notifications" key="notifications">
<NotificationsSettings />
</Panel>
<Panel header="Course Preferences" key="preferences">
<CoursePreferenceSettings />
</Panel>
</Collapse>
) : (
<Menu
style={{ background: "none", marginTop: "10px" }}
defaultSelectedKeys={[currentSettings]}
onClick={(e) => setCurrentSettings(e.key as SettingsOptions)}
>
<Menu.Item key={SettingsOptions.PROFILE} icon={<UserOutlined />}>
Personal Information
</Menu.Item>
{isTAOrProfessor && (
<Menu.Item
key={SettingsOptions.TEAMS_SETTINGS}
icon={<WindowsOutlined />}
>
Teams Settings
</Menu.Item>
)}
<Menu.Item
key={SettingsOptions.NOTIFICATIONS}
icon={<BellOutlined />}
>
Notifications
</Menu.Item>
<Menu.Item key={SettingsOptions.PREFERENCES} icon={<BookOutlined />}>
Course Preferences
</Menu.Item>
</Menu>
)}
</>
);
const DesktopSettingsSubpage = () => (
<Col>
{currentSettings === SettingsOptions.PROFILE && <ProfileSettings />}
{currentSettings === SettingsOptions.NOTIFICATIONS && (
<NotificationsSettings />
)}
{currentSettings === SettingsOptions.TEAMS_SETTINGS && <TeamsSettings />}
{currentSettings === SettingsOptions.PREFERENCES && (
<CoursePreferenceSettings />
)}
</Col>
);
return (
<div>
{isMobile ? (
<Col>
<AvatarSettings />
<SettingsMenu />
</Col>
) : (
<Row>
<Col span={5} style={{ textAlign: "center" }}>
<AvatarSettings />
<SettingsMenu />
</Col>
<VerticalDivider />
<Space direction="vertical" size={40} style={{ flexGrow: 1 }}>
<DesktopSettingsSubpage />
</Space>
</Row>
)}
</div>
);
}
Example #12
Source File: index.tsx From Aragorn with MIT License | 4 votes |
FileManage = () => {
const {
state: {
uploaderProfiles,
configuration: { defaultUploaderProfileId }
}
} = useAppContext();
const [windowHeight, setWindowHeight] = useState(window.innerHeight);
useEffect(() => {
function handleResize() {
setWindowHeight(window.innerHeight);
}
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
const { id } = useParams<{ id: string }>();
const [hasFileManageFeature, setHasFileManageFeature] = useState(false);
const [uploaderProfile, setUploaderProfile] = useState({} as UploaderProfile);
useEffect(() => {
const currentId = id || defaultUploaderProfileId;
setCurrentProfile(currentId as string);
}, []);
useEffect(() => {
if (uploaderProfile?.id) {
getList();
}
}, [uploaderProfile]);
const [list, setList] = useState([] as ListFile[]);
const [listLoading, setListLoading] = useState(false);
const getList = (directoryPath?: string) => {
setListLoading(true);
ipcRenderer.send('file-list-get', uploaderProfile.id, directoryPath);
};
const [dirPath, setDirPath] = useState([] as string[]);
useEffect(() => {
function handleListGetReply(_, res?: FileListResponse) {
setListLoading(false);
if (res === undefined) {
setHasFileManageFeature(false);
setList([]);
message.info(`${uploaderProfile.uploaderName}暂不支持文件管理功能`);
return;
}
setHasFileManageFeature(true);
if (res.success) {
setList(res.data);
} else {
message.error(`文件列表获取失败 ${res.desc || ''}`);
}
}
function handleFileDeleteReply(_, res?: DeleteFileResponse) {
if (res === undefined) {
return;
}
if (res.success) {
message.success({ content: '文件删除成功', key: 'file-manage-delete' });
getList(dirPath.join('/'));
} else {
message.error({ content: `文件删除失败 ${res.desc || ''}`, key: 'file-manage-delete' });
}
}
function handleFileUploadReply() {
getList(dirPath.join('/'));
}
function handleDirectoryCreateReply(_, res?: CreateDirectoryResponse) {
if (res === undefined) {
return;
}
if (res.success) {
message.success('目录创建成功');
setModalVisible(false);
getList(dirPath.join('/'));
} else {
message.error(`目录创建失败 ${res.desc || ''}`);
}
}
function handleExportReplay(_, res) {
setExportLoading(false);
if (res) {
shell.showItemInFolder(res);
setRowKeys([]);
setSelectRows([]);
}
}
ipcRenderer.on('file-list-get-reply', handleListGetReply);
ipcRenderer.on('file-delete-reply', handleFileDeleteReply);
ipcRenderer.on('file-upload-reply', handleFileUploadReply);
ipcRenderer.on('directory-create-reply', handleDirectoryCreateReply);
ipcRenderer.on('export-reply', handleExportReplay);
return () => {
ipcRenderer.removeListener('file-list-get-reply', handleListGetReply);
ipcRenderer.removeListener('file-delete-reply', handleFileDeleteReply);
ipcRenderer.removeListener('file-upload-reply', handleFileUploadReply);
ipcRenderer.removeListener('directory-create-reply', handleDirectoryCreateReply);
ipcRenderer.removeListener('export-reply', handleExportReplay);
};
}, [uploaderProfile, dirPath]);
const handleNameClick = (record: ListFile) => {
if (record.type === 'directory') {
const newPath = [...dirPath, formatFileName(record.name)];
setDirPath(newPath);
getList(newPath.join('/'));
} else {
clipboard.writeText(record.url as string);
message.success('链接已复制到粘贴板');
}
};
const handlePathClick = (index: number) => {
if (index === -1) {
setDirPath([]);
getList();
} else {
const newPath = dirPath.slice(0, index + 1);
setDirPath(newPath);
getList(newPath.join('/'));
}
};
const setCurrentProfile = (uploaderProfileId: string) => {
setDirPath([]);
const uploaderProfile = uploaderProfiles.find(item => item.id === uploaderProfileId);
setUploaderProfile(uploaderProfile as UploaderProfile);
};
const formatFileName = (name: string) => {
if (dirPath.length > 0) {
const pathPrefix = dirPath.join('/') + '/';
return name.split(pathPrefix).pop() || '';
} else {
return name;
}
};
const [selectRowKeys, setRowKeys] = useState([] as string[]);
const [selectRows, setSelectRows] = useState([] as ListFile[]);
const handleTableRowChange = (selectedRowKeys, selectedRows: ListFile[]) => {
setRowKeys(selectedRowKeys);
setSelectRows(selectedRows);
};
const handleRefresh = () => {
getList(dirPath.join('/'));
};
const handleBatchDelete = () => {
Modal.confirm({
title: '确认删除',
onOk: () => {
const names = selectRows.map(item => [...dirPath, formatFileName(item.name)].join('/'));
message.info({ content: '正在删除,请稍后...', key: 'file-manage-delete' });
ipcRenderer.send('file-delete', uploaderProfile.id, names);
}
});
};
const handleDelete = (record: ListFile) => {
let name = record.name;
Modal.confirm({
title: '确认删除',
content: name,
onOk: () => {
let name = record.name;
if (record.type === 'directory') {
name = `${[...dirPath, record.name].join('/')}/`;
} else {
name = [...dirPath, formatFileName(record.name)].join('/');
}
message.info({ content: '正在删除,请稍后...', key: 'file-manage-delete' });
ipcRenderer.send('file-delete', uploaderProfile.id, [name]);
}
});
};
const uploadRef = useRef<HTMLInputElement>(null);
const handleFileUpload = (event: React.FormEvent<HTMLInputElement>) => {
const fileList = event.currentTarget.files || [];
const filesPath = Array.from(fileList).map(file => file.path);
const pathPrefix = dirPath.join('/');
ipcRenderer.send('file-upload', uploaderProfile.id, filesPath, pathPrefix);
event.currentTarget.value = '';
};
const [modalVisible, setModalVisible] = useState(false);
const [form] = Form.useForm();
const handleCreateDirectory = () => {
form.validateFields().then(values => {
ipcRenderer.send('directory-create', uploaderProfile.id, values?.directoryPath || '');
});
};
const handleDownload = (record: ListFile) => {
ipcRenderer.send('file-download', record.name, record.url);
};
const [exportLoading, setExportLoading] = useState(false);
const handleExport = () => {
const data = selectRows.map(item => {
const fileNameArr = item.name.split('.');
fileNameArr.pop();
return {
name: fileNameArr.join('.'),
url: item.url
};
});
setExportLoading(true);
ipcRenderer.send('export', data);
};
const columns: ColumnsType<ListFile> = [
{
title: '文件名',
dataIndex: 'name',
ellipsis: true,
render: (val: string, record: ListFile) => (
<div style={{ display: 'flex', alignItems: 'center' }}>
{record.type === 'directory' ? (
<FolderFilled style={{ fontSize: 16 }} />
) : (
<FileOutlined style={{ fontSize: 16 }} />
)}
{record.type === 'directory' ? (
<a
title={val}
onClick={() => handleNameClick(record)}
className="table-filename"
style={{ marginLeft: 10, overflow: 'hidden', textOverflow: 'ellipsis' }}
>
{formatFileName(val)}
</a>
) : (
<Popover
placement="topLeft"
content={() =>
/(jpg|png|gif|jpeg)$/.test(val) ? (
<Image
style={{ maxWidth: 500 }}
src={record.url}
fallback="data:image/png;base64,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"
/>
) : (
val
)
}
trigger="hover"
>
<a
title={val}
onClick={() => handleNameClick(record)}
className="table-filename"
style={{ marginLeft: 10, overflow: 'hidden', textOverflow: 'ellipsis' }}
>
{formatFileName(val)}
</a>
</Popover>
)}
</div>
)
},
{
title: '文件大小',
dataIndex: 'size',
ellipsis: true,
width: 120,
render: val => (val ? filesize(val) : '-')
},
{
title: '更新时间',
dataIndex: 'lastModified',
ellipsis: true,
width: 200,
render: val => (val ? dayjs(val).format('YYYY-MM-DD HH:mm:ss') : '-')
},
{
title: '操作',
width: 120,
render: (_, record) => (
<Space>
{record.type !== 'directory' && (
<>
<DownloadOutlined onClick={() => handleDownload(record)} />
<CopyOutlined onClick={() => handleNameClick(record)} />
</>
)}
<DeleteOutlined onClick={() => handleDelete(record)} />
</Space>
)
}
];
return (
<div className="storage-page">
<header>
<span>文件管理</span>
<Divider />
</header>
<Space style={{ marginBottom: 10 }}>
<Select style={{ minWidth: 120 }} value={uploaderProfile?.id} onChange={setCurrentProfile}>
{uploaderProfiles.map(item => (
<Select.Option key={item.name} value={item.id}>
{item.name}
</Select.Option>
))}
</Select>
<Button
title="上传"
icon={<UploadOutlined />}
disabled={!hasFileManageFeature}
type="primary"
onClick={() => {
uploadRef.current?.click();
}}
/>
<Button title="刷新" icon={<ReloadOutlined />} disabled={!hasFileManageFeature} onClick={handleRefresh} />
<Button
title="创建文件夹"
icon={<FolderAddOutlined />}
disabled={!hasFileManageFeature}
onClick={() => {
setModalVisible(true);
}}
/>
<Button
title="导出"
icon={<ExportOutlined />}
disabled={selectRows.length === 0}
onClick={handleExport}
loading={exportLoading}
/>
<Button title="删除" icon={<DeleteOutlined />} disabled={selectRows.length === 0} onClick={handleBatchDelete} />
</Space>
<Breadcrumb style={{ marginBottom: 10 }}>
<Breadcrumb.Item>
<a onClick={() => handlePathClick(-1)}>全部文件</a>
</Breadcrumb.Item>
{dirPath.map((item, index) => (
<Breadcrumb.Item key={item}>
<a onClick={() => handlePathClick(index)}>{item}</a>
</Breadcrumb.Item>
))}
</Breadcrumb>
<div className="table-wrapper">
<Table
size="small"
rowKey="name"
scroll={{ y: windowHeight - 270 }}
dataSource={list}
columns={columns}
pagination={{
size: 'small',
defaultPageSize: 100,
pageSizeOptions: ['50', '100', '200'],
hideOnSinglePage: true
}}
loading={listLoading}
rowSelection={{
onChange: handleTableRowChange,
selectedRowKeys: selectRowKeys,
getCheckboxProps: record => ({ disabled: record?.type === 'directory' })
}}
/>
</div>
<input ref={uploadRef} type="file" multiple hidden onChange={handleFileUpload} />
<Modal
title="创建目录"
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onOk={handleCreateDirectory}
destroyOnClose={true}
>
<Form form={form} preserve={false}>
<Form.Item
label="目录名称"
name="directoryPath"
rules={[{ required: true }, { pattern: domainPathRegExp, message: '目录名不能以 / 开头或结尾' }]}
>
<Input autoFocus />
</Form.Item>
</Form>
</Modal>
</div>
);
}
Example #13
Source File: index.tsx From Aragorn with MIT License | 4 votes |
Dashboard = () => {
const {
state: {
uploaderProfiles,
configuration: { defaultUploaderProfileId },
uploadedFiles
}
} = useAppContext();
const history = useHistory();
const [selectRowKeys, setRowKeys] = useState([]);
const [selectRows, setSelectRows] = useState([] as UploadedFileInfo[]);
const handleProfileAdd = () => {
history.push('/uploader');
};
const handleProfileClick = id => {
if (id === defaultUploaderProfileId) {
history.push(`/profile/${id}`);
} else {
ipcRenderer.send('set-default-uploader-profile', id);
}
};
const handleCopy = url => {
clipboard.writeText(url);
message.success('已复制到粘贴板');
};
const handleOpen = path => {
shell.showItemInFolder(path);
};
const handleTableRowChange = (selectedRowKeys, selectedRows) => {
setRowKeys(selectedRowKeys);
setSelectRows(selectedRows);
};
const handleClear = () => {
const ids = selectRows.map(item => item.id);
ipcRenderer.send('clear-upload-history', ids);
setRowKeys([]);
};
const handleReUpload = () => {
const data = selectRows.map(item => {
return { id: item.uploaderProfileId, path: item.path };
});
ipcRenderer.send('file-reupload', data);
setRowKeys([]);
};
const columns: ColumnsType<UploadedFileInfo> = [
{
title: '文件名',
dataIndex: 'name',
ellipsis: true,
render: (val, record) => (
<Popover
placement="topLeft"
content={() =>
/(jpg|png|gif|jpeg)$/.test(val) ? (
<Image
style={{ maxWidth: 500 }}
src={record.url}
fallback="data:image/png;base64,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"
/>
) : (
val
)
}
trigger="hover"
>
<span onClick={() => handleCopy(record.url)} className="row-item">
{val}
</span>
</Popover>
)
},
{
title: '类型',
dataIndex: 'type',
ellipsis: true,
width: 120
},
{
title: '上传器配置',
dataIndex: 'uploaderProfileId',
ellipsis: true,
width: 120,
render: val => (
<a onClick={() => handleProfileClick(val)}>
{uploaderProfiles.find(item => item.id === val)?.name || '未找到'}
</a>
)
},
{
title: '状态',
dataIndex: 'url',
ellipsis: true,
width: 80,
render: val => (
<>
<Badge status={val ? 'success' : 'error'} />
{val ? '成功' : '失败'}
</>
)
},
{
title: '上传时间',
dataIndex: 'date',
width: 180,
ellipsis: true,
render: val => dayjs(val).format('YYYY-MM-DD HH:mm:ss')
},
{
title: '操作',
width: 80,
render: (_, record) => (
<Space>
<FolderOpenOutlined onClick={() => handleOpen(record.path)} />
<CopyOutlined onClick={() => handleCopy(record.url)} />
</Space>
)
}
];
return (
<div className="dashboard-page">
<header>
<span>控制台</span>
<Divider />
</header>
<main>
<div className="profile-wrapper">
<div className="title">上传器配置</div>
<div className="card-wrapper">
{uploaderProfiles.map(item => (
<div
key={item.id}
className={item.id === defaultUploaderProfileId ? 'card card-active' : 'card'}
onClick={() => handleProfileClick(item.id)}
>
<Box className="card-icon" />
<span>{item.name}</span>
</div>
))}
<div className="card" onClick={handleProfileAdd}>
<Plus className="card-icon" />
</div>
</div>
</div>
<div className="history-wrapper">
<div className="title">最近上传</div>
<div className="card-wrapper">
{selectRowKeys.length > 0 && (
<Space style={{ marginBottom: 10 }}>
<Button icon={<DeleteOutlined />} onClick={handleClear}>
清除
</Button>
<Button icon={<UploadOutlined />} onClick={handleReUpload}>
重新上传
</Button>
</Space>
)}
<Table
size="small"
rowKey="id"
dataSource={uploadedFiles}
columns={columns}
rowSelection={{ onChange: handleTableRowChange, selectedRowKeys: selectRowKeys }}
/>
</div>
</div>
</main>
</div>
);
}
Example #14
Source File: index.tsx From fe-v5 with Apache License 2.0 | 4 votes |
Indicator: React.FC = () => {
const { t } = useTranslation();
// 数据定义
const [form] = Form.useForm();
const tableRef = useRef(null as any);
const exportTextRef = useRef(null as any);
const [modal, setModal] = useState<boolean>(false);
const [modalType, setModalType] = useState('create');
const [exportList, setExportList] = useState([] as string[]);
const [editingKey, setEditingKey] = useState<Partial<InterfaceItem>>({});
const [query, setQuery] = useState<string>('');
const history = useHistory();
const moreOperations: MoreOptions = {
导入指标: 'import',
导出指标: 'export',
};
const optMap = {
import: t('导入'),
edit: t('编辑'),
export: t('导出'),
create: t('创建'),
}; // 弹窗操作
const handleOpen = (type: string = 'create') => {
setModalType(type);
setModal(true);
};
const handleCancel = () => {
setModal(false);
}; // 接口操作
const handleEdit = (item: InterfaceItem) => {
setEditingKey(item);
};
const handleDelete = (item) => {
deleteIndicator([item.id]).then(async (res) => {
await tableRef.current.refreshList();
message.success(t('删除指标成功'));
});
};
const handleAdd = async () => {
try {
const values = await form.validateFields();
addIndicator(values.metrics || '').then(async (res) => {
if (res && res.success) {
await tableRef.current.refreshList();
setModal(false);
message.success(t('创建指标成功'));
}
});
} catch (e) {}
}; // 更多操作
const [oType, setOType] = useState<string>(t('更多操作'));
const onSelect = (val: string): void => {
switch (val) {
case 'import':
setModal(true);
setModalType('import');
break;
case 'export':
if (exportList.length <= 0) {
message.warning(t('请勾选需要导出的指标'));
} else {
setModal(true);
setModalType('export');
setTimeout(() => {
exportTextRef.current && exportTextRef.current.focus();
});
}
break;
default:
break;
}
setOType(val);
}; // table
const handleEditChange = (e, record, index, field) => {
let targetCol = Object.assign({}, record);
targetCol[field] = e.target.value;
setEditingKey(targetCol);
};
const renderInput = (text, record, index, field) => {
if (record.id === editingKey.id) {
return (
<Input
defaultValue={text}
onPressEnter={() => handleEditOption('save')}
onChange={(e) => handleEditChange(e, record, index, field)}
/>
);
} else {
return <span>{text}</span>;
}
};
const handleEditOption = async (type = '') => {
if (type === 'save') {
let id = editingKey.id || -1;
await editIndicator(id, {
description: editingKey.description,
metric: editingKey.metric,
});
message.success(t('编辑成功'));
tableRef.current.refreshList();
}
setEditingKey({} as any);
};
const columns = [
{
title: t('指标名称'),
dataIndex: 'metric',
key: 'metric',
render: (text: string, record: InterfaceItem) => {
return (
<a
onClick={() => {
let path = {
pathname: `/metric/explorer`,
state: { name: text, description: record.description },
};
history.push(path);
}}
>
{text}
</a>
);
},
},
{
title: t('释义'),
dataIndex: 'description',
width: '40%',
key: 'description',
render: (text: string, record: InterfaceItem, index: number) => {
return renderInput(text, record, index, 'description');
},
},
{
title: t('操作'),
dataIndex: '',
key: 'operations',
width: '15%',
render: (_: any, item: any) => {
return (
<div className='operations'>
{item.id !== editingKey.id ? (
<div>
<span
className='operation-item edit'
onClick={() => handleEdit(item)}
>
{t('编辑')}
</span>
{/* <Popconfirm
title='确定删除该指标?'
onConfirm={() => handleDelete(item)}
okText='确定'
cancelText='取消'
>
<span className='operation-item delete'>删除</span>
</Popconfirm> */}
<div
className='table-operator-area-warning'
style={{
display: 'inline-block',
marginLeft: 10,
}}
onClick={() => {
confirm({
title: t('确定删除该指标?'),
icon: <ExclamationCircleOutlined />,
onOk: () => {
handleDelete(item);
},
});
}}
>
{t('删除')}
</div>
</div>
) : (
<div>
<span
className='operation-item edit-save'
onClick={() => handleEditOption('save')}
>
{t('保存')}
</span>
<span
className='operation-item edit-cancel'
onClick={() => handleEditOption('cancel')}
>
{t('取消')}
</span>
</div>
)}
</div>
);
},
},
];
const onSearchQuery = (e) => {
let val = e.target.value;
setQuery(val);
};
const rowSelection = {
onChange: (selectedRowKeys, selectedRows) => {
let list: string[] = [];
selectedRows.map((item) => {
list.push(`${item.metric}:${item.description}`);
});
setExportList(list);
},
};
const handleExportTxt = () => {
download(exportList);
};
return (
<PageLayout title={t('指标释义')} icon={<BulbOutlined />}>
<div className='indicator-index'>
<div className='indicator-operations'>
<Input
className={'searchInput'}
onPressEnter={onSearchQuery}
prefix={<SearchOutlined />}
placeholder={t('指标名称或释义')}
/>
<div className='operations'>
<Button.Group>
<Button
size='middle'
type='default'
icon={<DownloadOutlined />}
onClick={() => onSelect('import')}
>
{t('导入')}
</Button>
<Button
size='middle'
type='default'
icon={<UploadOutlined />}
onClick={() => onSelect('export')}
>
{t('导出')}
</Button>
</Button.Group>
</div>
</div>
<div className='indicator-main'>
<BaseTable
fetchHandle={getIndicatorList}
ref={tableRef}
fetchParams={{
query: query,
}}
rowSelection={{ ...rowSelection }}
rowKey={(record: { id: number }) => {
return record.id;
}}
columns={columns}
/>
</div>
</div>
<Modal
title={optMap[modalType]}
destroyOnClose={true}
footer={
modalType !== 'export' && [
<Button key='delete' onClick={handleCancel}>
{t('取消')}
</Button>,
<Button key='submit' type='primary' onClick={handleAdd}>
{t('确定')}
</Button>,
]
}
onCancel={handleCancel}
visible={modal}
>
<p
style={{
color: '#999',
}}
>
{modalType === 'export' ? (
<a onClick={handleExportTxt}>Download.txt</a>
) : (
<span>{t('一行一个')}</span>
)}
</p>
{(() => {
switch (modalType) {
case 'export':
return (
<div
contentEditable='true'
suppressContentEditableWarning={true}
ref={exportTextRef}
style={{
height: '200px',
border: '1px solid #d9d9d9',
overflow: 'auto',
padding: '10px',
}}
>
{exportList.map((item, index) => {
return <div key={index}>{item}</div>;
})}
</div>
);
break;
case 'import':
case 'create':
return (
<Form name={modalType + '-dialog'} form={form} preserve={false}>
<Form.Item
name={'metrics'}
key={'metrics'}
rules={[
{
required: true,
message: t('不能为空'),
validateTrigger: 'trigger',
},
]}
>
<TextArea
placeholder={'name:description'}
rows={4}
></TextArea>
</Form.Item>
</Form>
);
break;
}
})()}
</Modal>
</PageLayout>
);
}
Example #15
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
BasicInfo = (props: Props) => {
const { data } = props;
const [loading, setLoading] = useState(false);
const [photo, setPhoto] = useState(data?.photo);
const {
form: { getFieldDecorator, getFieldsValue },
} = props;
const service = new Service('tenant');
const uploadProps: UploadProps = {
// accept: ,
action: '/jetlinks/file/static',
headers: {
'X-Access-Token': getAccessToken(),
},
showUploadList: false,
onChange(info) {
if (info.file.status === 'uploading') {
setLoading(true);
}
if (info.file.status === 'done') {
setPhoto(info.file.response.result);
message.success('上传成功');
setLoading(false);
}
},
};
const updateInfo = () => {
setLoading(true);
const temp = getFieldsValue();
service.update({ ...data, ...temp, photo }).subscribe(
response => {
setLoading(false);
},
() => {},
() => message.success('保存成功'),
);
};
const formLayout = {
labelCol: { span: 9 },
wrapperCol: { span: 15 },
};
return (
<div className={styles.right}>
<Spin spinning={loading}>
<div className={styles.baseView}>
<div className={styles.left}>
<Form {...formLayout}>
<Form.Item label="租户名称">
{getFieldDecorator('name', {
initialValue: data?.name,
})(<Input />)}
</Form.Item>
<Form.Item label="状态">
<Tag>{data?.state?.text}</Tag>
</Form.Item>
<Form.Item label="创建时间">
{moment(data?.createTime).format('YYYY-MM-DD HH:mm:ss')}
</Form.Item>
<Form.Item label="说明">
{getFieldDecorator('description', {
initialValue: data?.description,
})(<Input.TextArea placeholder="说明" rows={4} />)}
</Form.Item>
<Form.Item>
<Button
style={{ marginLeft: 200 }}
htmlType="submit"
type="primary"
onClick={updateInfo}
>
更新基本信息
</Button>
</Form.Item>
</Form>
</div>
<div className={styles.right}>
<>
<div className={styles.avatar_title}>头像</div>
<div className={styles.avatar}>
<img src={photo || data?.photo || defaultimg} alt="avatar" />
</div>
<Upload {...uploadProps} showUploadList={false}>
<div className={styles.button_view}>
<Button>
<UploadOutlined />
更换图片
</Button>
</div>
</Upload>
</>
</div>
</div>
</Spin>
</div>
);
}
Example #16
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
Config: React.FC<Props> = props => {
const [loading, setLoading] = useState(false);
const { form: { getFieldDecorator, getFieldsValue }, settings } = props;
const [titleIcon, setTitleIcon] = useState(settings.titleIcon);
const updateSetting = () => {
const { dispatch } = props;
dispatch({
type: 'settings/settingData',
payload: { ...settings, ...getFieldsValue(), titleIcon },
// callback:()=>{message.success('保存成功')}
callback:(response:any)=>{
if(response.status === 200){
message.success('更新成功');
}else{
message.success('更新失败');
}
}
})
}
const uploadProps: UploadProps = {
// accept: ,
action: '/jetlinks/file/static',
headers: {
'X-Access-Token': getAccessToken(),
},
showUploadList: false,
onChange(info) {
if (info.file.status === 'uploading') {
setLoading(true);
}
if (info.file.status === 'done') {
setTitleIcon(info.file.response.result);
message.success('上传成功');
setLoading(false);
}
},
};
return (
<GridContent>
<div
className={styles.main}
>
<div className={styles.leftMenu}>
<Menu
mode='inline'
selectedKeys={['basic']}
>
<Menu.Item key="basic">系统配置</Menu.Item>
{/* <Menu.Item key="advance">高级</Menu.Item> */}
</Menu>
</div>
<Spin spinning={loading}>
<div className={styles.right}>
<div className={styles.title}>系统配置</div>
<div className={styles.baseView}>
<div className={styles.left}>
<Form
layout="vertical"
hideRequiredMark
>
<Form.Item
label="系统名称"
>
{getFieldDecorator('title', {
initialValue: settings.title,
})(
<Input />
)}
</Form.Item>
<Form.Item
label="主题色"
>
{getFieldDecorator('navTheme', {
initialValue: settings.navTheme
})(
<Select onChange={(e: string) => { localStorage.setItem('theme', e) }}>
<Select.Option value="light">light</Select.Option>
<Select.Option value="dark">dark</Select.Option>
</Select>
)}
</Form.Item>
{/* <Form.Item
label="系统简介"
>
<Input.TextArea
placeholder="系统简介"
rows={4}
/>
</Form.Item> */}
<Form.Item>
<Button htmlType="submit" type="primary" onClick={updateSetting}>
更新基本信息
</Button>
</Form.Item>
</Form>
</div>
<div className={styles.right}>
<>
<div className={styles.avatar_title}>
系统LOGO
</div>
<div className={styles.avatar}>
<img src={titleIcon||logo} alt='default'/>
</div>
<Upload {...uploadProps} showUploadList={false}>
<div className={styles.button_view}>
<Button>
<UploadOutlined />
更换LOGO
</Button>
</div>
</Upload>
</>
</div>
</div>
</div>
</Spin>
</div>
</GridContent>
);
}
Example #17
Source File: palette.tsx From jmix-frontend with Apache License 2.0 | 4 votes |
palette = () => (
<Palette>
<Category name="Text">
<Component name="Formatted Message">
<Variant>
<FormattedMessage />
</Variant>
</Component>
<Component name="Heading">
<Variant name="h1">
<Typography.Title></Typography.Title>
</Variant>
<Variant name="h2">
<Typography.Title level={2}></Typography.Title>
</Variant>
<Variant name="h3">
<Typography.Title level={3}></Typography.Title>
</Variant>
<Variant name="h4">
<Typography.Title level={4}></Typography.Title>
</Variant>
<Variant name="h5">
<Typography.Title level={5}></Typography.Title>
</Variant>
</Component>
<Component name="Text">
<Variant>
<Typography.Text></Typography.Text>
</Variant>
<Variant name="Secondary">
<Typography.Text type="secondary"></Typography.Text>
</Variant>
<Variant name="Success">
<Typography.Text type="success"></Typography.Text>
</Variant>
<Variant name="Warning">
<Typography.Text type="warning"></Typography.Text>
</Variant>
<Variant name="Danger">
<Typography.Text type="danger"></Typography.Text>
</Variant>
<Variant name="Disabled">
<Typography.Text disabled></Typography.Text>
</Variant>
</Component>
</Category>
<Category name="Layout">
<Component name="Divider">
<Variant>
<Divider />
</Variant>
</Component>
<Component name="Grid">
<Variant name="Simple Row">
<Row></Row>
</Variant>
<Variant name="Two columns">
<Row>
<Col span={12}></Col>
<Col span={12}></Col>
</Row>
</Variant>
<Variant name="Three columns">
<Row>
<Col span={8}></Col>
<Col span={8}></Col>
<Col span={8}></Col>
</Row>
</Variant>
</Component>
<Component name="Space">
<Variant>
<Space />
</Variant>
<Variant name="Small">
<Space size={"small"} />
</Variant>
<Variant name="Large">
<Space size={"large"} />
</Variant>
</Component>
</Category>
<Category name="Controls">
<Component name="Autocomplete">
<Variant>
<AutoComplete placeholder="input here" />
</Variant>
</Component>
<Component name="Button">
<Variant>
<Button></Button>
</Variant>
<Variant name="Primary">
<Button type="primary"></Button>
</Variant>
<Variant name="Link">
<Button type="link"></Button>
</Variant>
<Variant name="Dropdown">
<Dropdown
trigger={["click"]}
overlay={
<Menu>
<Menu.Item></Menu.Item>
<Menu.Item></Menu.Item>
<Menu.Item></Menu.Item>
</Menu>
}
>
<Button></Button>
</Dropdown>
</Variant>
</Component>
<Component name="Checkbox">
<Variant>
<Checkbox />
</Variant>
</Component>
<Component name="Switch">
<Variant>
<Switch />
</Variant>
</Component>
<Component name="Radio Group">
<Variant>
<Radio.Group>
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
<Radio value={4}>D</Radio>
</Radio.Group>
</Variant>
<Variant name="Button">
<Radio.Group>
<Radio.Button value={1}>A</Radio.Button>
<Radio.Button value={2}>B</Radio.Button>
<Radio.Button value={3}>C</Radio.Button>
<Radio.Button value={4}>D</Radio.Button>
</Radio.Group>
</Variant>
</Component>
<Component name="DatePicker">
<Variant>
<DatePicker />
</Variant>
<Variant name="Range">
<DatePicker.RangePicker />
</Variant>
</Component>
<Component name="TimePicker">
<Variant>
<TimePicker />
</Variant>
<Variant name="Range">
<TimePicker.RangePicker />
</Variant>
</Component>
<Component name="Input">
<Variant>
<Input />
</Variant>
<Variant name="Number">
<InputNumber />
</Variant>
</Component>
<Component name="Select">
<Variant>
<Select defaultValue="1">
<Select.Option value="1">1</Select.Option>
<Select.Option value="2">2</Select.Option>
</Select>
</Variant>
<Variant name="Multiple">
<Select defaultValue={["1"]} mode="multiple" allowClear>
<Select.Option value="1">1</Select.Option>
<Select.Option value="2">2</Select.Option>
</Select>
</Variant>
</Component>
<Component name="Link">
<Variant>
<Typography.Link href="" target="_blank"></Typography.Link>
</Variant>
</Component>
<Component name="Slider">
<Variant>
<Slider defaultValue={30} />
</Variant>
<Variant name="Range">
<Slider range defaultValue={[20, 50]} />
</Variant>
</Component>
</Category>
<Category name="Data Display">
<Component name="Field">
<Variant>
<Field
entityName={ENTITY_NAME}
disabled={readOnlyMode}
propertyName=""
formItemProps={{
style: { marginBottom: "12px" }
}}
/>
</Variant>
</Component>
<Component name="Card">
<Variant>
<Card />
</Variant>
<Variant name="With Title">
<Card>
<Card title="Card title">
<p>Card content</p>
</Card>
</Card>
</Variant>
<Variant name="My custom card">
<Card>
<Card title="Card title">
<p>Card content</p>
<Avatar />
</Card>
</Card>
</Variant>
</Component>
<Component name="Tabs">
<Variant>
<Tabs defaultActiveKey="1">
<Tabs.TabPane tab="Tab 1" key="1">
Content of Tab Pane 1
</Tabs.TabPane>
<Tabs.TabPane tab="Tab 2" key="2">
Content of Tab Pane 2
</Tabs.TabPane>
<Tabs.TabPane tab="Tab 3" key="3">
Content of Tab Pane 3
</Tabs.TabPane>
</Tabs>
</Variant>
<Variant name="Tab Pane">
<Tabs.TabPane></Tabs.TabPane>
</Variant>
</Component>
<Component name="Collapse">
<Variant>
<Collapse defaultActiveKey="1">
<Collapse.Panel
header="This is panel header 1"
key="1"
></Collapse.Panel>
<Collapse.Panel
header="This is panel header 2"
key="2"
></Collapse.Panel>
<Collapse.Panel
header="This is panel header 3"
key="3"
></Collapse.Panel>
</Collapse>
</Variant>
</Component>
<Component name="Image">
<Variant>
<Image width={200} src="" />
</Variant>
</Component>
<Component name="Avatar">
<Variant>
<Avatar icon={<UserOutlined />} />
</Variant>
<Variant name="Image">
<Avatar src="https://joeschmoe.io/api/v1/random" />
</Variant>
</Component>
<Component name="Badge">
<Variant>
<Badge count={1}></Badge>
</Variant>
</Component>
<Component name="Statistic">
<Variant>
<Statistic title="Title" value={112893} />
</Variant>
</Component>
<Component name="Alert">
<Variant name="Success">
<Alert message="Text" type="success" />
</Variant>
<Variant name="Info">
<Alert message="Text" type="info" />
</Variant>
<Variant name="Warning">
<Alert message="Text" type="warning" />
</Variant>
<Variant name="Error">
<Alert message="Text" type="error" />
</Variant>
</Component>
<Component name="List">
<Variant>
<List
bordered
dataSource={[]}
renderItem={item => <List.Item></List.Item>}
/>
</Variant>
</Component>
</Category>
<Category name="Icons">
<Component name="Arrow">
<Variant name="Up">
<ArrowUpOutlined />
</Variant>
<Variant name="Down">
<ArrowDownOutlined />
</Variant>
<Variant name="Left">
<ArrowLeftOutlined />
</Variant>
<Variant name="Right">
<ArrowRightOutlined />
</Variant>
</Component>
<Component name="Question">
<Variant>
<QuestionOutlined />
</Variant>
<Variant name="Circle">
<QuestionCircleOutlined />
</Variant>
</Component>
<Component name="Plus">
<Variant>
<PlusOutlined />
</Variant>
<Variant name="Circle">
<PlusCircleOutlined />
</Variant>
</Component>
<Component name="Info">
<Variant>
<InfoOutlined />
</Variant>
<Variant name="Circle">
<InfoCircleOutlined />
</Variant>
</Component>
<Component name="Exclamation">
<Variant>
<ExclamationOutlined />
</Variant>
<Variant name="Circle">
<ExclamationCircleOutlined />
</Variant>
</Component>
<Component name="Close">
<Variant>
<CloseOutlined />
</Variant>
<Variant name="Circle">
<CloseCircleOutlined />
</Variant>
</Component>
<Component name="Check">
<Variant>
<CheckOutlined />
</Variant>
<Variant name="Circle">
<CheckCircleOutlined />
</Variant>
</Component>
<Component name="Edit">
<Variant>
<EditOutlined />
</Variant>
</Component>
<Component name="Copy">
<Variant>
<CopyOutlined />
</Variant>
</Component>
<Component name="Delete">
<Variant>
<DeleteOutlined />
</Variant>
</Component>
<Component name="Bars">
<Variant>
<BarsOutlined />
</Variant>
</Component>
<Component name="Bell">
<Variant>
<BellOutlined />
</Variant>
</Component>
<Component name="Clear">
<Variant>
<ClearOutlined />
</Variant>
</Component>
<Component name="Download">
<Variant>
<DownloadOutlined />
</Variant>
</Component>
<Component name="Upload">
<Variant>
<UploadOutlined />
</Variant>
</Component>
<Component name="Sync">
<Variant>
<SyncOutlined />
</Variant>
</Component>
<Component name="Save">
<Variant>
<SaveOutlined />
</Variant>
</Component>
<Component name="Search">
<Variant>
<SearchOutlined />
</Variant>
</Component>
<Component name="Settings">
<Variant>
<SettingOutlined />
</Variant>
</Component>
<Component name="Paperclip">
<Variant>
<PaperClipOutlined />
</Variant>
</Component>
<Component name="Phone">
<Variant>
<PhoneOutlined />
</Variant>
</Component>
<Component name="Mail">
<Variant>
<MailOutlined />
</Variant>
</Component>
<Component name="Home">
<Variant>
<HomeOutlined />
</Variant>
</Component>
<Component name="Contacts">
<Variant>
<ContactsOutlined />
</Variant>
</Component>
<Component name="User">
<Variant>
<UserOutlined />
</Variant>
<Variant name="Add">
<UserAddOutlined />
</Variant>
<Variant name="Remove">
<UserDeleteOutlined />
</Variant>
</Component>
<Component name="Team">
<Variant>
<TeamOutlined />
</Variant>
</Component>
</Category>
<Category name="Screens">
<Component name="ExampleCustomScreen">
<Variant>
<ExampleCustomScreen />
</Variant>
</Component>
<Component name="CustomEntityFilterTest">
<Variant>
<CustomEntityFilterTest />
</Variant>
</Component>
<Component name="CustomFormControls">
<Variant>
<CustomFormControls />
</Variant>
</Component>
<Component name="CustomDataDisplayComponents">
<Variant>
<CustomDataDisplayComponents />
</Variant>
</Component>
<Component name="CustomAppLayouts">
<Variant>
<CustomAppLayouts />
</Variant>
</Component>
<Component name="CustomControls">
<Variant>
<CustomControls />
</Variant>
</Component>
<Component name="ErrorBoundaryTests">
<Variant>
<ErrorBoundaryTests />
</Variant>
</Component>
<Component name="TestBlankScreen">
<Variant>
<TestBlankScreen />
</Variant>
</Component>
<Component name="CarEditor">
<Variant>
<CarEditor />
</Variant>
</Component>
<Component name="CarBrowserCards">
<Variant>
<CarBrowserCards />
</Variant>
</Component>
<Component name="CarBrowserList">
<Variant>
<CarBrowserList />
</Variant>
</Component>
<Component name="CarBrowserTable">
<Variant>
<CarBrowserTable />
</Variant>
</Component>
<Component name="CarCardsGrid">
<Variant>
<CarCardsGrid />
</Variant>
</Component>
<Component name="FavoriteCars">
<Variant>
<FavoriteCars />
</Variant>
</Component>
<Component name="CarCardsWithDetails">
<Variant>
<CarCardsWithDetails />
</Variant>
</Component>
<Component name="CarTableWithFilters">
<Variant>
<CarTableWithFilters />
</Variant>
</Component>
<Component name="CarMasterDetail">
<Variant>
<CarMasterDetail />
</Variant>
</Component>
<Component name="FormWizardCompositionO2O">
<Variant>
<FormWizardCompositionO2O />
</Variant>
</Component>
<Component name="FormWizardEditor">
<Variant>
<FormWizardEditor />
</Variant>
</Component>
<Component name="FormWizardBrowserTable">
<Variant>
<FormWizardBrowserTable />
</Variant>
</Component>
<Component name="CarMultiSelectionTable">
<Variant>
<CarMultiSelectionTable />
</Variant>
</Component>
<Component name="DatatypesTestEditor">
<Variant>
<DatatypesTestEditor />
</Variant>
</Component>
<Component name="DatatypesTestBrowserCards">
<Variant>
<DatatypesTestBrowserCards />
</Variant>
</Component>
<Component name="DatatypesTestBrowserList">
<Variant>
<DatatypesTestBrowserList />
</Variant>
</Component>
<Component name="DatatypesTestBrowserTable">
<Variant>
<DatatypesTestBrowserTable />
</Variant>
</Component>
<Component name="DatatypesTestCards">
<Variant>
<DatatypesTestCards />
</Variant>
</Component>
<Component name="AssociationO2OEditor">
<Variant>
<AssociationO2OEditor />
</Variant>
</Component>
<Component name="AssociationO2OBrowserTable">
<Variant>
<AssociationO2OBrowserTable />
</Variant>
</Component>
<Component name="AssociationO2MEditor">
<Variant>
<AssociationO2MEditor />
</Variant>
</Component>
<Component name="AssociationO2MBrowserTable">
<Variant>
<AssociationO2MBrowserTable />
</Variant>
</Component>
<Component name="AssociationM2OEditor">
<Variant>
<AssociationM2OEditor />
</Variant>
</Component>
<Component name="AssociationM2OBrowserTable">
<Variant>
<AssociationM2OBrowserTable />
</Variant>
</Component>
<Component name="AssociationM2MEditor">
<Variant>
<AssociationM2MEditor />
</Variant>
</Component>
<Component name="AssociationM2MBrowserTable">
<Variant>
<AssociationM2MBrowserTable />
</Variant>
</Component>
<Component name="CompositionO2OEditor">
<Variant>
<CompositionO2OEditor />
</Variant>
</Component>
<Component name="CompositionO2OBrowserTable">
<Variant>
<CompositionO2OBrowserTable />
</Variant>
</Component>
<Component name="CompositionO2MEditor">
<Variant>
<CompositionO2MEditor />
</Variant>
</Component>
<Component name="CompositionO2MBrowserTable">
<Variant>
<CompositionO2MBrowserTable />
</Variant>
</Component>
<Component name="DeeplyNestedTestEntityEditor">
<Variant>
<DeeplyNestedTestEntityEditor />
</Variant>
</Component>
<Component name="DeeplyNestedO2MTestEntityTable">
<Variant>
<DeeplyNestedO2MTestEntityTable />
</Variant>
</Component>
<Component name="DeeplyNestedO2MTestEntityEditor">
<Variant>
<DeeplyNestedO2MTestEntityEditor />
</Variant>
</Component>
<Component name="IntIdEditor">
<Variant>
<IntIdEditor />
</Variant>
</Component>
<Component name="IntIdBrowserTable">
<Variant>
<IntIdBrowserTable />
</Variant>
</Component>
<Component name="IntIdBrowserCards">
<Variant>
<IntIdBrowserCards />
</Variant>
</Component>
<Component name="IntIdBrowserList">
<Variant>
<IntIdBrowserList />
</Variant>
</Component>
<Component name="IntIdentityIdCards">
<Variant>
<IntIdentityIdCards />
</Variant>
</Component>
<Component name="IntIdentityIdEditor">
<Variant>
<IntIdentityIdEditor />
</Variant>
</Component>
<Component name="IntIdentityIdBrowserTable">
<Variant>
<IntIdentityIdBrowserTable />
</Variant>
</Component>
<Component name="IntIdentityIdBrowserCards">
<Variant>
<IntIdentityIdBrowserCards />
</Variant>
</Component>
<Component name="IntIdentityIdBrowserList">
<Variant>
<IntIdentityIdBrowserList />
</Variant>
</Component>
<Component name="StringIdCards">
<Variant>
<StringIdCards />
</Variant>
</Component>
<Component name="StringIdMgtCardsEdit">
<Variant>
<StringIdMgtCardsEdit />
</Variant>
</Component>
<Component name="StringIdBrowserCards">
<Variant>
<StringIdBrowserCards />
</Variant>
</Component>
<Component name="StringIdBrowserList">
<Variant>
<StringIdBrowserList />
</Variant>
</Component>
<Component name="StringIdBrowserTable">
<Variant>
<StringIdBrowserTable />
</Variant>
</Component>
<Component name="WeirdStringIdEditor">
<Variant>
<WeirdStringIdEditor />
</Variant>
</Component>
<Component name="WeirdStringIdBrowserCards">
<Variant>
<WeirdStringIdBrowserCards />
</Variant>
</Component>
<Component name="WeirdStringIdBrowserList">
<Variant>
<WeirdStringIdBrowserList />
</Variant>
</Component>
<Component name="WeirdStringIdBrowserTable">
<Variant>
<WeirdStringIdBrowserTable />
</Variant>
</Component>
<Component name="BoringStringIdEditor">
<Variant>
<BoringStringIdEditor />
</Variant>
</Component>
<Component name="BoringStringIdBrowserTable">
<Variant>
<BoringStringIdBrowserTable />
</Variant>
</Component>
<Component name="TrickyIdEditor">
<Variant>
<TrickyIdEditor />
</Variant>
</Component>
<Component name="TrickyIdBrowserTable">
<Variant>
<TrickyIdBrowserTable />
</Variant>
</Component>
</Category>
</Palette>
)
Example #18
Source File: index.tsx From jetlinks-ui-antd with MIT License | 4 votes |
BaseView: React.FC<Props> = (props) => {
const { form: { getFieldDecorator, getFieldsValue }, dispatch } = props;
const service = new Service('user/detail');
const [user, setUser] = useState<Partial<UserDetail>>({});
const [loading, setLoading] = useState<boolean>(false);
const [avatar, setAvatar] = useState<string>('');
useEffect(() => {
service.get().subscribe(data => {
setUser(data);
setAvatar(data.avatar);
});
}, []);
const uploadProps: UploadProps = {
// accept: ,
action: '/jetlinks/file/static',
headers: {
'X-Access-Token': getAccessToken(),
},
showUploadList: false,
onChange(info) {
if (info.file.status === 'uploading') {
setLoading(true);
}
if (info.file.status === 'done') {
setAvatar(info.file.response.result);
message.success('上传成功');
setLoading(false);
}
},
};
const update = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const data: any = { ...getFieldsValue(), avatar };
if (data && data.mainTenant) {
service.setMainTenant(data.mainTenant).subscribe();
}
service.save(data).subscribe(() => {
message.success('保存成功!');
if (dispatch) {
dispatch({
type: 'user/saveCurrentUser',
payload: {
avatar: avatar,
}
});
}
}, () => {
message.error('保存失败');
})
}
return (
<Spin spinning={loading}>
<div className={styles.baseView}>
<div className={styles.left}>
<Form
layout="vertical"
onSubmit={update}
>
<Form.Item label="姓名">
{getFieldDecorator('name', {
initialValue: user.name,
})(
<Input />
)}
</Form.Item>
{
user.tenants && user.tenants?.length > 0 && (
<Form.Item label="主租户">
{getFieldDecorator('mainTenant', {
initialValue: user.tenants.find((i: any) => i.mainTenant === true)?.tenantId,
})(
<Select allowClear>
{user.tenants.map((item: any) => <Select.Option key={item.tenantId} value={item.tenantId}>{item.tenantName}</Select.Option>)}
</Select>
)}
</Form.Item>
)
}
<Form.Item label="邮箱">
{getFieldDecorator('email', {
initialValue: user.email,
})(
<Input />
)}
</Form.Item>
<Form.Item label="联系电话">
{getFieldDecorator('telephone', {
initialValue: user.telephone,
})(
<Input />
)}
</Form.Item>
<Form.Item label="说明">
{getFieldDecorator('description', {
initialValue: user.description
})(
<Input.TextArea rows={3} />
)}
</Form.Item>
<Form.Item>
<Button htmlType="submit" type="primary">更新信息</Button>
</Form.Item>
</Form>
</div>
<div className={styles.right}>
<div className={styles.avatar_title}>
头像
</div>
<div className={styles.avatar}>
<img src={avatar || defaultImg} alt="avatar" />
</div>
<Upload {...uploadProps} showUploadList={false}>
<div className={styles.button_view}>
<Button>
<UploadOutlined />更换头像
</Button>
</div>
</Upload>
</div>
</div>
</Spin>
)
}
Example #19
Source File: TemplateInfoModal.tsx From yugong with MIT License | 4 votes |
TemplateInfoModal: React.FC<Props> = ({ visible, onOk, onCancel }) => {
const [tags, setTags] = useState<queryTagParams[]>([]);
const pageData = useSelector((state: RootState) => state.pageData);
const [defaultValue, setDefaultValue] = useState<AnyObject>();
const [csrfToken] = useCookie('csrfToken')
const getTags = useCallback(async () => {
const tagsResult = await queryTag();
setTags(tagsResult);
}, []);
useEffect(() => {
const { template = {}, pageTitle } = pageData;
const { title, cove, tag, describe, terminal, isPublic } = template;
const defaultParams: TemplateInfo = {
title: title || pageTitle,
cove: !!cove ? [{thumbUrl: cove}] : [],
tag: !!tag ? tag.split(',') : [],
isPublic: (isPublic === 1),
describe,
terminal,
};
setDefaultValue(defaultParams);
}, [pageData, pageData.template, visible]);
useEffect(() => {
getTags();
}, [getTags]);
const handleSubmit = useCallback(
(data: AnyObject) => {
if (!isType(data, 'Object')) return;
data.describe = data.describe || '';
if (onOk instanceof Function) onOk(data);
},
[onOk]
);
return (
<Modal
key={`${visible}`}
title="模版信息"
visible={visible}
onCancel={onCancel}
okText={'确定'}
cancelText={'取消'}
footer={null}
>
<Form
name="templateInfo"
labelCol={{ span: 5 }}
wrapperCol={{ span: 19 }}
initialValues={defaultValue}
onFinish={handleSubmit}
>
<Form.Item
label="模板标题"
name="title"
rules={[{ required: true, message: '请填写模板标题' }]}
>
<Input />
</Form.Item>
<Form.Item
label="终端"
name="terminal"
rules={[{ required: true, message: '请选择终端' }]}
>
<Select placeholder="请选择">
<Select.Option value="mobile">移动端</Select.Option>
<Select.Option value="pc">PC端</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="cove"
label="封面图片"
valuePropName="fileList"
getValueFromEvent={normFile}
extra="模版封面图片"
rules={[{ required: true, message: '请上传封面图片' }]}
>
<Upload
action="/api/upload"
listType="picture"
maxCount={1}
headers={{
'x-csrf-token': csrfToken || ''
}}
>
<Button icon={<UploadOutlined />}>上传图片</Button>
</Upload>
</Form.Item>
<Form.Item label="描述" name="describe">
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item
label="标签"
name="tag"
rules={[{ required: true, message: '请选择标签' }]}
>
<Select mode="multiple" allowClear placeholder="标签">
{tags.map((item) => (
<Select.Option key={item.id} value={`${item.id}`}>
{item.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
name="isPublic"
valuePropName="checked"
wrapperCol={{ offset: 9, span: 17 }}
>
<Checkbox>发布为公共模板</Checkbox>
</Form.Item>
<Form.Item wrapperCol={{ offset: 10, span: 14 }}>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>
);
}
Example #20
Source File: UploadImg.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
export function RealUploadImg(
props: UploadImgProps,
ref: any
): React.ReactElement {
const { t } = useTranslation(NS_FORMS);
const action = `api/gateway/object_store.object_store.PutObject/api/v1/objectStore/bucket/${props.bucketName}/object`;
const [value, setValue] = React.useState(props.value);
const [imageList, setImageList] = useState(transformToImageList(props.value));
const [previewImage, setPreviewImage] = useState("");
const [previewVisible, setPreviewVisible] = useState(false);
const [disabled, setDisabled] = useState(false);
const [allUser, serAllUser] = useState<UserInfo[]>();
const theme = useCurrentTheme();
const buttonIcon: MenuIcon = {
lib: "easyops",
category: "colored-common",
icon: theme == "dark-v2" ? "upload-dark" : "upload-light",
};
React.useEffect(() => {
setValue(props.value);
const isDifferent = compareValues(props.value?.images, imageList);
if (isDifferent) {
setImageList(transformToImageList(props.value));
}
}, [props.value]);
React.useEffect(() => {
const getAllUser = async () => {
const userMap = await getRuntime().getAllUserMapAsync();
serAllUser([...userMap.values()]);
};
if (props.showMentions) {
getAllUser();
}
}, [props.showMentions]);
const transformResponseToUrl = (objectName: string) => {
const url = `api/gateway/object_store.object_store.GetObject/api/v1/objectStore/bucket/${props.bucketName}/object/${objectName}`;
return props.useFullUrlPath ? `/next/${url}` : `${url}`;
};
const handleValueChange = (v: UploadImgValue) => {
let newValue = { ...value, ...v };
if (
(newValue.text === "" || isNil(newValue.text)) &&
isEmpty(newValue.images)
) {
newValue = null;
}
setValue(newValue);
props.onChange?.(newValue);
};
const handleFilesChange = async (
newFile: ImageItem,
newFileList: ImageItem[],
isDone: boolean
): Promise<void> => {
if (isDone) {
if (props.maxNumber === 1) {
newFile.preview =
newFile.preview || (await getBase64(newFile.originFileObj));
setImageList([
{
...newFile,
},
]);
handleValueChange({
images: [
{
...(props.getPreview ? { preview: newFile.preview } : {}),
url: newFile.url,
name: newFile.name,
},
],
});
} else {
setImageList(
update(newFileList, {
[newFileList.length - 1]: { $set: newFile },
})
);
handleValueChange({
images: update(value?.images || [], {
$push: [
{
...(props.getPreview ? { preview: newFile.preview } : {}),
url: newFile.url,
name: newFile.name,
},
],
}),
});
}
} else {
if (props.maxNumber === 1) {
setImageList([{ ...newFile }]);
} else {
setImageList(newFileList);
}
}
};
const handlePreview = async (file: any): Promise<void> => {
if (!file.preview && file.originFileObj) {
file.preview = await getBase64(file.originFileObj);
}
setPreviewImage(file.preview || file.url);
setPreviewVisible(true);
};
const handleChange = ({
file,
fileList,
}: {
file: UploadFile;
fileList: UploadFile[];
}): void => {
if (some(fileList, ["status", "uploading"])) {
setDisabled(true);
} else {
setDisabled(false);
}
if (file.status === "removed") {
const index = findIndex(imageList, ["uid", file.uid]);
handleValueChange({
images: update(value.images, { $splice: [[index, 1]] }),
});
setImageList(fileList);
} else if (file.status === "error") {
setDisabled(false);
const index = findIndex(imageList, ["uid", file.uid]);
if (index !== -1) {
setImageList(update(imageList, { $splice: [[index, 1]] }));
}
message.error("上传文件失败");
} else {
if (file?.type.startsWith("image/")) {
handleFilesChange(file, [...fileList], false);
if (file.response && file.status === "done") {
file.url = transformResponseToUrl(file.response.data.objectName);
handleFilesChange(file, [...fileList], true);
}
} else {
setDisabled(false);
}
}
};
const handleCancel = (): void => {
setPreviewVisible(false);
};
const uploadButton = (): React.ReactElement => {
if (props.hideUploadButton && !props.uploadDraggable) {
return null;
}
if (props.uploadDraggable) {
return (
<>
<p className="ant-upload-drag-icon">
<GeneralIcon icon={buttonIcon} />
</p>
<p className="ant-upload-text">
{props.draggableUploadText ?? t(K.DRAGGABLE_UPLOAD_TEXT)}
</p>
<p className="ant-upload-hint">
{props.draggableUploadHint ?? t(K.DRAGGABLE_UPLOAD_HINT)}
</p>
</>
);
}
if (props.listType === "picture-card") {
return (
<div>
{props.maxNumber === 1 && disabled ? (
<LoadingOutlined />
) : theme === "dark-v2" ? (
<ImageUploadDark />
) : (
<ImageUpload />
)}
<div className="ant-upload-text" style={{ marginTop: "-8px" }}>
上传图片
</div>
</div>
);
} else {
return (
<Button>
<UploadOutlined /> Upload
</Button>
);
}
};
const uploadNode = (): React.ReactElement => {
return !props.maxNumber || imageList?.length < props.maxNumber
? uploadButton()
: null;
};
const filesPasted = (e): void => {
const items = e.clipboardData.items;
forEach(items, async (item) => {
const file = item.getAsFile();
if (file?.type.startsWith("image/")) {
if (
props.maxNumber &&
imageList?.length >= props.maxNumber &&
props.maxNumber !== 1
) {
message.error(`仅支持上传 ${props.maxNumber} 张图片`);
return;
}
if (disabled) {
message.error("还有附件正在上传,请稍候再试。");
return;
}
const fileInfo: any = {
originFileObj: file,
type: file.type,
name: file.name,
size: file.size,
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
uid: uniqueId("-img"),
status: "uploading",
percent: 0,
};
const oldList = cloneDeep(imageList);
handleFilesChange(fileInfo, [...oldList, fileInfo], false);
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
fileInfo.preview = reader.result as string;
fileInfo.percent = 100;
};
// 上传文件
setDisabled(true);
try {
const response = await ObjectStoreApi_putObject(props.bucketName, {
file: file,
});
fileInfo.status = "done";
fileInfo.url = transformResponseToUrl(response.objectName);
handleFilesChange(fileInfo, [...oldList, fileInfo], true);
setDisabled(false);
} catch (err) {
message.error("上传失败");
setImageList(oldList);
setDisabled(false);
}
}
});
};
const handleTextChange = (e: any): void => {
handleValueChange({
text: e.target.value,
});
};
const handleMentionsChange = (value: string): void => {
handleValueChange({
text: value,
});
};
const handleRemove = (e: any): void => {
props.onRemove?.(e);
};
const handleBeforeUpload = (file: RcFile): Promise<RcFile> => {
return new Promise((resolve, reject) => {
if (!file.type?.startsWith("image/")) {
message.error("仅支持上传图片文件");
reject(new Error("仅支持上传图片文件"));
}
if (FileUtils.sizeCompare(file, props.limitSize ?? 10)) {
message.error(`上传文件体积大于限定体积`);
reject(new Error("上传文件体积大于限定体积"));
}
resolve(file);
});
};
const fileInfoNode = (file: UploadFile): ReactNode => (
<>
<div className={styles["upload-file-main-info"]}>
<span className={styles["upload-file-name"]}>{file.name}</span>
<span className={styles["upload-file-size"]}>
{file.size &&
(file.status === "uploading"
? `${sizeFormat(file.size)} (${Math.floor(file.percent)}%Done)`
: sizeFormat(file.size))}
</span>
</div>
<div className={styles["upload-file-else-info"]}>
{(file.status === "error" || file.status === "uploading") && (
<span className={styles["upload-file-error-info"]}>
{file.status === "error" && "Wrong!"}
</span>
)}
</div>
</>
);
const cloneFileItemNode = (
node: ReactElement,
file: UploadFile
): ReactNode => {
const nodeChildren = React.Children.map(node?.props?.children, (child) => {
if (
child?.props?.className
?.split(" ")
?.includes("ant-upload-list-item-name")
) {
return React.cloneElement(child, null, fileInfoNode(file));
}
return cloneFileItemNode(child, file);
});
if (React.isValidElement(node)) {
// children是function额外处理
if (node?.props?.children instanceof Function)
return React.cloneElement(node, null, node.props.children);
return React.cloneElement(node, null, nodeChildren);
}
return node;
};
const textProps = {
progress: {
strokeColor: "#2FC25B",
trailColor: "var(--theme-gray-background)",
strokeWidth: "1px",
showInfo: false,
},
showUploadList: {
// eslint-disable-next-line react/display-name
removeIcon: (file: UploadFile): ReactNode =>
file.status === "error" ? (
<GeneralIcon
icon={{
lib: "antd",
theme: "outlined",
icon: "close",
}}
/>
) : (
<GeneralIcon
icon={{
lib: "easyops",
category: "default",
icon: "delete",
}}
/>
),
},
// eslint-disable-next-line react/display-name
iconRender: (file: UploadFile): ReactNode =>
file.status === "uploading" ? (
<LoadingOutlined />
) : (
<GeneralIcon
icon={{
lib: "antd",
icon: "file-text",
theme: "outlined",
}}
/>
),
};
const pictureProps = {
progress: {
strokeColor: "var(--color-brand)",
trailColor: "#FFF",
strokeWidth: "4px",
showInfo: false,
},
showUploadList: {
// eslint-disable-next-line react/display-name
removeIcon: (file: UploadFile): ReactNode =>
file.status === "error" ? (
<GeneralIcon
icon={{
lib: "antd",
theme: "outlined",
icon: "close",
}}
/>
) : (
<GeneralIcon
icon={{
lib: "easyops",
category: "default",
icon: "delete",
}}
/>
),
},
// eslint-disable-next-line react/display-name
itemRender: (originNode: ReactElement, file: UploadFile): ReactNode => {
return cloneFileItemNode(originNode, file);
},
};
let typeProps = {};
if (props.listType === "picture") {
typeProps = pictureProps;
} else if (props.listType === "text") {
typeProps = textProps;
}
const uploadProps = {
className: classNames({
[styles.uploadContainerDisplayNone]:
props.uploadDraggable &&
props.maxNumber &&
imageList?.length >= props.maxNumber,
}),
method: "put",
action,
listType: props.listType,
fileList: imageList,
onPreview: handlePreview,
onChange: handleChange,
onRemove: handleRemove,
beforeUpload: handleBeforeUpload,
supportServerRender: true,
disabled,
};
return (
<div ref={ref} className={styles.uploadContainer}>
{props.showTextarea && (
<Input.TextArea
onPaste={(e) => filesPasted(e)}
onChange={handleTextChange}
className={styles.textContainer}
value={value?.text || ""}
placeholder={props.placeholder}
autoSize={props.autoSize}
/>
)}
{props.showMentions && !props.showTextarea && (
<Mentions
rows={2}
onChange={handleMentionsChange}
value={value?.text || ""}
autoSize={props.autoSize}
className={styles.textContainer}
onPaste={(e) => filesPasted(e)}
placeholder={props.placeholder}
>
{allUser &&
allUser.map((item) => (
<Mentions.Option value={item.name} key={item.name}>
<Avatar
src={item.user_icon}
size={24}
className={classNames(styles.avatar, {
[styles.defaultIcon]: !item.user_icon,
})}
>
{!item.user_icon && item.name?.slice(0, 2)}
</Avatar>
{item.name}
</Mentions.Option>
))}
</Mentions>
)}
{props.uploadDraggable ? (
<Upload.Dragger {...uploadProps}>{uploadNode()}</Upload.Dragger>
) : (
<Upload {...uploadProps} {...typeProps}>
{uploadNode()}
</Upload>
)}
<Modal visible={previewVisible} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: "100%" }} src={previewImage} />
</Modal>
</div>
);
}
Example #21
Source File: CreateNewDashboardPage.tsx From iot-center-v2 with MIT License | 4 votes |
CreateNewDashboardPage: FunctionComponent<{
onEdit: () => void
clientId: string
}> = ({onEdit, clientId}) => {
const [helpText, setHelpText] = useState('')
useEffect(() => {
// load markdown from file
const fetchMarkdown = async () => {
try {
const [txt, dir] = await Promise.all([
// TODO: update document
fetch('/help/DynamicDashboardPage.md').then((x) => x.text()),
fetch('/api/dynamic/dir').then((x) => x.text()),
])
setHelpText(
(txt ?? '').startsWith('<!')
? 'HELP NOT FOUND'
: txt.replace('{Dynamic Dir}', dir)
)
} catch (e) {
console.error(e)
}
}
fetchMarkdown()
}, [])
const [newPageName, setNewPageName] = useState<string>()
const history = useHistory()
const onFileUpload = useCallback(
(file: RcFile) => {
const reader = new FileReader()
reader.onload = async (e) => {
const text = (e?.target?.result as string | undefined) ?? ''
await upload(file.name, text).then(onEdit)
const ext = path.extname(file.name).substring(1)
const name = file.name.split('.').slice(0, -1).join('.')
if (ext === 'json')
// TODO: make this different. this way isn't stable
setTimeout(() => history.push(`/dynamic/${clientId}/${name}`), 1000)
}
reader.readAsText(file)
// cancel default behaviour of file upload
return false
},
[clientId, history, onEdit]
)
return (
<>
<Modal
visible={typeof newPageName === 'string'}
onCancel={() => setNewPageName(undefined)}
onOk={() => {
if (newPageName === '') return
upload(`${newPageName}.json`, `{"cells":[]}`).then(() => {
setNewPageName(undefined)
onEdit()
// TODO: make this different. this way isn't stable
setTimeout(
() => history.push(`/dynamic/${clientId}/${newPageName}`),
1000
)
})
}}
>
<Input
value={newPageName}
onChange={(e) => setNewPageName(e.target.value)}
/>
</Modal>
<Card
title="How to create new dynamic dashboard"
extra={
<>
<Button onClick={() => setNewPageName('')}>Empty</Button>
<Upload
accept=".json,.svg"
multiple={true}
beforeUpload={onFileUpload}
>
<Button icon={<UploadOutlined />}>Upload</Button>
</Upload>
</>
}
>
<Markdown source={helpText} />
</Card>
</>
)
}
Example #22
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>
);
}
Example #23
Source File: Icon.tsx From html2sketch with MIT License | 4 votes |
IconSymbol: FC = () => {
return (
<Row>
{/*<CaretUpOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/1.CaretUpOutlined'}*/}
{/*/>*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.MailOutlined'}*/}
{/*/>*/}
{/*<StepBackwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
{/*<StepForwardOutlined*/}
{/* className="icon"*/}
{/* symbolName={'1.General/2.Icons/2.StepBackwardOutlined'}*/}
{/*/>*/}
<StepForwardOutlined />
<ShrinkOutlined />
<ArrowsAltOutlined />
<DownOutlined />
<UpOutlined />
<LeftOutlined />
<RightOutlined />
<CaretUpOutlined />
<CaretDownOutlined />
<CaretLeftOutlined />
<CaretRightOutlined />
<VerticalAlignTopOutlined />
<RollbackOutlined />
<FastBackwardOutlined />
<FastForwardOutlined />
<DoubleRightOutlined />
<DoubleLeftOutlined />
<VerticalLeftOutlined />
<VerticalRightOutlined />
<VerticalAlignMiddleOutlined />
<VerticalAlignBottomOutlined />
<ForwardOutlined />
<BackwardOutlined />
<EnterOutlined />
<RetweetOutlined />
<SwapOutlined />
<SwapLeftOutlined />
<SwapRightOutlined />
<ArrowUpOutlined />
<ArrowDownOutlined />
<ArrowLeftOutlined />
<ArrowRightOutlined />
<LoginOutlined />
<LogoutOutlined />
<MenuFoldOutlined />
<MenuUnfoldOutlined />
<BorderBottomOutlined />
<BorderHorizontalOutlined />
<BorderInnerOutlined />
<BorderOuterOutlined />
<BorderLeftOutlined />
<BorderRightOutlined />
<BorderTopOutlined />
<BorderVerticleOutlined />
<PicCenterOutlined />
<PicLeftOutlined />
<PicRightOutlined />
<RadiusBottomleftOutlined />
<RadiusBottomrightOutlined />
<RadiusUpleftOutlined />
<RadiusUprightOutlined />
<FullscreenOutlined />
<FullscreenExitOutlined />
<QuestionOutlined />
<PauseOutlined />
<MinusOutlined />
<PauseCircleOutlined />
<InfoOutlined />
<CloseOutlined />
<ExclamationOutlined />
<CheckOutlined />
<WarningOutlined />
<IssuesCloseOutlined />
<StopOutlined />
<EditOutlined />
<CopyOutlined />
<ScissorOutlined />
<DeleteOutlined />
<SnippetsOutlined />
<DiffOutlined />
<HighlightOutlined />
<AlignCenterOutlined />
<AlignLeftOutlined />
<AlignRightOutlined />
<BgColorsOutlined />
<BoldOutlined />
<ItalicOutlined />
<UnderlineOutlined />
<StrikethroughOutlined />
<RedoOutlined />
<UndoOutlined />
<ZoomInOutlined />
<ZoomOutOutlined />
<FontColorsOutlined />
<FontSizeOutlined />
<LineHeightOutlined />
<SortAscendingOutlined />
<SortDescendingOutlined />
<DragOutlined />
<OrderedListOutlined />
<UnorderedListOutlined />
<RadiusSettingOutlined />
<ColumnWidthOutlined />
<ColumnHeightOutlined />
<AreaChartOutlined />
<PieChartOutlined />
<BarChartOutlined />
<DotChartOutlined />
<LineChartOutlined />
<RadarChartOutlined />
<HeatMapOutlined />
<FallOutlined />
<RiseOutlined />
<StockOutlined />
<BoxPlotOutlined />
<FundOutlined />
<SlidersOutlined />
<AndroidOutlined />
<AppleOutlined />
<WindowsOutlined />
<IeOutlined />
<ChromeOutlined />
<GithubOutlined />
<AliwangwangOutlined />
<DingdingOutlined />
<WeiboSquareOutlined />
<WeiboCircleOutlined />
<TaobaoCircleOutlined />
<Html5Outlined />
<WeiboOutlined />
<TwitterOutlined />
<WechatOutlined />
<AlipayCircleOutlined />
<TaobaoOutlined />
<SkypeOutlined />
<FacebookOutlined />
<CodepenOutlined />
<CodeSandboxOutlined />
<AmazonOutlined />
<GoogleOutlined />
<AlipayOutlined />
<AntDesignOutlined />
<AntCloudOutlined />
<ZhihuOutlined />
<SlackOutlined />
<SlackSquareOutlined />
<BehanceSquareOutlined />
<DribbbleOutlined />
<DribbbleSquareOutlined />
<InstagramOutlined />
<YuqueOutlined />
<AlibabaOutlined />
<YahooOutlined />
<RedditOutlined />
<SketchOutlined />
<AccountBookOutlined />
<AlertOutlined />
<ApartmentOutlined />
<ApiOutlined />
<QqOutlined />
<MediumWorkmarkOutlined />
<GitlabOutlined />
<MediumOutlined />
<GooglePlusOutlined />
<AppstoreAddOutlined />
<AppstoreOutlined />
<AudioOutlined />
<AudioMutedOutlined />
<AuditOutlined />
<BankOutlined />
<BarcodeOutlined />
<BarsOutlined />
<BellOutlined />
<BlockOutlined />
<BookOutlined />
<BorderOutlined />
<BranchesOutlined />
<BuildOutlined />
<BulbOutlined />
<CalculatorOutlined />
<CalendarOutlined />
<CameraOutlined />
<CarOutlined />
<CarryOutOutlined />
<CiCircleOutlined />
<CiOutlined />
<CloudOutlined />
<ClearOutlined />
<ClusterOutlined />
<CodeOutlined />
<CoffeeOutlined />
<CompassOutlined />
<CompressOutlined />
<ContactsOutlined />
<ContainerOutlined />
<ControlOutlined />
<CopyrightCircleOutlined />
<CopyrightOutlined />
<CreditCardOutlined />
<CrownOutlined />
<CustomerServiceOutlined />
<DashboardOutlined />
<DatabaseOutlined />
<DeleteColumnOutlined />
<DeleteRowOutlined />
<DisconnectOutlined />
<DislikeOutlined />
<DollarCircleOutlined />
<DollarOutlined />
<DownloadOutlined />
<EllipsisOutlined />
<EnvironmentOutlined />
<EuroCircleOutlined />
<EuroOutlined />
<ExceptionOutlined />
<ExpandAltOutlined />
<ExpandOutlined />
<ExperimentOutlined />
<ExportOutlined />
<EyeOutlined />
<FieldBinaryOutlined />
<FieldNumberOutlined />
<FieldStringOutlined />
<DesktopOutlined />
<DingtalkOutlined />
<FileAddOutlined />
<FileDoneOutlined />
<FileExcelOutlined />
<FileExclamationOutlined />
<FileOutlined />
<FileImageOutlined />
<FileJpgOutlined />
<FileMarkdownOutlined />
<FilePdfOutlined />
<FilePptOutlined />
<FileProtectOutlined />
<FileSearchOutlined />
<FileSyncOutlined />
<FileTextOutlined />
<FileUnknownOutlined />
<FileWordOutlined />
<FilterOutlined />
<FireOutlined />
<FlagOutlined />
<FolderAddOutlined />
<FolderOutlined />
<FolderOpenOutlined />
<ForkOutlined />
<FormatPainterOutlined />
<FrownOutlined />
<FunctionOutlined />
<FunnelPlotOutlined />
<GatewayOutlined />
<GifOutlined />
<GiftOutlined />
<GlobalOutlined />
<GoldOutlined />
<GroupOutlined />
<HddOutlined />
<HeartOutlined />
<HistoryOutlined />
<HomeOutlined />
<HourglassOutlined />
<IdcardOutlined />
<ImportOutlined />
<InboxOutlined />
<InsertRowAboveOutlined />
<InsertRowBelowOutlined />
<InsertRowLeftOutlined />
<InsertRowRightOutlined />
<InsuranceOutlined />
<InteractionOutlined />
<KeyOutlined />
<LaptopOutlined />
<LayoutOutlined />
<LikeOutlined />
<LineOutlined />
<LinkOutlined />
<Loading3QuartersOutlined />
<LoadingOutlined />
<LockOutlined />
<MailOutlined />
<ManOutlined />
<MedicineBoxOutlined />
<MehOutlined />
<MenuOutlined />
<MergeCellsOutlined />
<MessageOutlined />
<MobileOutlined />
<MoneyCollectOutlined />
<MonitorOutlined />
<MoreOutlined />
<NodeCollapseOutlined />
<NodeExpandOutlined />
<NodeIndexOutlined />
<NotificationOutlined />
<NumberOutlined />
<PaperClipOutlined />
<PartitionOutlined />
<PayCircleOutlined />
<PercentageOutlined />
<PhoneOutlined />
<PictureOutlined />
<PoundCircleOutlined />
<PoundOutlined />
<PoweroffOutlined />
<PrinterOutlined />
<ProfileOutlined />
<ProjectOutlined />
<PropertySafetyOutlined />
<PullRequestOutlined />
<PushpinOutlined />
<QrcodeOutlined />
<ReadOutlined />
<ReconciliationOutlined />
<RedEnvelopeOutlined />
<ReloadOutlined />
<RestOutlined />
<RobotOutlined />
<RocketOutlined />
<SafetyCertificateOutlined />
<SafetyOutlined />
<ScanOutlined />
<ScheduleOutlined />
<SearchOutlined />
<SecurityScanOutlined />
<SelectOutlined />
<SendOutlined />
<SettingOutlined />
<ShakeOutlined />
<ShareAltOutlined />
<ShopOutlined />
<ShoppingCartOutlined />
<ShoppingOutlined />
<SisternodeOutlined />
<SkinOutlined />
<SmileOutlined />
<SolutionOutlined />
<SoundOutlined />
<SplitCellsOutlined />
<StarOutlined />
<SubnodeOutlined />
<SyncOutlined />
<TableOutlined />
<TabletOutlined />
<TagOutlined />
<TagsOutlined />
<TeamOutlined />
<ThunderboltOutlined />
<ToTopOutlined />
<ToolOutlined />
<TrademarkCircleOutlined />
<TrademarkOutlined />
<TransactionOutlined />
<TrophyOutlined />
<UngroupOutlined />
<UnlockOutlined />
<UploadOutlined />
<UsbOutlined />
<UserAddOutlined />
<UserDeleteOutlined />
<UserOutlined />
<UserSwitchOutlined />
<UsergroupAddOutlined />
<UsergroupDeleteOutlined />
<VideoCameraOutlined />
<WalletOutlined />
<WifiOutlined />
<BorderlessTableOutlined />
<WomanOutlined />
<BehanceOutlined />
<DropboxOutlined />
<DeploymentUnitOutlined />
<UpCircleOutlined />
<DownCircleOutlined />
<LeftCircleOutlined />
<RightCircleOutlined />
<UpSquareOutlined />
<DownSquareOutlined />
<LeftSquareOutlined />
<RightSquareOutlined />
<PlayCircleOutlined />
<QuestionCircleOutlined />
<PlusCircleOutlined />
<PlusSquareOutlined />
<MinusSquareOutlined />
<MinusCircleOutlined />
<InfoCircleOutlined />
<ExclamationCircleOutlined />
<CloseCircleOutlined />
<CloseSquareOutlined />
<CheckCircleOutlined />
<CheckSquareOutlined />
<ClockCircleOutlined />
<FormOutlined />
<DashOutlined />
<SmallDashOutlined />
<YoutubeOutlined />
<CodepenCircleOutlined />
<AliyunOutlined />
<PlusOutlined />
<LinkedinOutlined />
<AimOutlined />
<BugOutlined />
<CloudDownloadOutlined />
<CloudServerOutlined />
<CloudSyncOutlined />
<CloudUploadOutlined />
<CommentOutlined />
<ConsoleSqlOutlined />
<EyeInvisibleOutlined />
<FileGifOutlined />
<DeliveredProcedureOutlined />
<FieldTimeOutlined />
<FileZipOutlined />
<FolderViewOutlined />
<FundProjectionScreenOutlined />
<FundViewOutlined />
<MacCommandOutlined />
<PlaySquareOutlined />
<OneToOneOutlined />
<RotateLeftOutlined />
<RotateRightOutlined />
<SaveOutlined />
<SwitcherOutlined />
<TranslationOutlined />
<VerifiedOutlined />
<VideoCameraAddOutlined />
<WhatsAppOutlined />
{/*</Col>*/}
</Row>
);
}
Example #24
Source File: palette.tsx From jmix-frontend with Apache License 2.0 | 4 votes |
palette = () =>
<Palette>
<Category name="Text">
<Component name="Formatted Message">
<Variant>
<FormattedMessage />
</Variant>
</Component>
<Component name="Heading">
<Variant name='h1'>
<Typography.Title></Typography.Title>
</Variant>
<Variant name='h2'>
<Typography.Title level = {2}></Typography.Title>
</Variant>
<Variant name='h3'>
<Typography.Title level = {3}></Typography.Title>
</Variant>
<Variant name='h4'>
<Typography.Title level = {4}></Typography.Title>
</Variant>
<Variant name='h5'>
<Typography.Title level = {5}></Typography.Title>
</Variant>
</Component>
<Component name='Text'>
<Variant>
<Typography.Text></Typography.Text>
</Variant>
<Variant name = 'Secondary'>
<Typography.Text type="secondary"></Typography.Text>
</Variant>
<Variant name = 'Success'>
<Typography.Text type="success"></Typography.Text>
</Variant>
<Variant name = 'Warning'>
<Typography.Text type="warning"></Typography.Text>
</Variant>
<Variant name = 'Danger'>
<Typography.Text type="danger"></Typography.Text>
</Variant>
<Variant name = 'Disabled'>
<Typography.Text disabled></Typography.Text>
</Variant>
</Component>
</Category>
<Category name="Layout">
<Component name="Divider">
<Variant>
<Divider />
</Variant>
</Component>
<Component name="Grid">
<Variant name="Simple Row">
<Row></Row>
</Variant>
<Variant name="Two columns">
<Row>
<Col span={12}></Col>
<Col span={12}></Col>
</Row>
</Variant>
<Variant name="Three columns">
<Row>
<Col span={8}></Col>
<Col span={8}></Col>
<Col span={8}></Col>
</Row>
</Variant>
</Component>
<Component name="Space">
<Variant>
<Space />
</Variant>
<Variant name="Small">
<Space size={"small"} />
</Variant>
<Variant name="Large">
<Space size={"large"} />
</Variant>
</Component>
</Category>
<Category name="Controls">
<Component name="Autocomplete">
<Variant>
<AutoComplete placeholder="input here" />
</Variant>
</Component>
<Component name="Button">
<Variant>
<Button></Button>
</Variant>
<Variant name="Primary">
<Button type="primary" ></Button>
</Variant>
<Variant name="Link">
<Button type="link" ></Button>
</Variant>
<Variant name="Dropdown">
<Dropdown
trigger={['click']}
overlay={<Menu>
<Menu.Item>
</Menu.Item>
<Menu.Item>
</Menu.Item>
<Menu.Item>
</Menu.Item>
</Menu>}
>
<Button></Button>
</Dropdown>
</Variant>
</Component>
<Component name="Checkbox">
<Variant>
<Checkbox />
</Variant>
</Component>
<Component name='Switch'>
<Variant>
<Switch />
</Variant>
</Component>
<Component name='Radio Group'>
<Variant>
<Radio.Group>
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
<Radio value={4}>D</Radio>
</Radio.Group>
</Variant>
<Variant name = 'Button'>
<Radio.Group>
<Radio.Button value={1}>A</Radio.Button>
<Radio.Button value={2}>B</Radio.Button>
<Radio.Button value={3}>C</Radio.Button>
<Radio.Button value={4}>D</Radio.Button>
</Radio.Group>
</Variant>
</Component>
<Component name="DatePicker">
<Variant>
<DatePicker />
</Variant>
<Variant name="Range">
<DatePicker.RangePicker />
</Variant>
</Component>
<Component name="TimePicker">
<Variant>
<TimePicker />
</Variant>
<Variant name="Range">
<TimePicker.RangePicker />
</Variant>
</Component>
<Component name="Input">
<Variant>
<Input />
</Variant>
<Variant name='Number'>
<InputNumber />
</Variant>
</Component>
<Component name='Select'>
<Variant>
<Select defaultValue="1">
<Select.Option value="1">1</Select.Option>
<Select.Option value="2">2</Select.Option>
</Select>
</Variant>
<Variant name='Multiple'>
<Select
defaultValue={["1"]}
mode="multiple"
allowClear
>
<Select.Option value="1">1</Select.Option>
<Select.Option value="2">2</Select.Option>
</Select>
</Variant>
</Component>
<Component name="Link">
<Variant>
<Typography.Link href="" target="_blank">
</Typography.Link>
</Variant>
</Component>
<Component name='Slider'>
<Variant>
<Slider defaultValue={30} />
</Variant>
<Variant name = 'Range'>
<Slider range defaultValue={[20, 50]}/>
</Variant>
</Component>
</Category>
<Category name="Data Display">
<Component name="Field">
<Variant>
<Field
entityName={ENTITY_NAME}
disabled={readOnlyMode}
propertyName=''
formItemProps={{
style: { marginBottom: "12px" }
}}
/>
</Variant>
</Component>
<Component name="Card">
<Variant>
<Card />
</Variant>
<Variant name="With Title">
<Card>
<Card title="Card title">
<p>Card content</p>
</Card>
</Card>
</Variant>
<Variant name="My custom card">
<Card>
<Card title="Card title">
<p>Card content</p>
<Avatar />
</Card>
</Card>
</Variant>
</Component>
<Component name="Tabs">
<Variant>
<Tabs defaultActiveKey="1">
<Tabs.TabPane tab="Tab 1" key="1">
Content of Tab Pane 1
</Tabs.TabPane>
<Tabs.TabPane tab="Tab 2" key="2">
Content of Tab Pane 2
</Tabs.TabPane>
<Tabs.TabPane tab="Tab 3" key="3">
Content of Tab Pane 3
</Tabs.TabPane>
</Tabs>
</Variant>
<Variant name = "Tab Pane">
<Tabs.TabPane>
</Tabs.TabPane>
</Variant>
</Component>
<Component name="Collapse">
<Variant>
<Collapse defaultActiveKey='1'>
<Collapse.Panel header="This is panel header 1" key="1">
</Collapse.Panel>
<Collapse.Panel header="This is panel header 2" key="2">
</Collapse.Panel>
<Collapse.Panel header="This is panel header 3" key="3">
</Collapse.Panel>
</Collapse>
</Variant>
</Component>
<Component name="Image">
<Variant>
<Image
width={200}
src=""
/>
</Variant>
</Component>
<Component name="Avatar">
<Variant>
<Avatar icon={<UserOutlined />} />
</Variant>
<Variant name="Image">
<Avatar src="https://joeschmoe.io/api/v1/random" />
</Variant>
</Component>
<Component name="Badge">
<Variant>
<Badge count={1}>
</Badge>
</Variant>
</Component>
<Component name="Statistic">
<Variant>
<Statistic title="Title" value={112893} />
</Variant>
</Component>
<Component name="Alert">
<Variant name="Success">
<Alert message="Text" type="success" />
</Variant>
<Variant name="Info">
<Alert message="Text" type="info" />
</Variant>
<Variant name="Warning">
<Alert message="Text" type="warning" />
</Variant>
<Variant name="Error">
<Alert message="Text" type="error" />
</Variant>
</Component>
<Component name='List'>
<Variant>
<List
bordered
dataSource={[]}
renderItem={item => (
<List.Item>
</List.Item>
)}
/>
</Variant>
</Component>
</Category>
<Category name="Icons">
<Component name="Arrow">
<Variant name = 'Up'>
<ArrowUpOutlined />
</Variant>
<Variant name = 'Down'>
<ArrowDownOutlined />
</Variant>
<Variant name = 'Left'>
<ArrowLeftOutlined />
</Variant>
<Variant name = 'Right'>
<ArrowRightOutlined />
</Variant>
</Component>
<Component name = 'Question'>
<Variant>
<QuestionOutlined />
</Variant>
<Variant name = 'Circle'>
<QuestionCircleOutlined />
</Variant>
</Component>
<Component name = 'Plus'>
<Variant>
<PlusOutlined />
</Variant>
<Variant name = 'Circle'>
<PlusCircleOutlined />
</Variant>
</Component>
<Component name = 'Info'>
<Variant>
<InfoOutlined />
</Variant>
<Variant name = 'Circle'>
<InfoCircleOutlined />
</Variant>
</Component>
<Component name = 'Exclamation'>
<Variant>
<ExclamationOutlined />
</Variant>
<Variant name = 'Circle'>
<ExclamationCircleOutlined />
</Variant>
</Component>
<Component name = 'Close'>
<Variant>
<CloseOutlined />
</Variant>
<Variant name = 'Circle'>
<CloseCircleOutlined />
</Variant>
</Component>
<Component name = 'Check'>
<Variant>
<CheckOutlined />
</Variant>
<Variant name = 'Circle'>
<CheckCircleOutlined />
</Variant>
</Component>
<Component name = 'Edit'>
<Variant>
<EditOutlined />
</Variant>
</Component>
<Component name = 'Copy'>
<Variant>
<CopyOutlined />
</Variant>
</Component>
<Component name = 'Delete'>
<Variant>
<DeleteOutlined />
</Variant>
</Component>
<Component name = 'Bars'>
<Variant>
<BarsOutlined />
</Variant>
</Component>
<Component name = 'Bell'>
<Variant>
<BellOutlined />
</Variant>
</Component>
<Component name = 'Clear'>
<Variant>
<ClearOutlined />
</Variant>
</Component>
<Component name = 'Download'>
<Variant>
<DownloadOutlined />
</Variant>
</Component>
<Component name = 'Upload'>
<Variant>
<UploadOutlined />
</Variant>
</Component>
<Component name = 'Sync'>
<Variant>
<SyncOutlined />
</Variant>
</Component>
<Component name = 'Save'>
<Variant>
<SaveOutlined />
</Variant>
</Component>
<Component name = 'Search'>
<Variant>
<SearchOutlined />
</Variant>
</Component>
<Component name = 'Settings'>
<Variant>
<SettingOutlined />
</Variant>
</Component>
<Component name = 'Paperclip'>
<Variant>
<PaperClipOutlined />
</Variant>
</Component>
<Component name = 'Phone'>
<Variant>
<PhoneOutlined />
</Variant>
</Component>
<Component name = 'Mail'>
<Variant>
<MailOutlined />
</Variant>
</Component>
<Component name = 'Home'>
<Variant>
<HomeOutlined />
</Variant>
</Component>
<Component name = 'Contacts'>
<Variant>
<ContactsOutlined />
</Variant>
</Component>
<Component name = 'User'>
<Variant>
<UserOutlined />
</Variant>
<Variant name = 'Add'>
<UserAddOutlined />
</Variant>
<Variant name = 'Remove'>
<UserDeleteOutlined />
</Variant>
</Component>
<Component name = 'Team'>
<Variant>
<TeamOutlined />
</Variant>
</Component>
</Category>
</Palette>