@bexis2/bexis2-core-ui 0.3.12 → 0.3.13
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/README.md +1 -0
- package/dist/components/File/FileUploader.svelte +3 -3
- package/dist/components/Table/TableContent.svelte +202 -119
- package/dist/components/Table/TableFilter.svelte +146 -102
- package/dist/components/Table/TableFilter.svelte.d.ts +2 -3
- package/dist/components/Table/TableFilterServer.svelte +274 -0
- package/dist/components/Table/TableFilterServer.svelte.d.ts +22 -0
- package/dist/components/Table/TablePagination.svelte +72 -39
- package/dist/components/Table/TablePaginationServer.svelte +125 -0
- package/dist/components/Table/TablePaginationServer.svelte.d.ts +21 -0
- package/dist/components/Table/filter.js +40 -78
- package/dist/components/Table/shared.d.ts +32 -0
- package/dist/components/Table/shared.js +117 -0
- package/dist/components/form/DropdownKvP.svelte.d.ts +4 -4
- package/dist/components/form/MultiSelect.svelte.d.ts +6 -6
- package/dist/models/Enums.d.ts +18 -0
- package/dist/models/Enums.js +20 -0
- package/dist/models/Models.d.ts +43 -2
- package/dist/models/Models.js +28 -1
- package/package.json +2 -2
- package/src/lib/components/Table/TableContent.svelte +227 -151
- package/src/lib/components/Table/TableFilter.svelte +166 -102
- package/src/lib/components/Table/TableFilterServer.svelte +310 -0
- package/src/lib/components/Table/TablePagination.svelte +75 -39
- package/src/lib/components/Table/TablePaginationServer.svelte +133 -0
- package/src/lib/components/Table/filter.ts +42 -86
- package/src/lib/components/Table/shared.ts +141 -0
- package/src/lib/components/file/FileUploader.svelte +3 -3
- package/src/lib/models/Enums.ts +22 -0
- package/src/lib/models/Models.ts +63 -2
|
@@ -18,49 +18,85 @@
|
|
|
18
18
|
const goToNextPage = () => ($pageIndex += 1);
|
|
19
19
|
const goToPreviousPage = () => ($pageIndex -= 1);
|
|
20
20
|
|
|
21
|
+
// Handles the input change event
|
|
22
|
+
const handleChange = (e) => {
|
|
23
|
+
const value = e.target.value;
|
|
24
|
+
|
|
25
|
+
if (value > $pageCount) {
|
|
26
|
+
$pageIndex = $pageCount - 1;
|
|
27
|
+
} else if (value < 1) {
|
|
28
|
+
$pageIndex = 0;
|
|
29
|
+
} else {
|
|
30
|
+
$pageIndex = value - 1;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
21
34
|
$: goToFirstPageDisabled = !$pageIndex;
|
|
22
35
|
$: goToLastPageDisabled = $pageIndex == $pageCount - 1;
|
|
23
36
|
$: goToNextPageDisabled = !$hasNextPage;
|
|
24
37
|
$: goToPreviousPageDisabled = !$hasPreviousPage;
|
|
25
38
|
</script>
|
|
26
39
|
|
|
27
|
-
<div class="flex justify-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
40
|
+
<div class="flex justify-between w-full items-stretch gap-10">
|
|
41
|
+
<div class="flex justify-start">
|
|
42
|
+
<select
|
|
43
|
+
name="pageSize"
|
|
44
|
+
id="{id}-pageSize"
|
|
45
|
+
class="select variant-filled-primary w-min font-bold"
|
|
46
|
+
bind:value={$pageSize}
|
|
47
|
+
>
|
|
48
|
+
{#each pageSizes as size}
|
|
49
|
+
<option value={size}>{size}</option>
|
|
50
|
+
{/each}
|
|
51
|
+
</select>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="flex justify-center gap-1">
|
|
54
|
+
<button
|
|
55
|
+
class="btn btn-sm variant-filled-primary"
|
|
56
|
+
on:click|preventDefault={goToFirstPage}
|
|
57
|
+
disabled={goToFirstPageDisabled}
|
|
58
|
+
id="{id}-first"
|
|
59
|
+
>
|
|
60
|
+
<Fa icon={faAnglesLeft} /></button
|
|
61
|
+
>
|
|
62
|
+
<button
|
|
63
|
+
class="btn btn-sm variant-filled-primary"
|
|
64
|
+
id="{id}-previous"
|
|
65
|
+
on:click|preventDefault={goToPreviousPage}
|
|
66
|
+
disabled={goToPreviousPageDisabled}><Fa icon={faAngleLeft} /></button
|
|
67
|
+
>
|
|
68
|
+
<input
|
|
69
|
+
type="number"
|
|
70
|
+
class="input border border-primary-500 rounded flex w-24"
|
|
71
|
+
value={$pageIndex + 1}
|
|
72
|
+
max={$pageCount}
|
|
73
|
+
min={1}
|
|
74
|
+
on:change={handleChange}
|
|
75
|
+
/>
|
|
76
|
+
<button
|
|
77
|
+
class="btn btn-sm variant-filled-primary"
|
|
78
|
+
id="{id}-next"
|
|
79
|
+
on:click|preventDefault={goToNextPage}
|
|
80
|
+
disabled={goToNextPageDisabled}><Fa icon={faAngleRight} /></button
|
|
81
|
+
>
|
|
82
|
+
<button
|
|
83
|
+
class="btn btn-sm variant-filled-primary"
|
|
84
|
+
id="{id}-last"
|
|
85
|
+
on:click|preventDefault={goToLastPage}
|
|
86
|
+
disabled={goToLastPageDisabled}><Fa icon={faAnglesRight} /></button
|
|
87
|
+
>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="flex justify-end items-center">
|
|
90
|
+
<span class="text-sm text-gray-500">
|
|
91
|
+
{#if $pageCount > 0}
|
|
92
|
+
{#if $pageCount == 1}
|
|
93
|
+
1 page
|
|
94
|
+
{:else}
|
|
95
|
+
{$pageCount} pages
|
|
96
|
+
{/if}
|
|
97
|
+
{:else}
|
|
98
|
+
No pages
|
|
99
|
+
{/if}
|
|
100
|
+
</span>
|
|
101
|
+
</div>
|
|
66
102
|
</div>
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Fa from 'svelte-fa/src/fa.svelte';
|
|
3
|
+
import {
|
|
4
|
+
faAnglesRight,
|
|
5
|
+
faAngleRight,
|
|
6
|
+
faAnglesLeft,
|
|
7
|
+
faAngleLeft
|
|
8
|
+
} from '@fortawesome/free-solid-svg-icons';
|
|
9
|
+
|
|
10
|
+
export let id; // Unique table ID
|
|
11
|
+
export let pageIndex;
|
|
12
|
+
export let pageSize;
|
|
13
|
+
export let pageSizes; // Available page sizes
|
|
14
|
+
export let serverItemCount; // Total number of items expected from the server. `serverSide` must be true on table config.
|
|
15
|
+
export let updateTable; // Function to update table
|
|
16
|
+
|
|
17
|
+
// Flags for disabling buttons
|
|
18
|
+
let goToFirstPageDisabled = true;
|
|
19
|
+
let goToLastPageDisabled = true;
|
|
20
|
+
let goToNextPageDisabled = true;
|
|
21
|
+
let goToPreviousPageDisabled = true;
|
|
22
|
+
|
|
23
|
+
// Handles the input change event
|
|
24
|
+
const handleChange = (e) => {
|
|
25
|
+
const value = e.target.value;
|
|
26
|
+
|
|
27
|
+
if (value > pageCount) {
|
|
28
|
+
$pageIndex = pageCount - 1;
|
|
29
|
+
} else if (value < 1) {
|
|
30
|
+
$pageIndex = 0;
|
|
31
|
+
} else {
|
|
32
|
+
$pageIndex = value - 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
updateTable();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Main navigation function
|
|
39
|
+
const goTo = (dst: string) => {
|
|
40
|
+
switch (dst) {
|
|
41
|
+
case 'first':
|
|
42
|
+
$pageIndex = 0;
|
|
43
|
+
break;
|
|
44
|
+
case 'last':
|
|
45
|
+
$pageIndex = pageCount - 1;
|
|
46
|
+
break;
|
|
47
|
+
case 'next':
|
|
48
|
+
$pageIndex += 1;
|
|
49
|
+
break;
|
|
50
|
+
case 'previous':
|
|
51
|
+
$pageIndex -= 1;
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Fetch data for new parameters
|
|
58
|
+
updateTable();
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
$: pageCount = Math.ceil($serverItemCount / $pageSize);
|
|
62
|
+
$: goToFirstPageDisabled = !$pageIndex;
|
|
63
|
+
$: goToLastPageDisabled = $pageIndex == pageCount - 1;
|
|
64
|
+
$: goToNextPageDisabled = $pageIndex == pageCount - 1;
|
|
65
|
+
$: goToPreviousPageDisabled = !$pageIndex;
|
|
66
|
+
$: $pageSize && updateTable(); // Update query when page size changes
|
|
67
|
+
|
|
68
|
+
updateTable();
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<div class="flex justify-between w-full items-stretch gap-10">
|
|
72
|
+
<div class="flex justify-start">
|
|
73
|
+
<select
|
|
74
|
+
name="pageSize"
|
|
75
|
+
id="{id}-pageSize"
|
|
76
|
+
class="select variant-filled-primary w-min font-bold"
|
|
77
|
+
bind:value={$pageSize}
|
|
78
|
+
>
|
|
79
|
+
{#each pageSizes as size}
|
|
80
|
+
<option value={size}>{size}</option>
|
|
81
|
+
{/each}
|
|
82
|
+
</select>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="flex justify-center gap-1">
|
|
85
|
+
<button
|
|
86
|
+
class="btn btn-sm variant-filled-primary"
|
|
87
|
+
on:click|preventDefault={() => goTo('first')}
|
|
88
|
+
disabled={goToFirstPageDisabled}
|
|
89
|
+
id="{id}-first"
|
|
90
|
+
>
|
|
91
|
+
<Fa icon={faAnglesLeft} /></button
|
|
92
|
+
>
|
|
93
|
+
<button
|
|
94
|
+
class="btn btn-sm variant-filled-primary"
|
|
95
|
+
id="{id}-previous"
|
|
96
|
+
on:click|preventDefault={() => goTo('previous')}
|
|
97
|
+
disabled={goToPreviousPageDisabled}><Fa icon={faAngleLeft} /></button
|
|
98
|
+
>
|
|
99
|
+
<input
|
|
100
|
+
type="number"
|
|
101
|
+
class="input border border-primary-500 rounded flex w-24"
|
|
102
|
+
value={$pageIndex + 1}
|
|
103
|
+
max={pageCount}
|
|
104
|
+
min={1}
|
|
105
|
+
on:change={handleChange}
|
|
106
|
+
/>
|
|
107
|
+
<button
|
|
108
|
+
class="btn btn-sm variant-filled-primary"
|
|
109
|
+
id="{id}-next"
|
|
110
|
+
on:click|preventDefault={() => goTo('next')}
|
|
111
|
+
disabled={goToNextPageDisabled}><Fa icon={faAngleRight} /></button
|
|
112
|
+
>
|
|
113
|
+
<button
|
|
114
|
+
class="btn btn-sm variant-filled-primary"
|
|
115
|
+
id="{id}-last"
|
|
116
|
+
on:click|preventDefault={() => goTo('last')}
|
|
117
|
+
disabled={goToLastPageDisabled}><Fa icon={faAnglesRight} /></button
|
|
118
|
+
>
|
|
119
|
+
</div>
|
|
120
|
+
<div class="flex justify-end items-center">
|
|
121
|
+
<span class="text-sm text-gray-500">
|
|
122
|
+
{#if pageCount > 0}
|
|
123
|
+
{#if pageCount == 1}
|
|
124
|
+
1 page
|
|
125
|
+
{:else}
|
|
126
|
+
{pageCount} pages
|
|
127
|
+
{/if}
|
|
128
|
+
{:else}
|
|
129
|
+
No pages
|
|
130
|
+
{/if}
|
|
131
|
+
</span>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import type { ColumnFilterFn } from 'svelte-headless-table/lib/plugins';
|
|
2
2
|
import type { TableFilterFn } from 'svelte-headless-table/lib/plugins/addTableFilter';
|
|
3
3
|
|
|
4
|
+
import { FilterOptionsEnum } from '$models/Enums';
|
|
5
|
+
|
|
4
6
|
const textFilter = (filterOption, filterValue, value) => {
|
|
5
7
|
switch (filterOption) {
|
|
6
|
-
case
|
|
8
|
+
case FilterOptionsEnum.e:
|
|
7
9
|
return value.toLowerCase() === filterValue.toLowerCase();
|
|
8
|
-
case
|
|
10
|
+
case FilterOptionsEnum.ne:
|
|
9
11
|
return value.toLowerCase() !== filterValue.toLowerCase();
|
|
10
|
-
case
|
|
12
|
+
case FilterOptionsEnum.sw:
|
|
11
13
|
return value.toLowerCase().startsWith(filterValue.toLowerCase());
|
|
12
|
-
case
|
|
14
|
+
case FilterOptionsEnum.ew:
|
|
13
15
|
return value.toLowerCase().endsWith(filterValue.toLowerCase());
|
|
14
|
-
case
|
|
16
|
+
case FilterOptionsEnum.c:
|
|
15
17
|
return value.toLowerCase().includes(filterValue.toLowerCase());
|
|
16
|
-
case
|
|
18
|
+
case FilterOptionsEnum.nc:
|
|
17
19
|
return !value.toLowerCase().includes(filterValue.toLowerCase());
|
|
18
20
|
default:
|
|
19
21
|
return false;
|
|
@@ -22,17 +24,17 @@ const textFilter = (filterOption, filterValue, value) => {
|
|
|
22
24
|
|
|
23
25
|
const numberFilter = (filterOption, filterValue, value) => {
|
|
24
26
|
switch (filterOption) {
|
|
25
|
-
case
|
|
27
|
+
case FilterOptionsEnum.e:
|
|
26
28
|
return value === filterValue;
|
|
27
|
-
case
|
|
29
|
+
case FilterOptionsEnum.ne:
|
|
28
30
|
return value !== filterValue;
|
|
29
|
-
case
|
|
31
|
+
case FilterOptionsEnum.gt:
|
|
30
32
|
return value > filterValue;
|
|
31
|
-
case
|
|
33
|
+
case FilterOptionsEnum.lt:
|
|
32
34
|
return value < filterValue;
|
|
33
|
-
case
|
|
35
|
+
case FilterOptionsEnum.gte:
|
|
34
36
|
return value >= filterValue;
|
|
35
|
-
case
|
|
37
|
+
case FilterOptionsEnum.lte:
|
|
36
38
|
return value <= filterValue;
|
|
37
39
|
default:
|
|
38
40
|
return false;
|
|
@@ -43,93 +45,47 @@ const dateFilter = (filterOption, filterValue, value) => {
|
|
|
43
45
|
const filter = new Date(filterValue);
|
|
44
46
|
|
|
45
47
|
switch (filterOption) {
|
|
46
|
-
case
|
|
47
|
-
return value === filter;
|
|
48
|
-
case
|
|
49
|
-
return value >= filter;
|
|
50
|
-
case
|
|
51
|
-
return value > filter;
|
|
52
|
-
case
|
|
53
|
-
return value <= filter;
|
|
54
|
-
case
|
|
55
|
-
return value < filter;
|
|
56
|
-
case
|
|
57
|
-
return value !== filter;
|
|
48
|
+
case FilterOptionsEnum.o:
|
|
49
|
+
return value.getTime() === filter.getTime();
|
|
50
|
+
case FilterOptionsEnum.sf:
|
|
51
|
+
return value.getTime() >= filter.getTime();
|
|
52
|
+
case FilterOptionsEnum.a:
|
|
53
|
+
return value.getTime() > filter.getTime();
|
|
54
|
+
case FilterOptionsEnum.u:
|
|
55
|
+
return value.getTime() <= filter.getTime();
|
|
56
|
+
case FilterOptionsEnum.b:
|
|
57
|
+
return value.getTime() < filter.getTime();
|
|
58
|
+
case FilterOptionsEnum.no:
|
|
59
|
+
return value.getTime() !== filter.getTime();
|
|
58
60
|
default:
|
|
59
61
|
return false;
|
|
60
62
|
}
|
|
61
63
|
};
|
|
62
64
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
if (firstFilterValue == null && secondFilterValue == null) {
|
|
66
|
-
return true;
|
|
67
|
-
} else if (
|
|
68
|
-
(firstFilterOption == null || firstFilterValue == null) &&
|
|
69
|
-
secondFilterOption != null &&
|
|
70
|
-
secondFilterValue != null
|
|
71
|
-
) {
|
|
72
|
-
return numberFilter(secondFilterOption, secondFilterValue, value);
|
|
73
|
-
} else if (
|
|
74
|
-
(secondFilterOption == null || secondFilterValue == null) &&
|
|
75
|
-
firstFilterOption != null &&
|
|
76
|
-
firstFilterValue != null
|
|
77
|
-
) {
|
|
78
|
-
return numberFilter(firstFilterOption, firstFilterValue, value);
|
|
79
|
-
}
|
|
80
|
-
return (
|
|
81
|
-
numberFilter(firstFilterOption, firstFilterValue, value) &&
|
|
82
|
-
numberFilter(secondFilterOption, secondFilterValue, value)
|
|
83
|
-
);
|
|
84
|
-
};
|
|
65
|
+
const applyFilter = (filterValue, value, filterFn) => {
|
|
66
|
+
let result: boolean = true;
|
|
85
67
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else if (
|
|
91
|
-
(!firstFilterOption || !firstFilterValue) &&
|
|
92
|
-
secondFilterOption &&
|
|
93
|
-
secondFilterValue?.length
|
|
94
|
-
) {
|
|
95
|
-
return textFilter(secondFilterOption, secondFilterValue, value);
|
|
96
|
-
} else if (
|
|
97
|
-
(!secondFilterOption || !secondFilterValue?.length) &&
|
|
98
|
-
firstFilterOption &&
|
|
99
|
-
firstFilterValue?.length
|
|
100
|
-
) {
|
|
101
|
-
return textFilter(firstFilterOption, firstFilterValue, value);
|
|
102
|
-
}
|
|
103
|
-
return (
|
|
104
|
-
textFilter(firstFilterOption, firstFilterValue, value) &&
|
|
105
|
-
textFilter(secondFilterOption, secondFilterValue, value)
|
|
106
|
-
);
|
|
107
|
-
};
|
|
68
|
+
const filters = Object.keys(filterValue).map((key) => ({
|
|
69
|
+
option: key,
|
|
70
|
+
value: filterValue[key]
|
|
71
|
+
}));
|
|
108
72
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return true;
|
|
113
|
-
} else if ((!firstFilterOption || !firstFilterValue) && secondFilterOption && secondFilterValue) {
|
|
114
|
-
return dateFilter(secondFilterOption, secondFilterValue, value);
|
|
115
|
-
} else if ((!secondFilterOption || !secondFilterValue) && firstFilterOption && firstFilterValue) {
|
|
116
|
-
return dateFilter(firstFilterOption, firstFilterValue, value);
|
|
117
|
-
}
|
|
73
|
+
filters.forEach((filter) => {
|
|
74
|
+
result = result && (filter.value ? filterFn(filter.option, filter.value, value) : true);
|
|
75
|
+
});
|
|
118
76
|
|
|
119
|
-
return
|
|
120
|
-
dateFilter(firstFilterOption, firstFilterValue, value) &&
|
|
121
|
-
dateFilter(secondFilterOption, secondFilterValue, value)
|
|
122
|
-
);
|
|
77
|
+
return result;
|
|
123
78
|
};
|
|
124
79
|
|
|
125
80
|
export const columnFilter: ColumnFilterFn = ({ filterValue, value }) => {
|
|
126
|
-
if (typeof value === '
|
|
127
|
-
return
|
|
81
|
+
if (typeof value === 'object' && value instanceof Date) {
|
|
82
|
+
return applyFilter(filterValue, value, dateFilter);
|
|
128
83
|
} else if (typeof value === 'number') {
|
|
129
|
-
return
|
|
130
|
-
} else if (typeof value === '
|
|
131
|
-
return
|
|
84
|
+
return applyFilter(filterValue, value, numberFilter);
|
|
85
|
+
} else if (typeof value === 'string') {
|
|
86
|
+
return applyFilter(filterValue, value, textFilter);
|
|
132
87
|
}
|
|
88
|
+
|
|
133
89
|
return false;
|
|
134
90
|
};
|
|
135
91
|
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import type { FilterOptionsEnum } from '$models/Enums';
|
|
2
|
+
import type { Columns, Filter, ServerColumn } from '$models/Models';
|
|
3
|
+
|
|
4
|
+
// Function to determine minWidth for a column to simplify the logic in the HTML
|
|
5
|
+
export const minWidth = (id: string, columns: Columns | undefined) => {
|
|
6
|
+
if (columns && id in columns) {
|
|
7
|
+
return columns[id].minWidth ?? 0;
|
|
8
|
+
}
|
|
9
|
+
return 0;
|
|
10
|
+
};
|
|
11
|
+
// Function to determine fixedWidth for a column to simplify the logic in the HTML
|
|
12
|
+
export const fixedWidth = (id: string, columns: Columns | undefined) => {
|
|
13
|
+
if (columns && id in columns) {
|
|
14
|
+
return columns[id].fixedWidth ?? 0;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
};
|
|
18
|
+
// Function to create custom styles for the columns to simplify the logic in the HTML
|
|
19
|
+
export const cellStyle = (id: string, columns: Columns | undefined) => {
|
|
20
|
+
const minW = minWidth(id, columns);
|
|
21
|
+
const fixedW = fixedWidth(id, columns);
|
|
22
|
+
const styles: string[] = [];
|
|
23
|
+
|
|
24
|
+
// If minWidth is provided, add to styles
|
|
25
|
+
minW && styles.push(`min-width: ${minW}px`);
|
|
26
|
+
// If fixedWidth is provided, add to styles
|
|
27
|
+
fixedW && styles.push(`width: ${fixedW}px`);
|
|
28
|
+
// Create and return styles separated by ';'
|
|
29
|
+
return styles.join(';');
|
|
30
|
+
};
|
|
31
|
+
// Function to normalize the filters for back-end
|
|
32
|
+
export const normalizeFilters = (filters: {
|
|
33
|
+
[key: string]: { [key in FilterOptionsEnum]?: number | string | Date };
|
|
34
|
+
}) => {
|
|
35
|
+
let filter: Filter[] = [];
|
|
36
|
+
|
|
37
|
+
// Add filters to the request
|
|
38
|
+
Object.keys(filters).forEach((key) => {
|
|
39
|
+
Object.keys(filters[key])
|
|
40
|
+
.filter((k) => filters[key][k] !== undefined)
|
|
41
|
+
.forEach((k) => {
|
|
42
|
+
filter.push({
|
|
43
|
+
column: key,
|
|
44
|
+
filterBy: k as FilterOptionsEnum,
|
|
45
|
+
value: filters[key][k]
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return filter;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const exportAsCsv = (tableId: string, exportedData: string) => {
|
|
54
|
+
// Creating a hidden anchor element to download the CSV file
|
|
55
|
+
const anchor = document.createElement('a');
|
|
56
|
+
anchor.style.display = 'none';
|
|
57
|
+
anchor.href = `data:text/csv;charset=utf-8,${encodeURIComponent(exportedData)}`;
|
|
58
|
+
anchor.download = `${tableId}.csv`;
|
|
59
|
+
document.body.appendChild(anchor);
|
|
60
|
+
anchor.click();
|
|
61
|
+
document.body.removeChild(anchor);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Resetting the resized columns and/or rows
|
|
65
|
+
export const resetResize = (
|
|
66
|
+
headerRows: any,
|
|
67
|
+
pageRows: any,
|
|
68
|
+
tableId: string,
|
|
69
|
+
columns: Columns | undefined,
|
|
70
|
+
resizable: 'none' | 'rows' | 'columns' | 'both'
|
|
71
|
+
) => {
|
|
72
|
+
// Run only if resizable is not none
|
|
73
|
+
if (resizable === 'columns' || resizable === 'both') {
|
|
74
|
+
headerRows.forEach((row) => {
|
|
75
|
+
row.cells.forEach((cell) => {
|
|
76
|
+
const minW = minWidth(cell.id, columns);
|
|
77
|
+
const fixedW = fixedWidth(cell.id, columns);
|
|
78
|
+
// If a fixedWidth is provided for a column, then reset the width to that value
|
|
79
|
+
fixedW &&
|
|
80
|
+
document
|
|
81
|
+
.getElementById(`th-${tableId}-${cell.id}`)
|
|
82
|
+
?.style.setProperty('width', `${fixedW}px`);
|
|
83
|
+
// If a minWidth is provided for a column, then reset the width to that value
|
|
84
|
+
minW &&
|
|
85
|
+
document
|
|
86
|
+
.getElementById(`th-${tableId}-${cell.id}`)
|
|
87
|
+
?.style.setProperty('width', `${minW}px`);
|
|
88
|
+
// If neither minWidth nor fixedWidth provided for a column, then reset the width to auto
|
|
89
|
+
!minW &&
|
|
90
|
+
!fixedW &&
|
|
91
|
+
document.getElementById(`th-${tableId}-${cell.id}`)?.style.setProperty('width', 'auto');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (resizable === 'rows' || resizable === 'both') {
|
|
97
|
+
pageRows.forEach((row) => {
|
|
98
|
+
row.cells.forEach((cell) => {
|
|
99
|
+
// Reset all row heights to auto
|
|
100
|
+
document
|
|
101
|
+
.getElementById(`${tableId}-${cell.id}-${row.id}`)
|
|
102
|
+
?.style.setProperty('height', 'auto');
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const missingValuesFn = (key: number, missingValues: { [key: string | number]: string }) => {
|
|
109
|
+
return key in missingValues ? missingValues[key] : key.toString();
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const convertServerColumns = (columns: ServerColumn[]) => {
|
|
113
|
+
const columnsConfig: Columns = {};
|
|
114
|
+
|
|
115
|
+
columns.forEach((col) => {
|
|
116
|
+
let instructions = {};
|
|
117
|
+
|
|
118
|
+
// if (col.instructions?.displayPattern) {
|
|
119
|
+
// instructions = {
|
|
120
|
+
// toStringFn: (date: Date) =>
|
|
121
|
+
// date.toLocaleString('en-US', col.instructions?.displayPattern || {}),
|
|
122
|
+
// toSortableValueFn: (date: Date) => date.getTime(),
|
|
123
|
+
// toFilterableValueFn: (date: Date) => date
|
|
124
|
+
// };
|
|
125
|
+
// }
|
|
126
|
+
|
|
127
|
+
if (col.instructions?.missingValues) {
|
|
128
|
+
instructions = {
|
|
129
|
+
...instructions,
|
|
130
|
+
toStringFn: (key) => missingValuesFn(key, col.instructions?.missingValues || {})
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
columnsConfig[col.column] = {
|
|
135
|
+
exclude: col.exclude,
|
|
136
|
+
instructions
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return columnsConfig;
|
|
141
|
+
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
fileUploaderType
|
|
7
7
|
} from '../../models/Models.js';
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import Dropzone from 'svelte-file-dropzone';
|
|
10
10
|
import Fa from 'svelte-fa/src/fa.svelte';
|
|
11
11
|
|
|
12
12
|
import Spinner from '../page/Spinner.svelte';
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
{#if model}
|
|
170
170
|
<!--if model exist -->
|
|
171
171
|
<div>
|
|
172
|
-
<
|
|
172
|
+
<Dropzone
|
|
173
173
|
on:drop={handleFilesSelect}
|
|
174
174
|
accept={model.accept}
|
|
175
175
|
multiple={model.multiple}
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
{/each}
|
|
188
188
|
{/if}
|
|
189
189
|
</p>
|
|
190
|
-
</
|
|
190
|
+
</Dropzone>
|
|
191
191
|
{#if isUploading}
|
|
192
192
|
<ProgressBar value={undefined}/>
|
|
193
193
|
{/if}
|
package/src/lib/models/Enums.ts
CHANGED
|
@@ -38,3 +38,25 @@ export enum notificationType {
|
|
|
38
38
|
error,
|
|
39
39
|
surface
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
// Server-side table fitler types
|
|
43
|
+
export enum FilterOptionsEnum {
|
|
44
|
+
'e' = 'e', // Equal to
|
|
45
|
+
'ne' = 'ne', // Not equal to
|
|
46
|
+
'gt' = 'gt', // Greater than
|
|
47
|
+
'lt' = 'lt', // Less than
|
|
48
|
+
'gte' = 'gte', // Greater than or equal to
|
|
49
|
+
'lte' = 'lte', // Less than or equal to
|
|
50
|
+
|
|
51
|
+
'c' = 'c', // Contains
|
|
52
|
+
'nc' = 'nc', // Does not contain
|
|
53
|
+
'sw' = 'sw', // Starts with
|
|
54
|
+
'ew' = 'ew', // Ends with,
|
|
55
|
+
|
|
56
|
+
'o' = 'o', // On (date)
|
|
57
|
+
'sf' = 'sf', // Starting from (date)
|
|
58
|
+
'a' = 'a', // After (date)
|
|
59
|
+
'u' = 'u', // Until (date)
|
|
60
|
+
'b' = 'b', // Before (date)
|
|
61
|
+
'no' = 'no' // Not on (date)
|
|
62
|
+
}
|