-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilterable.toolbar.tsx
More file actions
114 lines (104 loc) · 4.66 KB
/
filterable.toolbar.tsx
File metadata and controls
114 lines (104 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { useCallback, useState } from 'react';
import { Button, Divider, Form, Icon, Label, Menu } from 'semantic-ui-react';
import { FormSelect } from 'semantic-ui-react';
import { entries, filter, find, flatMap, get, groupBy, head, map } from 'lodash-es';
import { FILTER_ACTIONS, RELATABLE_ICONS } from '../../relatable.types';
import { useRelatableStateContext, useRelatableToolbarContext } from '../../states';
import arrayHasItems from '../../utils/array-has-items';
import { getToolbarStateClass } from '../../utils/relatable-state-classes';
import { getRelatableAction } from '../../utils/relatable-actions';
import { columnHasAction } from '../../utils/column-actions';
import { withFilters, IWithFiltersInstance } from '../../add-ons';
import { ToolbarPopup } from './toolbar-popup';
import { Filter } from '../renderers';
import RelatableIcon from '../relatable-icon';
export default function FilterableToolbar() {
const { allColumns: columns, state: { filters }, onCustomFilterChange } = useRelatableStateContext<any, IWithFiltersInstance>();
const [selectedToolbarAction, setToolbar, clearToolbar] = useRelatableToolbarContext();
const appliedFilterValues = map(filters, ({value}) => value);
const isFiltered = arrayHasItems(appliedFilterValues);
return <ToolbarPopup
name={withFilters.name}
content={<FiltersPopup
columns={columns}
selectedToolbarAction={selectedToolbarAction}
appliedFilters={filters}
isFiltered={isFiltered}
onClose={clearToolbar}
onCustomFilterChange={onCustomFilterChange}/>}
selectedToolbarAction={selectedToolbarAction}
onClose={clearToolbar}>
<Menu.Item name="filter" onClick={() => setToolbar(withFilters.name)}>
<RelatableIcon name={RELATABLE_ICONS.FILTER}/>
Filters
{isFiltered &&
<Label className={isFiltered ? getToolbarStateClass('filterValue') : ''}>{appliedFilterValues.length}</Label>}
</Menu.Item>
</ToolbarPopup>;
}
function FiltersPopup({ columns, selectedToolbarAction, isFiltered, onClose, appliedFilters, onCustomFilterChange }: any) {
return <div className="relatable__toolbar-popup relatable__toolbar-filters-popup">
{isFiltered && <>
{flatMap(entries(groupBy(appliedFilters, 'id')), ([id, columnFilters]) => {
const column = find(columns, (column) => column.id === id);
return map(columnFilters, ({value}) => <Label key={`${id}: ${value.value}`} className="relatable__toolbar-value">
<FilterItem column={column} value={value}/>
<Icon name="close" onClick={() => onCustomFilterChange(column, FILTER_ACTIONS.FILTER_REMOVE, [value])}/>
</Label>);
})}
<Divider/>
</>}
<FiltersForm
columns={columns}
selectedToolbarAction={selectedToolbarAction}
onCustomFilterChange={onCustomFilterChange}
onClose={onClose}/>
</div>;
}
function FiltersForm({ columns, selectedToolbarAction, onCustomFilterChange, onClose }: any) {
const { availableGlobalActions } = useRelatableStateContext();
const relatableAction = getRelatableAction(availableGlobalActions, selectedToolbarAction.name);
const columnsToUse = filter(columns, (column) => relatableAction && columnHasAction(column, relatableAction));
const firstId = selectedToolbarAction.column
? selectedToolbarAction.column.id
: get(head(columnsToUse), 'id', undefined);
const [filterValue, onFilterValueChange] = useState<any>();
const [selectedColumnId, setSelectedColumnId] = useState<any>(firstId);
const selectedColumn = find(columnsToUse, ({ id }) => id === selectedColumnId);
const columnOptions = map(filter(columnsToUse, 'canFilter'), (column) => ({
key: column.id,
value: column.id,
text: column.Header,
}));
const onSubmit = useCallback(() => {
onClose();
onCustomFilterChange(selectedColumn, FILTER_ACTIONS.FILTER_ADD, [filterValue]);
}, [onCustomFilterChange, selectedColumn, filterValue]);
return <Form onSubmit={onSubmit} className="relatable__toolbar-filters-form">
<h3>Add filter</h3>
<Form.Group>
<Form.Field>
<FormSelect
options={columnOptions}
value={selectedColumnId}
search
onChange={(_, { value }) => setSelectedColumnId(value)}/>
</Form.Field>
<Filter column={selectedColumn} onChange={onFilterValueChange}/>
<Button
basic
icon
color="black"
className="relatable__toolbar-popup-button"
title="Add"
disabled={!filterValue}>
<Icon name="check"/>
</Button>
</Form.Group>
</Form>;
}
function FilterItem({ column, value }: any) {
return <span className="relatable__toolbar-filters-item">
{column.render('Header')}: {value.value}
</span>;
}