@likable-hair/svelte 4.0.6 → 4.0.7
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/dist/components/composed/common/QuickActions.css +2 -0
- package/dist/components/composed/common/QuickActions.svelte +34 -14
- package/dist/components/composed/common/QuickActions.svelte.d.ts +4 -8
- package/dist/components/composed/list/DynamicTable.svelte +112 -83
- package/dist/components/composed/list/DynamicTable.svelte.d.ts +11 -3
- package/dist/components/composed/list/PaginatedTable.svelte +8 -2
- package/dist/components/composed/list/PaginatedTable.svelte.d.ts +1 -0
- package/dist/components/composed/search/DynamicFilters.svelte +96 -85
- package/dist/components/composed/search/DynamicFilters.svelte.d.ts +10 -8
- package/dist/components/composed/search/FilterEditor.svelte +2 -1
- package/dist/components/composed/search/Filters.css +1 -0
- package/dist/components/composed/search/Filters.svelte +11 -4
- package/dist/components/simple/lists/SimpleTable.svelte +5 -2
- package/dist/components/simple/lists/SimpleTable.svelte.d.ts +6 -0
- package/package.json +1 -1
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
--quick-actions-default-background-color: rgb(var(--global-color-background-200));
|
|
3
3
|
--quick-actions-default-selected-items-button-background-color: rgb(var(--global-color-background-500));
|
|
4
4
|
--quick-actions-default-selected-items-button-background-color-hover: rgb(var(--global-color-background-300));
|
|
5
|
+
--quick-actions-default-selected-items-button-background-color-disabled: rgb(var(--global-color-background-300), .5);
|
|
6
|
+
--quick-actions-default-selected-items-button-color-disabled: rgb(var(--global-color-contrast-900), .5);
|
|
5
7
|
--quick-actions-default-z-index: 48;
|
|
6
8
|
|
|
7
9
|
--quick-actions-default-buttons-background-color: var(--quick-actions-background-color, var(--quick-actions-default-background-color));
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
</script>
|
|
3
3
|
|
|
4
4
|
<script lang="ts">import { Button, Icon, mediaQuery, ToolTip } from "../../..";
|
|
5
|
-
import DynamicTable from "../list/DynamicTable.svelte";
|
|
6
5
|
import { fly } from "svelte/transition";
|
|
7
6
|
import { cubicIn } from "svelte/easing";
|
|
8
7
|
import MenuOrDrawer from "./MenuOrDrawer.svelte";
|
|
9
8
|
import './QuickActions.css';
|
|
10
|
-
let { selectedItems,
|
|
11
|
-
let actions = $state([]), extraActions = $state([]), moreActionsActivator = $state(), openMoreActions = $state(false), infoActivators = $state({}), disabledInfoActivators = $state({});
|
|
9
|
+
let { selectedItems, disabled, actionsForSelectedItems, position = 'top', lang = 'en', onClose, } = $props();
|
|
10
|
+
let actions = $state([]), extraActions = $state([]), slotSelectActionsContainer = $state(), moreActionsActivator = $state(), openMoreActions = $state(false), infoActivators = $state({}), disabledInfoActivators = $state({});
|
|
12
11
|
$effect(() => {
|
|
13
12
|
if (!!slotSelectActionsContainer) {
|
|
14
13
|
let numberOfSplit = $mediaQuery.xl ? 5 :
|
|
@@ -28,7 +27,7 @@ $effect(() => {
|
|
|
28
27
|
});
|
|
29
28
|
</script>
|
|
30
29
|
|
|
31
|
-
{#if selectedItems
|
|
30
|
+
{#if selectedItems > 0}
|
|
32
31
|
<div
|
|
33
32
|
class="container-{position}"
|
|
34
33
|
transition:fly={{ delay: 150, duration: 150, y: -10, easing: cubicIn }}
|
|
@@ -37,8 +36,13 @@ $effect(() => {
|
|
|
37
36
|
class="select-container"
|
|
38
37
|
>
|
|
39
38
|
<div>
|
|
40
|
-
<button class="select-info" onclick={() =>
|
|
41
|
-
|
|
39
|
+
<button class="select-info" {disabled} onclick={() => {
|
|
40
|
+
infoActivators = {}
|
|
41
|
+
disabledInfoActivators = {}
|
|
42
|
+
if(onClose) onClose()
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{selectedItems} {lang == 'en' ? 'items selected' : 'righe selezionate'}
|
|
42
46
|
<Icon name="mdi-close" />
|
|
43
47
|
</button>
|
|
44
48
|
</div>
|
|
@@ -59,7 +63,9 @@ $effect(() => {
|
|
|
59
63
|
--button-box-shadow: none;
|
|
60
64
|
'
|
|
61
65
|
--button-height="20px"
|
|
62
|
-
|
|
66
|
+
--circular-loader-height="17px"
|
|
67
|
+
disabled={action.disabled || action.loading || disabled}
|
|
68
|
+
loading={action.loading}
|
|
63
69
|
onclick={action.onClick}
|
|
64
70
|
>
|
|
65
71
|
<div class="action" bind:this={disabledInfoActivators[action.label]}>
|
|
@@ -74,7 +80,7 @@ $effect(() => {
|
|
|
74
80
|
/>
|
|
75
81
|
</div>
|
|
76
82
|
<ToolTip
|
|
77
|
-
appearTimeout={
|
|
83
|
+
appearTimeout={500}
|
|
78
84
|
activator={infoActivators[action.label]}
|
|
79
85
|
>
|
|
80
86
|
<div
|
|
@@ -90,7 +96,7 @@ $effect(() => {
|
|
|
90
96
|
{action.label}
|
|
91
97
|
{#if !!action.disabledInfo && action.disabled}
|
|
92
98
|
<ToolTip
|
|
93
|
-
appearTimeout={
|
|
99
|
+
appearTimeout={300}
|
|
94
100
|
activator={disabledInfoActivators[action.label]}
|
|
95
101
|
>
|
|
96
102
|
<div
|
|
@@ -124,7 +130,6 @@ $effect(() => {
|
|
|
124
130
|
margin-left: 8px;
|
|
125
131
|
'
|
|
126
132
|
--button-height="20px"
|
|
127
|
-
disabled={disabled || loading}
|
|
128
133
|
onclick={(e) => {
|
|
129
134
|
openMoreActions = !openMoreActions;
|
|
130
135
|
}}
|
|
@@ -172,8 +177,10 @@ $effect(() => {
|
|
|
172
177
|
--button-disabled-color: var(--quick-actions-buttons-color-disabled, var(--quick-actions-default-buttons-color-disabled));
|
|
173
178
|
--button-box-shadow: none;
|
|
174
179
|
'
|
|
175
|
-
--button-height="
|
|
176
|
-
|
|
180
|
+
--button-height="30px"
|
|
181
|
+
--circular-loader-height="25px"
|
|
182
|
+
disabled={action.disabled || action.loading || disabled}
|
|
183
|
+
loading={action.loading}
|
|
177
184
|
onclick={action.onClick}
|
|
178
185
|
>
|
|
179
186
|
<div class="action" bind:this={disabledInfoActivators[action.label]}>
|
|
@@ -188,7 +195,7 @@ $effect(() => {
|
|
|
188
195
|
/>
|
|
189
196
|
</div>
|
|
190
197
|
<ToolTip
|
|
191
|
-
appearTimeout={
|
|
198
|
+
appearTimeout={500}
|
|
192
199
|
activator={infoActivators[action.label]}
|
|
193
200
|
>
|
|
194
201
|
<div
|
|
@@ -204,7 +211,7 @@ $effect(() => {
|
|
|
204
211
|
{action.label}
|
|
205
212
|
{#if !!action.disabledInfo && action.disabled}
|
|
206
213
|
<ToolTip
|
|
207
|
-
appearTimeout={
|
|
214
|
+
appearTimeout={300}
|
|
208
215
|
activator={disabledInfoActivators[action.label]}
|
|
209
216
|
>
|
|
210
217
|
<div
|
|
@@ -292,6 +299,19 @@ $effect(() => {
|
|
|
292
299
|
--quick-actions-selected-items-button-background-color-hover,
|
|
293
300
|
var(--quick-actions-default-selected-items-button-background-color-hover)
|
|
294
301
|
);
|
|
302
|
+
cursor: pointer;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.select-info:disabled {
|
|
306
|
+
background-color: var(
|
|
307
|
+
--quick-actions-selected-items-button-background-color-disabled,
|
|
308
|
+
var(--quick-actions-default-selected-items-button-background-color-disabled)
|
|
309
|
+
);
|
|
310
|
+
color: var(
|
|
311
|
+
--quick-actions-selected-items-button-color-disabled,
|
|
312
|
+
var(--quick-actions-default-selected-items-button-color-disabled)
|
|
313
|
+
);
|
|
314
|
+
cursor: not-allowed;
|
|
295
315
|
}
|
|
296
316
|
|
|
297
317
|
.select-actions-container {
|
|
@@ -2,26 +2,22 @@ export type Action = {
|
|
|
2
2
|
label: string;
|
|
3
3
|
icon?: string;
|
|
4
4
|
disabled?: boolean;
|
|
5
|
+
loading?: boolean;
|
|
5
6
|
info?: string;
|
|
6
7
|
disabledInfo?: string;
|
|
7
8
|
onClick: NonNullable<ComponentProps<typeof Button>['onclick']>;
|
|
8
9
|
};
|
|
9
10
|
import { Button } from "../../..";
|
|
10
11
|
import type { ComponentProps } from "svelte";
|
|
11
|
-
import DynamicTable from "../list/DynamicTable.svelte";
|
|
12
12
|
import './QuickActions.css';
|
|
13
13
|
interface Props {
|
|
14
|
-
selectedItems:
|
|
15
|
-
showSelectContainer: boolean;
|
|
16
|
-
isSelectedAll: boolean;
|
|
17
|
-
totalRows: number;
|
|
18
|
-
slotSelectActionsContainer?: HTMLElement;
|
|
14
|
+
selectedItems: number;
|
|
19
15
|
disabled: boolean;
|
|
20
|
-
loading: boolean;
|
|
21
16
|
actionsForSelectedItems: Action[];
|
|
22
17
|
position?: 'top' | 'bottom';
|
|
23
18
|
lang?: 'it' | 'en';
|
|
19
|
+
onClose?: () => void;
|
|
24
20
|
}
|
|
25
|
-
declare const QuickActions: import("svelte").Component<Props, {}, "
|
|
21
|
+
declare const QuickActions: import("svelte").Component<Props, {}, "">;
|
|
26
22
|
type QuickActions = ReturnType<typeof QuickActions>;
|
|
27
23
|
export default QuickActions;
|
|
@@ -25,25 +25,23 @@ onMount(() => {
|
|
|
25
25
|
updateHeaderHeight();
|
|
26
26
|
window.addEventListener('resize', updateHeaderHeight);
|
|
27
27
|
tableContainer?.addEventListener("scroll", setReachedBottomOrTop);
|
|
28
|
-
if (tableContainer?.scrollHeight && tableContainer.clientHeight
|
|
29
|
-
tableContainer.
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
resizeHeader(th, head);
|
|
42
|
-
}
|
|
28
|
+
if (tableContainer?.scrollHeight && tableContainer.clientHeight) {
|
|
29
|
+
hideScrollbar = tableContainer.scrollHeight > tableContainer.clientHeight;
|
|
30
|
+
}
|
|
31
|
+
for (const head of [...headers, { value: 'non-resizable', minWidth: DEFAULT_MIN_WIDTH_PX + 'px', maxWidth: DEFAULT_MAX_WIDTH_PX + 'px' }, { value: 'slot-append', minWidth: DEFAULT_MIN_WIDTH_PX + 'px', maxWidth: DEFAULT_MAX_WIDTH_PX + 'px' }]) {
|
|
32
|
+
let th;
|
|
33
|
+
if (head.value == 'non-resizable' || head.value == 'slot-append') {
|
|
34
|
+
th = document.getElementsByClassName(head.value).item(0);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
th = document.getElementById(head.value);
|
|
38
|
+
}
|
|
39
|
+
if (!!th) {
|
|
40
|
+
resizeHeader(th, head);
|
|
43
41
|
}
|
|
44
|
-
let table = document.getElementsByClassName('table')[0];
|
|
45
|
-
table.classList.add('resizable');
|
|
46
42
|
}
|
|
43
|
+
let table = document.getElementsByClassName('table')[0];
|
|
44
|
+
table.classList.add('resizable');
|
|
47
45
|
return () => {
|
|
48
46
|
window.removeEventListener('resize', updateHeaderHeight);
|
|
49
47
|
tableContainer?.removeEventListener("scroll", setReachedBottomOrTop);
|
|
@@ -60,6 +58,7 @@ function setReachedBottomOrTop() {
|
|
|
60
58
|
if (tableContainer) {
|
|
61
59
|
reachedBottom = tableContainer.scrollHeight - tableContainer.scrollTop === tableContainer.clientHeight;
|
|
62
60
|
reachedTop = tableContainer.scrollTop === 0;
|
|
61
|
+
hideScrollbar = tableContainer.scrollHeight > tableContainer.clientHeight;
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
$effect(() => {
|
|
@@ -95,8 +94,8 @@ const [send, receive] = crossfade({
|
|
|
95
94
|
};
|
|
96
95
|
},
|
|
97
96
|
});
|
|
98
|
-
let { headers = [], headersToShowInTable = headers, subHeaders = [], customizeHeaders = false, rows = [], sortedBy = $bindable(), sortDirection = $bindable("asc"), cellEdit = false, lang = "en", noItemsText = lang == 'en' ? "No items to show" : 'Nessun elemento da visualizzare', showSelect = false,
|
|
99
|
-
let openCellEditor = $state(false), cellEditorActivator = $state(), cellEditorContainer = $state(), menuElementCellEditor = $state(), menuElementQuickFilters = $state(), cellEditorInfoActive = $state(), saveEditDisabled = $state(false), searchBarInput = $state(undefined), openQuickFilter = $state(false), quickFilterActivator = $state(), quickFilterActive = $state(), globalBuilder = new FilterBuilder(),
|
|
97
|
+
let { headers = [], headersToShowInTable = headers, subHeaders = [], customizeHeaders = false, rows = [], sortedBy = $bindable(), sortDirection = $bindable("asc"), cellEdit = false, lang = "en", dateLocale, noItemsText = lang == 'en' ? "No items to show" : 'Nessun elemento da visualizzare', showSelect = false, showActions = true, selectMode = "single", selectedItems = $bindable([]), unselectedItems = $bindable([]), selectedAll = $bindable(false), showExpand = false, loading = false, disabled = false, filters = $bindable([]), searchBarColumns, searchBarVisible = false, searchBarPlaceholder = lang == 'en' ? "Type to search..." : "Scrivi per cercare...", filtersVisible = false, quickFiltersVisible = false, editFilterMode = "one-edit", showActiveFilters = true, quickFilters = [], actionsForSelectedItems = [], quickActionsDisabled = false, totalRows = rows.length, searchText = $bindable(), renderedRowsNumber = 100, sectionRowsNumber = 20, sectionThreshold = 2, backwardThresholdPixel = 100, forwardThresholdPixel = 100, uniqueKey = 'id', numberOfResultsVisible = false, endLineVisible = false, resizableColumns = false, resizedColumnSizeWithPadding = {}, class: clazz = {}, onapplyCustomQuickFilter, oncellClick, onfetchData, onfiltersChange, onsort, onremoveAllFilters, onremoveCustomQuickFilter, onremoveFilter, onrowClick, onsaveCellEdit, onsaveHeadersToShow, oncolumnResize, searchBarSnippet, customFilterChipSnippet, customFilterSnippet, filterAppendSnippet, onscroll, selectionSnippet: selectionInternalSnippet, itemLabelSnippet: itemLabelInternalSnippet, chipLabelSnippet, headerSnippet, headerLabelSnippet, rowAppendSnippet, rowActionsSnippet, customRowSnippet, subRowAppendSnippet, subHeaderLabelSnippet, subHeaderSnippet, subRowActionsSnippet, customSubRowSnippet, customQuickFilterSnippet, appendSnippet, } = $props();
|
|
98
|
+
let openCellEditor = $state(false), cellEditorActivator = $state(), cellEditorContainer = $state(), menuElementCellEditor = $state(), menuElementQuickFilters = $state(), cellEditorInfoActive = $state(), saveEditDisabled = $state(false), searchBarInput = $state(undefined), openQuickFilter = $state(false), quickFilterActivator = $state(), quickFilterActive = $state(), globalBuilder = new FilterBuilder(), calendarOpened = $state(false), calendarOpened2 = $state(false), selectedIndexes = [], cellEditorIndexRow = $state(), cellEditorIndexHeader = $state(), cellEditorSubItem = $state(), currentSectionNumber = $state(0), tableBody = $state(), tableContainer = $state(), userScrolling = $state(true), reachedBottom = $state(false), reachedTop = false, resizing = false, remainingWidth = $state(0), hideScrollbar = $state(false), sortModify;
|
|
100
99
|
const DEFAULT_MIN_WIDTH_PX = 100, DEFAULT_MAX_WIDTH_PX = 400;
|
|
101
100
|
let totalSections = $derived((totalRows - renderedRowsNumber) / sectionRowsNumber);
|
|
102
101
|
let hasMoreToRender = $derived(totalSections > currentSectionNumber);
|
|
@@ -137,11 +136,13 @@ function handleHeaderClick(header) {
|
|
|
137
136
|
sortDirection = "desc";
|
|
138
137
|
else if (sortDirection == "desc") {
|
|
139
138
|
sortedBy = undefined;
|
|
139
|
+
sortModify = undefined;
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
143
143
|
sortedBy = header.value;
|
|
144
144
|
sortDirection = "asc";
|
|
145
|
+
sortModify = header.sortModify;
|
|
145
146
|
}
|
|
146
147
|
handleSearchChange(searchText);
|
|
147
148
|
if (onsort) {
|
|
@@ -231,15 +232,21 @@ function handleCancelClick() {
|
|
|
231
232
|
openQuickFilter = false;
|
|
232
233
|
}
|
|
233
234
|
function handleSelect(item, shiftKeyPressed) {
|
|
234
|
-
let index =
|
|
235
|
-
|
|
235
|
+
let index = -1;
|
|
236
|
+
if (selectedAll) {
|
|
237
|
+
index = unselectedItems.findIndex((i) => i[uniqueKey] == item[uniqueKey]);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
index = selectedItems.findIndex((i) => i[uniqueKey] == item[uniqueKey]);
|
|
241
|
+
}
|
|
242
|
+
// if item is not in the selected/unselected items array, add it
|
|
236
243
|
if (index == -1) {
|
|
237
244
|
if (selectMode == "single") {
|
|
238
245
|
selectedItems = [item];
|
|
239
246
|
selectedIndexes = [rows.findIndex(r => r.item[uniqueKey] == item[uniqueKey])];
|
|
240
247
|
}
|
|
241
248
|
else if (selectMode == "multiple") {
|
|
242
|
-
if (shiftKeyPressed && selectedIndexes.length > 0
|
|
249
|
+
if (shiftKeyPressed && selectedIndexes.length > 0) {
|
|
243
250
|
let lastSelectedIndex = selectedIndexes[selectedIndexes.length - 1], selectedIndex = rows.findIndex(r => r.item[uniqueKey] == item[uniqueKey]);
|
|
244
251
|
if (selectedIndex != -1) {
|
|
245
252
|
if (selectedIndex < lastSelectedIndex) {
|
|
@@ -248,35 +255,46 @@ function handleSelect(item, shiftKeyPressed) {
|
|
|
248
255
|
selectedIndex = x;
|
|
249
256
|
}
|
|
250
257
|
for (let i = lastSelectedIndex + 1; i <= selectedIndex; i++) {
|
|
251
|
-
if (
|
|
252
|
-
|
|
258
|
+
if (selectedAll) {
|
|
259
|
+
if (!unselectedItems.find((unselectedItem) => unselectedItem[uniqueKey] == rows[i].item[uniqueKey])) {
|
|
260
|
+
unselectedItems = [...unselectedItems, rows[i].item];
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
if (!selectedItems.find((selectedItem) => selectedItem[uniqueKey] == rows[i].item[uniqueKey])) {
|
|
265
|
+
selectedItems = [...selectedItems, rows[i].item];
|
|
266
|
+
}
|
|
253
267
|
}
|
|
254
268
|
}
|
|
255
269
|
}
|
|
256
270
|
}
|
|
257
271
|
else {
|
|
258
|
-
|
|
272
|
+
if (selectedAll) {
|
|
273
|
+
unselectedItems = [...unselectedItems, item];
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
selectedItems = [...selectedItems, item];
|
|
277
|
+
}
|
|
259
278
|
selectedIndexes.push(rows.findIndex(r => r.item[uniqueKey] == item[uniqueKey]));
|
|
260
279
|
}
|
|
261
280
|
}
|
|
262
281
|
}
|
|
263
282
|
else {
|
|
264
|
-
|
|
283
|
+
if (selectedAll) {
|
|
284
|
+
unselectedItems = unselectedItems.filter((i) => i[uniqueKey] != item[uniqueKey]);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
selectedItems = selectedItems.filter((i) => i[uniqueKey] != item[uniqueKey]);
|
|
288
|
+
}
|
|
265
289
|
selectedIndexes = selectedIndexes.filter(r => r != rows.findIndex(r => r.item[uniqueKey] == item[uniqueKey]));
|
|
266
|
-
isSelectedAll = false;
|
|
267
290
|
}
|
|
268
291
|
}
|
|
269
292
|
function handleSelectAll() {
|
|
270
293
|
if (selectMode == "multiple") {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
selectedItems = rows.map((r) => r.item);
|
|
278
|
-
isSelectedAll = true;
|
|
279
|
-
}
|
|
294
|
+
selectedItems = [];
|
|
295
|
+
selectedIndexes = [];
|
|
296
|
+
unselectedItems = [];
|
|
297
|
+
selectedAll = !selectedAll;
|
|
280
298
|
}
|
|
281
299
|
}
|
|
282
300
|
function expandRow(row) {
|
|
@@ -309,13 +327,6 @@ $effect(() => {
|
|
|
309
327
|
else {
|
|
310
328
|
saveEditDisabled = false;
|
|
311
329
|
}
|
|
312
|
-
if (!!isSelectedAll &&
|
|
313
|
-
rows.length > 0 &&
|
|
314
|
-
!loading &&
|
|
315
|
-
!disabled &&
|
|
316
|
-
selectedItems.length < rows.length) {
|
|
317
|
-
selectedItems = rows.map((r) => r.item);
|
|
318
|
-
}
|
|
319
330
|
});
|
|
320
331
|
function searchTextBuilder(searchText) {
|
|
321
332
|
let builder;
|
|
@@ -331,9 +342,6 @@ function searchTextBuilder(searchText) {
|
|
|
331
342
|
}
|
|
332
343
|
});
|
|
333
344
|
}
|
|
334
|
-
if (!!sortedBy) {
|
|
335
|
-
builder.orderBy(sortedBy, sortDirection || "asc");
|
|
336
|
-
}
|
|
337
345
|
return builder;
|
|
338
346
|
}
|
|
339
347
|
let syncTimer;
|
|
@@ -358,6 +366,14 @@ function handleFiltersChange() {
|
|
|
358
366
|
tableContainer.scrollTop = 0;
|
|
359
367
|
setTimeout(() => userScrolling = true, 20);
|
|
360
368
|
}
|
|
369
|
+
if (!!sortedBy) {
|
|
370
|
+
if (sortModify) {
|
|
371
|
+
globalBuilder = sortModify({ builder: globalBuilder, sortDirection });
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
globalBuilder.orderBy(sortedBy, sortDirection || "asc");
|
|
375
|
+
}
|
|
376
|
+
}
|
|
361
377
|
if (onfiltersChange) {
|
|
362
378
|
onfiltersChange({
|
|
363
379
|
detail: {
|
|
@@ -630,9 +646,6 @@ function quickFilterBuilder(builder, quickFilter, clearPreaviousValue = true) {
|
|
|
630
646
|
}
|
|
631
647
|
}
|
|
632
648
|
}
|
|
633
|
-
if (!!sortedBy) {
|
|
634
|
-
builder.orderBy(sortedBy, sortDirection || "asc");
|
|
635
|
-
}
|
|
636
649
|
return builder;
|
|
637
650
|
}
|
|
638
651
|
function updateFilterValues(filter, updateMultiFilterValues) {
|
|
@@ -663,10 +676,7 @@ function updateFilterValues(filter, updateMultiFilterValues) {
|
|
|
663
676
|
}
|
|
664
677
|
updateMultiFilterValues(filter.name, newValue, newValid, newMode);
|
|
665
678
|
}
|
|
666
|
-
function handleRemoveAllFilters(
|
|
667
|
-
if (!!removeAllFilters) {
|
|
668
|
-
removeAllFilters();
|
|
669
|
-
}
|
|
679
|
+
function handleRemoveAllFilters() {
|
|
670
680
|
if (onremoveAllFilters) {
|
|
671
681
|
onremoveAllFilters();
|
|
672
682
|
}
|
|
@@ -879,17 +889,19 @@ function resizeHeader(th, header) {
|
|
|
879
889
|
</script>
|
|
880
890
|
|
|
881
891
|
{#if !!rows && Array.isArray(rows) && !!headersToShowInTable && Array.isArray(headersToShowInTable)}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
892
|
+
{#if showActions}
|
|
893
|
+
<QuickActions
|
|
894
|
+
selectedItems={selectedAll ? totalRows - unselectedItems.length : selectedItems.length}
|
|
895
|
+
disabled={quickActionsDisabled}
|
|
896
|
+
{actionsForSelectedItems}
|
|
897
|
+
{lang}
|
|
898
|
+
onClose={() => {
|
|
899
|
+
selectedAll = false
|
|
900
|
+
unselectedItems = []
|
|
901
|
+
selectedItems = []
|
|
902
|
+
}}
|
|
903
|
+
/>
|
|
904
|
+
{/if}
|
|
893
905
|
|
|
894
906
|
{#if searchBarVisible || filtersVisible || appendSnippet}
|
|
895
907
|
<div class="filter-container">
|
|
@@ -926,22 +938,23 @@ function resizeHeader(th, header) {
|
|
|
926
938
|
onremoveAllFilters={() => handleRemoveAllFilters()}
|
|
927
939
|
--filters-default-wrapper-width="100%"
|
|
928
940
|
{lang}
|
|
941
|
+
{dateLocale}
|
|
929
942
|
{editFilterMode}
|
|
930
943
|
{showActiveFilters}
|
|
931
944
|
appendSnippet={filterAppendSnippet}
|
|
932
945
|
customChipSnippet={customFilterChipSnippet}
|
|
933
946
|
>
|
|
934
|
-
{#snippet contentSnippet({ filters, mAndDown, updateMultiFilterValues,
|
|
947
|
+
{#snippet contentSnippet({ filters, mAndDown, updateMultiFilterValues, })}
|
|
935
948
|
{#key filters}
|
|
936
949
|
<DynamicFilters
|
|
937
950
|
{lang}
|
|
938
951
|
{filters}
|
|
939
952
|
{mAndDown}
|
|
940
953
|
onchange={e => updateFilterValues(e.detail.filter, updateMultiFilterValues)}
|
|
941
|
-
|
|
954
|
+
{updateMultiFilterValues}
|
|
942
955
|
>
|
|
943
|
-
{#snippet customSnippet({ filter })}
|
|
944
|
-
{@render customFilterSnippet?.({ filter,
|
|
956
|
+
{#snippet customSnippet({ filter, mAndDown, updateCustomFilterValues })}
|
|
957
|
+
{@render customFilterSnippet?.({ filter, mAndDown, updateCustomFilterValues })}
|
|
945
958
|
{/snippet}
|
|
946
959
|
</DynamicFilters>
|
|
947
960
|
{/key}
|
|
@@ -1007,7 +1020,7 @@ function resizeHeader(th, header) {
|
|
|
1007
1020
|
{/if}
|
|
1008
1021
|
|
|
1009
1022
|
<div class="outer-container">
|
|
1010
|
-
<div class="inner-container" bind:this={tableContainer} {onscroll}>
|
|
1023
|
+
<div class="inner-container" class:hide-scrollbar={hideScrollbar} bind:this={tableContainer} {onscroll}>
|
|
1011
1024
|
<InfiniteScroll
|
|
1012
1025
|
onloadMore={handleLoadBackward}
|
|
1013
1026
|
threshold={backwardThresholdPixel}
|
|
@@ -1027,7 +1040,7 @@ function resizeHeader(th, header) {
|
|
|
1027
1040
|
{#if selectMode === "multiple"}
|
|
1028
1041
|
<Checkbox
|
|
1029
1042
|
id="select-all"
|
|
1030
|
-
value={
|
|
1043
|
+
value={selectedAll}
|
|
1031
1044
|
disabled={disabled || loading}
|
|
1032
1045
|
onchange={handleSelectAll}
|
|
1033
1046
|
/>
|
|
@@ -1046,6 +1059,7 @@ function resizeHeader(th, header) {
|
|
|
1046
1059
|
<th
|
|
1047
1060
|
style={`${resizableColumns || !header.width ? '' : `width: ${header.width}`}`}
|
|
1048
1061
|
style:min-width={header.minWidth}
|
|
1062
|
+
style:max-width={header.maxWidth}
|
|
1049
1063
|
class:sortable={header.sortable}
|
|
1050
1064
|
onclick={() => handleHeaderClick(header)}
|
|
1051
1065
|
id={header.value}
|
|
@@ -1167,15 +1181,19 @@ function resizeHeader(th, header) {
|
|
|
1167
1181
|
class="item-row"
|
|
1168
1182
|
data-key={row.item[uniqueKey]}
|
|
1169
1183
|
style:background-color={
|
|
1170
|
-
!!row.item.disableEdit
|
|
1171
|
-
!!row.item.rowDisableBackgroundColor
|
|
1172
|
-
row.item.rowDisableBackgroundColor
|
|
1173
|
-
'var(--dynamic-table-row-disabled-background-color, var(--dynamic-table-default-row-disabled-background-color))'
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1184
|
+
!!row.item.disableEdit
|
|
1185
|
+
? !!row.item.rowDisableBackgroundColor
|
|
1186
|
+
? row.item.rowDisableBackgroundColor
|
|
1187
|
+
: 'var(--dynamic-table-row-disabled-background-color, var(--dynamic-table-default-row-disabled-background-color))'
|
|
1188
|
+
: expandedRows.findIndex(r => r.item[uniqueKey] == row.item[uniqueKey]) != -1
|
|
1189
|
+
? 'var(--dynamic-table-expanded-row-background-color, var(--dynamic-table-default-expanded-row-background-color))'
|
|
1190
|
+
: selectedAll
|
|
1191
|
+
? !unselectedItems.find(i => i[uniqueKey] == row.item[uniqueKey])
|
|
1192
|
+
? 'var(--dynamic-table-selected-row-background-color, var(--dynamic-table-default-selected-row-background-color))'
|
|
1193
|
+
: ''
|
|
1194
|
+
: selectedItems.find(i => i[uniqueKey] == row.item[uniqueKey])
|
|
1195
|
+
? 'var(--dynamic-table-selected-row-background-color, var(--dynamic-table-default-selected-row-background-color))'
|
|
1196
|
+
: ''
|
|
1179
1197
|
}
|
|
1180
1198
|
class:row-activator={cellEditorIndexRow == indexRow && !cellEditorSubItem}
|
|
1181
1199
|
onclick={() => handleRowClick(row.item)}
|
|
@@ -1184,9 +1202,15 @@ function resizeHeader(th, header) {
|
|
|
1184
1202
|
<td style:padding-left="0px" style:text-align="center">
|
|
1185
1203
|
<Checkbox
|
|
1186
1204
|
id={row.item[uniqueKey]}
|
|
1187
|
-
value={
|
|
1188
|
-
|
|
1189
|
-
|
|
1205
|
+
value={
|
|
1206
|
+
selectedAll ?
|
|
1207
|
+
unselectedItems.findIndex(
|
|
1208
|
+
(i) => i[uniqueKey] == row.item[uniqueKey]
|
|
1209
|
+
) == -1 :
|
|
1210
|
+
selectedItems.findIndex(
|
|
1211
|
+
(i) => i[uniqueKey] == row.item[uniqueKey]
|
|
1212
|
+
) != -1
|
|
1213
|
+
}
|
|
1190
1214
|
disabled={disabled || loading}
|
|
1191
1215
|
onchange={(e) => handleSelect(row.item, e.detail.shiftKeyPressed)}
|
|
1192
1216
|
/>
|
|
@@ -1270,6 +1294,7 @@ function resizeHeader(th, header) {
|
|
|
1270
1294
|
<th
|
|
1271
1295
|
style:width={subHeader.width}
|
|
1272
1296
|
style:min-width={subHeader.minWidth}
|
|
1297
|
+
style:max-width={subHeader.maxWidth}
|
|
1273
1298
|
class:sortable={subHeader.sortable}
|
|
1274
1299
|
onclick={() => handleHeaderClick(subHeader)}
|
|
1275
1300
|
>
|
|
@@ -1648,6 +1673,7 @@ function resizeHeader(th, header) {
|
|
|
1648
1673
|
: quickFilterActive.description,
|
|
1649
1674
|
multiple: true,
|
|
1650
1675
|
}}
|
|
1676
|
+
--autocomplete-border-radius= 0.5rem
|
|
1651
1677
|
--autocomplete-border="1px solid rgb(var(--global-color-background-500))"
|
|
1652
1678
|
--autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
|
|
1653
1679
|
/>
|
|
@@ -1833,10 +1859,13 @@ function resizeHeader(th, header) {
|
|
|
1833
1859
|
|
|
1834
1860
|
.inner-container {
|
|
1835
1861
|
overflow-y: auto;
|
|
1836
|
-
margin-right: -15px;
|
|
1837
1862
|
max-height: var(--dynamic-table-max-height, var(--dynamic-table-default-max-height));
|
|
1838
1863
|
}
|
|
1839
1864
|
|
|
1865
|
+
.hide-scrollbar {
|
|
1866
|
+
margin-right: -15px;
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1840
1869
|
.table {
|
|
1841
1870
|
background-color: var(
|
|
1842
1871
|
--dynamic-table-background-color,
|
|
@@ -127,12 +127,17 @@ declare class __sveltets_Render<Item extends {
|
|
|
127
127
|
cellEdit?: boolean;
|
|
128
128
|
noItemsText?: string;
|
|
129
129
|
showSelect?: boolean;
|
|
130
|
-
|
|
130
|
+
showActions?: boolean;
|
|
131
131
|
selectMode?: "single" | "multiple";
|
|
132
132
|
selectedItems?: (Item & {
|
|
133
133
|
disableEdit?: boolean;
|
|
134
134
|
rowDisableBackgroundColor?: string;
|
|
135
135
|
})[] | undefined;
|
|
136
|
+
unselectedItems?: (Item & {
|
|
137
|
+
disableEdit?: boolean;
|
|
138
|
+
rowDisableBackgroundColor?: string;
|
|
139
|
+
})[] | undefined;
|
|
140
|
+
selectedAll?: boolean;
|
|
136
141
|
showExpand?: boolean;
|
|
137
142
|
loading?: boolean;
|
|
138
143
|
disabled?: boolean;
|
|
@@ -143,10 +148,12 @@ declare class __sveltets_Render<Item extends {
|
|
|
143
148
|
filtersVisible?: boolean;
|
|
144
149
|
quickFiltersVisible?: boolean;
|
|
145
150
|
lang?: "it" | "en";
|
|
151
|
+
dateLocale?: "it" | "en";
|
|
146
152
|
editFilterMode?: "one-edit" | "multi-edit";
|
|
147
153
|
showActiveFilters?: boolean;
|
|
148
154
|
quickFilters?: QuickFilter[];
|
|
149
155
|
actionsForSelectedItems?: Action[];
|
|
156
|
+
quickActionsDisabled?: boolean;
|
|
150
157
|
totalRows?: number;
|
|
151
158
|
searchText?: string;
|
|
152
159
|
renderedRowsNumber?: number;
|
|
@@ -238,7 +245,8 @@ declare class __sveltets_Render<Item extends {
|
|
|
238
245
|
customFilterChipSnippet?: ComponentProps<typeof Filters>["customChipSnippet"];
|
|
239
246
|
customFilterSnippet?: Snippet<[{
|
|
240
247
|
filter: Filter | undefined;
|
|
241
|
-
|
|
248
|
+
mAndDown: boolean;
|
|
249
|
+
updateCustomFilterValues: Parameters<NonNullable<ComponentProps<typeof Filters>["contentSnippet"]>>[0]["updateMultiFilterValues"];
|
|
242
250
|
}]> | undefined;
|
|
243
251
|
onscroll?: UIEventHandler<HTMLDivElement>;
|
|
244
252
|
selectionSnippet?: ComponentProps<typeof Autocomplete>["selectionSnippet"];
|
|
@@ -522,7 +530,7 @@ declare class __sveltets_Render<Item extends {
|
|
|
522
530
|
};
|
|
523
531
|
events(): {};
|
|
524
532
|
slots(): {};
|
|
525
|
-
bindings(): "searchText" | "sortedBy" | "sortDirection" | "filters" | "selectedItems";
|
|
533
|
+
bindings(): "searchText" | "sortedBy" | "sortDirection" | "filters" | "selectedItems" | "unselectedItems" | "selectedAll";
|
|
526
534
|
exports(): {};
|
|
527
535
|
}
|
|
528
536
|
interface $$IsomorphicComponent {
|
|
@@ -13,7 +13,7 @@ let { headers = [], items = [], sortedBy = $bindable(undefined), sortDirection =
|
|
|
13
13
|
{ label: "50", value: 50 },
|
|
14
14
|
{ label: "100", value: 100 },
|
|
15
15
|
], hideRowsPerPage = false, totalElements = undefined, rowsPerPage = $bindable(20), filters = $bindable([]), searchBarColumns = undefined, searchBarVisible = true, searchBarPlaceholder = "Type something to search...", lang = "en", editFilterMode = "one-edit", showActiveFilters = true, resizableColumns = false, resizedColumnSizeWithPadding = {}, pointerOnRowHover = undefined, doubleClickActive = false, doubleClickDelay = 250, calculateRowStyles = undefined, calculateRowClasses = undefined, class: clazz = {}, onfiltersChange, onpaginationChange, onremoveFilter, onremoveAllFilters, customFilterChipSnippet, customFilterSnippet, filterAppendSnippet, onrowClick, onrowDoubleClick, appendSnippet, customSnippet, headerLabelSnippet, headerSnippet, rowActionsSnippet, onsort, footerSnippet, rangeDescriptorSnippet, searchBarSnippet, noDataSnippet, oncolumnResize, } = $props();
|
|
16
|
-
let searchBarInput = $state(), searchText = $state();
|
|
16
|
+
let searchBarInput = $state(), searchText = $state(), sortModify;
|
|
17
17
|
let rowsPerPageSelection = $state([]);
|
|
18
18
|
$effect(() => {
|
|
19
19
|
rowsPerPageSelection = [
|
|
@@ -74,6 +74,7 @@ function handleRemoveAllFilters() {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
function handleOnSort(event) {
|
|
77
|
+
sortModify = event.detail.sortModify;
|
|
77
78
|
handleFiltersChange();
|
|
78
79
|
if (onsort) {
|
|
79
80
|
onsort(event);
|
|
@@ -94,7 +95,12 @@ function buildFilters(params) {
|
|
|
94
95
|
});
|
|
95
96
|
}
|
|
96
97
|
if (!!sortedBy) {
|
|
97
|
-
|
|
98
|
+
if (sortModify) {
|
|
99
|
+
builder = sortModify({ builder, sortDirection: sortDirection || 'asc' });
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
builder.orderBy(sortedBy, sortDirection || "asc");
|
|
103
|
+
}
|
|
98
104
|
}
|
|
99
105
|
return builder;
|
|
100
106
|
}
|
|
@@ -31,6 +31,7 @@ declare const PaginatedTable: import("svelte").Component<Omit<{
|
|
|
31
31
|
detail: {
|
|
32
32
|
sortedBy: string | undefined;
|
|
33
33
|
sortDirection: string;
|
|
34
|
+
sortModify: import("../../simple/lists/SimpleTable.svelte").Header["sortModify"];
|
|
34
35
|
};
|
|
35
36
|
}) => void) | undefined;
|
|
36
37
|
onrowClick?: ((event: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">import { FilterEditor, Icon } from "../../..";
|
|
2
2
|
import {} from "svelte";
|
|
3
|
-
let { filters = [], lang = "en", mAndDown = false, onchange,
|
|
3
|
+
let { filters = [], lang = "en", mAndDown = false, onchange, updateMultiFilterValues, customSnippet: customSnippetInternal, } = $props();
|
|
4
4
|
let selectedFilter = $state();
|
|
5
5
|
let tmpFilters = $state(filters.reduce((acc, f) => {
|
|
6
6
|
if (f.active) {
|
|
@@ -8,14 +8,6 @@ let tmpFilters = $state(filters.reduce((acc, f) => {
|
|
|
8
8
|
}
|
|
9
9
|
return acc;
|
|
10
10
|
}, {}));
|
|
11
|
-
let activeFilter = $derived(Object.values(tmpFilters).reduce((count, filter) => {
|
|
12
|
-
if (filter.value !== undefined ||
|
|
13
|
-
filter.from !== undefined ||
|
|
14
|
-
filter.to !== undefined ||
|
|
15
|
-
(filter.values !== undefined && filter.values.length > 0))
|
|
16
|
-
count++;
|
|
17
|
-
return count;
|
|
18
|
-
}, 0));
|
|
19
11
|
let labelsMapper = lang == 'en' ? {
|
|
20
12
|
equal: { extended: "equal to", short: "equal" },
|
|
21
13
|
like: { short: "includes" },
|
|
@@ -43,46 +35,78 @@ function handleKeyPress(event, filter) {
|
|
|
43
35
|
selectFilter(filter);
|
|
44
36
|
}
|
|
45
37
|
}
|
|
46
|
-
function clearFilters() {
|
|
47
|
-
tmpFilters = {};
|
|
48
|
-
if (onremoveAllFilters) {
|
|
49
|
-
onremoveAllFilters();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
38
|
function handleFilterChange() {
|
|
53
|
-
if (!!selectedFilter
|
|
54
|
-
onchange
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
if (!!selectedFilter) {
|
|
40
|
+
if (!!onchange) {
|
|
41
|
+
onchange({
|
|
42
|
+
detail: {
|
|
43
|
+
filter: tmpFilters[selectedFilter.name]
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
filters = filters.map(f => {
|
|
48
|
+
if (f.name === selectedFilter?.name) {
|
|
49
|
+
return tmpFilters[selectedFilter.name];
|
|
57
50
|
}
|
|
51
|
+
return f;
|
|
58
52
|
});
|
|
59
53
|
}
|
|
60
54
|
}
|
|
55
|
+
function isActiveFilter(filter) {
|
|
56
|
+
let newValue = {}, newValid = false;
|
|
57
|
+
if (filter.type == 'select') {
|
|
58
|
+
newValue = filter.values;
|
|
59
|
+
if (!!newValue && newValue.length > 0) {
|
|
60
|
+
newValid = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if ('mode' in filter && filter.mode == 'between') {
|
|
64
|
+
newValue.to = filter.to;
|
|
65
|
+
newValue.from = filter.from;
|
|
66
|
+
if (!!newValue.from || !!newValue.to) {
|
|
67
|
+
newValid = true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (filter.type == 'custom') {
|
|
71
|
+
newValue = filter.value;
|
|
72
|
+
if ((Array.isArray(newValue) && newValue.length > 0) || (!Array.isArray(newValue) && !!newValue)) {
|
|
73
|
+
newValid = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
newValue = filter.value;
|
|
78
|
+
if (!!newValue) {
|
|
79
|
+
newValid = true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return newValid;
|
|
83
|
+
}
|
|
84
|
+
function updateCustomFilterValues(filterName, newValue, newValid, mode) {
|
|
85
|
+
let filter = filters.find(f => f.name === filterName);
|
|
86
|
+
if (!filter)
|
|
87
|
+
throw new Error('cannot find filter with name ' + filterName);
|
|
88
|
+
if (filter.type != 'custom')
|
|
89
|
+
throw new Error('filter is not custom');
|
|
90
|
+
filter.value = newValue;
|
|
91
|
+
filter.active = newValid;
|
|
92
|
+
if (updateMultiFilterValues) {
|
|
93
|
+
updateMultiFilterValues(filterName, newValue, newValid, mode);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
61
96
|
</script>
|
|
62
97
|
|
|
63
|
-
<div class="custom-filters-container">
|
|
98
|
+
<div class="custom-filters-container" class:yscroll={mAndDown}>
|
|
64
99
|
<div class="filters-selection">
|
|
65
|
-
|
|
66
|
-
{#if activeFilter > 0}
|
|
67
|
-
<div class="filter-info">
|
|
68
|
-
{activeFilter} {lang == 'en' ? 'applied' : activeFilter == 1 ? 'applicato' : 'applicati'}
|
|
69
|
-
<button class="clear-button" onclick={clearFilters}>✕</button>
|
|
70
|
-
</div>
|
|
71
|
-
{/if}
|
|
72
|
-
|
|
73
|
-
|
|
74
100
|
{#each filters as filter}
|
|
75
101
|
<div
|
|
76
102
|
tabindex="0"
|
|
77
103
|
role="button"
|
|
78
104
|
class="filters-selection-item"
|
|
79
|
-
class:selected={filter === selectedFilter}
|
|
80
|
-
onclick={() => selectFilter(filter)}
|
|
105
|
+
class:selected={filter.name === selectedFilter?.name || isActiveFilter(filter)} onclick={() => selectFilter(filter)}
|
|
81
106
|
onkeydown={(event) => handleKeyPress(event, filter)}
|
|
82
|
-
aria-pressed={filter === selectedFilter}
|
|
83
|
-
>
|
|
107
|
+
aria-pressed={filter.name === selectedFilter?.name} >
|
|
84
108
|
<div class="filters-selection-title">
|
|
85
|
-
{filter.label}
|
|
109
|
+
<div class="filters-selection-title-label">{filter.label}</div>
|
|
86
110
|
<Icon name="mdi-chevron-right-circle-outline" />
|
|
87
111
|
</div>
|
|
88
112
|
</div>
|
|
@@ -93,20 +117,32 @@ function handleFilterChange() {
|
|
|
93
117
|
<div class="filters-content">
|
|
94
118
|
{#if selectedFilter}
|
|
95
119
|
<div class="filters-content-box">
|
|
96
|
-
<h2>{selectedFilter.label}</h2>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
<h2>{selectedFilter.label}</h2>
|
|
121
|
+
{#key selectedFilter.label}
|
|
122
|
+
<FilterEditor
|
|
123
|
+
bind:filter={selectedFilter}
|
|
124
|
+
{lang}
|
|
125
|
+
{labelsMapper}
|
|
126
|
+
editFilterMode="one-edit"
|
|
127
|
+
bind:tmpFilter={tmpFilters[selectedFilter?.name || '']}
|
|
128
|
+
mobile={mAndDown}
|
|
129
|
+
onchange={handleFilterChange}
|
|
130
|
+
--simple-textfield-border-radius= 0.5rem
|
|
131
|
+
--simple-textfield-background-color= transparent
|
|
132
|
+
--simple-textfield-box-shadow= 'inset 0 0 0 1px rgb(var(--global-color-background-500))'
|
|
133
|
+
--simple-textfield-focus-box-shadow='inset 0 0 0 2px rgb(var(--global-color-primary-500))'
|
|
134
|
+
--chip-default-color="rgb(var(--global-color-primary-foreground))"
|
|
135
|
+
--autocomplete-border-radius= 0.5rem
|
|
136
|
+
--autocomplete-border="1px solid rgb(var(--global-color-background-500))"
|
|
137
|
+
--autocomplete-focus-box-shadow="0 0 0 2px rgb(var(--global-color-primary-500))"
|
|
138
|
+
--autocomplete-padding="9.6px 16px"
|
|
139
|
+
--autocomplete-background-color="transparent"
|
|
140
|
+
>
|
|
141
|
+
{#snippet customSnippet({ filter })}
|
|
142
|
+
{@render customSnippetInternal?.({ filter, mAndDown, updateCustomFilterValues })}
|
|
143
|
+
{/snippet}
|
|
144
|
+
</FilterEditor>
|
|
145
|
+
{/key}
|
|
110
146
|
</div>
|
|
111
147
|
{:else}
|
|
112
148
|
<div class="filters-content-box">
|
|
@@ -115,19 +151,20 @@ function handleFilterChange() {
|
|
|
115
151
|
{/if}
|
|
116
152
|
</div>
|
|
117
153
|
</div>
|
|
118
|
-
|
|
119
154
|
<style>
|
|
120
|
-
|
|
121
155
|
.custom-filters-container {
|
|
122
156
|
display: flex;
|
|
123
157
|
height: 70vh;
|
|
124
|
-
overflow-y: scroll;
|
|
125
158
|
}
|
|
126
159
|
|
|
160
|
+
.yscroll {
|
|
161
|
+
overflow-y: auto;
|
|
162
|
+
}
|
|
163
|
+
|
|
127
164
|
.filters-selection {
|
|
128
165
|
width: 40%;
|
|
129
166
|
padding: 1rem;
|
|
130
|
-
|
|
167
|
+
overflow-y: auto;
|
|
131
168
|
}
|
|
132
169
|
|
|
133
170
|
.filters-selection-item {
|
|
@@ -145,13 +182,19 @@ function handleFilterChange() {
|
|
|
145
182
|
justify-content: space-between;
|
|
146
183
|
}
|
|
147
184
|
|
|
185
|
+
.filters-selection-title-label{
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
text-overflow: ellipsis;
|
|
188
|
+
}
|
|
189
|
+
|
|
148
190
|
.filters-selection-item.selected {
|
|
149
191
|
border: 1px solid rgb(var(--global-color-primary-500));
|
|
150
192
|
background-color: rgb(var(--global-color-background-500));
|
|
151
193
|
}
|
|
152
194
|
|
|
153
195
|
.filters-content {
|
|
154
|
-
width: 60%;
|
|
196
|
+
min-width: 60%;
|
|
197
|
+
max-width: 60%;
|
|
155
198
|
}
|
|
156
199
|
.filters-content-box {
|
|
157
200
|
padding: 1rem;
|
|
@@ -162,36 +205,4 @@ function handleFilterChange() {
|
|
|
162
205
|
text-align: center;
|
|
163
206
|
font-weight: bold;
|
|
164
207
|
}
|
|
165
|
-
|
|
166
|
-
.filter-info {
|
|
167
|
-
display: inline-flex;
|
|
168
|
-
align-items: center;
|
|
169
|
-
padding: 0.25rem 0.5rem;
|
|
170
|
-
background-color: rgb(var(--global-color-background-700));
|
|
171
|
-
color: rgb(var(--global-color-primary-600));
|
|
172
|
-
border-radius: 1rem;
|
|
173
|
-
font-weight: bold;
|
|
174
|
-
font-size: 0.9rem;
|
|
175
|
-
margin-bottom: 10px;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.clear-button {
|
|
179
|
-
display: inline-flex;
|
|
180
|
-
justify-content: center;
|
|
181
|
-
align-items: center;
|
|
182
|
-
width: 1rem;
|
|
183
|
-
height: 1rem;
|
|
184
|
-
margin-left: 0.5rem;
|
|
185
|
-
border-radius: 50%;
|
|
186
|
-
background-color: rgb(var(--global-color-background-700));
|
|
187
|
-
color: rgb(var(--global-color-primary-600));
|
|
188
|
-
font-weight: bold;
|
|
189
|
-
cursor: pointer;
|
|
190
|
-
font-size: 0.8rem;
|
|
191
|
-
border: none;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
.clear-button:hover {
|
|
195
|
-
background-color: rgb(var(--global-color-background-500));
|
|
196
|
-
}
|
|
197
208
|
</style>
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
1
|
+
import type { DateMode, Filter, NumberMode, SelectMode, StringMode } from "../../../utils/filters/filters";
|
|
2
|
+
import { type Snippet } from "svelte";
|
|
3
|
+
declare const DynamicFilters: import("svelte").Component<{
|
|
5
4
|
filters?: Filter[];
|
|
6
5
|
lang?: "it" | "en";
|
|
7
6
|
mAndDown?: boolean;
|
|
8
|
-
onremoveAllFilters?: () => void;
|
|
9
7
|
onchange?: (event: {
|
|
10
8
|
detail: {
|
|
11
9
|
filter: Filter;
|
|
12
10
|
};
|
|
13
11
|
}) => void;
|
|
14
|
-
customSnippet?:
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
customSnippet?: Snippet<[{
|
|
13
|
+
filter: Filter | undefined;
|
|
14
|
+
mAndDown: boolean;
|
|
15
|
+
updateCustomFilterValues: (filterName: string, newValue: any, newValid: boolean, mode?: NumberMode | StringMode | SelectMode | DateMode) => void;
|
|
16
|
+
}]>;
|
|
17
|
+
updateMultiFilterValues?: (filterName: string, newValue: any, newValid: boolean, mode?: NumberMode | StringMode | SelectMode | DateMode) => void;
|
|
18
|
+
}, {}, "">;
|
|
17
19
|
type DynamicFilters = ReturnType<typeof DynamicFilters>;
|
|
18
20
|
export default DynamicFilters;
|
|
@@ -195,7 +195,8 @@ function onclick(event) {
|
|
|
195
195
|
--simple-text-field-margin-left="0px"
|
|
196
196
|
mobileDrawer={mobile}
|
|
197
197
|
onchange={handleChangeValue}
|
|
198
|
-
|
|
198
|
+
placeholder={editFilterMode == 'one-edit' ? tmpFilter?.label : undefined}
|
|
199
|
+
></Autocomplete>
|
|
199
200
|
</div>
|
|
200
201
|
{:else if tmpFilter.type === "select" && (tmpFilter.view === 'toggle')}
|
|
201
202
|
<div
|
|
@@ -117,8 +117,9 @@ function handleApplyFilterClick() {
|
|
|
117
117
|
let activeFilters = $derived(filters.filter((f) => f.active));
|
|
118
118
|
function handleRemoveFilter(filter) {
|
|
119
119
|
let filterIndex = filters.findIndex((f) => f.name === filter.name);
|
|
120
|
-
filters[filterIndex].active = false;
|
|
121
120
|
let filterName = filter.name;
|
|
121
|
+
filters[filterIndex].active = false;
|
|
122
|
+
tmpFilters[filterName].active = false;
|
|
122
123
|
if (Object.keys(filters[filterIndex]).includes('value')) {
|
|
123
124
|
//@ts-ignore
|
|
124
125
|
filters[filterIndex].value = undefined;
|
|
@@ -265,8 +266,12 @@ function updateMultiFilterValues(filterName, newValue, newValid, mode) {
|
|
|
265
266
|
}
|
|
266
267
|
else if ('mode' in tmpFilter && tmpFilter.mode == 'between') {
|
|
267
268
|
if (tmpFilter.type == 'date') {
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
if (newValue.from) {
|
|
270
|
+
tmpFilter.from = DateTime.fromJSDate(newValue.from).setLocale('it-IT').startOf('day').toJSDate();
|
|
271
|
+
}
|
|
272
|
+
if (newValue.to) {
|
|
273
|
+
tmpFilter.to = DateTime.fromJSDate(newValue.to).setLocale('it-IT').endOf('day').toJSDate();
|
|
274
|
+
}
|
|
270
275
|
}
|
|
271
276
|
else {
|
|
272
277
|
tmpFilter.from = newValue.from;
|
|
@@ -402,6 +407,7 @@ function onclick(event, stopPropagation = false) {
|
|
|
402
407
|
>
|
|
403
408
|
<Button
|
|
404
409
|
--button-color="var(--chip-color, var(--chip-default-color))"
|
|
410
|
+
--button-height="var(--filters-button-height, var(--filters-default-button-height))"
|
|
405
411
|
onclick={handleAddFilterClick}
|
|
406
412
|
>
|
|
407
413
|
<div class="filter-button-content">
|
|
@@ -423,6 +429,7 @@ function onclick(event, stopPropagation = false) {
|
|
|
423
429
|
>
|
|
424
430
|
<Button
|
|
425
431
|
--button-color="var(--chip-color, var(--chip-default-color))"
|
|
432
|
+
--button-height="var(--filters-button-height, var(--filters-default-button-height))"
|
|
426
433
|
onclick={handleAddFilterClick}
|
|
427
434
|
>
|
|
428
435
|
<div class="filter-button-content">
|
|
@@ -842,7 +849,7 @@ function onclick(event, stopPropagation = false) {
|
|
|
842
849
|
|
|
843
850
|
.filters-wrapper {
|
|
844
851
|
display: flex;
|
|
845
|
-
align-items:
|
|
852
|
+
align-items: start;
|
|
846
853
|
gap: 20px;
|
|
847
854
|
max-width: 100%;
|
|
848
855
|
width: var(
|
|
@@ -10,7 +10,7 @@ let { headers = [], items = [], sortedBy = $bindable(undefined), sortDirection =
|
|
|
10
10
|
if (!onrowClick && !!onrowDoubleClick) {
|
|
11
11
|
throw new Error('cannot define an onrowDoubleClick event without defining an onrowClick event');
|
|
12
12
|
}
|
|
13
|
-
let clickTimeout = undefined;
|
|
13
|
+
let clickTimeout = undefined, sortModify;
|
|
14
14
|
onMount(() => {
|
|
15
15
|
if (resizableColumns) {
|
|
16
16
|
if (!resizedColumnSizeWithPadding)
|
|
@@ -59,17 +59,20 @@ function handleHeaderClick(header) {
|
|
|
59
59
|
sortDirection = 'desc';
|
|
60
60
|
else if (sortDirection == 'desc') {
|
|
61
61
|
sortedBy = undefined;
|
|
62
|
+
sortModify = undefined;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
65
66
|
sortedBy = header.value;
|
|
66
67
|
sortDirection = 'asc';
|
|
68
|
+
sortModify = header.sortModify;
|
|
67
69
|
}
|
|
68
70
|
if (onsort) {
|
|
69
71
|
onsort({
|
|
70
72
|
detail: {
|
|
71
73
|
sortedBy,
|
|
72
|
-
sortDirection
|
|
74
|
+
sortDirection,
|
|
75
|
+
sortModify
|
|
73
76
|
}
|
|
74
77
|
});
|
|
75
78
|
}
|
|
@@ -6,6 +6,10 @@ export type Header<Data = any> = {
|
|
|
6
6
|
width?: string;
|
|
7
7
|
minWidth?: string;
|
|
8
8
|
sortable?: boolean;
|
|
9
|
+
sortModify?: (params: {
|
|
10
|
+
builder: FilterBuilder;
|
|
11
|
+
sortDirection: 'asc' | 'desc';
|
|
12
|
+
}) => FilterBuilder;
|
|
9
13
|
data?: Data;
|
|
10
14
|
};
|
|
11
15
|
export type CalculateRowStyles<T> = (item: T) => {
|
|
@@ -18,6 +22,7 @@ import '../../../css/main.css';
|
|
|
18
22
|
import './SimpleTable.css';
|
|
19
23
|
import { type Snippet } from 'svelte';
|
|
20
24
|
import type { ColumnBoolean, ColumnCheckBox, ColumnCustom, ColumnDate, ColumnIcon, ColumnNumber, ColumnString } from './columnTypes';
|
|
25
|
+
import type { FilterBuilder } from '../../..';
|
|
21
26
|
declare class __sveltets_Render<Item extends {
|
|
22
27
|
[key: string]: any;
|
|
23
28
|
}, Data> {
|
|
@@ -40,6 +45,7 @@ declare class __sveltets_Render<Item extends {
|
|
|
40
45
|
detail: {
|
|
41
46
|
sortedBy: string | undefined;
|
|
42
47
|
sortDirection: string;
|
|
48
|
+
sortModify: Header["sortModify"];
|
|
43
49
|
};
|
|
44
50
|
}) => void) | undefined;
|
|
45
51
|
onrowClick?: ((event: {
|