@lavalogic/scoria 0.0.29 → 0.0.30
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/Base/Pagination.svelte +237 -0
- package/dist/Components/Base/Pagination.svelte.d.ts +33 -0
- package/dist/Components/Dial.svelte +2 -2
- package/dist/Components/Table/Body/QuickSearchCell.svelte +14 -4
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +25 -14
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +49 -0
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte.d.ts +28 -0
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +15 -44
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +7 -1
- package/dist/Components/Table/Body/Rows/TableRow.svelte +5 -5
- package/dist/Components/Table/Body/TableBody.svelte +1 -1
- package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDef.svelte.js +2 -1
- package/dist/Components/Table/Misc/FilterInput.svelte +6 -0
- package/dist/Components/Table/Types/Columns/ColumnPinningState.d.ts +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.d.ts +1 -1
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.d.ts +1 -0
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +8 -3
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +8 -0
- package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +9 -11
- package/dist/Components/Table/Types/Context/TableContext.svelte.js +153 -143
- package/dist/Components/Table/Types/DataRepository/LocalTableDataRepository.svelte.js +6 -7
- package/dist/Components/Table/Types/Filtering/FilterValueType.d.ts +8 -0
- package/dist/Components/Table/Types/Filtering/FilterValueType.js +8 -0
- package/dist/Components/Table/Types/Filtering/NumberDateFilterMode.d.ts +0 -1
- package/dist/Components/Table/Types/Filtering/NumberDateFilterMode.js +1 -1
- package/dist/Delay/Delay.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +22 -21
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts" module>
|
|
4
|
+
import { autoPluralise, generateShortUUID } from '../../Helpers/Helpers.svelte.js';
|
|
5
|
+
import { Button, Colour, Icon, NumberInput, Side, Size, Variant } from '../../index.js';
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
|
|
8
|
+
export interface PaginationProps<T extends object> {
|
|
9
|
+
items: T[];
|
|
10
|
+
key: string & keyof T;
|
|
11
|
+
pageSize?: number;
|
|
12
|
+
snippet: Snippet<[T, number]>;
|
|
13
|
+
itemName?: string;
|
|
14
|
+
setPageSize?: (size: number) => void;
|
|
15
|
+
}
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<script lang="ts" generics="T extends object">
|
|
19
|
+
const {
|
|
20
|
+
items,
|
|
21
|
+
key,
|
|
22
|
+
pageSize = 20,
|
|
23
|
+
snippet,
|
|
24
|
+
itemName = 'Item',
|
|
25
|
+
setPageSize
|
|
26
|
+
}: PaginationProps<T> = $props();
|
|
27
|
+
|
|
28
|
+
const _uuid = generateShortUUID();
|
|
29
|
+
let pageIndex = $state(0);
|
|
30
|
+
let pageValue = $derived(pageIndex + 1);
|
|
31
|
+
const startIndex = $derived(pageIndex * pageSize);
|
|
32
|
+
const pageItems = $derived(items.slice(startIndex, startIndex + pageSize));
|
|
33
|
+
|
|
34
|
+
const lastPage = $derived(Math.ceil(items.length / pageSize));
|
|
35
|
+
const lastPageIndex = $derived(lastPage - 1);
|
|
36
|
+
|
|
37
|
+
let debounceTimeout = -1;
|
|
38
|
+
function onNumberInput(e: Event) {
|
|
39
|
+
const page = parseInt((e.target as HTMLInputElement).value);
|
|
40
|
+
|
|
41
|
+
clearTimeout(debounceTimeout);
|
|
42
|
+
if (!isNaN(page)) {
|
|
43
|
+
debounceTimeout = setTimeout(() => {
|
|
44
|
+
pageIndex = Math.max(page - 1, 0);
|
|
45
|
+
}, 400) as unknown as number;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let pageButtons: number[] = $state([]);
|
|
50
|
+
|
|
51
|
+
$effect(() => {
|
|
52
|
+
if (pageIndex == null) {
|
|
53
|
+
pageButtons = [1];
|
|
54
|
+
} else {
|
|
55
|
+
const startingPage = Math.min(lastPage - 2, pageIndex - 1);
|
|
56
|
+
const pageToStartWith = Math.max(1, Math.min(startingPage, lastPage - 4));
|
|
57
|
+
|
|
58
|
+
pageButtons = new Array(Math.min(lastPage, 5))
|
|
59
|
+
.fill(pageToStartWith)
|
|
60
|
+
.map((item, index) => item + index);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<!-- PROPER -->
|
|
66
|
+
<!--
|
|
67
|
+
|
|
68
|
+
<div class="pagination">
|
|
69
|
+
<div>page {pageIndex}</div>
|
|
70
|
+
<button
|
|
71
|
+
onclick={() => {
|
|
72
|
+
pageIndex = Math.max(pageIndex - 1, 0);
|
|
73
|
+
}}>Previous</button
|
|
74
|
+
>
|
|
75
|
+
<button
|
|
76
|
+
onclick={() => {
|
|
77
|
+
pageIndex = Math.min(pageIndex + 1, lastPageIndex);
|
|
78
|
+
}}>Next</button
|
|
79
|
+
>
|
|
80
|
+
</div>
|
|
81
|
+
</div> -->
|
|
82
|
+
|
|
83
|
+
<div class="wrapper">
|
|
84
|
+
{#each pageItems as item, index (item[key])}
|
|
85
|
+
{@render snippet(item, index)}
|
|
86
|
+
{/each}
|
|
87
|
+
<div class="spread_row bottom_row">
|
|
88
|
+
<div class="block">
|
|
89
|
+
<span>{items.length} {autoPluralise(itemName, items.length)}</span>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div class="block records-per-page">
|
|
93
|
+
<span>Records per Page: {pageSize}</span>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div class="spacer"></div>
|
|
97
|
+
<!-- {/* TODO switch to a lib element for this */} -->
|
|
98
|
+
|
|
99
|
+
<div class="scrollable">
|
|
100
|
+
<div class="block">
|
|
101
|
+
<Icon name="paper" colour={Colour['$ui-blue-6']} />
|
|
102
|
+
<span>{lastPage} {autoPluralise('Page', lastPage)}</span>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div class="block">
|
|
106
|
+
<label for="{_uuid}-jump-to-page"
|
|
107
|
+
><Icon name="arrow-move-horizontal" colour={Colour['$ui-blue-6']} /></label
|
|
108
|
+
>
|
|
109
|
+
|
|
110
|
+
<label for="{_uuid}-jump-to-page">Jump to page:</label>
|
|
111
|
+
|
|
112
|
+
<NumberInput id="{_uuid}-jump-to-page" value={pageValue} oninput={onNumberInput} />
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<div class="block nopad page-arrow">
|
|
116
|
+
<Button
|
|
117
|
+
variant={Variant.Toolbar}
|
|
118
|
+
disabled={pageIndex === 0}
|
|
119
|
+
side={Side.Bottom}
|
|
120
|
+
onclick={() => {
|
|
121
|
+
pageIndex = Math.max(pageIndex - 1, 0);
|
|
122
|
+
}}
|
|
123
|
+
size={Size.FillHeight}
|
|
124
|
+
iconLeft={{
|
|
125
|
+
name: 'left-close',
|
|
126
|
+
size: Size.FillHeight
|
|
127
|
+
}}>Previous Page</Button
|
|
128
|
+
>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
{#key pageButtons}
|
|
132
|
+
{#each pageButtons as pageNumber (pageNumber)}
|
|
133
|
+
<div class="block nopad">
|
|
134
|
+
<Button
|
|
135
|
+
variant={Variant.Toolbar}
|
|
136
|
+
side={Side.Bottom}
|
|
137
|
+
size={Size.FillHeight}
|
|
138
|
+
toggled={pageIndex + 1 === pageNumber}
|
|
139
|
+
onclick={() => {
|
|
140
|
+
pageIndex = pageNumber - 1;
|
|
141
|
+
}}>{pageNumber}</Button
|
|
142
|
+
>
|
|
143
|
+
</div>
|
|
144
|
+
{/each}
|
|
145
|
+
{/key}
|
|
146
|
+
|
|
147
|
+
<div class="block nopad page-arrow">
|
|
148
|
+
<Button
|
|
149
|
+
variant={Variant.Toolbar}
|
|
150
|
+
side={Side.Bottom}
|
|
151
|
+
size={Size.FillHeight}
|
|
152
|
+
onclick={() => {
|
|
153
|
+
pageIndex = Math.min(pageIndex + 1, lastPageIndex);
|
|
154
|
+
}}
|
|
155
|
+
disabled={pageIndex == lastPageIndex}
|
|
156
|
+
iconRight={{
|
|
157
|
+
name: 'right-close',
|
|
158
|
+
size: Size.FillHeight
|
|
159
|
+
}}>Next Page</Button
|
|
160
|
+
>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<style>.wrapper {
|
|
167
|
+
border: solid 3px #cbd4da;
|
|
168
|
+
border-radius: 4px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.spread_row {
|
|
172
|
+
border-top: solid 1px #cbd4da;
|
|
173
|
+
overflow: visible;
|
|
174
|
+
width: 100%;
|
|
175
|
+
z-index: 1;
|
|
176
|
+
display: flex;
|
|
177
|
+
flex-flow: row nowrap;
|
|
178
|
+
background-color: #cbd4da;
|
|
179
|
+
gap: 1px;
|
|
180
|
+
justify-content: flex-start;
|
|
181
|
+
align-items: stretch;
|
|
182
|
+
line-height: 1;
|
|
183
|
+
bottom: 0;
|
|
184
|
+
}
|
|
185
|
+
.spread_row.limited {
|
|
186
|
+
overflow: hidden;
|
|
187
|
+
}
|
|
188
|
+
.spread_row .scrollable {
|
|
189
|
+
display: flex;
|
|
190
|
+
flex-flow: row nowrap;
|
|
191
|
+
box-sizing: border-box;
|
|
192
|
+
overflow: auto;
|
|
193
|
+
background-color: #cbd4da;
|
|
194
|
+
gap: 1px;
|
|
195
|
+
}
|
|
196
|
+
.spread_row .scrollable > .block {
|
|
197
|
+
background-color: #ffffff;
|
|
198
|
+
}
|
|
199
|
+
.spread_row .block {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-flow: row nowrap;
|
|
202
|
+
align-items: center;
|
|
203
|
+
justify-content: center;
|
|
204
|
+
gap: 0.5rem;
|
|
205
|
+
padding: 0 0.6rem;
|
|
206
|
+
--input-height: 2rem;
|
|
207
|
+
--input-width: 4rem;
|
|
208
|
+
--input-border: none;
|
|
209
|
+
}
|
|
210
|
+
.spread_row .block.nopad {
|
|
211
|
+
padding: 0;
|
|
212
|
+
--button-padding-horizontal: 1rem;
|
|
213
|
+
--button-padding-vertical: 0.56rem;
|
|
214
|
+
}
|
|
215
|
+
.spread_row .block.nopad.page-arrow {
|
|
216
|
+
--button-padding-horizontal: 0.6rem;
|
|
217
|
+
--button-padding-vertical: 0.42rem;
|
|
218
|
+
}
|
|
219
|
+
.spread_row span,
|
|
220
|
+
.spread_row label {
|
|
221
|
+
white-space: nowrap;
|
|
222
|
+
font-size: 0.8125rem;
|
|
223
|
+
font-weight: 600;
|
|
224
|
+
color: #3a4952;
|
|
225
|
+
}
|
|
226
|
+
.spread_row > * {
|
|
227
|
+
background-color: #ffffff;
|
|
228
|
+
}
|
|
229
|
+
.spread_row > *:first-child {
|
|
230
|
+
border-bottom-left-radius: 4px;
|
|
231
|
+
}
|
|
232
|
+
.spread_row > *:last-child {
|
|
233
|
+
border-bottom-right-radius: 4px;
|
|
234
|
+
}
|
|
235
|
+
.spread_row .spacer {
|
|
236
|
+
flex-grow: 2;
|
|
237
|
+
}</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export interface PaginationProps<T extends object> {
|
|
3
|
+
items: T[];
|
|
4
|
+
key: string & keyof T;
|
|
5
|
+
pageSize?: number;
|
|
6
|
+
snippet: Snippet<[T, number]>;
|
|
7
|
+
itemName?: string;
|
|
8
|
+
setPageSize?: (size: number) => void;
|
|
9
|
+
}
|
|
10
|
+
declare function $$render<T extends object>(): {
|
|
11
|
+
props: PaginationProps<T>;
|
|
12
|
+
exports: {};
|
|
13
|
+
bindings: "";
|
|
14
|
+
slots: {};
|
|
15
|
+
events: {};
|
|
16
|
+
};
|
|
17
|
+
declare class __sveltets_Render<T extends object> {
|
|
18
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
19
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
20
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
21
|
+
bindings(): "";
|
|
22
|
+
exports(): {};
|
|
23
|
+
}
|
|
24
|
+
interface $$IsomorphicComponent {
|
|
25
|
+
new <T extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
26
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
27
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
28
|
+
<T extends object>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
29
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
30
|
+
}
|
|
31
|
+
declare const Pagination: $$IsomorphicComponent;
|
|
32
|
+
type Pagination<T extends object> = InstanceType<typeof Pagination<T>>;
|
|
33
|
+
export default Pagination;
|
|
@@ -122,9 +122,9 @@
|
|
|
122
122
|
onMouseUp();
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
+
const handledKeys = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Enter']);
|
|
125
126
|
function onkeydown(e: KeyboardEvent) {
|
|
126
|
-
|
|
127
|
-
if (handledKeys.includes(e.key)) {
|
|
127
|
+
if (handledKeys.has(e.key)) {
|
|
128
128
|
e.preventDefault();
|
|
129
129
|
|
|
130
130
|
if (e.key === 'ArrowLeft') {
|
|
@@ -27,10 +27,13 @@
|
|
|
27
27
|
import { StringFilterMode } from '../Types/Filtering/StringFilterMode.js';
|
|
28
28
|
import type { SelectOption } from '../../../Types/Internal/SelectOption.js';
|
|
29
29
|
import type { Column } from '../Types/Columns/Column.js';
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
import { AbstractDisplayDef } from '../Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js';
|
|
32
32
|
import { DateInputDef } from '../Types/Columns/Definitions/Accessors/DateInputDef.svelte.js';
|
|
33
33
|
import { SelectDef } from '../Types/Columns/Definitions/Accessors/SelectDef.svelte.js';
|
|
34
|
+
import { AccessorDef } from '../Types/Columns/Definitions/Accessors/AccessorDef.svelte.js';
|
|
35
|
+
import { NumberInputDef } from '../Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js';
|
|
36
|
+
import { dev } from '$app/environment';
|
|
34
37
|
|
|
35
38
|
export interface QuickSearchCellProps<T extends object> {
|
|
36
39
|
column: Column<T>;
|
|
@@ -61,7 +64,9 @@
|
|
|
61
64
|
hasFilterFn || hasAcceptableColumnType || (customFilters?.has(def.id) ?? false)
|
|
62
65
|
);
|
|
63
66
|
const isNumeric = $derived(
|
|
64
|
-
|
|
67
|
+
def instanceof NumberInputDef ||
|
|
68
|
+
def.filterValueType == 'Number' ||
|
|
69
|
+
customFilter?.type === CustomFilterType.Number
|
|
65
70
|
);
|
|
66
71
|
const options = $derived(
|
|
67
72
|
isSelect
|
|
@@ -87,8 +92,8 @@
|
|
|
87
92
|
let valueMin: number | null = $state(null);
|
|
88
93
|
let valueMax: number | null = $state(null);
|
|
89
94
|
|
|
90
|
-
// HACK crappy bodge to get typescript to understand that this won't be always null
|
|
91
95
|
let selectedOption: SelectOption<string | number> | null = $state(
|
|
96
|
+
// HACK crappy bodge to get typescript to understand that this won't be always null
|
|
92
97
|
null as unknown as SelectOption<string | number>
|
|
93
98
|
);
|
|
94
99
|
|
|
@@ -109,7 +114,6 @@
|
|
|
109
114
|
|
|
110
115
|
function getFilteringStateValue(): unknown {
|
|
111
116
|
const gotValue = tableContext.paginationRepo?.filtering.find((it) => it.id === def.id)?.value;
|
|
112
|
-
console.log(gotValue);
|
|
113
117
|
return gotValue;
|
|
114
118
|
}
|
|
115
119
|
|
|
@@ -123,6 +127,12 @@
|
|
|
123
127
|
const gotValue = getFilteringStateValue() as unknown as
|
|
124
128
|
| Array<string | number | SelectOption<string | number>>
|
|
125
129
|
| undefined;
|
|
130
|
+
if (dev) {
|
|
131
|
+
// eslint-disable-next-line no-debugger
|
|
132
|
+
debugger;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
//TODO redo the below in a more performant way if possible
|
|
126
136
|
const x = (await options).filter((it) => gotValue?.includes(it.value));
|
|
127
137
|
selectedOptions = x;
|
|
128
138
|
});
|
|
@@ -26,24 +26,31 @@
|
|
|
26
26
|
isBeingTargeted = false;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function makeKVPairs(item: string, index: number): readonly [string, number] {
|
|
30
|
+
return [item, index];
|
|
31
|
+
}
|
|
29
32
|
function togglePinLeft() {
|
|
30
33
|
if (columnDef == null) return;
|
|
31
34
|
|
|
32
35
|
tableContext.setColumnPinning((pinning) => {
|
|
33
|
-
const leftPinIndex = pinning.left?.
|
|
34
|
-
const left = pinning.left?.
|
|
36
|
+
const leftPinIndex = pinning.left?.get(columnDef!.id) ?? -1;
|
|
37
|
+
const left = [...(pinning.left?.keys() ?? [])];
|
|
35
38
|
if (leftPinIndex !== -1) {
|
|
36
39
|
left.splice(leftPinIndex, 1);
|
|
37
40
|
} else {
|
|
38
41
|
left.push(columnDef!.id);
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
const rightPinIndex = pinning.right?.
|
|
42
|
-
const right = pinning.right?.
|
|
44
|
+
const rightPinIndex = pinning.right?.get(columnDef!.id) ?? -1;
|
|
45
|
+
const right = [...(pinning.right?.keys() ?? [])];
|
|
43
46
|
if (rightPinIndex !== -1) {
|
|
44
47
|
right.splice(rightPinIndex, 1);
|
|
45
48
|
}
|
|
46
|
-
return {
|
|
49
|
+
return {
|
|
50
|
+
...pinning,
|
|
51
|
+
left: new Map(left.map(makeKVPairs)),
|
|
52
|
+
right: new Map(right.map(makeKVPairs))
|
|
53
|
+
};
|
|
47
54
|
});
|
|
48
55
|
}
|
|
49
56
|
|
|
@@ -51,8 +58,8 @@
|
|
|
51
58
|
if (columnDef == null) return;
|
|
52
59
|
|
|
53
60
|
tableContext.setColumnPinning((pinning) => {
|
|
54
|
-
const rightPinIndex = pinning.right?.
|
|
55
|
-
const right = pinning.right?.
|
|
61
|
+
const rightPinIndex = pinning.right?.get(columnDef!.id) ?? -1;
|
|
62
|
+
const right = [...(pinning.right?.keys() ?? [])];
|
|
56
63
|
|
|
57
64
|
if (rightPinIndex !== -1) {
|
|
58
65
|
right.splice(rightPinIndex, 1);
|
|
@@ -60,13 +67,17 @@
|
|
|
60
67
|
right.push(columnDef!.id);
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
const leftPinIndex = pinning.left?.
|
|
64
|
-
const left = pinning.left?.
|
|
70
|
+
const leftPinIndex = pinning.left?.get(columnDef!.id) ?? -1;
|
|
71
|
+
const left = [...(pinning.left?.keys() ?? [])];
|
|
65
72
|
if (leftPinIndex !== -1) {
|
|
66
73
|
left.splice(leftPinIndex, 1);
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
...pinning,
|
|
78
|
+
left: new Map(left.map(makeKVPairs)),
|
|
79
|
+
right: new Map(right.map(makeKVPairs))
|
|
80
|
+
};
|
|
70
81
|
});
|
|
71
82
|
}
|
|
72
83
|
|
|
@@ -114,22 +125,22 @@
|
|
|
114
125
|
/>
|
|
115
126
|
|
|
116
127
|
{#if tableContext.allowColumnReordering}
|
|
117
|
-
<!-- value={tableContext.columnPinning.left?.
|
|
128
|
+
<!-- value={tableContext.columnPinning.left?.has(columnDef.id) ?? false} -->
|
|
118
129
|
<Checkbox
|
|
119
130
|
disabled={isExpandColumn}
|
|
120
131
|
icon={{ name: 'pin-left' }}
|
|
121
132
|
id={`is-pinned-left-${tableContext.tableName}-${columnDef.id}`}
|
|
122
|
-
value={tableContext.columnPinning.left?.
|
|
133
|
+
value={tableContext.columnPinning.left?.has(columnDef.id) || false}
|
|
123
134
|
onchange={() => {
|
|
124
135
|
togglePinLeft();
|
|
125
136
|
}}
|
|
126
137
|
/>
|
|
127
|
-
<!-- value={tableContext.columnPinning.right?.
|
|
138
|
+
<!-- value={tableContext.columnPinning.right?.has(columnDef.id) ?? false} -->
|
|
128
139
|
<Checkbox
|
|
129
140
|
disabled={isExpandColumn}
|
|
130
141
|
icon={{ name: 'pin-right' }}
|
|
131
142
|
id={`is-pinned-right-${tableContext.tableName}-${columnDef.id}`}
|
|
132
|
-
value={tableContext.columnPinning.right?.
|
|
143
|
+
value={tableContext.columnPinning.right?.has(columnDef.id) || false}
|
|
133
144
|
onchange={() => {
|
|
134
145
|
togglePinRight();
|
|
135
146
|
}}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script lang="ts" module>
|
|
4
|
+
import FocusableImmutableCell from './FocusableImmutableCell.svelte';
|
|
5
|
+
import type { TableCell } from '../../../Types/Columns/TableCell.js';
|
|
6
|
+
import TableNumberInput from './TableNumberInput.svelte';
|
|
7
|
+
import TableDatePicker from './TableDatePicker.svelte';
|
|
8
|
+
import TableSelect from './TableSelect.svelte';
|
|
9
|
+
import TableQuerySelect from './TableQuerySelect.svelte';
|
|
10
|
+
import TableCheckbox from './TableCheckbox.svelte';
|
|
11
|
+
import TableTextInput from './TableTextInput.svelte';
|
|
12
|
+
import type { Component } from 'svelte';
|
|
13
|
+
import { AccessorDef } from '../../../Types/Columns/Definitions/Accessors/AccessorDef.svelte.js';
|
|
14
|
+
import type { ColumnDef } from '../../../Types/Columns/Definitions/ColumnDef.svelte.js';
|
|
15
|
+
|
|
16
|
+
export interface AccessorComponentProps<T extends object> {
|
|
17
|
+
cell: TableCell<T>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const cellTypes: Record<
|
|
21
|
+
'Number' | 'Date' | 'Select' | 'Checkbox' | 'Query' | 'Text',
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
+
Component<any>
|
|
24
|
+
> = {
|
|
25
|
+
Number: TableNumberInput,
|
|
26
|
+
Date: TableDatePicker,
|
|
27
|
+
Select: TableSelect,
|
|
28
|
+
Query: TableQuerySelect,
|
|
29
|
+
Checkbox: TableCheckbox,
|
|
30
|
+
Text: TableTextInput
|
|
31
|
+
} as const;
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<script lang="ts" generics="T extends object">
|
|
35
|
+
const { cell }: AccessorComponentProps<T> = $props();
|
|
36
|
+
|
|
37
|
+
const CurrentComponent = $derived(getAppropriateAccessorDef(cell.column.columnDef));
|
|
38
|
+
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
|
+
function getAppropriateAccessorDef(columnDef: ColumnDef<T>): Component<any> {
|
|
41
|
+
if (columnDef instanceof AccessorDef) {
|
|
42
|
+
return cellTypes[columnDef.accessorType];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return FocusableImmutableCell;
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<CurrentComponent {cell} />
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TableCell } from '../../../Types/Columns/TableCell.js';
|
|
2
|
+
export interface AccessorComponentProps<T extends object> {
|
|
3
|
+
cell: TableCell<T>;
|
|
4
|
+
}
|
|
5
|
+
declare function $$render<T extends object>(): {
|
|
6
|
+
props: AccessorComponentProps<T>;
|
|
7
|
+
exports: {};
|
|
8
|
+
bindings: "";
|
|
9
|
+
slots: {};
|
|
10
|
+
events: {};
|
|
11
|
+
};
|
|
12
|
+
declare class __sveltets_Render<T extends object> {
|
|
13
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
14
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
15
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
16
|
+
bindings(): "";
|
|
17
|
+
exports(): {};
|
|
18
|
+
}
|
|
19
|
+
interface $$IsomorphicComponent {
|
|
20
|
+
new <T extends object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
21
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
22
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
23
|
+
<T extends object>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
24
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
25
|
+
}
|
|
26
|
+
declare const AccessorComponent: $$IsomorphicComponent;
|
|
27
|
+
type AccessorComponent<T extends object> = InstanceType<typeof AccessorComponent<T>>;
|
|
28
|
+
export default AccessorComponent;
|
|
@@ -7,16 +7,9 @@
|
|
|
7
7
|
import type { Component } from 'svelte';
|
|
8
8
|
import ExpandCell from './ExpandCell.svelte';
|
|
9
9
|
import { ExpandDef } from '../../../Types/Columns/Definitions/Expand/ExpandDef.svelte.js';
|
|
10
|
-
import type { ColumnDef } from '../../../Types/Columns/Definitions/ColumnDef.svelte.js';
|
|
11
10
|
import type { TableCell } from '../../../Types/Columns/TableCell.js';
|
|
12
11
|
import { DisplayType } from '../../../Types/Columns/DisplayType.js';
|
|
13
|
-
|
|
14
|
-
import TableDatePicker from './TableDatePicker.svelte';
|
|
15
|
-
import TableSelect from './TableSelect.svelte';
|
|
16
|
-
import TableQuerySelect from './TableQuerySelect.svelte';
|
|
17
|
-
import TableCheckbox from './TableCheckbox.svelte';
|
|
18
|
-
import TableTextInput from './TableTextInput.svelte';
|
|
19
|
-
import { AccessorDef } from '../../../Types/Columns/Definitions/Accessors/AccessorDef.svelte.js';
|
|
12
|
+
|
|
20
13
|
import { ActionsDef } from '../../../Types/Columns/Definitions/Actions/ActionsDef.svelte.js';
|
|
21
14
|
import ValidityCell from './ValidityCell.svelte';
|
|
22
15
|
import TableRowSelectionCheckbox from './TableRowSelectionCheckbox.svelte';
|
|
@@ -28,19 +21,8 @@
|
|
|
28
21
|
import type { ProgressBarTableCell } from '../../../Types/Columns/ProgressBarTableCell.js';
|
|
29
22
|
import { RowSelectionDef } from '../../../Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js';
|
|
30
23
|
import type { ExpandTableCell } from '../../../Types/Columns/ExpandTableCell.js';
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'Number' | 'Date' | 'Select' | 'Checkbox' | 'Query' | 'Text',
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
-
Component<any>
|
|
36
|
-
> = {
|
|
37
|
-
Number: TableNumberInput,
|
|
38
|
-
Date: TableDatePicker,
|
|
39
|
-
Select: TableSelect,
|
|
40
|
-
Query: TableQuerySelect,
|
|
41
|
-
Checkbox: TableCheckbox,
|
|
42
|
-
Text: TableTextInput
|
|
43
|
-
} as const;
|
|
24
|
+
import type { ActionsTableCell } from './TableAction.svelte';
|
|
25
|
+
import AccessorComponent from './AccessorComponent.svelte';
|
|
44
26
|
|
|
45
27
|
export interface TableColumnProps<T extends object> {
|
|
46
28
|
cell: TableCell<T>;
|
|
@@ -65,15 +47,9 @@
|
|
|
65
47
|
return typeof valueOrComponent === 'function';
|
|
66
48
|
}
|
|
67
49
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (columnDef instanceof AccessorDef) {
|
|
71
|
-
return cellTypes[columnDef.accessorType];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return FocusableImmutableCell;
|
|
50
|
+
function isActionsDef(cell: TableCell<T>): cell is ActionsTableCell<T> {
|
|
51
|
+
return cell.column.columnDef instanceof ActionsDef;
|
|
75
52
|
}
|
|
76
|
-
|
|
77
53
|
function isExpandTableCell(cell: TableCell<T>): cell is ExpandTableCell<T> {
|
|
78
54
|
return cell.column.columnDef instanceof ExpandDef;
|
|
79
55
|
}
|
|
@@ -86,31 +62,26 @@
|
|
|
86
62
|
<ValidityCell {cell} />
|
|
87
63
|
{:else if columnDef instanceof RowSelectionDef}
|
|
88
64
|
<TableRowSelectionCheckbox {cell} />
|
|
89
|
-
{:else if
|
|
65
|
+
{:else if isActionsDef(cell)}
|
|
90
66
|
<ActionsCell {cell} />
|
|
91
67
|
{:else if isExpandTableCell(cell)}
|
|
92
68
|
<ExpandCell {cell} {expandedColumnDef} {onExpandChange} />
|
|
93
69
|
{:else if columnDef.columnType !== ColumnType.Display}
|
|
94
|
-
{
|
|
95
|
-
<CurrentComponent {cell} />
|
|
70
|
+
<AccessorComponent {cell} />
|
|
96
71
|
{:else}
|
|
97
72
|
{@const valueOrComponentPromise =
|
|
98
73
|
cell.column.columnDef.accessorFn?.(cell.row.original, cell.row.originalIndex) ??
|
|
99
74
|
cell.row.original[cell.column.id as keyof typeof cell.row.original] ??
|
|
100
75
|
null}
|
|
101
76
|
|
|
102
|
-
{#
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
{
|
|
106
|
-
|
|
107
|
-
{
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{/await}
|
|
111
|
-
{:else}
|
|
112
|
-
{@render ValueFallback(valueOrComponentPromise)}
|
|
113
|
-
{/if}
|
|
77
|
+
{#await valueOrComponentPromise}
|
|
78
|
+
<FocusableImmutableCell value={valueOrComponentPromise} {cell} />
|
|
79
|
+
{:then value}
|
|
80
|
+
{@render ValueFallback(value)}
|
|
81
|
+
{:catch e}
|
|
82
|
+
{@debug e}
|
|
83
|
+
<FocusableImmutableCell value={e?.toString()} {cell} />
|
|
84
|
+
{/await}
|
|
114
85
|
{/if}
|
|
115
86
|
{/if}
|
|
116
87
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
9
|
<script lang="ts" generics="T extends object">
|
|
10
|
+
import { dev } from '$app/environment';
|
|
10
11
|
import SingleSelect from '../../../../SingleSelect.svelte';
|
|
11
12
|
import type { SelectDef } from '../../../Types/Columns/Definitions/Accessors/SelectDef.svelte.js';
|
|
12
13
|
import type { TableCell } from '../../../Types/Columns/TableCell.js';
|
|
@@ -87,6 +88,9 @@
|
|
|
87
88
|
optionsPromise: Array<SelectOption<unknown>> | Promise<Array<SelectOption<unknown>>>,
|
|
88
89
|
value: unknown
|
|
89
90
|
): Promise<SelectOption<unknown> | null> {
|
|
91
|
+
void value;
|
|
92
|
+
void optionsPromise;
|
|
93
|
+
|
|
90
94
|
if (value == null) {
|
|
91
95
|
return null;
|
|
92
96
|
}
|
|
@@ -101,7 +105,9 @@
|
|
|
101
105
|
return foundOption ?? null;
|
|
102
106
|
}
|
|
103
107
|
|
|
104
|
-
|
|
108
|
+
if (dev) {
|
|
109
|
+
console.warn('could not match value to any type:', value);
|
|
110
|
+
}
|
|
105
111
|
|
|
106
112
|
return null;
|
|
107
113
|
}
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
|
|
64
64
|
const isAppropriateTableSide = $derived.by(() => {
|
|
65
65
|
if (side === 'left') {
|
|
66
|
-
return (tableContext.columnPinning.left?.
|
|
66
|
+
return (tableContext.columnPinning.left?.size ?? 0) > 0;
|
|
67
67
|
} else if (side === 'centre') {
|
|
68
68
|
return (
|
|
69
|
-
(tableContext.columnPinning.left?.
|
|
70
|
-
(tableContext.columnPinning.right?.
|
|
69
|
+
(tableContext.columnPinning.left?.size ?? 0) == 0 &&
|
|
70
|
+
(tableContext.columnPinning.right?.size ?? 0) != tableContext.columnDefs.length
|
|
71
71
|
);
|
|
72
72
|
} else {
|
|
73
|
-
return (tableContext.columnPinning.right?.
|
|
73
|
+
return (tableContext.columnPinning.right?.size ?? 0) == tableContext.columnDefs.length;
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
const showHighlightButton = $derived(rowIndex != null && isAppropriateTableSide);
|
|
@@ -125,7 +125,7 @@ onMouseLeave={onMouseLeave} -->
|
|
|
125
125
|
}}
|
|
126
126
|
/>
|
|
127
127
|
{/if}
|
|
128
|
-
{#each cells as cell (
|
|
128
|
+
{#each cells as cell (cell)}
|
|
129
129
|
<TableColumn {cell} {expandedColumnDef} {onExpandChange} />
|
|
130
130
|
{/each}
|
|
131
131
|
</tr>
|