feat: filters for alerts and reports list view (#11900)

This commit is contained in:
Lily Kuang 2020-12-04 09:58:34 -08:00 committed by GitHub
parent 77d362d306
commit 60122a2b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 20 deletions

View File

@ -62,6 +62,10 @@ const mockalerts = [...new Array(3)].map((_, i) => ({
type: 'alert',
}));
const mockUser = {
userId: 1,
};
fetchMock.get(alertsEndpoint, {
ids: [2, 0, 1],
result: mockalerts,
@ -74,7 +78,7 @@ fetchMock.put(alertEndpoint, { ...mockalerts[0], active: false });
fetchMock.put(alertsEndpoint, { ...mockalerts[0], active: false });
async function mountAndWait(props) {
const mounted = mount(<AlertList {...props} />, {
const mounted = mount(<AlertList {...props} user={mockUser} />, {
context: { store },
});
await waitForComponentToPaint(mounted);

View File

@ -25,8 +25,9 @@ import Icon, { IconName } from 'src/components/Icon';
import { Tooltip } from 'src/common/components/Tooltip';
import { Switch } from 'src/common/components/Switch';
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 { createFetchRelated, createErrorHandler } from 'src/views/CRUD/utils';
import withToasts from 'src/messageToasts/enhancers/withToasts';
import {
@ -42,16 +43,19 @@ interface AlertListProps {
addDangerToast: (msg: string) => void;
addSuccessToast: (msg: string) => void;
isReportEnabled: boolean;
user: {
userId: string | number;
};
}
const StatusIcon = styled(Icon)<{ status: string }>`
color: ${({ status, theme }) => {
switch (status) {
case 'alerting':
return '#FBC700';
case 'failed':
case 'Working':
return theme.colors.alert.base;
case 'Error':
return theme.colors.error.base;
case 'ok':
case 'Success':
return theme.colors.success.base;
default:
return theme.colors.grayscale.base;
@ -62,14 +66,15 @@ const StatusIcon = styled(Icon)<{ status: string }>`
function AlertList({
addDangerToast,
isReportEnabled = false,
user,
}: AlertListProps) {
const title = isReportEnabled ? t('report') : t('alert');
const initalFilters = useMemo(
() => [
{
id: 'type',
operator: 'eq',
value: isReportEnabled ? 'report' : 'alert',
operator: FilterOperators.equals,
value: isReportEnabled ? 'Report' : 'Alert',
},
],
[isReportEnabled],
@ -127,25 +132,25 @@ function AlertList({
status: '',
};
switch (lastState) {
case 'ok':
case 'Success':
lastStateConfig.name = 'check';
lastStateConfig.label = t('OK');
lastStateConfig.status = 'ok';
lastStateConfig.label = t('Success');
lastStateConfig.status = 'Success';
break;
case 'alerting':
case 'Working':
lastStateConfig.name = 'exclamation';
lastStateConfig.label = t('Alerting');
lastStateConfig.status = 'alerting';
lastStateConfig.label = t('Working');
lastStateConfig.status = 'Working';
break;
case 'failed':
case 'Error':
lastStateConfig.name = 'x-small';
lastStateConfig.label = t('Failed');
lastStateConfig.status = 'failed';
lastStateConfig.label = t('Error');
lastStateConfig.status = 'Error';
break;
default:
lastStateConfig.name = 'exclamation';
lastStateConfig.label = t('Alerting');
lastStateConfig.status = 'alerting';
lastStateConfig.label = t('Working');
lastStateConfig.status = 'Working';
}
return (
<Tooltip title={lastStateConfig.label} placement="bottom">
@ -181,6 +186,11 @@ function AlertList({
Header: t('Schedule'),
accessor: 'crontab',
},
{
accessor: 'created_by',
disableSortBy: true,
hidden: true,
},
{
Cell: ({
row: {
@ -275,6 +285,46 @@ function AlertList({
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 (
<>
<SubMenu
@ -303,6 +353,7 @@ function AlertList({
data={alerts}
emptyState={emptyState}
fetchData={fetchData}
filters={filters}
initialSort={initialSort}
loading={loading}
pageSize={PAGE_SIZE}

View File

@ -145,7 +145,7 @@ class ReportScheduleRestApi(BaseSupersetModelRestApi):
"name",
"type",
]
search_columns = ["name", "active", "created_by", "type"]
search_columns = ["name", "active", "created_by", "type", "last_state"]
search_filters = {"name": [ReportScheduleAllTextFilter]}
allowed_rel_fields = {"created_by", "chart", "dashboard"}
filter_rel_fields = {