mirror of
https://github.com/apache/superset.git
synced 2024-09-18 03:29:38 -04:00
feat: filters for alerts and reports list view (#11900)
This commit is contained in:
parent
77d362d306
commit
60122a2b2d
@ -62,6 +62,10 @@ const mockalerts = [...new Array(3)].map((_, i) => ({
|
|||||||
type: 'alert',
|
type: 'alert',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const mockUser = {
|
||||||
|
userId: 1,
|
||||||
|
};
|
||||||
|
|
||||||
fetchMock.get(alertsEndpoint, {
|
fetchMock.get(alertsEndpoint, {
|
||||||
ids: [2, 0, 1],
|
ids: [2, 0, 1],
|
||||||
result: mockalerts,
|
result: mockalerts,
|
||||||
@ -74,7 +78,7 @@ fetchMock.put(alertEndpoint, { ...mockalerts[0], active: false });
|
|||||||
fetchMock.put(alertsEndpoint, { ...mockalerts[0], active: false });
|
fetchMock.put(alertsEndpoint, { ...mockalerts[0], active: false });
|
||||||
|
|
||||||
async function mountAndWait(props) {
|
async function mountAndWait(props) {
|
||||||
const mounted = mount(<AlertList {...props} />, {
|
const mounted = mount(<AlertList {...props} user={mockUser} />, {
|
||||||
context: { store },
|
context: { store },
|
||||||
});
|
});
|
||||||
await waitForComponentToPaint(mounted);
|
await waitForComponentToPaint(mounted);
|
||||||
|
@ -25,8 +25,9 @@ import Icon, { IconName } from 'src/components/Icon';
|
|||||||
import { Tooltip } from 'src/common/components/Tooltip';
|
import { Tooltip } from 'src/common/components/Tooltip';
|
||||||
import { Switch } from 'src/common/components/Switch';
|
import { Switch } from 'src/common/components/Switch';
|
||||||
import FacePile from 'src/components/FacePile';
|
import FacePile from 'src/components/FacePile';
|
||||||
import ListView from 'src/components/ListView';
|
import ListView, { Filters, FilterOperators } from 'src/components/ListView';
|
||||||
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
import SubMenu, { SubMenuProps } from 'src/components/Menu/SubMenu';
|
||||||
|
import { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
|
||||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -42,16 +43,19 @@ interface AlertListProps {
|
|||||||
addDangerToast: (msg: string) => void;
|
addDangerToast: (msg: string) => void;
|
||||||
addSuccessToast: (msg: string) => void;
|
addSuccessToast: (msg: string) => void;
|
||||||
isReportEnabled: boolean;
|
isReportEnabled: boolean;
|
||||||
|
user: {
|
||||||
|
userId: string | number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const StatusIcon = styled(Icon)<{ status: string }>`
|
const StatusIcon = styled(Icon)<{ status: string }>`
|
||||||
color: ${({ status, theme }) => {
|
color: ${({ status, theme }) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'alerting':
|
case 'Working':
|
||||||
return '#FBC700';
|
return theme.colors.alert.base;
|
||||||
case 'failed':
|
case 'Error':
|
||||||
return theme.colors.error.base;
|
return theme.colors.error.base;
|
||||||
case 'ok':
|
case 'Success':
|
||||||
return theme.colors.success.base;
|
return theme.colors.success.base;
|
||||||
default:
|
default:
|
||||||
return theme.colors.grayscale.base;
|
return theme.colors.grayscale.base;
|
||||||
@ -62,14 +66,15 @@ const StatusIcon = styled(Icon)<{ status: string }>`
|
|||||||
function AlertList({
|
function AlertList({
|
||||||
addDangerToast,
|
addDangerToast,
|
||||||
isReportEnabled = false,
|
isReportEnabled = false,
|
||||||
|
user,
|
||||||
}: AlertListProps) {
|
}: AlertListProps) {
|
||||||
const title = isReportEnabled ? t('report') : t('alert');
|
const title = isReportEnabled ? t('report') : t('alert');
|
||||||
const initalFilters = useMemo(
|
const initalFilters = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{
|
{
|
||||||
id: 'type',
|
id: 'type',
|
||||||
operator: 'eq',
|
operator: FilterOperators.equals,
|
||||||
value: isReportEnabled ? 'report' : 'alert',
|
value: isReportEnabled ? 'Report' : 'Alert',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[isReportEnabled],
|
[isReportEnabled],
|
||||||
@ -127,25 +132,25 @@ function AlertList({
|
|||||||
status: '',
|
status: '',
|
||||||
};
|
};
|
||||||
switch (lastState) {
|
switch (lastState) {
|
||||||
case 'ok':
|
case 'Success':
|
||||||
lastStateConfig.name = 'check';
|
lastStateConfig.name = 'check';
|
||||||
lastStateConfig.label = t('OK');
|
lastStateConfig.label = t('Success');
|
||||||
lastStateConfig.status = 'ok';
|
lastStateConfig.status = 'Success';
|
||||||
break;
|
break;
|
||||||
case 'alerting':
|
case 'Working':
|
||||||
lastStateConfig.name = 'exclamation';
|
lastStateConfig.name = 'exclamation';
|
||||||
lastStateConfig.label = t('Alerting');
|
lastStateConfig.label = t('Working');
|
||||||
lastStateConfig.status = 'alerting';
|
lastStateConfig.status = 'Working';
|
||||||
break;
|
break;
|
||||||
case 'failed':
|
case 'Error':
|
||||||
lastStateConfig.name = 'x-small';
|
lastStateConfig.name = 'x-small';
|
||||||
lastStateConfig.label = t('Failed');
|
lastStateConfig.label = t('Error');
|
||||||
lastStateConfig.status = 'failed';
|
lastStateConfig.status = 'Error';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lastStateConfig.name = 'exclamation';
|
lastStateConfig.name = 'exclamation';
|
||||||
lastStateConfig.label = t('Alerting');
|
lastStateConfig.label = t('Working');
|
||||||
lastStateConfig.status = 'alerting';
|
lastStateConfig.status = 'Working';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Tooltip title={lastStateConfig.label} placement="bottom">
|
<Tooltip title={lastStateConfig.label} placement="bottom">
|
||||||
@ -181,6 +186,11 @@ function AlertList({
|
|||||||
Header: t('Schedule'),
|
Header: t('Schedule'),
|
||||||
accessor: 'crontab',
|
accessor: 'crontab',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessor: 'created_by',
|
||||||
|
disableSortBy: true,
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Cell: ({
|
Cell: ({
|
||||||
row: {
|
row: {
|
||||||
@ -275,6 +285,46 @@ function AlertList({
|
|||||||
slot: canCreate ? EmptyStateButton : null,
|
slot: canCreate ? EmptyStateButton : null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filters: Filters = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: t('Created By'),
|
||||||
|
id: 'created_by',
|
||||||
|
input: 'select',
|
||||||
|
operator: FilterOperators.relationOneMany,
|
||||||
|
unfilteredLabel: 'All',
|
||||||
|
fetchSelects: createFetchRelated(
|
||||||
|
'report',
|
||||||
|
'created_by',
|
||||||
|
createErrorHandler(errMsg =>
|
||||||
|
t('An error occurred while fetching created by values: %s', errMsg),
|
||||||
|
),
|
||||||
|
user.userId,
|
||||||
|
),
|
||||||
|
paginate: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: t('Status'),
|
||||||
|
id: 'last_state',
|
||||||
|
input: 'select',
|
||||||
|
operator: FilterOperators.equals,
|
||||||
|
unfilteredLabel: 'Any',
|
||||||
|
selects: [
|
||||||
|
{ label: t('Success'), value: 'Success' },
|
||||||
|
{ label: t('Working'), value: 'Working' },
|
||||||
|
{ label: t('Error'), value: 'Error' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: t('Search'),
|
||||||
|
id: 'name',
|
||||||
|
input: 'search',
|
||||||
|
operator: FilterOperators.contains,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubMenu
|
<SubMenu
|
||||||
@ -303,6 +353,7 @@ function AlertList({
|
|||||||
data={alerts}
|
data={alerts}
|
||||||
emptyState={emptyState}
|
emptyState={emptyState}
|
||||||
fetchData={fetchData}
|
fetchData={fetchData}
|
||||||
|
filters={filters}
|
||||||
initialSort={initialSort}
|
initialSort={initialSort}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
pageSize={PAGE_SIZE}
|
pageSize={PAGE_SIZE}
|
||||||
|
@ -145,7 +145,7 @@ class ReportScheduleRestApi(BaseSupersetModelRestApi):
|
|||||||
"name",
|
"name",
|
||||||
"type",
|
"type",
|
||||||
]
|
]
|
||||||
search_columns = ["name", "active", "created_by", "type"]
|
search_columns = ["name", "active", "created_by", "type", "last_state"]
|
||||||
search_filters = {"name": [ReportScheduleAllTextFilter]}
|
search_filters = {"name": [ReportScheduleAllTextFilter]}
|
||||||
allowed_rel_fields = {"created_by", "chart", "dashboard"}
|
allowed_rel_fields = {"created_by", "chart", "dashboard"}
|
||||||
filter_rel_fields = {
|
filter_rel_fields = {
|
||||||
|
Loading…
Reference in New Issue
Block a user