@teselagen/ui 0.8.6-beta.14 → 0.8.6-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.cjs.js +16339 -16263
- package/index.es.js +16339 -16263
- package/package.json +3 -3
- package/src/DataTable/index.js +1 -1
- package/src/DataTable/utils/filterLocalEntitiesToHasura.js +94 -46
- package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +625 -12
- package/src/DataTable/utils/queryParams.js +53 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teselagen/ui",
|
|
3
|
-
"version": "0.8.6-beta.
|
|
3
|
+
"version": "0.8.6-beta.15",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"@dnd-kit/core": "^6.1.0",
|
|
18
18
|
"@dnd-kit/modifiers": "^7.0.0",
|
|
19
19
|
"@dnd-kit/sortable": "^8.0.0",
|
|
20
|
+
"@teselagen/react-table": "6.10.16",
|
|
20
21
|
"classnames": "^2.3.2",
|
|
21
22
|
"color": "^3.2.1",
|
|
22
23
|
"copy-to-clipboard": "^3.3.1",
|
|
@@ -54,8 +55,7 @@
|
|
|
54
55
|
"chance": "^1.1.11",
|
|
55
56
|
"@dnd-kit/utilities": "3.2.2",
|
|
56
57
|
"@teselagen/file-utils": "0.3.20",
|
|
57
|
-
"@blueprintjs/icons": "3.33.0"
|
|
58
|
-
"jszip": "3.10.1"
|
|
58
|
+
"@blueprintjs/icons": "3.33.0"
|
|
59
59
|
},
|
|
60
60
|
"license": "MIT"
|
|
61
61
|
}
|
package/src/DataTable/index.js
CHANGED
|
@@ -92,9 +92,9 @@ import { viewColumn, openColumn, multiViewColumn } from "./viewColumn";
|
|
|
92
92
|
import convertSchema from "./utils/convertSchema";
|
|
93
93
|
import TableFormTrackerContext from "./TableFormTrackerContext";
|
|
94
94
|
import {
|
|
95
|
-
getCurrentParamsFromUrl,
|
|
96
95
|
getQueryParams,
|
|
97
96
|
makeDataTableHandlers,
|
|
97
|
+
getCurrentParamsFromUrl,
|
|
98
98
|
setCurrentParamsOnUrl
|
|
99
99
|
} from "./utils/queryParams";
|
|
100
100
|
import { useColumns } from "./Columns";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {} from "jszip";
|
|
2
1
|
import {
|
|
3
2
|
isEmpty,
|
|
4
3
|
every,
|
|
@@ -10,7 +9,9 @@ import {
|
|
|
10
9
|
includes,
|
|
11
10
|
isObject,
|
|
12
11
|
has,
|
|
13
|
-
orderBy
|
|
12
|
+
orderBy,
|
|
13
|
+
endsWith,
|
|
14
|
+
get
|
|
14
15
|
} from "lodash-es";
|
|
15
16
|
|
|
16
17
|
export function filterLocalEntitiesToHasura(
|
|
@@ -237,57 +238,104 @@ function applyOrderBy(records, _order_by) {
|
|
|
237
238
|
: [_order_by];
|
|
238
239
|
|
|
239
240
|
if (order_by.length > 0) {
|
|
240
|
-
const
|
|
241
|
-
const
|
|
242
|
-
const iteratees = [];
|
|
241
|
+
const orderFuncs = [];
|
|
242
|
+
const ascOrDescArray = [];
|
|
243
243
|
|
|
244
|
-
order_by.forEach(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
fields.push(field);
|
|
249
|
-
directions.push(direction);
|
|
244
|
+
order_by.forEach(
|
|
245
|
+
({ path, direction, type, sortFn, getValueToFilterOn, ownProps }) => {
|
|
246
|
+
// Default direction is "desc" if not specified
|
|
247
|
+
direction = direction || "desc";
|
|
250
248
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
249
|
+
if (sortFn) {
|
|
250
|
+
// Handle specifically custom sort functions
|
|
251
|
+
// First make sure we have an array of sort functions
|
|
252
|
+
const sortFnArray = Array.isArray(sortFn) ? sortFn : [sortFn];
|
|
253
|
+
|
|
254
|
+
// For each sort function
|
|
255
|
+
sortFnArray.forEach(fn => {
|
|
256
|
+
// First handle null check for this function's values
|
|
257
|
+
orderFuncs.push(r => {
|
|
258
|
+
const val = fn(r);
|
|
259
|
+
return val !== null && val !== undefined ? 1 : 0;
|
|
260
|
+
});
|
|
261
|
+
ascOrDescArray.push("desc"); // Always push nulls to the bottom
|
|
262
|
+
|
|
263
|
+
// Then the actual sort function
|
|
264
|
+
orderFuncs.push(fn);
|
|
265
|
+
ascOrDescArray.push(direction);
|
|
266
|
+
});
|
|
267
|
+
} else if (getValueToFilterOn) {
|
|
268
|
+
// Custom getValue function
|
|
269
|
+
// First handle null check
|
|
270
|
+
orderFuncs.push(r => {
|
|
271
|
+
const val = getValueToFilterOn(r, ownProps);
|
|
272
|
+
return val !== null && val !== undefined ? 1 : 0;
|
|
273
|
+
});
|
|
274
|
+
ascOrDescArray.push("desc"); // Always push nulls to the bottom
|
|
267
275
|
|
|
268
|
-
|
|
269
|
-
|
|
276
|
+
// Then the actual value getter function
|
|
277
|
+
orderFuncs.push(r => getValueToFilterOn(r, ownProps));
|
|
278
|
+
ascOrDescArray.push(direction);
|
|
279
|
+
} else if (type === "timestamp") {
|
|
280
|
+
// Sort nulls/undefined to the bottom regardless of sort direction
|
|
281
|
+
orderFuncs.push(r => {
|
|
282
|
+
const val = get(r, path);
|
|
283
|
+
// First check if value exists, this ensures nulls go to the bottom
|
|
284
|
+
return val ? 1 : 0;
|
|
285
|
+
});
|
|
286
|
+
ascOrDescArray.push("desc"); // always put nulls at the bottom
|
|
270
287
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
288
|
+
// Then actual timestamp sorting
|
|
289
|
+
orderFuncs.push(r => {
|
|
290
|
+
const val = get(r, path);
|
|
291
|
+
return val ? new Date(val).getTime() : -Infinity;
|
|
292
|
+
});
|
|
293
|
+
ascOrDescArray.push(direction);
|
|
294
|
+
} else if (path && endsWith(path.toLowerCase(), "id")) {
|
|
295
|
+
// Handle ID fields - sort numerically
|
|
296
|
+
// First handle null check
|
|
297
|
+
orderFuncs.push(r => {
|
|
298
|
+
const val = get(r, path);
|
|
299
|
+
return val !== null && val !== undefined ? 1 : 0;
|
|
300
|
+
});
|
|
301
|
+
ascOrDescArray.push("desc"); // Always push nulls to the bottom
|
|
276
302
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
303
|
+
// Then the actual ID parsing
|
|
304
|
+
orderFuncs.push(o => {
|
|
305
|
+
const val = get(o, path);
|
|
306
|
+
if (val === null || val === undefined) return -Infinity;
|
|
307
|
+
return parseInt(val, 10) || 0;
|
|
308
|
+
});
|
|
309
|
+
ascOrDescArray.push(direction);
|
|
310
|
+
} else {
|
|
311
|
+
// Default sorting
|
|
312
|
+
// First sort by existence (non-nulls first)
|
|
313
|
+
orderFuncs.push(r => {
|
|
314
|
+
const val = get(r, path);
|
|
315
|
+
return val !== null && val !== undefined ? 1 : 0;
|
|
316
|
+
});
|
|
317
|
+
ascOrDescArray.push("desc"); // Always put nulls at the bottom
|
|
318
|
+
|
|
319
|
+
// Then sort by actual value
|
|
320
|
+
orderFuncs.push(r => {
|
|
321
|
+
const val = get(r, path);
|
|
322
|
+
if (val === null || val === undefined) return -Infinity;
|
|
323
|
+
|
|
324
|
+
// For string sorting, implement natural sort
|
|
325
|
+
if (isString(val)) {
|
|
326
|
+
return val.toLowerCase().replace(/(\d+)/g, num =>
|
|
327
|
+
// Pad numbers with leading zeros for proper natural sort
|
|
328
|
+
num.padStart(10, "0")
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
return val;
|
|
332
|
+
});
|
|
333
|
+
ascOrDescArray.push(direction);
|
|
334
|
+
}
|
|
287
335
|
}
|
|
288
|
-
|
|
336
|
+
);
|
|
289
337
|
|
|
290
|
-
records =
|
|
338
|
+
records = orderBy(records, orderFuncs, ascOrDescArray);
|
|
291
339
|
}
|
|
292
340
|
return records;
|
|
293
341
|
}
|