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