diff --git a/superset-frontend/spec/javascripts/views/CRUD/alert/AlertList_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/alert/AlertList_spec.jsx
index 09a95c1af8..22bc86e44c 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/alert/AlertList_spec.jsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/alert/AlertList_spec.jsx
@@ -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(, {
+ const mounted = mount(, {
context: { store },
});
await waitForComponentToPaint(mounted);
diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
index 7313c87e4b..cc15595a69 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
@@ -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 (
@@ -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 (
<>