@@ -15,6 +15,21 @@ import { profiles } from '../../common/table/profiles.js';
1515import { applyProfile } from '../../../utilities/applyProfile.js' ;
1616import { tooltip } from '../../common/popover/tooltip.js' ;
1717
18+ /**
19+ * @typedef FilterConfiguration
20+ *
21+ * @property {string } name
22+ * @property {function|Component } filter
23+ * @property {string|Component } filterTooltip
24+ * @property {object|string|string[] } profiles
25+ */
26+
27+ /**
28+ * @typedef FiltersConfiguration
29+ *
30+ * @type {object<string, FilterConfiguration> } mapping: filterable property -> filter configuration
31+ */
32+
1833/**
1934 * Return the filters panel popover trigger
2035 *
@@ -23,67 +38,87 @@ import { tooltip } from '../../common/popover/tooltip.js';
2338const filtersToggleTrigger = ( ) => h ( 'button#openFilterToggle.btn.btn.btn-primary' , 'Filters' ) ;
2439
2540/**
26- * Return the filters panel popover content (i.e. the actual filters)
27- *
28- * TODO Separate filters from active columns
41+ * Create main header of the filters panel
42+ * @param {FilteringModel } filteringModel filtering model
43+ * @returns {Component } main panel header
44+ */
45+ const filtersToggleContentHeader = ( filteringModel ) => h ( '.flex-row.justify-between' , [
46+ h ( '.f4' , 'Filters' ) ,
47+ h (
48+ 'button#reset-filters.btn.btn-danger' ,
49+ {
50+ onclick : ( ) => filteringModel . resetFiltering
51+ ? filteringModel . resetFiltering ( )
52+ : filteringModel . reset ( true ) ,
53+ disabled : ! filteringModel . isAnyFilterActive ( ) ,
54+ } ,
55+ 'Reset all filters' ,
56+ ) ,
57+ ] ) ;
58+
59+ /**
60+ * Return the filters panel popover content section
2961 *
30- * @param {object } filteringModel the filtering model
31- * @param {object } columns the list of columns containing filters
62+ * @param {FilteringModel } filteringModel the filtering model
63+ * @param {FiltersConfiguration } filtersConfiguration filters configuration
3264 * @param {object } [configuration] additional configuration
3365 * @param {string } [configuration.profile = profiles.none] profile which filters should be rendered @see Column
34- * @return {Component } the filters panel
66+ * @return {Component } the filters section
3567 */
36- const filtersToggleContent = (
37- filteringModel ,
38- columns ,
39- { profile : appliedProfile = profiles . none } = { } ,
40- ) => h ( '.w-l.flex-column.p3.g3' , [
41- h ( '.flex-row.justify-between' , [
42- h ( '.f4' , 'Filters' ) ,
43- h (
44- 'button#reset-filters.btn.btn-danger' ,
45- {
46- onclick : ( ) => filteringModel . resetFiltering
47- ? filteringModel . resetFiltering ( )
48- : filteringModel . reset ( true ) ,
49- disabled : ! filteringModel . isAnyFilterActive ( ) ,
50- } ,
51- 'Reset all filters' ,
52- ) ,
53- ] ) ,
68+ export const filtersSection = ( filteringModel , filtersConfiguration , { profile : appliedProfile = profiles . none } = { } ) =>
5469 h ( '.flex-column.g2' , [
55- Object . entries ( columns )
70+ Object . entries ( filtersConfiguration )
5671 . filter ( ( [ _ , column ] ) => {
5772 let columnProfiles = column . profiles ?? [ profiles . none ] ;
5873 if ( typeof columnProfiles === 'string' ) {
5974 columnProfiles = [ columnProfiles ] ;
6075 }
6176 return applyProfile ( column , appliedProfile , columnProfiles ) ?. filter ;
6277 } )
63- . map ( ( [ columnKey , { name, filterTooltip, filter } ] ) => [
64- h ( `.flex-row.items-baseline.${ columnKey } -filter` , [
65- h ( '.w-30.f5.flex-row.items-center.g2' , [
66- name ,
67- filterTooltip ? tooltip ( info ( ) , filterTooltip ) : null ,
68- ] ) ,
69- h ( '.w-70' , typeof filter === 'function' ? filter ( filteringModel ) : filter ) ,
70- ] ) ,
71- ] ) ,
72- ] ) ,
78+ . map ( ( [ columnKey , { name, filterTooltip, filter } ] ) =>
79+ name
80+ ? [
81+ h ( `.flex-row.items-baseline.${ columnKey } -filter` , [
82+ h ( '.w-30.f5.flex-row.items-center.g2' , [
83+ name ,
84+ filterTooltip ? tooltip ( info ( ) , filterTooltip ) : null ,
85+ ] ) ,
86+ h ( '.w-70' , typeof filter === 'function' ? filter ( filteringModel ) : filter ) ,
87+ ] ) ,
88+ ]
89+ : typeof filter === 'function' ? filter ( filteringModel ) : filter ) ,
90+ ] ) ;
91+
92+ /**
93+ * Return the filters panel popover content (i.e. the actual filters)
94+ *
95+ * @param {FilteringModel } filteringModel the filtering model
96+ * @param {FiltersConfiguration } filtersConfiguration filters configuration
97+ * @param {object } [configuration] additional configuration
98+ * @param {string } [configuration.profile = profiles.none] profile which filters should be rendered @see Column
99+ * @return {Component } the filters panel
100+ */
101+ const filtersToggleContent = (
102+ filteringModel ,
103+ filtersConfiguration ,
104+ configuration = { } ,
105+ ) => h ( '.w-l.flex-column.p3.g3' , [
106+ filtersToggleContentHeader ( filteringModel ) ,
107+ filtersSection ( filteringModel , filtersConfiguration , configuration ) ,
73108] ) ;
74109
75110/**
76111 * Return component composed of the filtering popover and its button trigger
77112 *
78- * @param {object } filterModel the filter model
79- * @param {object } activeColumns the list of active columns containing the filtering configuration
113+ * @param {FilteringModel } filteringModel the filtering model
114+ * @param {FiltersConfiguration } filtersConfiguration filters configuration
80115 * @param {object } [configuration] optional configuration
81116 * @param {string } [configuration.profile] specify for which profile filtering should be enabled
82117 * @return {Component } the filter component
83118 */
84- export const filtersPanelPopover = ( filterModel , activeColumns , configuration ) => popover (
119+ export const filtersPanelPopover = ( filteringModel , filtersConfiguration , configuration ) => popover (
85120 filtersToggleTrigger ( ) ,
86- filtersToggleContent ( filterModel , activeColumns , configuration ) ,
121+ filtersToggleContent ( filteringModel , filtersConfiguration , configuration ) ,
87122 {
88123 ...PopoverTriggerPreConfiguration . click ,
89124 anchor : PopoverAnchors . RIGHT_START ,
0 commit comments