@bexis2/bexis2-core-ui 0.4.96 → 0.4.98
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 +104 -25
- package/dist/components/CodeEditor/CodeEditor.svelte +2 -2
- package/dist/components/Facets/ShowMore.svelte +4 -6
- package/dist/components/File/FileUploader.svelte +6 -3
- package/dist/components/Table/Table.svelte +26 -5
- package/dist/components/Table/TableContent.svelte +222 -22
- package/dist/components/Table/TablePaginationServer.svelte +27 -8
- package/dist/components/Table/clientDB.d.ts +22 -0
- package/dist/components/Table/clientDB.js +236 -0
- package/dist/components/Table/filter.js +5 -1
- package/dist/components/Table/tableWorker.d.ts +1 -0
- package/dist/components/Table/tableWorker.js +179 -0
- package/dist/components/Table/utils.d.ts +1 -2
- package/dist/components/Table/utils.js +45 -26
- package/dist/components/form/CheckboxKvPList.svelte +15 -15
- package/dist/components/form/CheckboxList.svelte +1 -1
- package/dist/components/form/DateInput.svelte +12 -1
- package/dist/components/form/DatePickerInput.svelte +51 -29
- package/dist/components/form/Dropdown.svelte +14 -3
- package/dist/components/form/DropdownKvP.svelte +13 -2
- package/dist/components/form/InputContainer.svelte +17 -15
- package/dist/components/form/MultiSelect.svelte +30 -29
- package/dist/components/form/NumberInput.svelte +12 -1
- package/dist/components/form/TextArea.svelte +12 -1
- package/dist/components/form/TextInput.svelte +12 -1
- package/dist/components/page/Alert.svelte +5 -1
- package/dist/components/page/BackToTop.svelte +3 -1
- package/dist/components/page/Docs.svelte +9 -2
- package/dist/components/page/GoToTop.svelte +14 -15
- package/dist/components/page/Page.svelte +50 -56
- package/dist/components/page/breadcrumb/BreadcrumbDataCaller.js +11 -15
- package/dist/components/page/menu/MenuAccountBar.svelte +1 -5
- package/dist/components/page/menu/MenuDataCaller.js +1 -1
- package/dist/components/page/menu/MenuItem.svelte +9 -7
- package/dist/components/page/menu/MenuSublist.svelte +7 -5
- package/dist/components/page/menu/SettingsBar.svelte +4 -1
- package/dist/components/toggle/Toggle.svelte +9 -9
- package/dist/css/core.ui.postcss +1 -2
- package/dist/services/Api.js +4 -4
- package/dist/services/BaseCaller.js +1 -1
- package/package.json +114 -114
- package/src/lib/components/CodeEditor/CodeEditor.svelte +4 -4
- package/src/lib/components/Facets/Facets.svelte +2 -2
- package/src/lib/components/Facets/ShowMore.svelte +4 -6
- package/src/lib/components/File/FileUploader.svelte +17 -14
- package/src/lib/components/Table/Table.svelte +31 -10
- package/src/lib/components/Table/TableContent.svelte +258 -33
- package/src/lib/components/Table/TableFilter.svelte +7 -2
- package/src/lib/components/Table/TablePagination.svelte +6 -2
- package/src/lib/components/Table/TablePaginationServer.svelte +36 -10
- package/src/lib/components/Table/clientDB.js +236 -0
- package/src/lib/components/Table/filter.ts +27 -23
- package/src/lib/components/Table/tableWorker.js +179 -0
- package/src/lib/components/Table/utils.ts +75 -56
- package/src/lib/components/form/Checkbox.svelte +1 -1
- package/src/lib/components/form/CheckboxKvPList.svelte +15 -16
- package/src/lib/components/form/CheckboxList.svelte +1 -1
- package/src/lib/components/form/DateInput.svelte +13 -2
- package/src/lib/components/form/DatePickerInput.svelte +51 -29
- package/src/lib/components/form/Dropdown.svelte +14 -3
- package/src/lib/components/form/DropdownKvP.svelte +13 -2
- package/src/lib/components/form/InputContainer.svelte +18 -17
- package/src/lib/components/form/MultiSelect.svelte +30 -29
- package/src/lib/components/form/NumberInput.svelte +21 -12
- package/src/lib/components/form/TextArea.svelte +13 -2
- package/src/lib/components/form/TextInput.svelte +13 -2
- package/src/lib/components/page/Alert.svelte +5 -1
- package/src/lib/components/page/BackToTop.svelte +3 -1
- package/src/lib/components/page/Docs.svelte +9 -2
- package/src/lib/components/page/GoToTop.svelte +14 -15
- package/src/lib/components/page/Notification.svelte +1 -1
- package/src/lib/components/page/Page.svelte +67 -78
- package/src/lib/components/page/breadcrumb/Breadcrumb.svelte +2 -3
- package/src/lib/components/page/breadcrumb/BreadcrumbDataCaller.js +11 -15
- package/src/lib/components/page/menu/MenuAccountBar.svelte +1 -6
- package/src/lib/components/page/menu/MenuDataCaller.js +1 -1
- package/src/lib/components/page/menu/MenuItem.svelte +10 -8
- package/src/lib/components/page/menu/MenuSublist.svelte +35 -41
- package/src/lib/components/page/menu/SettingsBar.svelte +5 -2
- package/src/lib/components/toggle/Toggle.svelte +28 -30
- package/src/lib/css/core.ui.postcss +1 -2
- package/src/lib/index.ts +1 -2
- package/src/lib/services/Api.ts +21 -20
- package/src/lib/services/BaseCaller.js +1 -1
- package/src/lib/stores/apiStores.ts +1 -5
- package/src/lib/stores/pageStores.ts +0 -2
|
@@ -67,7 +67,11 @@ const applyFilter = (filterValue, value, filterFn) => {
|
|
|
67
67
|
value: filterValue[key]
|
|
68
68
|
}));
|
|
69
69
|
filters.forEach((filter) => {
|
|
70
|
-
result =
|
|
70
|
+
result =
|
|
71
|
+
result &&
|
|
72
|
+
(filter.value !== undefined && filter.value !== '' && filter.value !== null
|
|
73
|
+
? filterFn(filter.option, filter.value, value)
|
|
74
|
+
: true);
|
|
71
75
|
});
|
|
72
76
|
return result;
|
|
73
77
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
// Lightweight web worker that stores rows in IndexedDB and answers simple queries
|
|
3
|
+
const DB_PREFIX = 'table-db-';
|
|
4
|
+
|
|
5
|
+
function openDB(name) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const req = indexedDB.open(DB_PREFIX + name, 1);
|
|
8
|
+
req.onupgradeneeded = () => {
|
|
9
|
+
const db = req.result;
|
|
10
|
+
if (!db.objectStoreNames.contains('rows')) {
|
|
11
|
+
db.createObjectStore('rows', { keyPath: '__id', autoIncrement: true });
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
req.onsuccess = () => resolve(req.result);
|
|
15
|
+
req.onerror = () => reject(req.error);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function clearStore(db) {
|
|
20
|
+
return new Promise((res, rej) => {
|
|
21
|
+
const tx = db.transaction('rows', 'readwrite');
|
|
22
|
+
const store = tx.objectStore('rows');
|
|
23
|
+
const r = store.clear();
|
|
24
|
+
r.onsuccess = () => res(undefined);
|
|
25
|
+
r.onerror = () => rej(r.error);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function bulkInsert(db, rows) {
|
|
30
|
+
return new Promise((res, rej) => {
|
|
31
|
+
const tx = db.transaction('rows', 'readwrite');
|
|
32
|
+
const store = tx.objectStore('rows');
|
|
33
|
+
for (let i = 0; i < rows.length; i++) {
|
|
34
|
+
// wrap row to avoid clashes with internal __id
|
|
35
|
+
const toPut = { __r: rows[i] };
|
|
36
|
+
store.add(toPut);
|
|
37
|
+
}
|
|
38
|
+
tx.oncomplete = () => res(undefined);
|
|
39
|
+
tx.onerror = () => rej(tx.error);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function matches(rowObj, q, filters) {
|
|
44
|
+
const row = rowObj.__r || rowObj;
|
|
45
|
+
// full text query
|
|
46
|
+
if (q && q.length > 0) {
|
|
47
|
+
const ql = String(q).toLowerCase();
|
|
48
|
+
let found = false;
|
|
49
|
+
for (const k in row) {
|
|
50
|
+
const v = row[k];
|
|
51
|
+
if (v == null) continue;
|
|
52
|
+
if (typeof v === 'string' && v.toLowerCase().includes(ql)) {
|
|
53
|
+
found = true;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
if (typeof v === 'number' && String(v).includes(ql)) {
|
|
57
|
+
found = true;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!found) return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// simple equality filters: filters is array of {column, filterBy, value}
|
|
65
|
+
if (filters && filters.length > 0) {
|
|
66
|
+
for (const f of filters) {
|
|
67
|
+
const col = (f.column || '').replaceAll('%%%', '.');
|
|
68
|
+
const val = f.value;
|
|
69
|
+
const actual = row[col] ?? row[f.column] ?? row[col.replaceAll('.', '%%%')];
|
|
70
|
+
if (val == null) continue;
|
|
71
|
+
if (typeof actual === 'string') {
|
|
72
|
+
if (!String(actual).toLowerCase().includes(String(val).toLowerCase())) return false;
|
|
73
|
+
} else if (typeof actual === 'number') {
|
|
74
|
+
if (Number(val) !== actual) return false;
|
|
75
|
+
} else {
|
|
76
|
+
if (actual !== val) return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// handle messages
|
|
85
|
+
let dbs = {};
|
|
86
|
+
let initCounts = {};
|
|
87
|
+
self.addEventListener('message', async (e) => {
|
|
88
|
+
const { type, payload } = e.data;
|
|
89
|
+
try {
|
|
90
|
+
if (type === 'init-start') {
|
|
91
|
+
const { tableId } = payload;
|
|
92
|
+
const db = await openDB(tableId);
|
|
93
|
+
await clearStore(db);
|
|
94
|
+
dbs[tableId] = db;
|
|
95
|
+
initCounts[tableId] = 0;
|
|
96
|
+
postMessage({ type: 'init-ack', payload: { tableId } });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (type === 'init-chunk') {
|
|
101
|
+
const { tableId, rows } = payload;
|
|
102
|
+
const db = dbs[tableId] || (await openDB(tableId));
|
|
103
|
+
await bulkInsert(db, rows);
|
|
104
|
+
initCounts[tableId] = (initCounts[tableId] || 0) + rows.length;
|
|
105
|
+
postMessage({ type: 'init-progress', payload: { tableId, inserted: initCounts[tableId] } });
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (type === 'init-done') {
|
|
110
|
+
const { tableId } = payload;
|
|
111
|
+
const total = initCounts[tableId] || 0;
|
|
112
|
+
postMessage({ type: 'inited', payload: { tableId, count: total } });
|
|
113
|
+
delete initCounts[tableId];
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (type === 'init') {
|
|
118
|
+
const { tableId, rows } = payload;
|
|
119
|
+
const db = await openDB(tableId);
|
|
120
|
+
await clearStore(db);
|
|
121
|
+
// insert in chunks to avoid blocking
|
|
122
|
+
const CHUNK = 1000;
|
|
123
|
+
for (let i = 0; i < rows.length; i += CHUNK) {
|
|
124
|
+
const chunk = rows.slice(i, i + CHUNK);
|
|
125
|
+
await bulkInsert(db, chunk);
|
|
126
|
+
}
|
|
127
|
+
dbs[tableId] = db;
|
|
128
|
+
postMessage({ type: 'inited', payload: { tableId, count: rows.length } });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (type === 'query') {
|
|
132
|
+
const { tableId, q, filters = [], offset = 0, limit = 100 } = payload;
|
|
133
|
+
const db = dbs[tableId] || (await openDB(tableId));
|
|
134
|
+
dbs[tableId] = db;
|
|
135
|
+
|
|
136
|
+
const tx = db.transaction('rows', 'readonly');
|
|
137
|
+
const store = tx.objectStore('rows');
|
|
138
|
+
const req = store.openCursor();
|
|
139
|
+
|
|
140
|
+
const results = [];
|
|
141
|
+
let total = 0;
|
|
142
|
+
let skipped = 0;
|
|
143
|
+
|
|
144
|
+
await new Promise((res, rej) => {
|
|
145
|
+
req.onsuccess = (evt) => {
|
|
146
|
+
const cursor = evt.target.result;
|
|
147
|
+
if (!cursor) {
|
|
148
|
+
res();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const rec = cursor.value;
|
|
152
|
+
if (matches(rec, q, filters)) {
|
|
153
|
+
total++;
|
|
154
|
+
if (skipped < offset) {
|
|
155
|
+
skipped++;
|
|
156
|
+
} else if (results.length < limit) {
|
|
157
|
+
results.push(rec.__r || rec);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
cursor.continue();
|
|
161
|
+
};
|
|
162
|
+
req.onerror = () => rej(req.error);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
postMessage({ type: 'result', payload: { tableId, rows: results, total } });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (type === 'clear') {
|
|
169
|
+
const { tableId } = payload;
|
|
170
|
+
const db = dbs[tableId] || (await openDB(tableId));
|
|
171
|
+
await clearStore(db);
|
|
172
|
+
postMessage({ type: 'cleared', payload: { tableId } });
|
|
173
|
+
}
|
|
174
|
+
} catch (err) {
|
|
175
|
+
postMessage({ type: 'error', payload: { message: err?.message ?? String(err) } });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SvelteComponent } from 'svelte';
|
|
2
2
|
import type { Writable } from 'svelte/store';
|
|
3
|
-
import { Receive } from '../../models/Models';
|
|
4
3
|
import type { FilterOptionsEnum } from '../../models/Enums';
|
|
5
4
|
import type { Columns, Filter, OrderBy, ServerColumn, ServerConfig } from '../../models/Models';
|
|
6
5
|
export declare const minWidth: (id: string, columns: Columns | undefined) => number;
|
|
@@ -23,7 +22,7 @@ export declare const missingValuesFn: (key: number | string, missingValues: {
|
|
|
23
22
|
}) => string | number;
|
|
24
23
|
export declare const updateTable: (pageSize: number, pageIndex: number, server: ServerConfig | undefined, filters: {
|
|
25
24
|
[key: string]: { [key in FilterOptionsEnum]?: number | string | Date; };
|
|
26
|
-
}, data: Writable<any[]>, serverItems: Writable<number> | undefined, columns: Columns | undefined, dispatch: any, order?: OrderBy[]) => Promise<
|
|
25
|
+
}, data: Writable<any[]>, serverItems: Writable<number> | undefined, columns: Columns | undefined, dispatch: any, order?: OrderBy[]) => Promise<Writable<any[]>>;
|
|
27
26
|
export declare const convertServerColumns: (serverColumns: ServerColumn[], columns: Columns | undefined) => Columns;
|
|
28
27
|
export declare const getMaxCellHeightInRow: (tableRef: HTMLTableElement, resizable: "columns" | "rows" | "none" | "both", optionsComponent: typeof SvelteComponent | undefined, rowHeights: Writable<{
|
|
29
28
|
[key: number]: {
|
|
@@ -31,9 +31,7 @@ export const cellStyle = (id, columns) => {
|
|
|
31
31
|
export const getResizeStyles = (rowHeights, id, index) => {
|
|
32
32
|
return `
|
|
33
33
|
min-height: ${rowHeights && rowHeights[+id] ? `${rowHeights[+id].min}px` : 'auto'};
|
|
34
|
-
max-height: ${index !== 0 && rowHeights && rowHeights[+id]
|
|
35
|
-
? `${rowHeights[+id].max}px`
|
|
36
|
-
: 'auto'};
|
|
34
|
+
max-height: ${index !== 0 && rowHeights && rowHeights[+id] ? `${rowHeights[+id].max}px` : 'auto'};
|
|
37
35
|
height: ${rowHeights && rowHeights[+id] ? `${rowHeights[+id].min}px` : 'auto'};
|
|
38
36
|
`;
|
|
39
37
|
};
|
|
@@ -86,7 +84,7 @@ export const jsonToCsv = (data) => {
|
|
|
86
84
|
// Create CSV rows
|
|
87
85
|
const rows = [
|
|
88
86
|
headers.join(','), // Header row
|
|
89
|
-
...json.map((row) => headers.map(header => escapeCsvCell(row[header])).join(',')) // Data rows
|
|
87
|
+
...json.map((row) => headers.map((header) => escapeCsvCell(row[header])).join(',')) // Data rows
|
|
90
88
|
];
|
|
91
89
|
// Join rows with newlines
|
|
92
90
|
return rows.join('\n');
|
|
@@ -154,7 +152,7 @@ export const updateTable = async (pageSize, pageIndex, server, filters, data, se
|
|
|
154
152
|
// remove %%% from the columns object
|
|
155
153
|
if (sendModel.order) {
|
|
156
154
|
sendModel.order.forEach((order) => {
|
|
157
|
-
if (order.column.includes(
|
|
155
|
+
if (order.column.includes('%%%')) {
|
|
158
156
|
const newKey = order.column.replaceAll('%%%', '.');
|
|
159
157
|
order.column = newKey;
|
|
160
158
|
}
|
|
@@ -190,6 +188,19 @@ export const updateTable = async (pageSize, pageIndex, server, filters, data, se
|
|
|
190
188
|
}
|
|
191
189
|
return value;
|
|
192
190
|
});
|
|
191
|
+
const rawCount = response.count;
|
|
192
|
+
const hasRawCount = rawCount !== undefined && rawCount !== null && String(rawCount).trim().length > 0;
|
|
193
|
+
const parsedServerCount = hasRawCount
|
|
194
|
+
? typeof rawCount === 'number'
|
|
195
|
+
? rawCount
|
|
196
|
+
: Number(String(rawCount).replace(/[^0-9.-]/g, ''))
|
|
197
|
+
: Number.NaN;
|
|
198
|
+
const hasServerCount = hasRawCount && Number.isFinite(parsedServerCount) && parsedServerCount >= 0;
|
|
199
|
+
const normalizedCount = hasServerCount
|
|
200
|
+
? parsedServerCount
|
|
201
|
+
: Array.isArray(response.data)
|
|
202
|
+
? response.data.length
|
|
203
|
+
: 0;
|
|
193
204
|
// console.log('Server response', response);
|
|
194
205
|
// Format server columns to the client columns
|
|
195
206
|
if (response.columns !== undefined) {
|
|
@@ -201,8 +212,8 @@ export const updateTable = async (pageSize, pageIndex, server, filters, data, se
|
|
|
201
212
|
//const key = col.key.replaceAll('.' ,'');
|
|
202
213
|
///console.log(key, col.column);
|
|
203
214
|
// set the key to the columns object
|
|
204
|
-
col.column = col.column.replaceAll('.',
|
|
205
|
-
col.key = col.key.replaceAll('.',
|
|
215
|
+
col.column = col.column.replaceAll('.', '%%%');
|
|
216
|
+
col.key = col.key.replaceAll('.', '%%%');
|
|
206
217
|
acc[col.key] = col.column;
|
|
207
218
|
//acc[col.column] = col.column;
|
|
208
219
|
return acc;
|
|
@@ -212,20 +223,23 @@ export const updateTable = async (pageSize, pageIndex, server, filters, data, se
|
|
|
212
223
|
response.data.forEach((row, index) => {
|
|
213
224
|
const tmp = {};
|
|
214
225
|
Object.keys(row).forEach((key) => {
|
|
215
|
-
tmp[clientCols[key.replaceAll('.',
|
|
226
|
+
tmp[clientCols[key.replaceAll('.', '%%%')]] = row[key];
|
|
216
227
|
});
|
|
217
228
|
tmpArr.push(tmp);
|
|
218
229
|
});
|
|
219
|
-
dispatch('fetch',
|
|
230
|
+
dispatch('fetch', {
|
|
231
|
+
columns,
|
|
232
|
+
count: hasServerCount ? parsedServerCount : tmpArr.length
|
|
233
|
+
});
|
|
234
|
+
serverItems?.set(hasServerCount ? parsedServerCount : tmpArr.length);
|
|
220
235
|
data.set(tmpArr);
|
|
221
236
|
// console.log('Server data', tmpArr);
|
|
222
237
|
return data;
|
|
223
238
|
}
|
|
224
|
-
serverItems?.set(
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return response;
|
|
239
|
+
serverItems?.set(normalizedCount);
|
|
240
|
+
// If backend does not provide column metadata, still render returned rows.
|
|
241
|
+
data.set(response.data ?? []);
|
|
242
|
+
return data;
|
|
229
243
|
};
|
|
230
244
|
// Function to convert server data to client data
|
|
231
245
|
export const convertServerColumns = (serverColumns, columns) => {
|
|
@@ -267,13 +281,13 @@ export const convertServerColumns = (serverColumns, columns) => {
|
|
|
267
281
|
};
|
|
268
282
|
}
|
|
269
283
|
if (columns && col.column in columns) {
|
|
270
|
-
columnsConfig[col.column.replaceAll('.',
|
|
271
|
-
...columns[col.column.replaceAll('.',
|
|
284
|
+
columnsConfig[col.column.replaceAll('.', '%%%')] = {
|
|
285
|
+
...columns[col.column.replaceAll('.', '%%%')],
|
|
272
286
|
instructions
|
|
273
287
|
};
|
|
274
288
|
}
|
|
275
289
|
else {
|
|
276
|
-
columnsConfig[col.column.replaceAll('.',
|
|
290
|
+
columnsConfig[col.column.replaceAll('.', '%%%')] = {
|
|
277
291
|
instructions
|
|
278
292
|
};
|
|
279
293
|
}
|
|
@@ -285,6 +299,7 @@ export const convertServerColumns = (serverColumns, columns) => {
|
|
|
285
299
|
export const getMaxCellHeightInRow = (tableRef, resizable, optionsComponent, rowHeights, tableId, rowHeight) => {
|
|
286
300
|
if (!tableRef || resizable === 'columns' || resizable === 'none')
|
|
287
301
|
return;
|
|
302
|
+
const measuredHeights = {};
|
|
288
303
|
tableRef.querySelectorAll('tbody tr').forEach((row, index) => {
|
|
289
304
|
const cells = row.querySelectorAll('td');
|
|
290
305
|
let maxHeight = optionsComponent ? 56 : 44;
|
|
@@ -299,17 +314,21 @@ export const getMaxCellHeightInRow = (tableRef, resizable, optionsComponent, row
|
|
|
299
314
|
minHeight = cellHeight + 2;
|
|
300
315
|
}
|
|
301
316
|
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
max: maxHeight - 24,
|
|
308
|
-
min: Math.max(minHeight - 24, rowHeight ?? 20)
|
|
309
|
-
}
|
|
317
|
+
const id = +row.id.split(`${tableId}-row-`)[1];
|
|
318
|
+
if (Number.isFinite(id)) {
|
|
319
|
+
measuredHeights[id] = {
|
|
320
|
+
max: maxHeight - 24,
|
|
321
|
+
min: Math.max(minHeight - 24, rowHeight ?? 20)
|
|
310
322
|
};
|
|
311
|
-
}
|
|
323
|
+
}
|
|
312
324
|
});
|
|
325
|
+
if (Object.keys(measuredHeights).length === 0) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
rowHeights.update((rh) => ({
|
|
329
|
+
...rh,
|
|
330
|
+
...measuredHeights
|
|
331
|
+
}));
|
|
313
332
|
};
|
|
314
333
|
// Calculates the minimum width of the cells in each column
|
|
315
334
|
export const getMinCellWidthInColumn = (tableRef, colWidths, headerRowsLength, resizable) => {
|
|
@@ -12,19 +12,19 @@ export let feedback;
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<InputContainer {id} label={title} {feedback} {required} {help} {description}>
|
|
15
|
-
<div
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</div>
|
|
15
|
+
<div class="flex gap-2" class:flex-col={vertical}>
|
|
16
|
+
{#each source as item}
|
|
17
|
+
<label class="flex items-center space-x-2" for={item.key}>
|
|
18
|
+
<input
|
|
19
|
+
class="checkbox"
|
|
20
|
+
type="checkbox"
|
|
21
|
+
bind:group={target}
|
|
22
|
+
checked={item.key}
|
|
23
|
+
value={item.key}
|
|
24
|
+
id={item.key}
|
|
25
|
+
/>
|
|
26
|
+
<p>{item.value}</p>
|
|
27
|
+
</label>
|
|
28
|
+
{/each}
|
|
29
|
+
</div>
|
|
30
30
|
</InputContainer>
|
|
@@ -11,7 +11,7 @@ export let feedback;
|
|
|
11
11
|
<InputContainer label={title} {feedback} {required} {description}>
|
|
12
12
|
{#each source as item}
|
|
13
13
|
<label class="flex items-center space-x-2" for={item}>
|
|
14
|
-
<input class="checkbox" type="checkbox" bind:group={target} value={item} id={item}/>
|
|
14
|
+
<input class="checkbox" type="checkbox" bind:group={target} value={item} id={item} />
|
|
15
15
|
<p>{item}</p>
|
|
16
16
|
</label>
|
|
17
17
|
{/each}
|
|
@@ -13,7 +13,18 @@ export let showDescription = false;
|
|
|
13
13
|
export let showIcon = false;
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<InputContainer
|
|
16
|
+
<InputContainer
|
|
17
|
+
{id}
|
|
18
|
+
{label}
|
|
19
|
+
{feedback}
|
|
20
|
+
{required}
|
|
21
|
+
{help}
|
|
22
|
+
{description}
|
|
23
|
+
{showDescription}
|
|
24
|
+
{showIcon}
|
|
25
|
+
on:showDescription
|
|
26
|
+
on:hideDescription
|
|
27
|
+
>
|
|
17
28
|
<input
|
|
18
29
|
{id}
|
|
19
30
|
class="input variant-form-material bg-zinc-50 dark:bg-zinc-700 placeholder:text-gray-400"
|
|
@@ -33,33 +33,55 @@ if (mode === "datetime") {
|
|
|
33
33
|
}
|
|
34
34
|
</script>
|
|
35
35
|
|
|
36
|
-
<InputContainer
|
|
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
|
-
|
|
36
|
+
<InputContainer
|
|
37
|
+
{id}
|
|
38
|
+
{label}
|
|
39
|
+
{feedback}
|
|
40
|
+
{required}
|
|
41
|
+
{help}
|
|
42
|
+
{description}
|
|
43
|
+
{showDescription}
|
|
44
|
+
{showIcon}
|
|
45
|
+
on:showDescription
|
|
46
|
+
on:hideDescription
|
|
47
|
+
>
|
|
48
|
+
<!-- 1. Wrap everything in a relative container so the icon positions against this boundary -->
|
|
49
|
+
<div class="relative w-full">
|
|
50
|
+
<SveltyPicker
|
|
51
|
+
{mode}
|
|
52
|
+
name={label}
|
|
53
|
+
{format}
|
|
54
|
+
{displayFormat}
|
|
55
|
+
{initialDate}
|
|
56
|
+
bind:value
|
|
57
|
+
on:input
|
|
58
|
+
on:change
|
|
59
|
+
{disabled}
|
|
60
|
+
{placeholder}
|
|
61
|
+
manualInput={true}
|
|
62
|
+
inputClasses="input variant-form-material bg-zinc-50 dark:bg-zinc-700 placeholder:text-gray-400 pr-10 {valid
|
|
63
|
+
? 'input-success'
|
|
64
|
+
: ''} {invalid ? 'input-error' : ''}"
|
|
65
|
+
/>
|
|
66
|
+
{#if mode === 'time'}
|
|
67
|
+
<Fa
|
|
68
|
+
icon={faClock}
|
|
69
|
+
class="absolute inset-y-2 right-0 flex items-center pr-3 pointer-events-none text-gray-400 dark:text-gray-300"
|
|
70
|
+
/>
|
|
71
|
+
{:else if mode === 'date'}
|
|
72
|
+
<Fa
|
|
73
|
+
icon={faCalendar}
|
|
74
|
+
class="absolute inset-y-2 right-0 flex items-center pr-3 pointer-events-none text-gray-400 dark:text-gray-300"
|
|
75
|
+
/>
|
|
76
|
+
{:else if mode === 'datetime'}
|
|
77
|
+
<Fa
|
|
78
|
+
icon={faCalendar}
|
|
79
|
+
class="absolute inset-y-2 right-5 flex items-center pr-3 pointer-events-none text-gray-400 dark:text-gray-300"
|
|
80
|
+
/>
|
|
81
|
+
<Fa
|
|
82
|
+
icon={faClock}
|
|
83
|
+
class="absolute inset-y-2 right-0 flex items-center pr-3 pointer-events-none text-gray-400 dark:text-gray-300"
|
|
84
|
+
/>
|
|
85
|
+
{/if}
|
|
86
|
+
</div>
|
|
65
87
|
</InputContainer>
|
|
@@ -20,16 +20,27 @@
|
|
|
20
20
|
|
|
21
21
|
function updatedSelectedValue(selection) {
|
|
22
22
|
if (selection != null) {
|
|
23
|
-
|
|
23
|
+
selected = selection;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function updatedTarget(value) {
|
|
28
|
-
|
|
28
|
+
target = value;
|
|
29
29
|
}
|
|
30
30
|
</script>
|
|
31
31
|
|
|
32
|
-
<InputContainer
|
|
32
|
+
<InputContainer
|
|
33
|
+
{id}
|
|
34
|
+
label={title}
|
|
35
|
+
{feedback}
|
|
36
|
+
{required}
|
|
37
|
+
{help}
|
|
38
|
+
{description}
|
|
39
|
+
{showDescription}
|
|
40
|
+
{showIcon}
|
|
41
|
+
on:showDescription
|
|
42
|
+
on:hideDescription
|
|
43
|
+
>
|
|
33
44
|
<select
|
|
34
45
|
{id}
|
|
35
46
|
class="select variant-form-material dark:bg-zinc-700 bg-zinc-50 placeholder:text-gray-400"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export let required = false;
|
|
12
12
|
export let complexTarget = false;
|
|
13
13
|
export let help = false;
|
|
14
|
-
export
|
|
14
|
+
export let description = '';
|
|
15
15
|
export let showDescription = false;
|
|
16
16
|
export let showIcon = false;
|
|
17
17
|
$: selected = null;
|
|
@@ -38,7 +38,18 @@
|
|
|
38
38
|
}
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
|
-
<InputContainer
|
|
41
|
+
<InputContainer
|
|
42
|
+
{id}
|
|
43
|
+
label={title}
|
|
44
|
+
{feedback}
|
|
45
|
+
{required}
|
|
46
|
+
{help}
|
|
47
|
+
{description}
|
|
48
|
+
{showDescription}
|
|
49
|
+
{showIcon}
|
|
50
|
+
on:showDescription
|
|
51
|
+
on:hideDescription
|
|
52
|
+
>
|
|
42
53
|
<select
|
|
43
54
|
{id}
|
|
44
55
|
class="select variant-form-material dark:bg-zinc-700 bg-zinc-50 placeholder:text-gray-400"
|
|
@@ -36,33 +36,35 @@ export function onMouseOut() {
|
|
|
36
36
|
on:focus={onMouseOver}
|
|
37
37
|
on:mouseout={onMouseOut}
|
|
38
38
|
on:blur={onMouseOut}
|
|
39
|
-
on:focusin={onMouseOver}
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
on:focusin={onMouseOver}
|
|
40
|
+
on:focusout={onMouseOut}
|
|
42
41
|
>
|
|
43
|
-
<label class="label w-full flex" for=
|
|
42
|
+
<label class="label w-full flex" for={id}>
|
|
44
43
|
<span class="grow"
|
|
45
44
|
>{label}
|
|
46
|
-
{#if required}
|
|
45
|
+
{#if required}
|
|
46
|
+
<span class="text-xs text-red-600">*</span>
|
|
47
|
+
{/if}
|
|
47
48
|
</span>
|
|
48
49
|
{#if description && showIcon}
|
|
49
|
-
|
|
50
|
+
<button class="badge" on:click={() => (showDescription = !showDescription)}
|
|
51
|
+
><Fa icon={faQuestion} /></button
|
|
52
|
+
>
|
|
50
53
|
{/if}
|
|
51
54
|
</label>
|
|
52
55
|
|
|
53
|
-
|
|
54
56
|
{#if description && showDescription}
|
|
55
|
-
<div
|
|
57
|
+
<div class="card text-sm text-gray-500 p-2 mb-2">{@html description}</div>
|
|
56
58
|
{/if}
|
|
57
59
|
<slot />
|
|
58
60
|
<div class="min-h-5">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
<span class="text-xs text-error-600">
|
|
62
|
+
{#if feedback}
|
|
63
|
+
<ul>
|
|
64
|
+
{#each feedback as message}
|
|
65
|
+
<li>{message}</li>
|
|
66
|
+
{/each}
|
|
67
|
+
</ul>
|
|
66
68
|
{/if}
|
|
67
69
|
</span>
|
|
68
70
|
</div>
|