diff --git a/src/App.less b/src/App.less index 11813ab0b..5356ab6e5 100644 --- a/src/App.less +++ b/src/App.less @@ -381,26 +381,6 @@ input::placeholder { } } -// antd表格排序icon特殊处理 -.ant-table-column-has-sorters .ant-table-column-sorter-inner { - .ant-table-column-sorter-up, - .ant-table-column-sorter-down { - transition: all 0.2s; - } - - &:has(.ant-table-column-sorter-up.active) { - .ant-table-column-sorter-down { - opacity: 0; - } - } - - &:has(.ant-table-column-sorter-down.active) { - .ant-table-column-sorter-up { - opacity: 0; - } - } -} - .theme-light.theme-light-gold { .login-main.integration { .ant-btn-primary { diff --git a/src/components/Contacts/index.tsx b/src/components/Contacts/index.tsx index 09613d2e7..76367c697 100644 --- a/src/components/Contacts/index.tsx +++ b/src/components/Contacts/index.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; -import { Drawer, Table, Switch, Space, Button, Modal, message } from 'antd'; +import { Drawer, Table, Switch, Space, Button, Modal, Dropdown, Menu, message } from 'antd'; +import { TableActionButton, TableActionTrigger } from '@/components/TableActionDropdown'; import { useTranslation } from 'react-i18next'; import _ from 'lodash'; import { CloseOutlined } from '@ant-design/icons'; @@ -97,59 +98,72 @@ export default function ContactDrawer(props: Props) { }, { title: t('common:table.operations'), - width: 100, + width: 64, + fixed: 'right' as const, render: (reocrd) => { return ( - - { - EditModal({ - initialValues: reocrd, - onOk: (values) => { - const oldIndex = _.findIndex(data, (item) => item.ident === reocrd.ident); - const newData = _.map(data, (item, idx) => { - if (idx === oldIndex) { - return values; - } - return item; - }); - putNotifyContacts(newData).then(() => { - setData(newData); - message.success(t('common:success.edit')); - }); - }, - }); - }} - > - {t('common:btn.edit')} - - {!reocrd.built_in && ( - - )} - + onCancel() {}, + }); + }} + > + {t('common:btn.delete')} + + + + )} + + } + > + + ); }, }, diff --git a/src/components/TableActionDropdown/index.tsx b/src/components/TableActionDropdown/index.tsx new file mode 100644 index 000000000..3fb7ed691 --- /dev/null +++ b/src/components/TableActionDropdown/index.tsx @@ -0,0 +1,96 @@ +import React from 'react'; +import { Button, Tooltip } from 'antd'; +import type { ButtonProps } from 'antd/lib/button'; +import { + CheckCircle, + Copy, + ExternalLink, + Eye, + Link as LinkIcon, + MoreVertical, + Network, + Pencil, + Play, + Search, + Settings, + ShieldCheck, + Sparkles, + Trash2, +} from 'lucide-react'; +import classNames from 'classnames'; +import { Link, LinkProps } from 'react-router-dom'; + +import './style.less'; + +const tableActionIconMap = { + default: CheckCircle, + edit: Pencil, + view: Eye, + settings: Settings, + access: Network, + permission: ShieldCheck, + copy: Copy, + delete: Trash2, + run: Play, + search: Search, + open: ExternalLink, + link: LinkIcon, + ai: Sparkles, +}; + +export type TableActionIconName = keyof typeof tableActionIconMap; + +export function TableActionIcon({ name }: { name: TableActionIconName }) { + const Icon = tableActionIconMap[name]; + return ; +} + +interface TableActionButtonProps extends Omit { + actionIcon?: TableActionIconName; + icon?: React.ReactNode; +} + +export function TableActionButton({ actionIcon, icon, className, type = 'link', ...rest }: TableActionButtonProps) { + return ( + + )} + {(IS_PLUS || !_.includes(['firemap', 'northstar'], record?.rule_prod)) && } - + } > - - {record.cate === 'prometheus' && anomalyEnabled === true && ( -
- {t('brain_result_btn')} -
- )} - + onCancel() {}, + }); + }} + > + {t('common:btn.delete')} + + + + } + > + + ); }, }, diff --git a/src/pages/alertRules/List/constants.ts b/src/pages/alertRules/List/constants.ts index dac1b27d8..24196474d 100644 --- a/src/pages/alertRules/List/constants.ts +++ b/src/pages/alertRules/List/constants.ts @@ -24,16 +24,6 @@ export const defaultColumnsConfigs = [ i18nKey: 'table.status', visible: true, }, - { - name: 'cate', - i18nKey: 'table.cate', - visible: true, - }, - { - name: 'datasource_ids', - i18nKey: 'table.datasource_ids', - visible: false, - }, { name: 'name', i18nKey: 'table.name', @@ -44,6 +34,11 @@ export const defaultColumnsConfigs = [ i18nKey: 'table.severity', visible: false, }, + { + name: 'datasource_ids', + i18nKey: 'table.datasource_ids', + visible: false, + }, { name: 'append_tags', i18nKey: 'table.append_tags', @@ -69,11 +64,6 @@ export const defaultColumnsConfigs = [ i18nKey: 'common:table.username', visible: true, }, - { - name: 'update_by_nickname', - i18nKey: 'common:table.nickname', - visible: true, - }, { name: 'disabled', i18nKey: 'table.disabled', diff --git a/src/pages/alertRules/List/index.tsx b/src/pages/alertRules/List/index.tsx index 245500e5f..45a7c4ef9 100644 --- a/src/pages/alertRules/List/index.tsx +++ b/src/pages/alertRules/List/index.tsx @@ -95,7 +95,7 @@ export default function List(props: ListProps) { }, [gids, refreshFlag]); return ( -
+
{ prod: string; severities: number[]; update_at: number; - update_by: number; + update_by: string; + update_by_nickname?: string; cur_event_count: number; } diff --git a/src/pages/builtInComponents/AlertRules/index.tsx b/src/pages/builtInComponents/AlertRules/index.tsx index 35de800e2..fa8f7353f 100644 --- a/src/pages/builtInComponents/AlertRules/index.tsx +++ b/src/pages/builtInComponents/AlertRules/index.tsx @@ -1,7 +1,7 @@ import React, { useState, useRef, useContext, useEffect } from 'react'; import _ from 'lodash'; import { Table, Space, Button, Input, Select, Dropdown, Menu, Modal, Tag, message } from 'antd'; -import { SearchOutlined, MoreOutlined } from '@ant-design/icons'; +import { SearchOutlined } from '@ant-design/icons'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import { useDebounceEffect } from 'ahooks'; @@ -10,6 +10,8 @@ import Export from '@/pages/dashboard/List/Export'; import AuthorizationWrapper from '@/components/AuthorizationWrapper'; import { CommonStateContext } from '@/App'; import { HelpLink } from '@/components/pageLayout'; +import { TableActionButton, TableActionTrigger } from '@/components/TableActionDropdown'; +import Tags from '@/components/TableTags/Tags'; import { RuleType } from './types'; import Import from './Import'; import { getPayloads, deletePayloads, getCates } from '../services'; @@ -205,29 +207,17 @@ export default function index(props: Props) { render: (val) => { const tags = _.compact(_.split(val, ' ')); return ( - - {_.map(tags, (tag, idx) => { - return ( - { - const queryItem = _.compact(_.split(filter.query, ' ')); - if (_.includes(queryItem, tag)) return; - setFilter((filter) => { - return { - ...filter, - query: filter.query ? filter.query + ' ' + tag : tag, - }; - }); - }} - > - {tag} - - ); - })} - + { + const queryItem = _.compact(_.split(filter.query, ' ')); + if (_.includes(queryItem, tag)) return; + setFilter((filter) => ({ + ...filter, + query: filter.query ? filter.query + ' ' + tag : tag, + })); + }} + /> ); }, }, @@ -245,14 +235,19 @@ export default function index(props: Props) { }, { title: t('common:table.operations'), - width: 100, + width: 64, + fixed: 'right' as const, render: (record) => { return ( - { Import({ data: formatBeautifyJson(record.content), @@ -264,10 +259,11 @@ export default function index(props: Props) { }} > {t('import_to_buisGroup')} - + - { Export({ data: formatBeautifyJson(record.content, 'array'), @@ -275,12 +271,13 @@ export default function index(props: Props) { }} > {t('common:btn.export')} - + {record.updated_by !== 'system' && ( - { PayloadFormModal({ darkMode, @@ -297,38 +294,40 @@ export default function index(props: Props) { }} > {t('common:btn.edit')} - + )} {record.updated_by !== 'system' && ( - - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + fetchCates(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + fetchCates(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deletePayloads([record.id]).then(() => { + fetchData(); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - + <> + + + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deleteMetrics([record.id]).then(() => { + message.success(t('common:success.delete')); + setRefreshFlag(_.uniqueId('refreshFlag_')); + }); + }, + }); + }} + > + {t('common:btn.delete')} + + + )} } > - - )} - + onCancel() {}, + }); + }} + > + {t('common:btn.delete')} + + + + )} + + } + > + + ); }, }, diff --git a/src/pages/dashboard/List/constants.ts b/src/pages/dashboard/List/constants.ts index d4d88ba61..00b7a4e01 100644 --- a/src/pages/dashboard/List/constants.ts +++ b/src/pages/dashboard/List/constants.ts @@ -41,11 +41,6 @@ export const defaultColumnsConfigs = [ i18nKey: 'common:table.username', visible: false, }, - { - name: 'update_by_nickname', - i18nKey: 'common:table.nickname', - visible: false, - }, { name: 'public', i18nKey: 'public.name', diff --git a/src/pages/dashboard/List/index.tsx b/src/pages/dashboard/List/index.tsx index a6f47a8cf..4c958f1d5 100644 --- a/src/pages/dashboard/List/index.tsx +++ b/src/pages/dashboard/List/index.tsx @@ -19,8 +19,8 @@ */ import React, { useState, useEffect, useContext } from 'react'; import { Link } from 'react-router-dom'; -import { Table, Tag, Modal, Space, Button, Dropdown, Menu, message, Tooltip } from 'antd'; -import { FundViewOutlined, EditOutlined, ShareAltOutlined, MoreOutlined } from '@ant-design/icons'; +import { Table, Modal, Space, Dropdown, Menu, message, Tooltip } from 'antd'; +import { FundViewOutlined, EditOutlined, ShareAltOutlined } from '@ant-design/icons'; import moment from 'moment'; import _ from 'lodash'; import { useTranslation } from 'react-i18next'; @@ -33,6 +33,8 @@ import { getBusiGroupsDashboards, getBusiGroupsPublicDashboards, cloneDashboard, import PageLayout from '@/components/pageLayout'; import { CommonStateContext } from '@/App'; import BusinessGroupSideBarWithAll, { getDefaultGidsInDashboard } from '@/components/BusinessGroup/BusinessGroupSideBarWithAll'; +import { TableActionButton, TableActionTrigger } from '@/components/TableActionDropdown'; +import Tags from '@/components/TableTags/Tags'; import usePagination from '@/components/usePagination'; import { getDefaultColumnsConfigs, ajustColumns } from '@/components/OrganizeColumns'; import { getBusiGroups } from '@/components/BusinessGroup'; @@ -143,26 +145,15 @@ export default function index() { className='mt-2' dataSource={data} columns={ajustColumns( - _.concat( - businessGroup.isLeaf && gids !== '-1' && gids !== '-2' - ? [] - : ([ - { - title: t('common:business_group'), - dataIndex: 'group_id', - width: 100, - render: (id) => { - return _.find(busiGroups, { id })?.name; - }, - }, - ] as any), - [ - { - title: t('name'), - dataIndex: 'name', - className: 'name-column', - render: (text: string, record: DashboardType) => { - return ( + _.concat([ + { + title: t('name'), + dataIndex: 'name', + className: 'name-column', + render: (text: string, record: DashboardType) => { + const groupName = _.find(busiGroups, { id: record.group_id })?.name; + return ( +
{text} - ); - }, + {groupName && {groupName}} +
+ ); }, - { - title: t('tags'), - dataIndex: 'tags', - className: 'tags-column', - render: (text: string) => ( - <> - {_.map(_.split(text, ' '), (tag, index) => { - return tag ? ( - { - const queryItem = searchVal.length > 0 ? searchVal.split(' ') : []; - if (queryItem.includes(tag)) return; - setsearchVal((searchVal) => { - if (searchVal) { - sessionStorage.setItem(SEARCH_SESSION_STORAGE_KEY, searchVal + ' ' + tag); - return searchVal + ' ' + tag; - } - sessionStorage.setItem(SEARCH_SESSION_STORAGE_KEY, tag); - return tag; - }); - }} - > - {tag} - - ) : null; - })} - - ), - }, - { - title: t('common:table.note'), - dataIndex: 'note', - className: 'note-column', - }, - { - title: t('common:table.update_at'), - width: 150, - dataIndex: 'update_at', - render: (text: number) => moment.unix(text).format('YYYY-MM-DD HH:mm:ss'), - }, - { - title: t('common:table.username'), - dataIndex: 'update_by', - width: 100, - }, - { - title: t('common:table.nickname'), - dataIndex: 'update_by_nickname', - width: 100, + }, + { + title: t('tags'), + dataIndex: 'tags', + className: 'tags-column', + render: (text: string) => ( + { + const queryItem = searchVal.length > 0 ? searchVal.split(' ') : []; + if (queryItem.includes(tag)) return; + setsearchVal((searchVal) => { + if (searchVal) { + sessionStorage.setItem(SEARCH_SESSION_STORAGE_KEY, searchVal + ' ' + tag); + return searchVal + ' ' + tag; + } + sessionStorage.setItem(SEARCH_SESSION_STORAGE_KEY, tag); + return tag; + }); + }} + /> + ), + }, + { + title: t('common:table.note'), + dataIndex: 'note', + className: 'note-column', + }, + { + title: t('common:table.update_at'), + width: 100, + dataIndex: 'update_at', + render: (text: number) => { + return ( +
+
{moment.unix(text).format('YYYY-MM-DD')}
+
{moment.unix(text).format('HH:mm:ss')}
+
+ ); }, - { - title: t('public.name'), - width: 150, - dataIndex: 'public', - className: 'published-cell', - render: (val: number, record: DashboardType) => { - let content: React.ReactNode = null; - if (val === 1 && record.public_cate !== undefined) { - if (record.public_cate === 0) { - content = ( - -
- - {t('public.theme_link.dark')} - -
-
- - {t('public.theme_link.light')} - -
- - } + }, + { + title: t('common:table.username'), + dataIndex: 'update_by', + render: (val: string, record: any) => ( +
+
{val}
+ {record.update_by_nickname &&
{record.update_by_nickname}
} +
+ ), + }, + { + title: t('public.name'), + width: 150, + dataIndex: 'public', + className: 'published-cell', + render: (val: number, record: DashboardType) => { + let content: React.ReactNode = null; + if (val === 1 && record.public_cate !== undefined) { + if (record.public_cate === 0) { + content = ( + +
+ + {t('public.theme_link.dark')} + +
+
+ + {t('public.theme_link.light')} + +
+ + } + > + - - {t(`public.cate.${record.public_cate}`)} - -
- ); - } else { - content = t(`public.cate.${record.public_cate}`); - } + {t(`public.cate.${record.public_cate}`)} + +
+ ); } else { - content = t('public.unpublic'); + content = t(`public.cate.${record.public_cate}`); } + } else { + content = t('public.unpublic'); + } - return ( - - {content} - {gids !== '-1' && ( - { - PublicForm({ - busiGroups, - boardId: record.id, - initialValues: { - public: val, - public_cate: record.public_cate, - bgids: record.bgids, - }, - onOk: () => { - setRefreshKey(_.uniqueId('refreshKey_')); - }, - }); - }} - /> - )} - - ); - }, + return ( + + {content} + {gids !== '-1' && ( + { + PublicForm({ + busiGroups, + boardId: record.id, + initialValues: { + public: val, + public_cate: record.public_cate, + bgids: record.bgids, + }, + onOk: () => { + setRefreshKey(_.uniqueId('refreshKey_')); + }, + }); + }} + /> + )} + + ); }, - { - title: t('common:table.operations'), - render: (text: string, record: DashboardType) => { - return ( - - {gids !== '-1' && ( - - - - )} - {gids && gids !== '-1' && ( - - - - )} + }, + { + title: t('common:table.operations'), + width: 64, + fixed: 'right' as const, + render: (text: string, record: DashboardType) => { + return ( + + {gids !== '-1' && ( - + {t('common:btn.clone')} + - {gids !== '-1' && ( + )} + + { + const exportData = await getDashboard(record.id); + Export({ + data: exportDataStringify(exportData), + }); + }} + > + {t('common:btn.export')} + + + {gids !== '-1' && ( + <> + - + - )} - - } - > - - )} - - {record.plugin_type === 'cloudwatch' && ( - + }} + > + {record.status === 'enabled' ? t('disable') : t('enable')} + + + {record.plugin_type === 'cloudwatch' && ( + + + + )} + {record.status === 'disabled' && ( + <> + - + { + Modal.confirm({ + title: t('common:confirm.delete'), + onOk() { + deleteDataSourceById(record.id).then(() => { + message.success(t('common:success.delete')); + setRefresh((oldVal) => !oldVal); + }); + }, + }); + }} + > + {t('common:btn.delete')} + - - } - > - + )} + - + } > - + )} + - + } > -