add more filters

This commit is contained in:
Simon Larsen 2022-09-04 20:15:37 +01:00
parent ecb8a46739
commit 07e336e90d
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
6 changed files with 101 additions and 62 deletions

View File

@ -1,3 +1,4 @@
import BaseModel from 'Common/Models/BaseModel';
import { JSONObject } from 'Common/Types/JSON';
import ObjectID from 'Common/Types/ObjectID';
import { ReactElement } from 'react';
@ -18,6 +19,7 @@ export default interface Columns<TEntity> {
disableSort?: boolean;
type: FieldType;
isFilterable: boolean;
filterEntityType?: BaseModel | undefined,
actionButtons?: Array<ActionButton>;
getElement?:
| ((

View File

@ -1,13 +1,11 @@
import { JSONObject } from 'Common/Types/JSON';
import React, { FunctionComponent, ReactElement } from 'react';
import TableBody from './TableBody';
import TableHeader from './TableHeader';
import TableHeader, { FilterData } from './TableHeader';
import Columns from './Types/Columns';
import Pagination from '../Pagination/Pagination';
import SortOrder from 'Common/Types/Database/SortOrder';
import Dictionary from 'Common/Types/Dictionary';
import ActionButtonSchema from '../ActionButton/ActionButtonSchema';
import Search from 'Common/Types/Database/Search';
import ErrorMessage from '../ErrorMessage/ErrorMessage';
import ComponentLoader from '../ComponentLoader/ComponentLoader';
@ -30,8 +28,8 @@ export interface ComponentProps {
onSortChanged: (sortBy: string, sortOrder: SortOrder) => void;
showFilter?: undefined | boolean;
onFilterChanged?:
| undefined
| ((filterData: Dictionary<string | boolean | Search | Date>) => void);
| undefined
| ((filterData: FilterData) => void);
}
const Table: FunctionComponent<ComponentProps> = (

View File

@ -13,6 +13,11 @@ import Input from '../Input/Input';
import FieldType from '../Types/FieldType';
import Search from 'Common/Types/Database/Search';
import OneUptimeDate from 'Common/Types/Date';
import BaseModel from 'Common/Models/BaseModel';
import ObjectID from 'Common/Types/ObjectID';
import Dropdown, { DropdownValue } from '../Dropdown/Dropdown';
export type FilterData = Dictionary<string | DropdownValue | Array<DropdownValue> | boolean | Search | Date | BaseModel | Array<BaseModel> | ObjectID | Array<ObjectID> | number>;
export interface ComponentProps {
columns: Columns;
@ -20,8 +25,8 @@ export interface ComponentProps {
onSortChanged: (sortBy: string, sortOrder: SortOrder) => void;
showFilter: boolean;
onFilterChanged?:
| undefined
| ((filterData: Dictionary<string | boolean | Search | Date>) => void);
| undefined
| ((filterData: FilterData) => void);
}
const TableHeader: FunctionComponent<ComponentProps> = (
@ -32,7 +37,7 @@ const TableHeader: FunctionComponent<ComponentProps> = (
// should filter on textboxes and checkboxes.
const [filterData, setFilterData] = useState<
Dictionary<string | boolean | Search | Date>
FilterData
>({});
useEffect(() => {
@ -112,61 +117,92 @@ const TableHeader: FunctionComponent<ComponentProps> = (
{props.columns.map((column: Column, i: number) => {
return (
<td key={i}>
{column.isFilterable && (
<Input
onChange={(
changedValue: string | Date
) => {
if (column.key) {
if (!changedValue) {
delete filterData[
column.key
];
}
if (
changedValue &&
column.type ===
FieldType.Date
) {
filterData[column.key] =
OneUptimeDate.asDateForDatabaseQuery(
changedValue as string
);
}
if (
changedValue &&
column.type ===
FieldType.Text
) {
filterData[column.key] =
new Search(
changedValue as string
);
}
setFilterData(filterData);
if (props.onFilterChanged) {
props.onFilterChanged(
filterData
);
}
{column.isFilterable && column.key && (
<div>
{(column.type === FieldType.Entity || column.type === FieldType.EntityArray) && column.filterDropdownOptions && <Dropdown options={column.filterDropdownOptions} onChange={(value: DropdownValue | Array<DropdownValue>) => {
if (!column.key) {
return;
}
if (!value || (Array.isArray(value) && value.length === 0)) {
delete filterData[
column.key
];
} else {
filterData[column.key] = value;
}
setFilterData(filterData);
if (props.onFilterChanged) {
props.onFilterChanged(
filterData
);
}
}}
initialValue={(
filterData[column.key || ''] || ''
).toString()}
placeholder={`Filter by ${column.title}`}
className={'form-control'}
type={
column.type === FieldType.Date
? 'date'
: 'text'
}
/>
isMultiSelect={column.type === FieldType.EntityArray}
placeholder={`Filter by ${column.title}`}
className={'form-control'}
/>}
{(column.type === FieldType.Date || column.type === FieldType.ObjectID || column.type === FieldType.Text) && <Input
onChange={(
changedValue: string | Date
) => {
if (column.key) {
if (!changedValue) {
delete filterData[
column.key
];
}
if (
changedValue &&
column.type ===
FieldType.Date
) {
filterData[column.key] =
OneUptimeDate.asDateForDatabaseQuery(
changedValue as string
);
}
if (
changedValue &&
column.type ===
FieldType.Text
) {
filterData[column.key] =
new Search(
changedValue as string
);
}
setFilterData(filterData);
if (props.onFilterChanged) {
props.onFilterChanged(
filterData
);
}
}
}}
initialValue={(
filterData[column.key || ''] || ''
).toString()}
placeholder={`Filter by ${column.title}`}
className={'form-control'}
type={
column.type === FieldType.Date
? 'date'
: 'text'
}
/>}
</div>
)}
</td>
);
})}

View File

@ -1,5 +1,6 @@
import { JSONObject } from 'Common/Types/JSON';
import { ReactElement } from 'react';
import { DropdownOption } from '../../Dropdown/Dropdown';
import FieldType from '../../Types/FieldType';
export default interface Column {
@ -8,6 +9,7 @@ export default interface Column {
disableSort?: boolean;
type: FieldType;
isFilterable?: boolean;
filterDropdownOptions?: Array<DropdownOption> | undefined;
key?: string | null; //can be null because actions column does not have a key.
getElement?:
| ((

View File

@ -17,6 +17,7 @@ enum FieldType {
Actions = 'Actions',
Boolean = 'Boolean',
Entity = 'Entity',
EntityArray = 'EntityArray',
Markdown = 'Markdown',
}

View File

@ -130,7 +130,7 @@ const IncidentsPage: FunctionComponent<PageComponentProps> = (
},
},
title: 'Current State',
type: FieldType.Text,
type: FieldType.Entity,
getElement: (item: JSONObject): ReactElement => {
if (item['currentIncidentState']) {
return (
@ -165,7 +165,7 @@ const IncidentsPage: FunctionComponent<PageComponentProps> = (
},
},
title: 'Monitors Affected',
type: FieldType.Text,
type: FieldType.EntityArray,
getElement: (item: JSONObject): ReactElement => {
return (
<MonitorsElement