@wordpress/dataviews 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/LICENSE.md +1 -1
- package/README.md +30 -6
- package/build/add-filter.js +109 -49
- package/build/add-filter.js.map +1 -1
- package/build/constants.js +24 -2
- package/build/constants.js.map +1 -1
- package/build/dataviews.js +12 -9
- package/build/dataviews.js.map +1 -1
- package/build/dropdown-menu-helper.js +72 -0
- package/build/dropdown-menu-helper.js.map +1 -0
- package/build/filter-summary.js +43 -54
- package/build/filter-summary.js.map +1 -1
- package/build/filters.js +27 -17
- package/build/filters.js.map +1 -1
- package/build/index.js +13 -0
- package/build/index.js.map +1 -1
- package/build/item-actions.js +12 -12
- package/build/item-actions.js.map +1 -1
- package/build/pagination.js +31 -65
- package/build/pagination.js.map +1 -1
- package/build/reset-filters.js +8 -8
- package/build/reset-filters.js.map +1 -1
- package/build/search.js +8 -6
- package/build/search.js.map +1 -1
- package/build/utils.js +71 -0
- package/build/utils.js.map +1 -0
- package/build/view-actions.js +72 -95
- package/build/view-actions.js.map +1 -1
- package/build/view-grid.js +4 -6
- package/build/view-grid.js.map +1 -1
- package/build/view-list.js +26 -13
- package/build/view-list.js.map +1 -1
- package/build/view-table.js +153 -154
- package/build/view-table.js.map +1 -1
- package/build-module/add-filter.js +113 -53
- package/build-module/add-filter.js.map +1 -1
- package/build-module/constants.js +20 -0
- package/build-module/constants.js.map +1 -1
- package/build-module/dataviews.js +13 -10
- package/build-module/dataviews.js.map +1 -1
- package/build-module/dropdown-menu-helper.js +64 -0
- package/build-module/dropdown-menu-helper.js.map +1 -0
- package/build-module/filter-summary.js +45 -56
- package/build-module/filter-summary.js.map +1 -1
- package/build-module/filters.js +26 -17
- package/build-module/filters.js.map +1 -1
- package/build-module/index.js +1 -0
- package/build-module/index.js.map +1 -1
- package/build-module/item-actions.js +12 -12
- package/build-module/item-actions.js.map +1 -1
- package/build-module/pagination.js +35 -69
- package/build-module/pagination.js.map +1 -1
- package/build-module/reset-filters.js +6 -6
- package/build-module/reset-filters.js.map +1 -1
- package/build-module/search.js +7 -6
- package/build-module/search.js.map +1 -1
- package/build-module/utils.js +63 -0
- package/build-module/utils.js.map +1 -0
- package/build-module/view-actions.js +73 -97
- package/build-module/view-actions.js.map +1 -1
- package/build-module/view-grid.js +4 -6
- package/build-module/view-grid.js.map +1 -1
- package/build-module/view-list.js +27 -14
- package/build-module/view-list.js.map +1 -1
- package/build-module/view-table.js +156 -157
- package/build-module/view-table.js.map +1 -1
- package/build-style/style-rtl.css +180 -70
- package/build-style/style.css +180 -70
- package/package.json +11 -10
- package/src/add-filter.js +227 -68
- package/src/constants.js +16 -0
- package/src/dataviews.js +19 -12
- package/src/dropdown-menu-helper.js +61 -0
- package/src/filter-summary.js +70 -103
- package/src/filters.js +41 -24
- package/src/index.js +1 -0
- package/src/item-actions.js +30 -25
- package/src/pagination.js +75 -123
- package/src/reset-filters.js +5 -5
- package/src/search.js +8 -6
- package/src/style.scss +182 -48
- package/src/utils.js +51 -0
- package/src/view-actions.js +113 -114
- package/src/view-grid.js +4 -4
- package/src/view-list.js +42 -28
- package/src/view-table.js +280 -238
|
@@ -8,14 +8,17 @@ import classNames from 'classnames';
|
|
|
8
8
|
* WordPress dependencies
|
|
9
9
|
*/
|
|
10
10
|
import { useAsyncList } from '@wordpress/compose';
|
|
11
|
-
import { __experimentalHStack as HStack, __experimentalVStack as VStack } from '@wordpress/components';
|
|
11
|
+
import { __experimentalHStack as HStack, __experimentalVStack as VStack, Button } from '@wordpress/components';
|
|
12
12
|
import { ENTER, SPACE } from '@wordpress/keycodes';
|
|
13
|
+
import { info } from '@wordpress/icons';
|
|
14
|
+
import { __ } from '@wordpress/i18n';
|
|
13
15
|
export default function ViewList({
|
|
14
16
|
view,
|
|
15
17
|
fields,
|
|
16
18
|
data,
|
|
17
19
|
getItemId,
|
|
18
20
|
onSelectionChange,
|
|
21
|
+
onDetailsChange,
|
|
19
22
|
selection,
|
|
20
23
|
deferredRendering
|
|
21
24
|
}) {
|
|
@@ -35,41 +38,51 @@ export default function ViewList({
|
|
|
35
38
|
}
|
|
36
39
|
};
|
|
37
40
|
return createElement("ul", {
|
|
38
|
-
className: "dataviews-list
|
|
39
|
-
}, usedData.map(
|
|
41
|
+
className: "dataviews-view-list"
|
|
42
|
+
}, usedData.map(item => {
|
|
40
43
|
return createElement("li", {
|
|
41
|
-
key: getItemId
|
|
44
|
+
key: getItemId(item),
|
|
45
|
+
className: classNames({
|
|
46
|
+
'is-selected': selection.includes(item.id)
|
|
47
|
+
})
|
|
48
|
+
}, createElement(HStack, {
|
|
49
|
+
className: "dataviews-view-list__item-wrapper"
|
|
42
50
|
}, createElement("div", {
|
|
43
51
|
role: "button",
|
|
44
52
|
tabIndex: 0,
|
|
45
53
|
"aria-pressed": selection.includes(item.id),
|
|
46
54
|
onKeyDown: onEnter(item),
|
|
47
|
-
className:
|
|
48
|
-
'dataviews-list-view__item-selected': selection.includes(item.id)
|
|
49
|
-
}),
|
|
55
|
+
className: "dataviews-view-list__item",
|
|
50
56
|
onClick: () => onSelectionChange([item])
|
|
51
57
|
}, createElement(HStack, {
|
|
52
|
-
spacing: 3
|
|
58
|
+
spacing: 3,
|
|
59
|
+
justify: "start"
|
|
53
60
|
}, createElement("div", {
|
|
54
|
-
className: "dataviews-
|
|
61
|
+
className: "dataviews-view-list__media-wrapper"
|
|
55
62
|
}, mediaField?.render({
|
|
56
63
|
item
|
|
57
64
|
}) || createElement("div", {
|
|
58
|
-
className: "dataviews-
|
|
59
|
-
})), createElement(
|
|
65
|
+
className: "dataviews-view-list__media-placeholder"
|
|
66
|
+
})), createElement(VStack, {
|
|
60
67
|
spacing: 1
|
|
61
68
|
}, primaryField?.render({
|
|
62
69
|
item
|
|
63
70
|
}), createElement("div", {
|
|
64
|
-
className: "dataviews-
|
|
71
|
+
className: "dataviews-view-list__fields"
|
|
65
72
|
}, visibleFields.map(field => {
|
|
66
73
|
return createElement("span", {
|
|
67
74
|
key: field.id,
|
|
68
|
-
className: "dataviews-
|
|
75
|
+
className: "dataviews-view-list__field"
|
|
69
76
|
}, field.render({
|
|
70
77
|
item
|
|
71
78
|
}));
|
|
72
|
-
})))))
|
|
79
|
+
}))))), onDetailsChange && createElement(Button, {
|
|
80
|
+
className: "dataviews-view-list__details-button",
|
|
81
|
+
onClick: () => onDetailsChange([item]),
|
|
82
|
+
icon: info,
|
|
83
|
+
label: __('View details'),
|
|
84
|
+
size: "compact"
|
|
85
|
+
})));
|
|
73
86
|
}));
|
|
74
87
|
}
|
|
75
88
|
//# sourceMappingURL=view-list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["classNames","useAsyncList","__experimentalHStack","HStack","__experimentalVStack","VStack","ENTER","SPACE","ViewList","view","fields","data","getItemId","onSelectionChange","selection","deferredRendering","shownData","step","usedData","mediaField","find","field","id","layout","primaryField","visibleFields","filter","hiddenFields","includes","onEnter","item","event","keyCode","createElement","className","map","
|
|
1
|
+
{"version":3,"names":["classNames","useAsyncList","__experimentalHStack","HStack","__experimentalVStack","VStack","Button","ENTER","SPACE","info","__","ViewList","view","fields","data","getItemId","onSelectionChange","onDetailsChange","selection","deferredRendering","shownData","step","usedData","mediaField","find","field","id","layout","primaryField","visibleFields","filter","hiddenFields","includes","onEnter","item","event","keyCode","createElement","className","map","key","role","tabIndex","onKeyDown","onClick","spacing","justify","render","icon","label","size"],"sources":["@wordpress/dataviews/src/view-list.js"],"sourcesContent":["/**\n * External dependencies\n */\nimport classNames from 'classnames';\n\n/**\n * WordPress dependencies\n */\nimport { useAsyncList } from '@wordpress/compose';\nimport {\n\t__experimentalHStack as HStack,\n\t__experimentalVStack as VStack,\n\tButton,\n} from '@wordpress/components';\nimport { ENTER, SPACE } from '@wordpress/keycodes';\nimport { info } from '@wordpress/icons';\nimport { __ } from '@wordpress/i18n';\n\nexport default function ViewList( {\n\tview,\n\tfields,\n\tdata,\n\tgetItemId,\n\tonSelectionChange,\n\tonDetailsChange,\n\tselection,\n\tdeferredRendering,\n} ) {\n\tconst shownData = useAsyncList( data, { step: 3 } );\n\tconst usedData = deferredRendering ? shownData : data;\n\tconst mediaField = fields.find(\n\t\t( field ) => field.id === view.layout.mediaField\n\t);\n\tconst primaryField = fields.find(\n\t\t( field ) => field.id === view.layout.primaryField\n\t);\n\tconst visibleFields = fields.filter(\n\t\t( field ) =>\n\t\t\t! view.hiddenFields.includes( field.id ) &&\n\t\t\t! [ view.layout.primaryField, view.layout.mediaField ].includes(\n\t\t\t\tfield.id\n\t\t\t)\n\t);\n\n\tconst onEnter = ( item ) => ( event ) => {\n\t\tconst { keyCode } = event;\n\t\tif ( [ ENTER, SPACE ].includes( keyCode ) ) {\n\t\t\tonSelectionChange( [ item ] );\n\t\t}\n\t};\n\n\treturn (\n\t\t<ul className=\"dataviews-view-list\">\n\t\t\t{ usedData.map( ( item ) => {\n\t\t\t\treturn (\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={ getItemId( item ) }\n\t\t\t\t\t\tclassName={ classNames( {\n\t\t\t\t\t\t\t'is-selected': selection.includes( item.id ),\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<HStack className=\"dataviews-view-list__item-wrapper\">\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\t\t\ttabIndex={ 0 }\n\t\t\t\t\t\t\t\taria-pressed={ selection.includes( item.id ) }\n\t\t\t\t\t\t\t\tonKeyDown={ onEnter( item ) }\n\t\t\t\t\t\t\t\tclassName=\"dataviews-view-list__item\"\n\t\t\t\t\t\t\t\tonClick={ () => onSelectionChange( [ item ] ) }\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<HStack spacing={ 3 } justify=\"start\">\n\t\t\t\t\t\t\t\t\t<div className=\"dataviews-view-list__media-wrapper\">\n\t\t\t\t\t\t\t\t\t\t{ mediaField?.render( { item } ) || (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"dataviews-view-list__media-placeholder\"></div>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<VStack spacing={ 1 }>\n\t\t\t\t\t\t\t\t\t\t{ primaryField?.render( { item } ) }\n\t\t\t\t\t\t\t\t\t\t<div className=\"dataviews-view-list__fields\">\n\t\t\t\t\t\t\t\t\t\t\t{ visibleFields.map( ( field ) => {\n\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={ field.id }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"dataviews-view-list__field\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{ field.render( {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\titem,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t} ) }\n\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t} ) }\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{ onDetailsChange && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tclassName=\"dataviews-view-list__details-button\"\n\t\t\t\t\t\t\t\t\tonClick={ () =>\n\t\t\t\t\t\t\t\t\t\tonDetailsChange( [ item ] )\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ticon={ info }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'View details' ) }\n\t\t\t\t\t\t\t\t\tsize=\"compact\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</li>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t</ul>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,111 +1,99 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import classNames from 'classnames';
|
|
6
|
+
|
|
2
7
|
/**
|
|
3
8
|
* WordPress dependencies
|
|
4
9
|
*/
|
|
5
10
|
import { __ } from '@wordpress/i18n';
|
|
6
11
|
import { useAsyncList } from '@wordpress/compose';
|
|
7
|
-
import {
|
|
12
|
+
import { unseen, funnel } from '@wordpress/icons';
|
|
8
13
|
import { Button, Icon, privateApis as componentsPrivateApis } from '@wordpress/components';
|
|
9
|
-
import { Children, Fragment } from '@wordpress/element';
|
|
14
|
+
import { Children, Fragment, forwardRef, useEffect, useId, useRef, useState } from '@wordpress/element';
|
|
10
15
|
|
|
11
16
|
/**
|
|
12
17
|
* Internal dependencies
|
|
13
18
|
*/
|
|
14
19
|
import { unlock } from './lock-unlock';
|
|
15
20
|
import ItemActions from './item-actions';
|
|
16
|
-
import { ENUMERATION_TYPE,
|
|
21
|
+
import { ENUMERATION_TYPE, OPERATORS, SORTING_DIRECTIONS } from './constants';
|
|
22
|
+
import { DropdownMenuRadioItemCustom } from './dropdown-menu-helper';
|
|
17
23
|
const {
|
|
18
24
|
DropdownMenuV2: DropdownMenu,
|
|
19
25
|
DropdownMenuGroupV2: DropdownMenuGroup,
|
|
20
26
|
DropdownMenuItemV2: DropdownMenuItem,
|
|
27
|
+
DropdownMenuRadioItemV2: DropdownMenuRadioItem,
|
|
21
28
|
DropdownMenuSeparatorV2: DropdownMenuSeparator,
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
DropdownMenuItemLabelV2: DropdownMenuItemLabel,
|
|
30
|
+
DropdownMenuItemHelpTextV2: DropdownMenuItemHelpText
|
|
24
31
|
} = unlock(componentsPrivateApis);
|
|
25
|
-
const
|
|
26
|
-
asc:
|
|
27
|
-
|
|
28
|
-
label: __('Sort ascending')
|
|
29
|
-
},
|
|
30
|
-
desc: {
|
|
31
|
-
icon: arrowDown,
|
|
32
|
-
label: __('Sort descending')
|
|
33
|
-
}
|
|
32
|
+
const sortArrows = {
|
|
33
|
+
asc: '↑',
|
|
34
|
+
desc: '↓'
|
|
34
35
|
};
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
const sanitizeOperators = field => {
|
|
37
|
+
let operators = field.filterBy?.operators;
|
|
38
|
+
if (!operators || !Array.isArray(operators)) {
|
|
39
|
+
operators = Object.keys(OPERATORS);
|
|
40
|
+
}
|
|
41
|
+
return operators.filter(operator => Object.keys(OPERATORS).includes(operator));
|
|
38
42
|
};
|
|
39
|
-
function HeaderMenu({
|
|
43
|
+
const HeaderMenu = forwardRef(function HeaderMenu({
|
|
40
44
|
field,
|
|
41
45
|
view,
|
|
42
|
-
onChangeView
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
onChangeView,
|
|
47
|
+
onHide
|
|
48
|
+
}, ref) {
|
|
45
49
|
const isHidable = field.enableHiding !== false;
|
|
46
|
-
|
|
47
|
-
return field.header;
|
|
48
|
-
}
|
|
50
|
+
const isSortable = field.enableSorting !== false;
|
|
49
51
|
const isSorted = view.sort?.field === field.id;
|
|
50
|
-
let filter, filterInView;
|
|
51
|
-
const
|
|
52
|
-
if (field.type === ENUMERATION_TYPE) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
elements: field.elements || []
|
|
63
|
-
};
|
|
64
|
-
filterInView = {
|
|
65
|
-
field: filter.field,
|
|
66
|
-
operator: filter.operators[0],
|
|
67
|
-
value: undefined
|
|
68
|
-
};
|
|
69
|
-
}
|
|
52
|
+
let filter, filterInView, activeElement, activeOperator, otherFilters;
|
|
53
|
+
const operators = sanitizeOperators(field);
|
|
54
|
+
if (field.type === ENUMERATION_TYPE && operators.length > 0) {
|
|
55
|
+
filter = {
|
|
56
|
+
field: field.id,
|
|
57
|
+
operators,
|
|
58
|
+
elements: field.elements || []
|
|
59
|
+
};
|
|
60
|
+
filterInView = view.filters.find(f => f.field === filter.field);
|
|
61
|
+
otherFilters = view.filters.filter(f => f.field !== filter.field);
|
|
62
|
+
activeElement = filter.elements.find(element => element.value === filterInView?.value);
|
|
63
|
+
activeOperator = filterInView?.operator || filter.operators[0];
|
|
70
64
|
}
|
|
71
65
|
const isFilterable = !!filter;
|
|
72
|
-
if (isFilterable) {
|
|
73
|
-
|
|
74
|
-
columnFilters.forEach(columnFilter => {
|
|
75
|
-
if (columnFilter.field === filter.field) {
|
|
76
|
-
filterInView = {
|
|
77
|
-
...columnFilter
|
|
78
|
-
};
|
|
79
|
-
} else {
|
|
80
|
-
otherFilters.push(columnFilter);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
66
|
+
if (!isSortable && !isHidable && !isFilterable) {
|
|
67
|
+
return field.header;
|
|
83
68
|
}
|
|
84
69
|
return createElement(DropdownMenu, {
|
|
85
70
|
align: "start",
|
|
86
71
|
trigger: createElement(Button, {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
72
|
+
size: "compact",
|
|
73
|
+
className: "dataviews-view-table-header-button",
|
|
74
|
+
ref: ref,
|
|
75
|
+
variant: "tertiary"
|
|
76
|
+
}, field.header, isSorted && createElement("span", {
|
|
77
|
+
"aria-hidden": "true"
|
|
78
|
+
}, isSorted && sortArrows[view.sort.direction])),
|
|
79
|
+
style: {
|
|
80
|
+
minWidth: '240px'
|
|
81
|
+
}
|
|
82
|
+
}, createElement(WithSeparators, null, isSortable && createElement(DropdownMenuGroup, null, Object.entries(SORTING_DIRECTIONS).map(([direction, info]) => {
|
|
83
|
+
const isChecked = isSorted && view.sort.direction === direction;
|
|
84
|
+
const value = `${field.id}-${direction}`;
|
|
85
|
+
return createElement(DropdownMenuRadioItem, {
|
|
86
|
+
key: value
|
|
87
|
+
// All sorting radio items share the same name, so that
|
|
88
|
+
// selecting a sorting option automatically deselects the
|
|
89
|
+
// previously selected one, even if it is displayed in
|
|
90
|
+
// another submenu. The field and direction are passed via
|
|
91
|
+
// the `value` prop.
|
|
92
|
+
,
|
|
93
|
+
name: "view-table-sorting",
|
|
94
|
+
value: value,
|
|
95
|
+
checked: isChecked,
|
|
96
|
+
onChange: () => {
|
|
109
97
|
onChangeView({
|
|
110
98
|
...view,
|
|
111
99
|
sort: {
|
|
@@ -114,96 +102,72 @@ function HeaderMenu({
|
|
|
114
102
|
}
|
|
115
103
|
});
|
|
116
104
|
}
|
|
117
|
-
}, info.label);
|
|
105
|
+
}, createElement(DropdownMenuItemLabel, null, info.label));
|
|
118
106
|
})), isHidable && createElement(DropdownMenuItem, {
|
|
119
|
-
role: "menuitemradio",
|
|
120
|
-
"aria-checked": false,
|
|
121
107
|
prefix: createElement(Icon, {
|
|
122
108
|
icon: unseen
|
|
123
109
|
}),
|
|
124
|
-
|
|
125
|
-
|
|
110
|
+
onClick: () => {
|
|
111
|
+
onHide(field);
|
|
126
112
|
onChangeView({
|
|
127
113
|
...view,
|
|
128
114
|
hiddenFields: view.hiddenFields.concat(field.id)
|
|
129
115
|
});
|
|
130
116
|
}
|
|
131
|
-
}, __('Hide')), isFilterable && createElement(DropdownMenuGroup, null, createElement(
|
|
117
|
+
}, createElement(DropdownMenuItemLabel, null, __('Hide'))), isFilterable && createElement(DropdownMenuGroup, null, createElement(DropdownMenu, {
|
|
132
118
|
key: filter.field,
|
|
133
|
-
trigger: createElement(
|
|
119
|
+
trigger: createElement(DropdownMenuItem, {
|
|
134
120
|
prefix: createElement(Icon, {
|
|
135
121
|
icon: funnel
|
|
136
122
|
}),
|
|
137
|
-
suffix: createElement(
|
|
138
|
-
|
|
139
|
-
})
|
|
140
|
-
}, __('Filter by'))
|
|
123
|
+
suffix: activeElement && createElement("span", {
|
|
124
|
+
"aria-hidden": "true"
|
|
125
|
+
}, activeOperator in OPERATORS && `${OPERATORS[activeOperator].label} `, activeElement?.label)
|
|
126
|
+
}, createElement(DropdownMenuItemLabel, null, __('Filter by')))
|
|
141
127
|
}, createElement(WithSeparators, null, createElement(DropdownMenuGroup, null, filter.elements.map(element => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// Intentionally use loose comparison, so it does type conversion.
|
|
145
|
-
// This covers the case where a top-level filter for the same field converts a number into a string.
|
|
146
|
-
/* eslint-disable eqeqeq */
|
|
147
|
-
isActive = element.value == filterInView.value;
|
|
148
|
-
/* eslint-enable eqeqeq */
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return createElement(DropdownMenuItem, {
|
|
128
|
+
const isActive = activeElement?.value === element.value;
|
|
129
|
+
return createElement(DropdownMenuRadioItemCustom, {
|
|
152
130
|
key: element.value,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}),
|
|
158
|
-
onSelect: () => {
|
|
131
|
+
name: `view-table-${filter.field}`,
|
|
132
|
+
value: element.value,
|
|
133
|
+
checked: isActive,
|
|
134
|
+
onClick: () => {
|
|
159
135
|
onChangeView({
|
|
160
136
|
...view,
|
|
137
|
+
page: 1,
|
|
161
138
|
filters: [...otherFilters, {
|
|
162
139
|
field: filter.field,
|
|
163
|
-
operator:
|
|
140
|
+
operator: activeOperator,
|
|
164
141
|
value: isActive ? undefined : element.value
|
|
165
142
|
}]
|
|
166
143
|
});
|
|
167
144
|
}
|
|
168
|
-
}, element.label);
|
|
169
|
-
})), filter.operators.length > 1 && createElement(
|
|
170
|
-
trigger: createElement(
|
|
171
|
-
suffix: createElement(
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
}, __('Conditions'))
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
filters: [...otherFilters, {
|
|
185
|
-
field: filter.field,
|
|
186
|
-
operator: OPERATOR_IN,
|
|
187
|
-
value: filterInView?.value
|
|
188
|
-
}]
|
|
189
|
-
})
|
|
190
|
-
}, __('Is')), createElement(DropdownMenuItem, {
|
|
191
|
-
key: "not-in-filter",
|
|
192
|
-
role: "menuitemradio",
|
|
193
|
-
"aria-checked": filterInView?.operator === OPERATOR_NOT_IN,
|
|
194
|
-
prefix: filterInView?.operator === OPERATOR_NOT_IN && createElement(Icon, {
|
|
195
|
-
icon: check
|
|
196
|
-
}),
|
|
197
|
-
onSelect: () => onChangeView({
|
|
145
|
+
}, createElement(DropdownMenuItemLabel, null, element.label), !!element.description && createElement(DropdownMenuItemHelpText, null, element.description));
|
|
146
|
+
})), filter.operators.length > 1 && createElement(DropdownMenu, {
|
|
147
|
+
trigger: createElement(DropdownMenuItem, {
|
|
148
|
+
suffix: createElement("span", {
|
|
149
|
+
"aria-hidden": "true"
|
|
150
|
+
}, OPERATORS[activeOperator]?.label)
|
|
151
|
+
}, createElement(DropdownMenuItemLabel, null, __('Conditions')))
|
|
152
|
+
}, Object.entries(OPERATORS).map(([operator, {
|
|
153
|
+
label,
|
|
154
|
+
key
|
|
155
|
+
}]) => createElement(DropdownMenuRadioItem, {
|
|
156
|
+
key: key,
|
|
157
|
+
name: `view-table-${filter.field}-conditions`,
|
|
158
|
+
value: operator,
|
|
159
|
+
checked: activeOperator === operator,
|
|
160
|
+
onChange: e => onChangeView({
|
|
198
161
|
...view,
|
|
162
|
+
page: 1,
|
|
199
163
|
filters: [...otherFilters, {
|
|
200
164
|
field: filter.field,
|
|
201
|
-
operator:
|
|
165
|
+
operator: e.target.value,
|
|
202
166
|
value: filterInView?.value
|
|
203
167
|
}]
|
|
204
168
|
})
|
|
205
|
-
},
|
|
206
|
-
}
|
|
169
|
+
}, createElement(DropdownMenuItemLabel, null, label)))))))));
|
|
170
|
+
});
|
|
207
171
|
function WithSeparators({
|
|
208
172
|
children
|
|
209
173
|
}) {
|
|
@@ -221,25 +185,43 @@ function ViewTable({
|
|
|
221
185
|
isLoading = false,
|
|
222
186
|
deferredRendering
|
|
223
187
|
}) {
|
|
188
|
+
const headerMenuRefs = useRef(new Map());
|
|
189
|
+
const headerMenuToFocusRef = useRef();
|
|
190
|
+
const [nextHeaderMenuToFocus, setNextHeaderMenuToFocus] = useState();
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (headerMenuToFocusRef.current) {
|
|
193
|
+
headerMenuToFocusRef.current.focus();
|
|
194
|
+
headerMenuToFocusRef.current = undefined;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
const asyncData = useAsyncList(data);
|
|
198
|
+
const tableNoticeId = useId();
|
|
199
|
+
if (nextHeaderMenuToFocus) {
|
|
200
|
+
// If we need to force focus, we short-circuit rendering here
|
|
201
|
+
// to prevent any additional work while we handle that.
|
|
202
|
+
// Clearing out the focus directive is necessary to make sure
|
|
203
|
+
// future renders don't cause unexpected focus jumps.
|
|
204
|
+
headerMenuToFocusRef.current = nextHeaderMenuToFocus;
|
|
205
|
+
setNextHeaderMenuToFocus();
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const onHide = field => {
|
|
209
|
+
const hidden = headerMenuRefs.current.get(field.id);
|
|
210
|
+
const fallback = headerMenuRefs.current.get(hidden.fallback);
|
|
211
|
+
setNextHeaderMenuToFocus(fallback?.node);
|
|
212
|
+
};
|
|
224
213
|
const visibleFields = fields.filter(field => !view.hiddenFields.includes(field.id) && ![view.layout.mediaField, view.layout.primaryField].includes(field.id));
|
|
225
|
-
const
|
|
226
|
-
const usedData = deferredRendering ? shownData : data;
|
|
214
|
+
const usedData = deferredRendering ? asyncData : data;
|
|
227
215
|
const hasData = !!usedData?.length;
|
|
228
|
-
if (isLoading) {
|
|
229
|
-
// TODO:Add spinner or progress bar..
|
|
230
|
-
return createElement("div", {
|
|
231
|
-
className: "dataviews-loading"
|
|
232
|
-
}, createElement("h3", null, __('Loading')));
|
|
233
|
-
}
|
|
234
216
|
const sortValues = {
|
|
235
217
|
asc: 'ascending',
|
|
236
218
|
desc: 'descending'
|
|
237
219
|
};
|
|
238
|
-
return createElement("div", {
|
|
239
|
-
className: "dataviews-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}, createElement("thead", null, createElement("tr", null, visibleFields.map(field => createElement("th", {
|
|
220
|
+
return createElement("div", null, createElement("table", {
|
|
221
|
+
className: "dataviews-view-table",
|
|
222
|
+
"aria-busy": isLoading,
|
|
223
|
+
"aria-describedby": tableNoticeId
|
|
224
|
+
}, createElement("thead", null, createElement("tr", null, visibleFields.map((field, index) => createElement("th", {
|
|
243
225
|
key: field.id,
|
|
244
226
|
style: {
|
|
245
227
|
width: field.width || undefined,
|
|
@@ -250,13 +232,26 @@ function ViewTable({
|
|
|
250
232
|
"aria-sort": view.sort?.field === field.id && sortValues[view.sort.direction],
|
|
251
233
|
scope: "col"
|
|
252
234
|
}, createElement(HeaderMenu, {
|
|
235
|
+
ref: node => {
|
|
236
|
+
if (node) {
|
|
237
|
+
headerMenuRefs.current.set(field.id, {
|
|
238
|
+
node,
|
|
239
|
+
fallback: visibleFields[index > 0 ? index - 1 : 1]?.id
|
|
240
|
+
});
|
|
241
|
+
} else {
|
|
242
|
+
headerMenuRefs.current.delete(field.id);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
253
245
|
field: field,
|
|
254
246
|
view: view,
|
|
255
|
-
onChangeView: onChangeView
|
|
247
|
+
onChangeView: onChangeView,
|
|
248
|
+
onHide: onHide
|
|
256
249
|
}))), !!actions?.length && createElement("th", {
|
|
257
250
|
"data-field-id": "actions"
|
|
258
|
-
},
|
|
259
|
-
|
|
251
|
+
}, createElement("span", {
|
|
252
|
+
className: "dataviews-view-table-header"
|
|
253
|
+
}, __('Actions'))))), createElement("tbody", null, hasData && usedData.map(item => createElement("tr", {
|
|
254
|
+
key: getItemId(item)
|
|
260
255
|
}, visibleFields.map(field => createElement("td", {
|
|
261
256
|
key: field.id,
|
|
262
257
|
style: {
|
|
@@ -269,9 +264,13 @@ function ViewTable({
|
|
|
269
264
|
}))), !!actions?.length && createElement("td", null, createElement(ItemActions, {
|
|
270
265
|
item: item,
|
|
271
266
|
actions: actions
|
|
272
|
-
})))))),
|
|
273
|
-
className:
|
|
274
|
-
|
|
267
|
+
})))))), createElement("div", {
|
|
268
|
+
className: classNames({
|
|
269
|
+
'dataviews-loading': isLoading,
|
|
270
|
+
'dataviews-no-results': !hasData && !isLoading
|
|
271
|
+
}),
|
|
272
|
+
id: tableNoticeId
|
|
273
|
+
}, !hasData && createElement("p", null, isLoading ? __('Loading…') : __('No results'))));
|
|
275
274
|
}
|
|
276
275
|
export default ViewTable;
|
|
277
276
|
//# sourceMappingURL=view-table.js.map
|