antd/lib/table#ColumnType TypeScript Examples
The following examples show how to use
antd/lib/table#ColumnType.
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: Table.tsx From posthog-foss with MIT License | 6 votes |
export function createdAtColumn<T extends Record<string, any> = Record<string, any>>(): ColumnType<T> {
return {
title: normalizeColumnTitle('Created'),
align: 'right',
render: function RenderCreatedAt(_, item): JSX.Element | undefined | '' {
return (
item.created_at && (
<div style={{ whiteSpace: 'nowrap' }}>
<TZLabel time={item.created_at} />
</div>
)
)
},
sorter: (a, b) => (new Date(a.created_at) > new Date(b.created_at) ? 1 : -1),
}
}
Example #2
Source File: Table.tsx From posthog-foss with MIT License | 5 votes |
export function createdByColumn<T extends Record<string, any> = Record<string, any>>(items: T[]): ColumnType<T> {
const { user } = useValues(userLogic)
return {
title: normalizeColumnTitle('Created by'),
render: function Render(_: any, item: any) {
return (
<Row align="middle" wrap={false}>
{item.created_by && (
<ProfilePicture name={item.created_by.first_name} email={item.created_by.email} size="md" />
)}
<div style={{ maxWidth: 250, width: 'auto', verticalAlign: 'middle', marginLeft: 8 }}>
{item.created_by ? item.created_by.first_name || item.created_by.email : '-'}
</div>
</Row>
)
},
filters: uniqueBy(
items.map((item: T) => {
if (!item.created_by) {
return {
text: '(none)',
value: null,
}
}
return {
text: item.created_by?.first_name || item.created_by?.email,
value: item.created_by?.uuid,
}
}),
(item) => item?.value
).sort((a, b) => {
// Current user first
if (a.value === user?.uuid) {
return -10
}
if (b.value === user?.uuid) {
return 10
}
return (a.text + '').localeCompare(b.text + '')
}),
onFilter: (value, item) => (value === null && item.created_by === null) || item.created_by?.uuid === value,
sorter: (a, b) =>
(a.created_by?.first_name || a.created_by?.email || '').localeCompare(
b.created_by?.first_name || b.created_by?.email || ''
),
}
}
Example #3
Source File: Invite.tsx From tailchat with GNU General Public License v3.0 | 4 votes |
GroupInvite: React.FC<{
groupId: string;
}> = React.memo((props) => {
const groupId = props.groupId;
const { loading, value, refresh } = useAsyncRefresh(async () => {
const list = await getAllGroupInviteCode(groupId);
return list.reverse(); // 倒序返回
}, [groupId]);
const handleCreateInvite = useCallback(() => {
openModal(
<CreateGroupInvite
groupId={groupId}
onInviteCreated={() => {
refresh();
}}
/>
);
}, [groupId, refresh]);
const handleCopyInviteCode = useCallback((inviteCode: string) => {
copy(generateInviteCodeUrl(inviteCode));
showToasts(t('邀请链接已复制到剪切板'), 'success');
}, []);
const handleDeleteInvite = useCallback(
async (inviteId: string) => {
if (await openReconfirmModalP()) {
await deleteGroupInvite(groupId, inviteId);
await refresh();
}
},
[groupId, refresh]
);
const columns: ColumnType<GroupInviteType>[] = useMemo(
() => [
{
title: t('邀请码'),
dataIndex: 'code',
},
{
title: t('创建时间'),
dataIndex: 'createdAt',
render: (date) => (
<Tooltip title={formatFullTime(date)}>
{datetimeFromNow(date)}
</Tooltip>
),
},
{
title: t('过期时间'),
dataIndex: 'expiredAt',
render: (date) => {
if (!date) {
return t('永不过期');
}
if (new Date(date).valueOf() < Date.now()) {
return t('已过期');
}
return (
<Tooltip title={formatFullTime(date)}>
{datetimeFromNow(date)}
</Tooltip>
);
},
},
{
title: t('创建者'),
dataIndex: 'creator',
render: (userId) => <UserName userId={userId} />,
},
{
title: t('操作'),
dataIndex: '_id',
render: (id: string, record) => {
return (
<Space>
<IconBtn
title={t('复制邀请链接')}
shape="square"
icon="mdi:content-copy"
onClick={() => handleCopyInviteCode(record.code)}
/>
<IconBtn
title={t('删除')}
shape="square"
icon="mdi:delete-outline"
danger={true}
onClick={() => handleDeleteInvite(id)}
/>
</Space>
);
},
},
],
[handleCopyInviteCode, handleDeleteInvite]
);
return (
<LoadingOnFirst spinning={loading}>
<div className="text-right mb-2">
<Button type="primary" onClick={handleCreateInvite}>
{t('创建邀请码')}
</Button>
</div>
<Table
columns={columns}
dataSource={value}
pagination={{
hideOnSinglePage: true,
}}
/>
</LoadingOnFirst>
);
})
Example #4
Source File: PageTable.tsx From fe-v5 with Apache License 2.0 | 4 votes |
PageTable: React.FC<Props> = ({ bgid }) => {
const [severity, setSeverity] = useState<number>();
const [clusters, setClusters] = useState<string[]>([]);
const { t, i18n } = useTranslation();
const history = useHistory();
const [modalType, setModalType] = useState<ModalStatus>(ModalStatus.None);
const [selectRowKeys, setSelectRowKeys] = useState<React.Key[]>([]);
const [selectedRows, setSelectedRows] = useState<strategyItem[]>([]);
const [exportData, setExportData] = useState<string>('');
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
const [query, setQuery] = useState<string>('');
const [isModalVisible, setisModalVisible] = useState<boolean>(false);
const [currentStrategyDataAll, setCurrentStrategyDataAll] = useState([]);
const [currentStrategyData, setCurrentStrategyData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
if (bgid) {
getAlertRules();
}
}, [bgid, severity]);
useEffect(() => {
filterData();
}, [query, clusters, currentStrategyDataAll]);
const getAlertRules = async () => {
if (!bgid) {
return;
}
setLoading(true);
const { success, dat } = await getStrategyGroupSubList({ id: bgid });
if (success) {
setCurrentStrategyDataAll(dat.filter((item) => !severity || item.severity === severity) || []);
setLoading(false);
}
};
const filterData = () => {
const data = JSON.parse(JSON.stringify(currentStrategyDataAll));
const res = data.filter((item) => {
const lowerCaseQuery = query.toLowerCase();
return (
(item.name.toLowerCase().indexOf(lowerCaseQuery) > -1 || item.append_tags.join(' ').toLowerCase().indexOf(lowerCaseQuery) > -1) &&
((clusters && clusters?.indexOf(item.cluster) > -1) || clusters?.length === 0)
);
});
setCurrentStrategyData(res || []);
};
const goToAddWarningStrategy = () => {
curBusiItem?.id && history.push(`/alert-rules/add/${curBusiItem.id}`);
};
const handleClickEdit = (id, isClone = false) => {
curBusiItem?.id && history.push(`/alert-rules/edit/${id}${isClone ? '?mode=clone' : ''}`);
};
const refreshList = () => {
getAlertRules();
};
const columns: ColumnType<strategyItem>[] = [
{
title: t('集群'),
dataIndex: 'cluster',
render: (data) => {
return <div>{data}</div>;
},
},
{
title: t('级别'),
dataIndex: 'severity',
render: (data) => {
return <Tag color={priorityColor[data - 1]}>S{data}</Tag>;
},
},
{
title: t('名称'),
dataIndex: 'name',
render: (data, record) => {
return (
<div
className='table-active-text'
onClick={() => {
handleClickEdit(record.id);
}}
>
{data}
</div>
);
},
},
{
title: t('告警接收者'),
dataIndex: 'notify_groups_obj',
width: 100,
render: (data, record) => {
return (
(data.length &&
data.map(
(
user: {
nickname: string;
username: string;
} & { name: string },
index: number,
) => {
return <ColorTag text={user.nickname || user.username || user.name} key={index}></ColorTag>;
},
)) || <div></div>
);
},
},
{
title: t('附加标签'),
dataIndex: 'append_tags',
render: (data) => {
const array = data || [];
return (
(array.length &&
array.map((tag: string, index: number) => {
return <ColorTag text={tag} key={index}></ColorTag>;
})) || <div></div>
);
},
},
{
title: t('更新时间'),
dataIndex: 'update_at',
width: 120,
render: (text: string) => dayjs(Number(text) * 1000).format('YYYY-MM-DD HH:mm:ss'),
},
{
title: t('启用'),
dataIndex: 'disabled',
render: (disabled, record) => (
<Switch
checked={disabled === strategyStatus.Enable}
size='small'
onChange={() => {
const { id, disabled } = record;
updateAlertRules(
{
ids: [id],
fields: {
disabled: !disabled ? 1 : 0,
},
},
curBusiItem.id,
).then(() => {
refreshList();
});
}}
/>
),
},
{
title: t('操作'),
dataIndex: 'operator',
width: 100,
render: (data, record) => {
return (
<div className='table-operator-area'>
<div
className='table-operator-area-normal'
onClick={() => {
handleClickEdit(record.id, true);
}}
>
{t('克隆')}
</div>
<div
className='table-operator-area-warning'
onClick={() => {
confirm({
title: t('是否删除该告警规则?'),
onOk: () => {
deleteStrategy([record.id], curBusiItem.id).then(() => {
message.success(t('删除成功'));
refreshList();
});
},
onCancel() {},
});
}}
>
{t('删除')}
</div>
</div>
);
},
},
];
const toOneArr = (arr, res, name) => {
arr.forEach((ele) => {
if (Array.isArray(ele)) {
toOneArr(ele, res, name);
} else {
res.push(ele[name]);
}
});
};
const openModel = (title, item) => {
if (selectRowKeys.length == 0) {
message.warning(t('请先选择策略'));
return;
}
setisModalVisible(true);
};
const menu = useMemo(() => {
return (
<ul className='ant-dropdown-menu'>
<li className='ant-dropdown-menu-item' onClick={() => setModalType(ModalStatus.BuiltIn)}>
<span>{t('导入告警规则')}</span>
</li>
<li
className='ant-dropdown-menu-item'
onClick={() => {
if (selectedRows.length) {
const exportData = selectedRows.map((item) => {
return { ...item, ...exportIgnoreAttrsObj };
});
setExportData(JSON.stringify(exportData, null, 2));
setModalType(ModalStatus.Export);
} else {
message.warning(t('未选择任何规则'));
}
}}
>
<span>{t('导出告警规则')}</span>
</li>
<li
className='ant-dropdown-menu-item'
onClick={() => {
if (selectRowKeys.length) {
confirm({
title: t('是否批量删除告警规则?'),
onOk: () => {
deleteStrategy(selectRowKeys as number[], curBusiItem?.id).then(() => {
message.success(t('删除成功'));
refreshList();
});
},
onCancel() {},
});
} else {
message.warning(t('未选择任何规则'));
}
}}
>
<span>{t('批量删除规则')}</span>
</li>
<li
className='ant-dropdown-menu-item'
onClick={() => {
openModel(t('批量更新规则'), 1);
}}
>
<span>{t('批量更新规则')}</span>
</li>
</ul>
);
}, [selectRowKeys, t]);
const handleImportStrategy = async (data) => {
const { dat } = await addOrEditStrategy(data, curBusiItem.id, 'Post');
return dat || {};
};
const editModalFinish = async (isOk, fieldsData?) => {
if (isOk) {
const res = await updateAlertRules(
{
ids: selectRowKeys,
fields: fieldsData,
},
curBusiItem.id,
);
if (!res.err) {
message.success('修改成功!');
refreshList();
setisModalVisible(false);
} else {
message.error(res.err);
}
} else {
setisModalVisible(false);
}
};
return (
<div className='strategy-table-content'>
<div className='strategy-table-search table-handle'>
<div className='strategy-table-search-left'>
<RefreshIcon
className='strategy-table-search-left-refresh'
onClick={() => {
refreshList();
}}
/>
<ColumnSelect noLeftPadding noRightPadding={false} onSeverityChange={(e) => setSeverity(e)} onClusterChange={(e) => setClusters(e)} />
<SearchInput className={'searchInput'} placeholder={t('搜索名称或标签')} onSearch={setQuery} allowClear />
</div>
<div className='strategy-table-search-right'>
<Button type='primary' onClick={goToAddWarningStrategy} className='strategy-table-search-right-create' ghost>
{t('新增告警规则')}
</Button>
<div className={'table-more-options'}>
<Dropdown overlay={menu} trigger={['click']}>
<Button onClick={(e) => e.stopPropagation()}>
{t('更多操作')}
<DownOutlined
style={{
marginLeft: 2,
}}
/>
</Button>
</Dropdown>
</div>
</div>
</div>
<Table
rowKey='id'
// sticky
pagination={{
total: currentStrategyData.length,
showQuickJumper: true,
showSizeChanger: true,
showTotal: (total) => {
return `共 ${total} 条数据`;
},
pageSizeOptions: pageSizeOptionsDefault,
defaultPageSize: 30,
}}
loading={loading}
dataSource={currentStrategyData}
rowSelection={{
selectedRowKeys: selectedRows.map((item) => item.id),
onChange: (selectedRowKeys: React.Key[], selectedRows: strategyItem[]) => {
setSelectRowKeys(selectedRowKeys);
setSelectedRows(selectedRows);
},
}}
columns={columns}
/>
<ImportAndDownloadModal
bgid={bgid}
status={modalType}
fetchBuiltinFunc={getBuiltinAlerts}
submitBuiltinFunc={createBuiltinAlerts}
onClose={() => {
setModalType(ModalStatus.None);
}}
onSuccess={() => {
getAlertRules();
}}
onSubmit={handleImportStrategy}
label='告警规则'
title={
ModalStatus.Export === modalType ? (
'告警规则'
) : (
<Tabs defaultActiveKey={ModalStatus.BuiltIn} onChange={(e: ModalStatus) => setModalType(e)} className='custom-import-alert-title'>
<TabPane tab=' 导入内置告警规则' key={ModalStatus.BuiltIn}></TabPane>
<TabPane tab='导入告警规则JSON' key={ModalStatus.Import}></TabPane>
</Tabs>
)
}
exportData={exportData}
/>
{isModalVisible && <EditModal isModalVisible={isModalVisible} editModalFinish={editModalFinish} />}
</div>
);
}
Example #5
Source File: ruleModal.tsx From fe-v5 with Apache License 2.0 | 4 votes |
ruleModal: React.FC<props> = ({ visible, ruleModalClose, subscribe }) => {
const { t } = useTranslation();
const { curBusiItem } = useSelector<RootState, CommonStoreState>((state) => state.common);
// const { busiGroups } = useSelector<RootState, CommonStoreState>((state) => state.common);
const [busiGroups, setBusiGroups] = useState<{ id: number; name: string }[]>([]);
const [currentStrategyDataAll, setCurrentStrategyDataAll] = useState([]);
const [currentStrategyData, setCurrentStrategyData] = useState([]);
const [bgid, setBgid] = useState(curBusiItem.id);
const [query, setQuery] = useState<string>('');
useEffect(() => {
setBgid(curBusiItem.id);
}, [curBusiItem]);
useEffect(() => {
getAlertRules();
}, [bgid]);
useEffect(() => {
getTeamList('');
}, []);
useEffect(() => {
filterData();
}, [query, currentStrategyDataAll]);
// 获取业务组列表
const getTeamList = (query: string) => {
console.log(111);
let params = {
all: 1,
query,
limit: 200,
};
getBusinessTeamList(params).then((data) => {
setBusiGroups(data.dat || []);
});
};
const debounceFetcher = useCallback(debounce(getTeamList, 400), []);
const getAlertRules = async () => {
const { success, dat } = await getStrategyGroupSubList({ id: bgid });
if (success) {
setCurrentStrategyDataAll(dat || []);
}
};
const bgidChange = (val) => {
setBgid(val);
};
const filterData = () => {
const data = JSON.parse(JSON.stringify(currentStrategyDataAll));
const res = data.filter((item) => {
return item.name.indexOf(query) > -1 || item.append_tags.join(' ').indexOf(query) > -1;
});
setCurrentStrategyData(res || []);
};
const onSearchQuery = (e) => {
let val = e.target.value;
setQuery(val);
};
const columns: ColumnType<strategyItem>[] = [
{
title: t('集群'),
dataIndex: 'cluster',
render: (data) => {
return <div>{data}</div>;
},
},
{
title: t('级别'),
dataIndex: 'severity',
render: (data) => {
return <Tag color={priorityColor[data - 1]}>S{data}</Tag>;
},
},
{
title: t('名称'),
dataIndex: 'name',
render: (data, record) => {
return (
<div
className='table-active-text'
onClick={() => {
// handleClickEdit(record.id);
}}
>
{data}
</div>
);
},
},
{
title: t('告警接收者'),
dataIndex: 'notify_groups_obj',
render: (data, record) => {
return (
(data.length &&
data.map(
(
user: {
nickname: string;
username: string;
} & { name: string },
index: number,
) => {
return <ColorTag text={user.nickname || user.username || user.name} key={index}></ColorTag>;
},
)) || <div></div>
);
},
},
{
title: t('附加标签'),
dataIndex: 'append_tags',
render: (data) => {
const array = data || [];
return (
(array.length &&
array.map((tag: string, index: number) => {
return <ColorTag text={tag} key={index}></ColorTag>;
})) || <div></div>
);
},
},
{
title: t('更新时间'),
dataIndex: 'update_at',
render: (text: string) => dayjs(Number(text) * 1000).format('YYYY-MM-DD HH:mm:ss'),
},
{
title: t('启用'),
dataIndex: 'disabled',
render: (disabled, record) => (
<Switch
checked={disabled === strategyStatus.Enable}
disabled
size='small'
onChange={() => {
const { id, disabled } = record;
// updateAlertRules({
// ids: [id],
// fields: {
// disabled: !disabled ? 1 : 0
// }
// }, curBusiItem.id
// ).then(() => {
// refreshList();
// });
}}
/>
),
},
{
title: t('操作'),
dataIndex: 'operator',
fixed: 'right',
width: 100,
render: (data, record) => {
return (
<div className='table-operator-area'>
<div
className='table-operator-area-normal'
onClick={() => {
handleSubscribe(record);
}}
>
{t('订阅')}
</div>
</div>
);
},
},
];
const handleSubscribe = (record) => {
subscribe(record);
};
const modalClose = () => {
ruleModalClose();
};
return (
<>
<Modal
title={t('订阅告警规则')}
footer=''
forceRender
visible={visible}
onCancel={() => {
modalClose();
}}
width={'80%'}
>
<div>
<Select
style={{ width: '280px' }}
value={bgid}
onChange={bgidChange}
showSearch
optionFilterProp='children'
filterOption={false}
onSearch={(e) => debounceFetcher(e)}
onBlur={() => getTeamList('')}
>
{busiGroups.map((item) => (
<Option value={item.id} key={item.id}>
{item.name}
</Option>
))}
</Select>
<Input style={{ marginLeft: 10, width: '280px' }} onPressEnter={onSearchQuery} prefix={<SearchOutlined />} placeholder={t('规则名称、附加标签')} />
</div>
<div className='rule_modal_table'>
<Table
rowKey='id'
pagination={{
total: currentStrategyData.length,
showQuickJumper: true,
showSizeChanger: true,
showTotal: (total) => {
return `共 ${total} 条数据`;
},
pageSizeOptions: pageSizeOptionsDefault,
defaultPageSize: 30,
}}
dataSource={currentStrategyData}
columns={columns}
/>
</div>
</Modal>
</>
);
}