@neovici/cosmoz-omnitable 12.0.2 → 12.2.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/cosmoz-omnitable-column.js +6 -1
- package/cosmoz-omnitable-header-row.js +18 -0
- package/cosmoz-omnitable-styles.js +40 -2
- package/cosmoz-omnitable.js +37 -539
- package/lib/render-footer.js +71 -0
- package/lib/render-header.js +34 -0
- package/lib/render-list.js +62 -0
- package/lib/settings/cosmoz-omnitable-settings.js +1 -2
- package/lib/settings/cosmoz-omnitable-sort-group.js +74 -0
- package/lib/settings/use-settings.js +7 -5
- package/lib/use-dom-columns.js +34 -28
- package/lib/use-fast-layout.js +21 -3
- package/lib/use-footer.js +22 -0
- package/lib/use-header.js +72 -0
- package/lib/use-list.js +214 -0
- package/lib/use-omnitable.js +50 -92
- package/lib/use-processed-items.js +37 -16
- package/lib/use-public-interface.js +96 -0
- package/package.json +1 -1
- package/lib/settings/cosmoz-omnitable-group.js +0 -51
- package/lib/settings/cosmoz-omnitable-sort.js +0 -23
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { html } from 'lit-html';
|
|
2
|
+
import { ngettext, _ } from '@neovici/cosmoz-i18next';
|
|
3
|
+
import { saveAsCsvAction } from './save-as-csv-action';
|
|
4
|
+
import { saveAsXlsxAction } from './save-as-xlsx-action';
|
|
5
|
+
import { isEmpty } from '@neovici/cosmoz-utils/template';
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line max-lines-per-function
|
|
8
|
+
export const renderFooter = ({
|
|
9
|
+
columns,
|
|
10
|
+
selectedItems,
|
|
11
|
+
csvFilename,
|
|
12
|
+
xlsxFilename,
|
|
13
|
+
xlsxSheetname,
|
|
14
|
+
topPlacement
|
|
15
|
+
}) => {
|
|
16
|
+
return html`
|
|
17
|
+
<cosmoz-bottom-bar
|
|
18
|
+
id="bottomBar"
|
|
19
|
+
?active=${!isEmpty(selectedItems.length)}
|
|
20
|
+
>
|
|
21
|
+
<slot name="info" slot="info">
|
|
22
|
+
${ngettext(
|
|
23
|
+
'{0} selected item',
|
|
24
|
+
'{0} selected items',
|
|
25
|
+
selectedItems.length
|
|
26
|
+
)}
|
|
27
|
+
</slot>
|
|
28
|
+
<slot name="actions" id="actions"></slot>
|
|
29
|
+
<!-- These slots are needed by cosmoz-bottom-bar
|
|
30
|
+
as it might change the slot of the actions to distribute them in the menu -->
|
|
31
|
+
<slot name="bottom-bar-toolbar" slot="bottom-bar-toolbar"></slot>
|
|
32
|
+
<slot name="bottom-bar-menu" slot="bottom-bar-menu"></slot>
|
|
33
|
+
<cosmoz-dropdown-menu slot="extra" placement=${topPlacement}>
|
|
34
|
+
<svg
|
|
35
|
+
slot="button"
|
|
36
|
+
width="14"
|
|
37
|
+
height="18"
|
|
38
|
+
viewBox="0 0 14 18"
|
|
39
|
+
fill="none"
|
|
40
|
+
stroke="currentColor"
|
|
41
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
42
|
+
>
|
|
43
|
+
<path
|
|
44
|
+
d="M1 8.5L7.00024 14.5L13 8.5"
|
|
45
|
+
stroke-width="2"
|
|
46
|
+
stroke-linecap="round"
|
|
47
|
+
stroke-linejoin="round"
|
|
48
|
+
/>
|
|
49
|
+
<path d="M13 17L1 17" stroke-width="2" stroke-linecap="round" />
|
|
50
|
+
<path d="M7 1V13" stroke-width="2" stroke-linecap="round" />
|
|
51
|
+
</svg>
|
|
52
|
+
<button
|
|
53
|
+
@click=${() => saveAsCsvAction(columns, selectedItems, csvFilename)}
|
|
54
|
+
>
|
|
55
|
+
${_('Save as CSV')}
|
|
56
|
+
</button>
|
|
57
|
+
<button
|
|
58
|
+
@click=${() =>
|
|
59
|
+
saveAsXlsxAction(
|
|
60
|
+
columns,
|
|
61
|
+
selectedItems,
|
|
62
|
+
xlsxFilename,
|
|
63
|
+
xlsxSheetname
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
${_('Save as XLSX')}
|
|
67
|
+
</button>
|
|
68
|
+
<slot name="download-menu"></slot>
|
|
69
|
+
</cosmoz-dropdown-menu>
|
|
70
|
+
</cosmoz-bottom-bar>`;
|
|
71
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { html } from 'lit-html';
|
|
2
|
+
|
|
3
|
+
export const renderHeader = ({
|
|
4
|
+
allSelected,
|
|
5
|
+
onAllCheckboxChange,
|
|
6
|
+
sortAndGroup,
|
|
7
|
+
dataIsValid,
|
|
8
|
+
data,
|
|
9
|
+
columns,
|
|
10
|
+
filters,
|
|
11
|
+
groupOnColumn,
|
|
12
|
+
setFilterState,
|
|
13
|
+
settingsConfig,
|
|
14
|
+
}) => {
|
|
15
|
+
return html` <sort-and-group-provider .value=${sortAndGroup}>
|
|
16
|
+
<div class="header" id="header">
|
|
17
|
+
<input
|
|
18
|
+
class="checkbox all"
|
|
19
|
+
type="checkbox"
|
|
20
|
+
.checked=${allSelected}
|
|
21
|
+
@input=${onAllCheckboxChange}
|
|
22
|
+
?disabled=${!dataIsValid}
|
|
23
|
+
/>
|
|
24
|
+
<cosmoz-omnitable-header-row
|
|
25
|
+
.data=${data}
|
|
26
|
+
.columns=${columns}
|
|
27
|
+
.filters=${filters}
|
|
28
|
+
.groupOnColumn=${groupOnColumn}
|
|
29
|
+
.setFilterState=${setFilterState}
|
|
30
|
+
.settingsConfig=${settingsConfig}
|
|
31
|
+
></cosmoz-omnitable-header-row>
|
|
32
|
+
</div>
|
|
33
|
+
</sort-and-group-provider>`;
|
|
34
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* eslint-disable max-lines-per-function */
|
|
2
|
+
import { _ } from '@neovici/cosmoz-i18next';
|
|
3
|
+
import { html } from 'lit-html';
|
|
4
|
+
import { when } from 'lit-html/directives/when.js';
|
|
5
|
+
|
|
6
|
+
export const renderList = ({
|
|
7
|
+
processedItems,
|
|
8
|
+
dataIsValid,
|
|
9
|
+
filterIsTooStrict,
|
|
10
|
+
loading,
|
|
11
|
+
displayEmptyGroups,
|
|
12
|
+
compareItemsFn,
|
|
13
|
+
setSelectedItems,
|
|
14
|
+
renderItem,
|
|
15
|
+
renderGroup,
|
|
16
|
+
}) => {
|
|
17
|
+
return html` ${when(
|
|
18
|
+
!dataIsValid,
|
|
19
|
+
() => html` <div class="tableContent-empty">
|
|
20
|
+
<slot name="empty-set-message">
|
|
21
|
+
<iron-icon icon="icons:announcement"></iron-icon>
|
|
22
|
+
<div class="tableContent-empty-message">
|
|
23
|
+
<h3>${_('Working set empty')}</h3>
|
|
24
|
+
<p>${_('No data to display')}</p>
|
|
25
|
+
</div>
|
|
26
|
+
</slot>
|
|
27
|
+
</div>`
|
|
28
|
+
)}
|
|
29
|
+
${when(
|
|
30
|
+
filterIsTooStrict,
|
|
31
|
+
() => html` <div class="tableContent-empty">
|
|
32
|
+
<iron-icon icon="icons:announcement"></iron-icon>
|
|
33
|
+
<div>
|
|
34
|
+
<h3>${_('Filter too strict')}</h3>
|
|
35
|
+
<p>${_('No matches for selection')}</p>
|
|
36
|
+
</div>
|
|
37
|
+
</div>`
|
|
38
|
+
)}
|
|
39
|
+
${when(
|
|
40
|
+
loading,
|
|
41
|
+
() => html` <div class="tableContent-empty overlay">
|
|
42
|
+
<paper-spinner-lite active></paper-spinner-lite>
|
|
43
|
+
<div>
|
|
44
|
+
<h3>${_('Data set is updating')}</h3>
|
|
45
|
+
</div>
|
|
46
|
+
</div>`
|
|
47
|
+
)}
|
|
48
|
+
<div class="tableContent-scroller" id="scroller">
|
|
49
|
+
<cosmoz-grouped-list
|
|
50
|
+
id="groupedList"
|
|
51
|
+
.data=${processedItems}
|
|
52
|
+
@selected-items-changed=${(event) =>
|
|
53
|
+
setSelectedItems(event.detail.value)}
|
|
54
|
+
.displayEmptyGroups=${
|
|
55
|
+
displayEmptyGroups /* TODO: check if still works */
|
|
56
|
+
}
|
|
57
|
+
.compareItemsFn=${compareItemsFn}
|
|
58
|
+
.renderItem=${renderItem}
|
|
59
|
+
.renderGroup=${renderGroup}
|
|
60
|
+
></cosmoz-grouped-list>
|
|
61
|
+
</div>`;
|
|
62
|
+
};
|
|
@@ -4,8 +4,7 @@ import { _ } from '@neovici/cosmoz-i18next';
|
|
|
4
4
|
import { isEmpty } from '@neovici/cosmoz-utils/template';
|
|
5
5
|
import { defaultPlacement } from '@neovici/cosmoz-dropdown';
|
|
6
6
|
import '@neovici/cosmoz-collapse';
|
|
7
|
-
import sort from './cosmoz-omnitable-sort';
|
|
8
|
-
import group from './cosmoz-omnitable-group';
|
|
7
|
+
import { sort, group } from './cosmoz-omnitable-sort-group';
|
|
9
8
|
import style, { dropdown as dropdownStyle } from './style.css';
|
|
10
9
|
import useSettingsUi from './use-settings-ui';
|
|
11
10
|
import { close, pull, arrow } from '../icons';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { html } from 'haunted';
|
|
2
|
+
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
3
|
+
import { triangle } from '../icons';
|
|
4
|
+
|
|
5
|
+
export const render = ({ column, on, descending, setOn, setDescending }) => {
|
|
6
|
+
const { name, title } = column ?? {};
|
|
7
|
+
return html`<button
|
|
8
|
+
class="sg"
|
|
9
|
+
title=${title}
|
|
10
|
+
data-on=${ifDefined(
|
|
11
|
+
(name === on && (descending ? 'desc' : 'asc')) || undefined
|
|
12
|
+
)}
|
|
13
|
+
@click=${(e) => {
|
|
14
|
+
const on = e.currentTarget?.dataset.on;
|
|
15
|
+
if (!on) {
|
|
16
|
+
setOn(name);
|
|
17
|
+
setDescending(false);
|
|
18
|
+
}
|
|
19
|
+
if (on === 'asc') {
|
|
20
|
+
setDescending(true);
|
|
21
|
+
} else if (on === 'desc') {
|
|
22
|
+
setOn();
|
|
23
|
+
setDescending(false);
|
|
24
|
+
}
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
<span>${title}</span> ${triangle}
|
|
28
|
+
</button>`;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const renderAll = ({ columns, ...thru }) =>
|
|
32
|
+
columns?.map((column) => render({ column, ...thru }));
|
|
33
|
+
|
|
34
|
+
export const group = () => html`
|
|
35
|
+
<sort-and-group-consumer
|
|
36
|
+
class="sgs"
|
|
37
|
+
.render=${({
|
|
38
|
+
columns,
|
|
39
|
+
groupOn: on,
|
|
40
|
+
setGroupOn: setOn,
|
|
41
|
+
groupOnDescending: descending,
|
|
42
|
+
setGroupOnDescending: setDescending,
|
|
43
|
+
} = {}) =>
|
|
44
|
+
renderAll({
|
|
45
|
+
columns: columns?.filter?.((c) => c['groupOn']),
|
|
46
|
+
on,
|
|
47
|
+
setOn,
|
|
48
|
+
descending,
|
|
49
|
+
setDescending,
|
|
50
|
+
})}
|
|
51
|
+
>
|
|
52
|
+
</sort-and-group-consumer>
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
export const sort = () => html`
|
|
56
|
+
<sort-and-group-consumer
|
|
57
|
+
class="sgs"
|
|
58
|
+
.render=${({
|
|
59
|
+
columns,
|
|
60
|
+
sortOn: on,
|
|
61
|
+
setSortOn: setOn,
|
|
62
|
+
descending,
|
|
63
|
+
setDescending,
|
|
64
|
+
} = {}) =>
|
|
65
|
+
renderAll({
|
|
66
|
+
columns: columns?.filter?.((c) => c['sortOn']),
|
|
67
|
+
on,
|
|
68
|
+
setOn,
|
|
69
|
+
descending,
|
|
70
|
+
setDescending,
|
|
71
|
+
})}
|
|
72
|
+
>
|
|
73
|
+
</sort-and-group-consumer>
|
|
74
|
+
`;
|
|
@@ -2,10 +2,11 @@ import { useMemo, useState, useRef, useCallback } from 'haunted';
|
|
|
2
2
|
|
|
3
3
|
import useSavedSettings from './use-saved-settings';
|
|
4
4
|
import normalize, { sgProps } from './normalize';
|
|
5
|
+
import { useDOMColumns } from '../use-dom-columns';
|
|
5
6
|
|
|
6
|
-
export default ({ settingsId,
|
|
7
|
+
export default ({ settingsId, host }) => {
|
|
7
8
|
const initial = useMemo(
|
|
8
|
-
() => Object.fromEntries(sgProps.map((k) => [k,
|
|
9
|
+
() => Object.fromEntries(sgProps.map((k) => [k, host[k]])),
|
|
9
10
|
[]
|
|
10
11
|
),
|
|
11
12
|
resetRef = useRef(),
|
|
@@ -20,16 +21,17 @@ export default ({ settingsId, initial: ini, ...thru }) => {
|
|
|
20
21
|
setSettings,
|
|
21
22
|
onReset
|
|
22
23
|
),
|
|
23
|
-
{
|
|
24
|
+
{ enabledColumns } = host,
|
|
25
|
+
columns = useDOMColumns(host, { enabledColumns }),
|
|
24
26
|
normalizedSettings = useMemo(
|
|
25
27
|
() =>
|
|
26
28
|
normalize({
|
|
29
|
+
columns,
|
|
27
30
|
settings,
|
|
28
31
|
savedSettings,
|
|
29
32
|
initial,
|
|
30
|
-
...thru,
|
|
31
33
|
}),
|
|
32
|
-
[settings, savedSettings
|
|
34
|
+
[columns, settings, savedSettings]
|
|
33
35
|
),
|
|
34
36
|
normalizedColumns = useMemo(
|
|
35
37
|
() =>
|
package/lib/use-dom-columns.js
CHANGED
|
@@ -1,48 +1,56 @@
|
|
|
1
|
-
import { useEffect, useState } from 'haunted';
|
|
1
|
+
import { useEffect, useLayoutEffect, useState } from 'haunted';
|
|
2
2
|
import { memooize } from './memoize';
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
verifyColumnSetup = columns => {
|
|
4
|
+
const columnSymbol = Symbol('column'),
|
|
5
|
+
verifyColumnSetup = (columns) => {
|
|
7
6
|
let ok = true;
|
|
8
|
-
const columnNames = columns.map(c => c.name);
|
|
7
|
+
const columnNames = columns.map((c) => c.name);
|
|
9
8
|
// Check if column names are set
|
|
10
|
-
columns.forEach(column => {
|
|
9
|
+
columns.forEach((column) => {
|
|
11
10
|
if (column.name != null) {
|
|
12
11
|
return;
|
|
13
12
|
}
|
|
14
13
|
ok = false;
|
|
15
14
|
// eslint-disable-next-line no-console
|
|
16
|
-
console.error(
|
|
15
|
+
console.error(
|
|
16
|
+
'The name attribute needs to be set on all columns! Missing on column',
|
|
17
|
+
column
|
|
18
|
+
);
|
|
17
19
|
});
|
|
18
20
|
|
|
19
|
-
columns.forEach(column => {
|
|
20
|
-
if (
|
|
21
|
+
columns.forEach((column) => {
|
|
22
|
+
if (
|
|
23
|
+
columnNames.indexOf(column.name) ===
|
|
24
|
+
columnNames.lastIndexOf(column.name)
|
|
25
|
+
) {
|
|
21
26
|
return;
|
|
22
27
|
}
|
|
23
28
|
ok = false;
|
|
24
29
|
// eslint-disable-next-line no-console
|
|
25
|
-
console.error(
|
|
30
|
+
console.error(
|
|
31
|
+
'The name attribute needs to be unique among all columns! Not unique on column',
|
|
32
|
+
column
|
|
33
|
+
);
|
|
26
34
|
});
|
|
27
35
|
return ok;
|
|
28
36
|
},
|
|
29
|
-
|
|
30
37
|
// eslint-disable-next-line max-lines-per-function
|
|
31
38
|
domColumnsToConfig = (host, { enabledColumns }) => {
|
|
32
|
-
const domColumns = host.shadowRoot
|
|
39
|
+
const domColumns = host.shadowRoot
|
|
40
|
+
.querySelector('#columnsSlot')
|
|
33
41
|
.assignedElements({ flatten: true })
|
|
34
|
-
.filter(child => child.isOmnitableColumn && !child.hidden);
|
|
42
|
+
.filter((child) => child.isOmnitableColumn && !child.hidden);
|
|
35
43
|
|
|
36
44
|
if (!verifyColumnSetup(domColumns)) {
|
|
37
45
|
return [];
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
const columns = Array.isArray(enabledColumns)
|
|
41
|
-
? domColumns.filter(column => enabledColumns.includes(column.name))
|
|
42
|
-
: domColumns.filter(column => !column.disabled);
|
|
49
|
+
? domColumns.filter((column) => enabledColumns.includes(column.name))
|
|
50
|
+
: domColumns.filter((column) => !column.disabled);
|
|
43
51
|
|
|
44
52
|
// eslint-disable-next-line max-lines-per-function
|
|
45
|
-
return columns.map(column => ({
|
|
53
|
+
return columns.map((column) => ({
|
|
46
54
|
name: column.name,
|
|
47
55
|
title: column.title,
|
|
48
56
|
|
|
@@ -109,18 +117,20 @@ const
|
|
|
109
117
|
ownerTree: column.ownerTree,
|
|
110
118
|
keyProperty: column.keyProperty,
|
|
111
119
|
|
|
112
|
-
[columnSymbol]: column
|
|
120
|
+
[columnSymbol]: column,
|
|
113
121
|
}));
|
|
114
122
|
},
|
|
115
|
-
|
|
116
123
|
useDOMColumns = (host, { enabledColumns }) => {
|
|
117
|
-
const
|
|
118
|
-
|
|
124
|
+
const [columns, setColumns] = useState([]);
|
|
125
|
+
|
|
126
|
+
useLayoutEffect(() => {
|
|
127
|
+
setColumns(domColumnsToConfig(host, { enabledColumns }));
|
|
128
|
+
}, []);
|
|
119
129
|
|
|
120
130
|
useEffect(() => {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
const slot = host.shadowRoot.querySelector('#columnsSlot'),
|
|
132
|
+
handler = () =>
|
|
133
|
+
setColumns(domColumnsToConfig(host, { enabledColumns }));
|
|
124
134
|
|
|
125
135
|
handler();
|
|
126
136
|
slot.addEventListener('slotchange', handler);
|
|
@@ -134,8 +144,4 @@ const
|
|
|
134
144
|
return columns;
|
|
135
145
|
};
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
export {
|
|
139
|
-
columnSymbol,
|
|
140
|
-
useDOMColumns
|
|
141
|
-
};
|
|
147
|
+
export { columnSymbol, useDOMColumns };
|
package/lib/use-fast-layout.js
CHANGED
|
@@ -8,12 +8,14 @@ import { render } from 'lit-html';
|
|
|
8
8
|
|
|
9
9
|
export const useFastLayout = ({
|
|
10
10
|
host,
|
|
11
|
+
columns,
|
|
11
12
|
settings,
|
|
12
13
|
setSettings,
|
|
13
|
-
groupOnColumn,
|
|
14
14
|
resizeSpeedFactor,
|
|
15
|
+
sortAndGroupOptions,
|
|
15
16
|
}) => {
|
|
16
17
|
const canvasWidth = useCanvasWidth(host),
|
|
18
|
+
{ groupOnColumn } = sortAndGroupOptions,
|
|
17
19
|
layout = useLayout({
|
|
18
20
|
canvasWidth,
|
|
19
21
|
groupOnColumn,
|
|
@@ -23,6 +25,19 @@ export const useFastLayout = ({
|
|
|
23
25
|
layoutCss = useMemo(
|
|
24
26
|
() => toCss(tweenedlayout, settings.columns),
|
|
25
27
|
[tweenedlayout]
|
|
28
|
+
),
|
|
29
|
+
collapsedColumns = useMemo(
|
|
30
|
+
() =>
|
|
31
|
+
settings.columns.reduce(
|
|
32
|
+
(acc, column, index) =>
|
|
33
|
+
layout[index] != null ||
|
|
34
|
+
column.name === groupOnColumn?.name ||
|
|
35
|
+
column.disabled
|
|
36
|
+
? acc
|
|
37
|
+
: [...acc, columns.find((c) => c.name === column.name)],
|
|
38
|
+
[]
|
|
39
|
+
),
|
|
40
|
+
[columns, settings, layout]
|
|
26
41
|
);
|
|
27
42
|
|
|
28
43
|
useResizableColumns({
|
|
@@ -32,7 +47,10 @@ export const useFastLayout = ({
|
|
|
32
47
|
setSettings: (update) => setSettings(update(settings)),
|
|
33
48
|
});
|
|
34
49
|
|
|
35
|
-
useLayoutEffect(
|
|
50
|
+
useLayoutEffect(
|
|
51
|
+
() => render(layoutCss, host.shadowRoot.querySelector('#layoutStyle')),
|
|
52
|
+
[layoutCss]
|
|
53
|
+
);
|
|
36
54
|
|
|
37
|
-
return
|
|
55
|
+
return { collapsedColumns };
|
|
38
56
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defaultPlacement } from '@neovici/cosmoz-dropdown';
|
|
2
|
+
const _defaultPlacement = ['top-right', ...defaultPlacement];
|
|
3
|
+
|
|
4
|
+
export const useFooter = ({
|
|
5
|
+
host,
|
|
6
|
+
...rest
|
|
7
|
+
}) => {
|
|
8
|
+
const {
|
|
9
|
+
csvFilename = 'omnitable.csv',
|
|
10
|
+
xlsxFilename = 'omnitable.xlsx',
|
|
11
|
+
xlsxSheetname = 'Omnitable',
|
|
12
|
+
topPlacement = _defaultPlacement,
|
|
13
|
+
} = host;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
csvFilename,
|
|
17
|
+
xlsxFilename,
|
|
18
|
+
xlsxSheetname,
|
|
19
|
+
topPlacement,
|
|
20
|
+
...rest,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* eslint-disable max-lines-per-function */
|
|
2
|
+
import { useEffect, useMemo } from 'haunted';
|
|
3
|
+
|
|
4
|
+
export const useHeader = ({
|
|
5
|
+
host,
|
|
6
|
+
selectedItems,
|
|
7
|
+
data,
|
|
8
|
+
sortAndGroupOptions,
|
|
9
|
+
collapsedColumns,
|
|
10
|
+
settings,
|
|
11
|
+
filterFunctions,
|
|
12
|
+
settingS,
|
|
13
|
+
filters,
|
|
14
|
+
...rest
|
|
15
|
+
}) => {
|
|
16
|
+
const allSelected =
|
|
17
|
+
data && data.length > 0 && selectedItems.length === data.length,
|
|
18
|
+
onAllCheckboxChange = (event) => {
|
|
19
|
+
if (event.target.checked) {
|
|
20
|
+
host.shadowRoot.querySelector('#groupedList').selectAll();
|
|
21
|
+
} else {
|
|
22
|
+
host.shadowRoot.querySelector('#groupedList').deselectAll();
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{ groupOnColumn } = sortAndGroupOptions,
|
|
26
|
+
hasHiddenFilter = useMemo(
|
|
27
|
+
() =>
|
|
28
|
+
[
|
|
29
|
+
groupOnColumn,
|
|
30
|
+
...collapsedColumns,
|
|
31
|
+
...settings.columns.filter((s) => s.disabled),
|
|
32
|
+
].some(
|
|
33
|
+
(column) =>
|
|
34
|
+
column && Object.keys(filterFunctions).includes(column.name)
|
|
35
|
+
),
|
|
36
|
+
[filterFunctions, settings, collapsedColumns]
|
|
37
|
+
),
|
|
38
|
+
settingsConfig = useMemo(
|
|
39
|
+
() => ({
|
|
40
|
+
...settingS,
|
|
41
|
+
collapsed: collapsedColumns,
|
|
42
|
+
badge: hasHiddenFilter,
|
|
43
|
+
filters,
|
|
44
|
+
}),
|
|
45
|
+
[settingS, collapsedColumns, hasHiddenFilter, filters]
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const el = host.shadowRoot.querySelector('#tableContent'),
|
|
50
|
+
observer = new ResizeObserver((entries) =>
|
|
51
|
+
requestAnimationFrame(() => {
|
|
52
|
+
host.style.setProperty(
|
|
53
|
+
'--ot-height',
|
|
54
|
+
entries[0]?.contentRect.height + 'px'
|
|
55
|
+
);
|
|
56
|
+
})
|
|
57
|
+
);
|
|
58
|
+
observer.observe(el);
|
|
59
|
+
return () => observer.unobserve(el);
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
allSelected,
|
|
64
|
+
onAllCheckboxChange,
|
|
65
|
+
data,
|
|
66
|
+
settingsConfig,
|
|
67
|
+
filters,
|
|
68
|
+
groupOnColumn,
|
|
69
|
+
sortAndGroup: sortAndGroupOptions.sortAndGroup,
|
|
70
|
+
...rest,
|
|
71
|
+
};
|
|
72
|
+
};
|