@poirazis/supercomponents-shared 1.2.14 → 1.2.16
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/index.js +11177 -11403
- package/dist/index.umd.cjs +15 -14
- package/package.json +8 -8
- package/src/lib/SuperButton/SuperButton.svelte +16 -21
- package/src/lib/SuperField/SuperField.svelte +13 -14
- package/src/lib/SuperForm/InnerForm.svelte +9 -2
- package/src/lib/SuperForm/SuperForm.svelte +5 -5
- package/src/lib/SuperPopover/SuperPopover.svelte +1 -1
- package/src/lib/SuperTable/SuperTable.svelte +4 -3
- package/src/lib/SuperTable/controls/RowButtonsColumn.svelte +1 -1
- package/src/lib/SuperTable/controls/SelectionColumn.svelte +1 -1
- package/src/lib/SuperTableCells/CellCommon.css +97 -35
- package/src/lib/SuperTableCells/CellDatetime.svelte +2 -3
- package/src/lib/SuperTableCells/CellLink.svelte +8 -8
- package/src/lib/SuperTableCells/CellOptions.svelte +321 -237
- package/src/lib/SuperTableCells/CellOptionsAdvanced.svelte +209 -186
- package/src/lib/SuperTableCells/CellSkeleton.svelte +1 -1
- package/src/lib/SuperTableCells/CellString.svelte +19 -39
- package/src/lib/SuperTableCells/CellStringSimple.svelte +1 -4
- package/src/lib/SuperTableColumn/SuperTableColumn.svelte +2 -2
- package/src/lib/SuperTableColumn/parts/SuperColumnRow.svelte +1 -1
- package/src/lib/SuperTableCells/JSDOC_GUIDE.md +0 -869
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { getContext, createEventDispatcher, onMount, tick } from "svelte";
|
|
3
3
|
import SuperPopover from "../SuperPopover/SuperPopover.svelte";
|
|
4
|
+
import "./CellCommon.css";
|
|
4
5
|
import fsm from "svelte-fsm";
|
|
5
6
|
|
|
6
7
|
const dispatch = createEventDispatcher();
|
|
@@ -16,160 +17,62 @@
|
|
|
16
17
|
let editor;
|
|
17
18
|
let optionsList;
|
|
18
19
|
let options = memo([]);
|
|
19
|
-
let labels = {};
|
|
20
|
+
let labels = memo({});
|
|
20
21
|
let optionColors = {};
|
|
21
22
|
let filteredOptions = [];
|
|
22
23
|
let focusedOptionIdx = -1;
|
|
23
24
|
let timer;
|
|
24
25
|
let localValue = [];
|
|
25
26
|
|
|
26
|
-
let searchTerm =
|
|
27
|
-
let inputValue =
|
|
28
|
-
let isInitialLoad = false;
|
|
27
|
+
let searchTerm = null;
|
|
28
|
+
let inputValue = null;
|
|
29
29
|
let initLimit = 15;
|
|
30
|
+
let fetch;
|
|
31
|
+
let loading = false;
|
|
32
|
+
let optionsSource = "schema";
|
|
33
|
+
|
|
34
|
+
// Handle Options from Data Source
|
|
35
|
+
const dataSourceStore = memo(cellOptions?.datasource);
|
|
36
|
+
$: dataSourceStore.set(cellOptions.datasource);
|
|
37
|
+
|
|
38
|
+
$: ({
|
|
39
|
+
controlType,
|
|
40
|
+
optionsSource,
|
|
41
|
+
limit,
|
|
42
|
+
sortColumn,
|
|
43
|
+
sortOrder,
|
|
44
|
+
valueColumn,
|
|
45
|
+
labelColumn,
|
|
46
|
+
iconColumn,
|
|
47
|
+
colorColumn,
|
|
48
|
+
customOptions,
|
|
49
|
+
optionsViewMode,
|
|
50
|
+
role,
|
|
51
|
+
readonly,
|
|
52
|
+
disabled,
|
|
53
|
+
error,
|
|
54
|
+
color,
|
|
55
|
+
background,
|
|
56
|
+
filter,
|
|
57
|
+
pickerWidth,
|
|
58
|
+
} = cellOptions);
|
|
30
59
|
|
|
31
60
|
const createFetch = (datasource) => {
|
|
32
|
-
|
|
61
|
+
defaultQuery = QueryUtils.buildQuery(cellOptions.filter || []);
|
|
62
|
+
initLimit = limit || 15;
|
|
63
|
+
|
|
33
64
|
return fetchData({
|
|
34
65
|
API,
|
|
35
66
|
datasource,
|
|
36
67
|
options: {
|
|
68
|
+
query: defaultQuery,
|
|
37
69
|
sortColumn: cellOptions.sortColumn,
|
|
38
70
|
sortOrder: cellOptions.sortOrder,
|
|
39
|
-
limit
|
|
71
|
+
limit,
|
|
40
72
|
},
|
|
41
73
|
});
|
|
42
74
|
};
|
|
43
75
|
|
|
44
|
-
export const cellState = fsm("Loading", {
|
|
45
|
-
"*": {
|
|
46
|
-
goTo(state) {
|
|
47
|
-
return state;
|
|
48
|
-
},
|
|
49
|
-
refresh() {
|
|
50
|
-
$options = [];
|
|
51
|
-
return "Loading";
|
|
52
|
-
},
|
|
53
|
-
loadSchemaOptions() {
|
|
54
|
-
optionColors = fieldSchema?.optionColors || {};
|
|
55
|
-
$options = fieldSchema?.constraints?.inclusion || [];
|
|
56
|
-
labels = {};
|
|
57
|
-
filteredOptions = $options;
|
|
58
|
-
},
|
|
59
|
-
loadDataOptions(rows) {
|
|
60
|
-
$options = [];
|
|
61
|
-
labels = {};
|
|
62
|
-
if (rows && rows.length) {
|
|
63
|
-
rows.forEach((row) => {
|
|
64
|
-
$options.push(row[valueColumn]?.toString());
|
|
65
|
-
labels[row[valueColumn]] = row[labelColumn || valueColumn];
|
|
66
|
-
if (colorColumn) optionColors[row[valueColumn]] = row[colorColumn];
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
$options = $options;
|
|
70
|
-
filteredOptions = $options;
|
|
71
|
-
if (isInitialLoad) isInitialLoad = false;
|
|
72
|
-
},
|
|
73
|
-
loadCustomOptions() {
|
|
74
|
-
if (customOptions?.length) {
|
|
75
|
-
customOptions.forEach((row) => {
|
|
76
|
-
$options.push(row.value || row);
|
|
77
|
-
labels[row.value] = row.label || row;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
$options = $options;
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
Loading: {
|
|
84
|
-
_enter() {
|
|
85
|
-
if (cellOptions.optionsSource != "data" || $fetch?.loaded)
|
|
86
|
-
this.goTo.debounce(15, cellOptions.initialState || "View");
|
|
87
|
-
},
|
|
88
|
-
_exit() {
|
|
89
|
-
if (cellOptions.optionsSource == "custom") this.loadCustomOptions();
|
|
90
|
-
else if (optionsSource == "data") this.loadDataOptions($fetch?.rows);
|
|
91
|
-
else this.loadSchemaOptions();
|
|
92
|
-
|
|
93
|
-
filteredOptions = $options;
|
|
94
|
-
},
|
|
95
|
-
syncFetch(fetch) {
|
|
96
|
-
if (fetch?.loaded) {
|
|
97
|
-
return cellOptions.initialState || "View";
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
focus(e) {
|
|
101
|
-
if (!cellOptions.readonly && !cellOptions.disabled) {
|
|
102
|
-
return "Editing";
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
View: {
|
|
107
|
-
_enter() {
|
|
108
|
-
searchTerm = null;
|
|
109
|
-
editorState.filterOptions();
|
|
110
|
-
},
|
|
111
|
-
focus(e) {
|
|
112
|
-
if (!readonly && !disabled) {
|
|
113
|
-
return "Editing";
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
Editing: {
|
|
118
|
-
_enter() {
|
|
119
|
-
editorState.open();
|
|
120
|
-
originalValue = JSON.stringify(
|
|
121
|
-
Array.isArray(value) ? value : value ? [value] : [],
|
|
122
|
-
);
|
|
123
|
-
inputValue = multi ? "" : labels[localValue[0]] || localValue[0] || "";
|
|
124
|
-
|
|
125
|
-
dispatch("enteredit");
|
|
126
|
-
},
|
|
127
|
-
_exit() {
|
|
128
|
-
editorState.close();
|
|
129
|
-
dispatch("exitedit");
|
|
130
|
-
},
|
|
131
|
-
toggle(e) {
|
|
132
|
-
editorState.toggle();
|
|
133
|
-
},
|
|
134
|
-
focusout(e) {
|
|
135
|
-
dispatch("focusout");
|
|
136
|
-
|
|
137
|
-
// For debounced inputs, dispatch the current value immediately on focusout
|
|
138
|
-
if (cellOptions.debounce && isDirty) {
|
|
139
|
-
clearTimeout(timer);
|
|
140
|
-
dispatch("change", multi ? localValue : localValue[0]);
|
|
141
|
-
} else {
|
|
142
|
-
this.submit();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return "View";
|
|
146
|
-
},
|
|
147
|
-
popupfocusout(e) {
|
|
148
|
-
if (anchor != e?.relatedTarget) {
|
|
149
|
-
this.submit();
|
|
150
|
-
return "View";
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
submit() {
|
|
154
|
-
if (isDirty && !cellOptions.debounce) {
|
|
155
|
-
if (multi) dispatch("change", localValue);
|
|
156
|
-
else dispatch("change", localValue[0]);
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
clear() {
|
|
160
|
-
localValue = [];
|
|
161
|
-
anchor?.focus();
|
|
162
|
-
if (cellOptions.debounce) dispatch("change", null);
|
|
163
|
-
},
|
|
164
|
-
cancel() {
|
|
165
|
-
localValue = JSON.parse(originalValue);
|
|
166
|
-
searchTerm = null;
|
|
167
|
-
anchor?.blur();
|
|
168
|
-
return "View";
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
|
|
173
76
|
const editorState = fsm("Closed", {
|
|
174
77
|
"*": {
|
|
175
78
|
toggleOption(idx) {
|
|
@@ -188,7 +91,9 @@
|
|
|
188
91
|
if (localValue[0] == option) localValue.length = 0;
|
|
189
92
|
else localValue[0] = option;
|
|
190
93
|
|
|
191
|
-
|
|
94
|
+
localValue = [...localValue];
|
|
95
|
+
|
|
96
|
+
inputValue = $labels[localValue[0]] || localValue[0] || "";
|
|
192
97
|
}
|
|
193
98
|
|
|
194
99
|
if (cellOptions.debounce) {
|
|
@@ -210,44 +115,77 @@
|
|
|
210
115
|
}
|
|
211
116
|
},
|
|
212
117
|
filterOptions(term) {
|
|
213
|
-
if (
|
|
118
|
+
if (optionsSource == "data") {
|
|
214
119
|
// For datasource, update the fetch with filter
|
|
215
|
-
let appliedFilter =
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
valueType: "Value",
|
|
225
|
-
},
|
|
226
|
-
];
|
|
120
|
+
let appliedFilter = {};
|
|
121
|
+
|
|
122
|
+
// Start with base filter or create new one
|
|
123
|
+
if (
|
|
124
|
+
filter &&
|
|
125
|
+
typeof filter === "object" &&
|
|
126
|
+
Object.keys(filter).length > 0
|
|
127
|
+
) {
|
|
128
|
+
appliedFilter = JSON.parse(JSON.stringify(filter)); // Deep clone
|
|
227
129
|
} else {
|
|
228
|
-
|
|
130
|
+
// Create a base filter object
|
|
131
|
+
appliedFilter = {
|
|
132
|
+
logicalOperator: "all",
|
|
133
|
+
onEmptyFilter: "all",
|
|
134
|
+
groups: [],
|
|
135
|
+
};
|
|
229
136
|
}
|
|
137
|
+
|
|
138
|
+
// Add search term as a new filter group if provided
|
|
139
|
+
if (term != null && term.trim() !== "") {
|
|
140
|
+
const searchFilterGroup = {
|
|
141
|
+
logicalOperator: "any",
|
|
142
|
+
filters: [
|
|
143
|
+
{
|
|
144
|
+
valueType: "Value",
|
|
145
|
+
field: labelColumn || valueColumn,
|
|
146
|
+
type: "string",
|
|
147
|
+
constraints: {
|
|
148
|
+
type: "string",
|
|
149
|
+
length: {},
|
|
150
|
+
presence: false,
|
|
151
|
+
},
|
|
152
|
+
operator: "fuzzy",
|
|
153
|
+
noValue: false,
|
|
154
|
+
value: term,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Add the search filter group
|
|
160
|
+
if (!appliedFilter.groups) {
|
|
161
|
+
appliedFilter.groups = [];
|
|
162
|
+
}
|
|
163
|
+
appliedFilter.groups.push(searchFilterGroup);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const query = QueryUtils.buildQuery(appliedFilter);
|
|
230
167
|
fetch?.update({
|
|
231
|
-
query
|
|
168
|
+
query,
|
|
232
169
|
});
|
|
233
|
-
// Keep filteredOptions in sync
|
|
234
|
-
filteredOptions = $options;
|
|
235
170
|
} else {
|
|
236
171
|
// Client-side filtering for non-datasource
|
|
237
172
|
if (term) {
|
|
238
173
|
filteredOptions = $options.filter((x) =>
|
|
239
|
-
x?.toLocaleLowerCase().
|
|
174
|
+
x?.toLocaleLowerCase().includes(term.toLocaleLowerCase()),
|
|
240
175
|
);
|
|
241
176
|
} else {
|
|
242
177
|
filteredOptions = $options;
|
|
243
178
|
}
|
|
244
179
|
}
|
|
245
180
|
},
|
|
181
|
+
clearFilter() {
|
|
182
|
+
searchTerm = null;
|
|
183
|
+
this.filterOptions();
|
|
184
|
+
},
|
|
246
185
|
},
|
|
247
186
|
Open: {
|
|
248
187
|
_enter() {
|
|
249
188
|
searchTerm = "";
|
|
250
|
-
this.filterOptions();
|
|
251
189
|
focusedOptionIdx = -1;
|
|
252
190
|
},
|
|
253
191
|
toggle() {
|
|
@@ -258,6 +196,7 @@
|
|
|
258
196
|
},
|
|
259
197
|
handleKeyboard(e) {
|
|
260
198
|
if (e.key === "Backspace" || e.key === "Delete") {
|
|
199
|
+
console.log(searchTerm, "before deletion");
|
|
261
200
|
searchTerm = searchTerm.slice(0, -1);
|
|
262
201
|
this.filterOptions(searchTerm);
|
|
263
202
|
} else if (e.key.length === 1 && /[a-zA-Z0-9]/.test(e.key)) {
|
|
@@ -346,10 +285,7 @@
|
|
|
346
285
|
},
|
|
347
286
|
},
|
|
348
287
|
Closed: {
|
|
349
|
-
_enter() {
|
|
350
|
-
searchTerm = null;
|
|
351
|
-
focusedOptionIdx = -1;
|
|
352
|
-
},
|
|
288
|
+
_enter() {},
|
|
353
289
|
toggle() {
|
|
354
290
|
return "Open";
|
|
355
291
|
},
|
|
@@ -401,6 +337,170 @@
|
|
|
401
337
|
},
|
|
402
338
|
});
|
|
403
339
|
|
|
340
|
+
export const cellState = fsm("View", {
|
|
341
|
+
"*": {
|
|
342
|
+
goTo(state) {
|
|
343
|
+
return state;
|
|
344
|
+
},
|
|
345
|
+
refresh() {
|
|
346
|
+
$options = [];
|
|
347
|
+
optionColors = {};
|
|
348
|
+
$labels = {};
|
|
349
|
+
filteredOptions = [];
|
|
350
|
+
if (optionsSource != "data") {
|
|
351
|
+
this.loadOptions(optionsSource);
|
|
352
|
+
}
|
|
353
|
+
return optionsSource == "data" ? "Loading" : "View";
|
|
354
|
+
},
|
|
355
|
+
reload() {
|
|
356
|
+
this.loadOptions(optionsSource);
|
|
357
|
+
},
|
|
358
|
+
loadSchemaOptions() {
|
|
359
|
+
try {
|
|
360
|
+
optionColors = fieldSchema?.optionColors || {};
|
|
361
|
+
$options = fieldSchema?.constraints?.inclusion || [];
|
|
362
|
+
$labels = {};
|
|
363
|
+
filteredOptions = $options;
|
|
364
|
+
} catch (e) {}
|
|
365
|
+
},
|
|
366
|
+
loadDataOptions(rows) {
|
|
367
|
+
$options = [];
|
|
368
|
+
$labels = {};
|
|
369
|
+
let primaryDisplay = labelColumn || labelColumn;
|
|
370
|
+
if (rows && rows.length) {
|
|
371
|
+
rows.forEach((row) => {
|
|
372
|
+
$options.push(row[valueColumn]);
|
|
373
|
+
$labels[row[valueColumn]] = row[primaryDisplay];
|
|
374
|
+
if (colorColumn) optionColors[row[valueColumn]] = row[colorColumn];
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
$options = $options;
|
|
379
|
+
filteredOptions = $options;
|
|
380
|
+
},
|
|
381
|
+
loadCustomOptions() {
|
|
382
|
+
if (customOptions?.length) {
|
|
383
|
+
customOptions.forEach((row) => {
|
|
384
|
+
$options.push(row.value || row);
|
|
385
|
+
$labels[row.value] = row.label || row;
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
$options = $options;
|
|
389
|
+
filteredOptions = $options;
|
|
390
|
+
},
|
|
391
|
+
loadOptions(src) {
|
|
392
|
+
if (src == "data") {
|
|
393
|
+
this.loadDataOptions($fetch?.rows);
|
|
394
|
+
} else if (src == "custom") {
|
|
395
|
+
this.loadCustomOptions();
|
|
396
|
+
} else {
|
|
397
|
+
this.loadSchemaOptions();
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
Loading: {
|
|
402
|
+
_enter() {
|
|
403
|
+
fetch = createFetch($dataSourceStore);
|
|
404
|
+
loading = true;
|
|
405
|
+
},
|
|
406
|
+
_exit() {
|
|
407
|
+
loading = false;
|
|
408
|
+
},
|
|
409
|
+
refresh() {},
|
|
410
|
+
reload() {},
|
|
411
|
+
syncFetch(fetch) {
|
|
412
|
+
if (fetch?.loaded) {
|
|
413
|
+
return cellOptions.initialState || "View";
|
|
414
|
+
}
|
|
415
|
+
},
|
|
416
|
+
focus(e) {
|
|
417
|
+
if (!cellOptions.readonly && !cellOptions.disabled) {
|
|
418
|
+
return "Editing";
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
},
|
|
422
|
+
View: {
|
|
423
|
+
_enter() {
|
|
424
|
+
searchTerm = null;
|
|
425
|
+
editorState.filterOptions();
|
|
426
|
+
},
|
|
427
|
+
toggle(e) {
|
|
428
|
+
if (cellOptions.disabled || cellOptions.readonly) return;
|
|
429
|
+
return "Editing";
|
|
430
|
+
},
|
|
431
|
+
focus(e) {
|
|
432
|
+
if (!readonly && !disabled) {
|
|
433
|
+
return "Editing";
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
Editing: {
|
|
438
|
+
_enter() {
|
|
439
|
+
editorState.open();
|
|
440
|
+
|
|
441
|
+
setTimeout(() => {
|
|
442
|
+
editor?.focus();
|
|
443
|
+
}, 30);
|
|
444
|
+
originalValue = JSON.stringify(
|
|
445
|
+
Array.isArray(value) ? value : value ? [value] : [],
|
|
446
|
+
);
|
|
447
|
+
inputValue = multi ? "" : $labels[localValue[0]] || localValue[0] || "";
|
|
448
|
+
|
|
449
|
+
dispatch("enteredit");
|
|
450
|
+
},
|
|
451
|
+
_exit() {
|
|
452
|
+
searchTerm = null;
|
|
453
|
+
inputValue = null;
|
|
454
|
+
editorState.close();
|
|
455
|
+
dispatch("exitedit");
|
|
456
|
+
},
|
|
457
|
+
toggle(e) {
|
|
458
|
+
if (!inputSelect && searchTerm) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
e.preventDefault();
|
|
462
|
+
editorState.toggle();
|
|
463
|
+
},
|
|
464
|
+
focusout(e) {
|
|
465
|
+
if (anchor.contains(e.relatedTarget)) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
if (cellOptions.debounce && isDirty) {
|
|
470
|
+
clearTimeout(timer);
|
|
471
|
+
dispatch("change", multi ? localValue : localValue[0]);
|
|
472
|
+
} else {
|
|
473
|
+
this.submit();
|
|
474
|
+
}
|
|
475
|
+
dispatch("focusout");
|
|
476
|
+
return "View";
|
|
477
|
+
},
|
|
478
|
+
popupfocusout(e) {
|
|
479
|
+
if (anchor != e?.relatedTarget) {
|
|
480
|
+
this.submit();
|
|
481
|
+
return "View";
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
submit() {
|
|
485
|
+
if (isDirty && !cellOptions.debounce) {
|
|
486
|
+
if (multi) dispatch("change", localValue);
|
|
487
|
+
else dispatch("change", localValue[0]);
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
clear() {
|
|
491
|
+
localValue = [];
|
|
492
|
+
anchor?.focus();
|
|
493
|
+
if (cellOptions.debounce) dispatch("change", null);
|
|
494
|
+
},
|
|
495
|
+
cancel() {
|
|
496
|
+
localValue = JSON.parse(originalValue);
|
|
497
|
+
searchTerm = null;
|
|
498
|
+
anchor?.blur();
|
|
499
|
+
return "View";
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
|
|
404
504
|
const colors = derivedMemo(options, ($options) => {
|
|
405
505
|
let obj = {};
|
|
406
506
|
$options.forEach(
|
|
@@ -447,54 +547,23 @@
|
|
|
447
547
|
Array.isArray(value) ? value : value ? [value] : [],
|
|
448
548
|
);
|
|
449
549
|
|
|
450
|
-
$: ({
|
|
451
|
-
controlType,
|
|
452
|
-
optionsSource,
|
|
453
|
-
valueColumn,
|
|
454
|
-
labelColumn,
|
|
455
|
-
iconColumn,
|
|
456
|
-
colorColumn,
|
|
457
|
-
customOptions,
|
|
458
|
-
optionsViewMode,
|
|
459
|
-
role,
|
|
460
|
-
readonly,
|
|
461
|
-
disabled,
|
|
462
|
-
error,
|
|
463
|
-
color,
|
|
464
|
-
background,
|
|
465
|
-
} = cellOptions);
|
|
466
|
-
|
|
467
|
-
// Handle Options from Data Source
|
|
468
|
-
const dataSourceStore = memo(cellOptions?.datasource ?? {});
|
|
469
|
-
$: dataSourceStore.set(cellOptions.datasource);
|
|
470
|
-
$: fetch = createFetch($dataSourceStore);
|
|
471
|
-
$: if (optionsSource == "data") {
|
|
472
|
-
initLimit = 15;
|
|
473
|
-
isInitialLoad = true;
|
|
474
|
-
}
|
|
475
|
-
$: query = QueryUtils.buildQuery(cellOptions.filter);
|
|
476
550
|
$: inputSelect = controlType == "inputSelect";
|
|
477
551
|
|
|
478
|
-
$:
|
|
479
|
-
|
|
480
|
-
query,
|
|
481
|
-
sortColumn: cellOptions.sortColumn,
|
|
482
|
-
sortOrder: cellOptions.sortOrder,
|
|
483
|
-
limit: initLimit,
|
|
484
|
-
});
|
|
552
|
+
$: defaultQuery = QueryUtils.buildQuery(filter || []);
|
|
553
|
+
$: fetch?.update?.({ query: defaultQuery });
|
|
485
554
|
|
|
486
555
|
$: cellState.syncFetch($fetch);
|
|
487
556
|
$: cellState.loadDataOptions($fetch?.rows);
|
|
488
557
|
|
|
489
558
|
// React to property changes
|
|
490
|
-
$: cellState.refresh(
|
|
559
|
+
$: cellState.refresh($dataSourceStore, optionsSource);
|
|
560
|
+
|
|
561
|
+
$: cellState.reload(
|
|
491
562
|
fieldSchema,
|
|
492
|
-
optionsSource,
|
|
493
563
|
labelColumn,
|
|
494
564
|
valueColumn,
|
|
495
565
|
iconColumn,
|
|
496
566
|
colorColumn,
|
|
497
|
-
$dataSourceStore,
|
|
498
567
|
customOptions,
|
|
499
568
|
);
|
|
500
569
|
|
|
@@ -509,18 +578,15 @@
|
|
|
509
578
|
$: inEdit = $cellState == "Editing";
|
|
510
579
|
$: pills = optionsViewMode == "pills";
|
|
511
580
|
$: bullets = optionsViewMode == "bullets";
|
|
581
|
+
$: plaintext = optionsViewMode == "text";
|
|
512
582
|
|
|
513
583
|
$: multi =
|
|
514
584
|
fieldSchema && fieldSchema.type ? fieldSchema.type == "array" : multi;
|
|
515
585
|
|
|
516
|
-
$: placeholder =
|
|
586
|
+
$: placeholder = cellOptions.placeholder || "";
|
|
517
587
|
$: icon = searchTerm && isEmpty ? "ph ph-magnifying-glass" : cellOptions.icon;
|
|
518
588
|
$: open = $editorState == "Open";
|
|
519
589
|
|
|
520
|
-
const focus = (node) => {
|
|
521
|
-
node?.focus();
|
|
522
|
-
};
|
|
523
|
-
|
|
524
590
|
onMount(() => {
|
|
525
591
|
if (autofocus)
|
|
526
592
|
setTimeout(() => {
|
|
@@ -542,15 +608,15 @@
|
|
|
542
608
|
class:disabled
|
|
543
609
|
class:readonly
|
|
544
610
|
class:error
|
|
545
|
-
style:color
|
|
546
|
-
style:background
|
|
547
611
|
class:inline={role == "inlineInput"}
|
|
548
612
|
class:tableCell={role == "tableCell"}
|
|
549
613
|
class:formInput={role == "formInput"}
|
|
550
614
|
class:has-popup={controlType == "select"}
|
|
551
615
|
class:open-popup={open}
|
|
616
|
+
style:color
|
|
617
|
+
style:background
|
|
552
618
|
on:focusin={cellState.focus}
|
|
553
|
-
on:focusout={cellState.focusout}
|
|
619
|
+
on:focusout={controlType != "inputSelect" ? cellState.focusout : undefined}
|
|
554
620
|
on:keydown={editorState.handleKeyboard}
|
|
555
621
|
on:mousedown={cellState.toggle}
|
|
556
622
|
>
|
|
@@ -580,7 +646,7 @@
|
|
|
580
646
|
{#if pills}
|
|
581
647
|
<div class="loope"></div>
|
|
582
648
|
{/if}
|
|
583
|
-
<span> {labels[val] || val} </span>
|
|
649
|
+
<span> {$labels[val] || val} </span>
|
|
584
650
|
</div>
|
|
585
651
|
{/each}
|
|
586
652
|
</div>
|
|
@@ -596,24 +662,24 @@
|
|
|
596
662
|
if (!multi) localValue[0] = e.target.value?.trim();
|
|
597
663
|
editorState.filterOptions(e.target.value);
|
|
598
664
|
}}
|
|
599
|
-
|
|
665
|
+
on:focusout={cellState.focusout}
|
|
600
666
|
{placeholder}
|
|
601
667
|
/>
|
|
602
|
-
<div
|
|
668
|
+
<div
|
|
669
|
+
class="control-icon"
|
|
670
|
+
style:border-left="1px solid var(--spectrum-global-color-blue-400)"
|
|
671
|
+
style:padding-left="0.75rem"
|
|
672
|
+
>
|
|
603
673
|
<i class="ph ph-caret-down"></i>
|
|
604
674
|
</div>
|
|
605
675
|
{:else}
|
|
606
676
|
<div class="value" class:placeholder={isEmpty && !searchTerm}>
|
|
607
|
-
{#if isEmpty
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
{multi || localValue.length > 1
|
|
614
|
-
? localValue.join(", ")
|
|
615
|
-
: labels[localValue[0]] || localValue[0]}
|
|
616
|
-
</span>
|
|
677
|
+
{#if isEmpty}
|
|
678
|
+
{#if open}
|
|
679
|
+
{searchTerm ? searchTerm : "Type to search..."}
|
|
680
|
+
{:else}
|
|
681
|
+
{loading ? "Loading..." : placeholder}
|
|
682
|
+
{/if}
|
|
617
683
|
{:else}
|
|
618
684
|
<div
|
|
619
685
|
class="items"
|
|
@@ -621,21 +687,28 @@
|
|
|
621
687
|
class:bullets
|
|
622
688
|
style:justify-content={cellOptions.align ?? "flex-start"}
|
|
623
689
|
>
|
|
624
|
-
{#
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
<
|
|
632
|
-
|
|
633
|
-
|
|
690
|
+
{#if plaintext}
|
|
691
|
+
{#each localValue as val, idx (val)}
|
|
692
|
+
{$labels[val] || val}
|
|
693
|
+
{idx < localValue.length - 1 ? ", " : ""}
|
|
694
|
+
{/each}
|
|
695
|
+
{:else}
|
|
696
|
+
{#each localValue as val, idx}
|
|
697
|
+
<div
|
|
698
|
+
class="item"
|
|
699
|
+
style:--option-color={$colors[val] ||
|
|
700
|
+
colorsArray[idx % colorsArray.length]}
|
|
701
|
+
>
|
|
702
|
+
<div class="loope"></div>
|
|
703
|
+
<span> {isObjects ? "JSON" : $labels[val] || val} </span>
|
|
704
|
+
</div>
|
|
705
|
+
{/each}
|
|
706
|
+
{/if}
|
|
634
707
|
</div>
|
|
635
708
|
{/if}
|
|
636
709
|
</div>
|
|
637
710
|
{#if !readonly && (role == "formInput" || inEdit)}
|
|
638
|
-
<i class="ph ph-caret-down control-icon"
|
|
711
|
+
<i class="ph ph-caret-down control-icon"></i>
|
|
639
712
|
{/if}
|
|
640
713
|
{/if}
|
|
641
714
|
</div>
|
|
@@ -643,9 +716,16 @@
|
|
|
643
716
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
644
717
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
645
718
|
{#if inEdit}
|
|
646
|
-
<SuperPopover
|
|
719
|
+
<SuperPopover
|
|
720
|
+
{anchor}
|
|
721
|
+
useAnchorWidth
|
|
722
|
+
minWidth={pickerWidth}
|
|
723
|
+
align="left"
|
|
724
|
+
maxHeight={250}
|
|
725
|
+
{open}
|
|
726
|
+
>
|
|
647
727
|
<div class="picker" on:mousedown|stopPropagation|preventDefault>
|
|
648
|
-
{#if searchTerm && !isEmpty}
|
|
728
|
+
{#if searchTerm && !inputSelect && !isEmpty}
|
|
649
729
|
<div class="searchControl">
|
|
650
730
|
<i
|
|
651
731
|
class="search-icon ph ph-magnifying-glass"
|
|
@@ -661,12 +741,14 @@
|
|
|
661
741
|
on:mouseleave={() => (focusedOptionIdx = -1)}
|
|
662
742
|
on:scroll={optionsSource == "data" ? editorState.handleScroll : null}
|
|
663
743
|
>
|
|
664
|
-
{#if
|
|
744
|
+
{#if $fetch?.loading && !$fetch?.loaded}
|
|
665
745
|
<div class="option loading">
|
|
666
746
|
<i class="ph ph-spinner spin"></i>
|
|
667
747
|
Loading...
|
|
668
748
|
</div>
|
|
669
|
-
{
|
|
749
|
+
{/if}
|
|
750
|
+
|
|
751
|
+
{#if filteredOptions?.length}
|
|
670
752
|
{#each filteredOptions as option, idx (idx)}
|
|
671
753
|
<div
|
|
672
754
|
class="option"
|
|
@@ -685,18 +767,20 @@
|
|
|
685
767
|
: "ph-fill ph-square"}
|
|
686
768
|
style:color={$colors[option]}
|
|
687
769
|
></i>
|
|
688
|
-
{labels[option] || option}
|
|
770
|
+
{$labels[option] || option}
|
|
689
771
|
</span>
|
|
690
772
|
<i class="ph ph-check"></i>
|
|
691
773
|
</div>
|
|
692
774
|
{/each}
|
|
693
|
-
{#if
|
|
775
|
+
{#if $fetch?.loading}
|
|
694
776
|
<div class="option loading">
|
|
695
777
|
<i class="ph ph-spinner spin"></i>
|
|
696
778
|
Loading more...
|
|
697
779
|
</div>
|
|
698
780
|
{/if}
|
|
699
|
-
{
|
|
781
|
+
{/if}
|
|
782
|
+
|
|
783
|
+
{#if filteredOptions?.length === 0 && $fetch.loaded}
|
|
700
784
|
<div class="option">
|
|
701
785
|
<span>
|
|
702
786
|
<i class="ri-close-line"></i>
|
|
@@ -713,7 +797,7 @@
|
|
|
713
797
|
.searchControl {
|
|
714
798
|
display: flex;
|
|
715
799
|
align-items: center;
|
|
716
|
-
height: 2rem;
|
|
800
|
+
min-height: 2rem;
|
|
717
801
|
border-bottom: 1px solid var(--spectrum-global-color-gray-300);
|
|
718
802
|
}
|
|
719
803
|
.options {
|
|
@@ -726,13 +810,13 @@
|
|
|
726
810
|
}
|
|
727
811
|
|
|
728
812
|
.option {
|
|
729
|
-
min-height: 1.
|
|
813
|
+
min-height: 1.85rem;
|
|
730
814
|
display: flex;
|
|
731
815
|
gap: 0.5rem;
|
|
732
816
|
align-items: center;
|
|
733
817
|
justify-content: space-between;
|
|
734
818
|
cursor: pointer;
|
|
735
|
-
padding:
|
|
819
|
+
padding: 0rem 0.5rem;
|
|
736
820
|
|
|
737
821
|
&.selected {
|
|
738
822
|
color: var(--spectrum-global-color-gray-800);
|