Compare commits

...

1 Commits

Author SHA1 Message Date
Yunus A M
69e311e612 feat: add support for bulk actions on alerts 2024-03-18 17:54:00 +05:30
5 changed files with 135 additions and 16 deletions

View File

@@ -1,8 +1,21 @@
.DynamicColumnTable {
.dynamicColumnTable {
display: flex;
flex-direction: column;
width: 100%;
.dynamicColumeTableHeader {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 1rem;
.selectedRowActions {
display: flex;
align-items: center;
gap: 0.5rem;
}
}
.dynamicColumnTable-button {
align-self: flex-end;
margin: 10px 0;

View File

@@ -1,7 +1,8 @@
/* eslint-disable react/jsx-props-no-spreading */
import './DynamicColumnTable.syles.scss';
import { Button, Dropdown, MenuProps, Switch } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { Button, Dropdown, MenuProps, Popconfirm, Switch } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { SlidersHorizontal } from 'lucide-react';
import { memo, useEffect, useState } from 'react';
@@ -20,11 +21,23 @@ function DynamicColumnTable({
columns,
dynamicColumns,
onDragColumn,
multiRowActionsEnabled,
multiRowActions,
...restProps
}: DynamicColumnTableProps): JSX.Element {
const [columnsData, setColumnsData] = useState<ColumnsType | undefined>(
columns,
);
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
const onSelectChange = (newSelectedRowKeys: React.Key[]): void => {
setSelectedRowKeys(newSelectedRowKeys);
};
const rowSelection = {
selectedRowKeys,
onChange: onSelectChange,
};
useEffect(() => {
setColumnsData(columns);
@@ -81,23 +94,61 @@ function DynamicColumnTable({
type: 'checkbox',
})) || [];
const hasSelected = selectedRowKeys.length > 0;
const cancel = (
e?: React.MouseEvent<HTMLElement, MouseEvent> | undefined,
): void => {
console.log(e);
};
return (
<div className="DynamicColumnTable">
{dynamicColumns && (
<Dropdown
getPopupContainer={popupContainer}
menu={{ items }}
trigger={['click']}
>
<Button
className="dynamicColumnTable-button filter-btn"
size="middle"
icon={<SlidersHorizontal size={14} />}
/>
</Dropdown>
)}
<div className="dynamicColumnTable">
<div className="dynamicColumeTableHeader">
{multiRowActionsEnabled && hasSelected && (
<div className="selectedRowActions">
<span style={{ marginLeft: 8 }}>
Selected {selectedRowKeys.length} alerts
</span>
{multiRowActionsEnabled &&
multiRowActions &&
multiRowActions.map((action) => (
<Popconfirm
key={action.key}
title={action.title}
description={action.description}
icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
placement="topRight"
onConfirm={action.onConfirm}
onCancel={cancel}
okText="Yes"
>
<Button className="periscope-btn" size="middle" icon={action.btnIcon}>
{action.btnText}
</Button>
</Popconfirm>
))}
</div>
)}
{dynamicColumns && (
<Dropdown
getPopupContainer={popupContainer}
menu={{ items }}
trigger={['click']}
>
<Button
className="dynamicColumnTable-button filter-btn"
size="middle"
icon={<SlidersHorizontal size={14} />}
/>
</Dropdown>
)}
</div>
<ResizeTable
rowSelection={rowSelection}
columns={columnsData}
onDragColumn={onDragColumn}
{...restProps}
@@ -108,6 +159,7 @@ function DynamicColumnTable({
DynamicColumnTable.defaultProps = {
onDragColumn: undefined,
multiRowActionsEnabled: false,
};
export default memo(DynamicColumnTable);

View File

@@ -2,16 +2,29 @@
import { TableProps } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { ColumnGroupType, ColumnType } from 'antd/lib/table';
import React from 'react';
import { TableDataSource } from './contants';
export interface ResizeTableProps extends TableProps<any> {
onDragColumn?: (fromIndex: number, toIndex: number) => void;
}
export interface MultiRowActionsProps {
key: string;
title: string;
description: string;
onConfirm: VoidFunction;
btnIcon: React.ReactElement;
btnText: string;
}
export interface DynamicColumnTableProps extends TableProps<any> {
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
dynamicColumns: TableProps<any>['columns'];
onDragColumn?: (fromIndex: number, toIndex: number) => void;
multiRowActions?: MultiRowActionsProps[];
multiRowActionsEnabled?: boolean;
}
export type GetVisibleColumnsFunction = (

View File

@@ -22,6 +22,7 @@ import { useNotifications } from 'hooks/useNotifications';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history';
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
import { Megaphone, MegaphoneOff, Trash2 } from 'lucide-react';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { UseQueryResult } from 'react-query';
@@ -325,6 +326,43 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
});
}
const handleEnableAll = (): void => {
console.log('Enable all the selected alerts');
};
const handleDisableAll = (): void => {
console.log('Disable all the selected alerts');
};
const handleDeleteAll = (): void => {
console.log('Delete all the selected alerts');
};
const multiRowActions = [
{
key: 'enableSelected',
title: 'Enable all the selected alerts',
description: 'Are you sure to enable all the selected alerts?',
onConfirm: handleEnableAll,
btnIcon: <Megaphone size={14} />,
btnText: 'Enable',
},
{
key: 'disableSelected',
title: 'Disable all the selected alerts',
description: ' Are you sure to disable all the selected alerts?',
onConfirm: handleDisableAll,
btnIcon: <MegaphoneOff size={14} />,
btnText: 'Disable',
},
{
key: 'deleteSelected',
title: 'Delete all the selected alerts',
description: ' Are you sure to delete all the selected alerts?',
onConfirm: handleDeleteAll,
btnIcon: <Trash2 size={14} />,
btnText: 'Delete',
},
];
return (
<>
<SearchContainer>
@@ -354,6 +392,8 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
rowKey="id"
dataSource={data}
dynamicColumns={dynamicColumns}
multiRowActionsEnabled
multiRowActions={multiRowActions}
onChange={handleChange}
pagination={{
defaultCurrent: Number(paginationParam) || 1,

View File

@@ -382,6 +382,7 @@ func (aH *APIHandler) RegisterRoutes(router *mux.Router, am *AuthMiddleware) {
router.HandleFunc("/api/v1/rules/{id}", am.EditAccess(aH.editRule)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/rules/{id}", am.EditAccess(aH.deleteRule)).Methods(http.MethodDelete)
router.HandleFunc("/api/v1/rules/{id}", am.EditAccess(aH.patchRule)).Methods(http.MethodPatch)
router.HandleFunc("/api/v1/rules/bulk", am.EditAccess(aH.bulkActionRule)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/testRule", am.EditAccess(aH.testRule)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/dashboards", am.ViewAccess(aH.getDashboards)).Methods(http.MethodGet)