@teselagen/ui 0.8.6-beta.2 → 0.8.6-beta.21
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/DataTable/utils/initializeHasuraWhereAndFilter.d.ts +0 -1
- package/DataTable/utils/queryParams.d.ts +13 -2
- package/DataTable/utils/tableQueryParamsToHasuraClauses.d.ts +1 -1
- package/README.md +1 -1
- package/index.cjs.js +312 -127
- package/index.d.ts +1 -0
- package/index.es.js +312 -127
- package/package.json +1 -1
- package/src/DataTable/Columns.js +1 -1
- package/src/DataTable/index.js +2 -2
- package/src/DataTable/utils/filterLocalEntitiesToHasura.js +131 -8
- package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +719 -21
- package/src/DataTable/utils/initializeHasuraWhereAndFilter.js +1 -12
- package/src/DataTable/utils/queryParams.js +176 -91
- package/src/DataTable/utils/tableQueryParamsToHasuraClauses.js +185 -168
- package/src/DataTable/utils/tableQueryParamsToHasuraClauses.test.js +50 -11
- package/src/index.js +1 -0
- package/src/utils/determineBlackOrWhiteTextColor.js +8 -1
- package/utils/determineBlackOrWhiteTextColor.d.ts +1 -2
|
@@ -8,19 +8,8 @@ export function initializeHasuraWhereAndFilter(
|
|
|
8
8
|
if (typeof additionalFilter === "function") {
|
|
9
9
|
const newWhere = additionalFilter(where, currentParams);
|
|
10
10
|
if (newWhere) {
|
|
11
|
-
where
|
|
12
|
-
...where,
|
|
13
|
-
...newWhere
|
|
14
|
-
};
|
|
11
|
+
Object.assign(where, newWhere);
|
|
15
12
|
}
|
|
16
13
|
} else if (typeof additionalFilter === "object")
|
|
17
14
|
where._and.push(additionalFilter);
|
|
18
15
|
}
|
|
19
|
-
|
|
20
|
-
export const addCustomColumnFilters = (where, fields, currentParams) => {
|
|
21
|
-
fields.forEach(field => {
|
|
22
|
-
const { customColumnFilter, filterDisabled } = field;
|
|
23
|
-
if (filterDisabled || !customColumnFilter) return;
|
|
24
|
-
customColumnFilter(where, currentParams);
|
|
25
|
-
});
|
|
26
|
-
};
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import queryString from "qs";
|
|
2
|
-
import { uniqBy, clone, camelCase } from "lodash-es";
|
|
2
|
+
import { uniqBy, clone, camelCase, forEach } from "lodash-es";
|
|
3
3
|
import {
|
|
4
4
|
getFieldsMappedByCCDisplayName,
|
|
5
5
|
tableQueryParamsToHasuraClauses
|
|
6
6
|
} from "./tableQueryParamsToHasuraClauses";
|
|
7
7
|
import { filterLocalEntitiesToHasura } from "./filterLocalEntitiesToHasura";
|
|
8
|
-
import {
|
|
9
|
-
addCustomColumnFilters,
|
|
10
|
-
initializeHasuraWhereAndFilter
|
|
11
|
-
} from "./initializeHasuraWhereAndFilter";
|
|
8
|
+
import { initializeHasuraWhereAndFilter } from "./initializeHasuraWhereAndFilter";
|
|
12
9
|
|
|
13
10
|
const defaultPageSizes = [5, 10, 15, 25, 50, 100, 200, 400];
|
|
14
11
|
|
|
@@ -56,7 +53,6 @@ function safeParse(val) {
|
|
|
56
53
|
return val;
|
|
57
54
|
}
|
|
58
55
|
}
|
|
59
|
-
|
|
60
56
|
export function getCurrentParamsFromUrl(location, isSimple) {
|
|
61
57
|
let { search } = location;
|
|
62
58
|
if (isSimple) {
|
|
@@ -242,9 +238,30 @@ export function makeDataTableHandlers({
|
|
|
242
238
|
};
|
|
243
239
|
}
|
|
244
240
|
|
|
241
|
+
function cleanupFilters({ filters, ccFields }) {
|
|
242
|
+
(filters || []).forEach(filter => {
|
|
243
|
+
const { filterOn, filterValue } = filter;
|
|
244
|
+
const field = ccFields[filterOn];
|
|
245
|
+
if (field.type === "number" || field.type === "integer") {
|
|
246
|
+
filter.filterValue = Array.isArray(filterValue)
|
|
247
|
+
? filterValue.map(val => Number(val))
|
|
248
|
+
: Number(filterValue);
|
|
249
|
+
}
|
|
250
|
+
if (
|
|
251
|
+
filter.selectedFilter === "inList" &&
|
|
252
|
+
typeof filter.filterValue === "number"
|
|
253
|
+
) {
|
|
254
|
+
// if an inList value only has two items like
|
|
255
|
+
// 2.3 then it will get parsed to a number and
|
|
256
|
+
// break, convert it back to a string here
|
|
257
|
+
filter.filterValue = filter.filterValue.toString();
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
245
262
|
export function getQueryParams({
|
|
246
263
|
currentParams,
|
|
247
|
-
|
|
264
|
+
urlConnected,
|
|
248
265
|
defaults,
|
|
249
266
|
schema,
|
|
250
267
|
isInfinite,
|
|
@@ -253,98 +270,166 @@ export function getQueryParams({
|
|
|
253
270
|
additionalFilter,
|
|
254
271
|
doNotCoercePageSize,
|
|
255
272
|
noOrderError,
|
|
256
|
-
|
|
273
|
+
isCodeModel,
|
|
257
274
|
ownProps
|
|
258
275
|
}) {
|
|
259
|
-
|
|
260
|
-
if (currentParams[key] === undefined) {
|
|
261
|
-
delete currentParams[key]; //we want to use the default value if any of these are undefined
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
const tableQueryParams = {
|
|
265
|
-
...defaults,
|
|
266
|
-
...currentParams
|
|
267
|
-
};
|
|
268
|
-
let { page, pageSize, searchTerm, filters, order } = tableQueryParams;
|
|
269
|
-
if (page <= 0 || isNaN(page)) {
|
|
270
|
-
page = undefined;
|
|
271
|
-
}
|
|
272
|
-
if (isInfinite) {
|
|
273
|
-
page = undefined;
|
|
274
|
-
pageSize = undefined;
|
|
275
|
-
}
|
|
276
|
-
if (pageSize !== undefined && !doNotCoercePageSize) {
|
|
277
|
-
//pageSize might come in as an unexpected number so we coerce it to be one of the nums in our pageSizes array
|
|
278
|
-
const closest = clone(window.tgPageSizes || defaultPageSizes).sort(
|
|
279
|
-
(a, b) => Math.abs(pageSize - a) - Math.abs(pageSize - b)
|
|
280
|
-
)[0];
|
|
281
|
-
pageSize = closest;
|
|
282
|
-
}
|
|
276
|
+
let errorParsingUrlString;
|
|
283
277
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
const ccDisplayName = orderVal.replace(/^-/gi, "");
|
|
289
|
-
const schemaForField = ccFields[ccDisplayName];
|
|
290
|
-
if (schemaForField) {
|
|
291
|
-
const { path } = schemaForField;
|
|
292
|
-
const reversed = ccDisplayName !== orderVal;
|
|
293
|
-
const prefix = reversed ? "-" : "";
|
|
294
|
-
cleanedOrder.push(prefix + path);
|
|
295
|
-
} else {
|
|
296
|
-
!noOrderError &&
|
|
297
|
-
console.error(
|
|
298
|
-
"No schema for field found!",
|
|
299
|
-
ccDisplayName,
|
|
300
|
-
JSON.stringify(schema.fields, null, 2)
|
|
301
|
-
);
|
|
278
|
+
try {
|
|
279
|
+
Object.keys(currentParams).forEach(function (key) {
|
|
280
|
+
if (currentParams[key] === undefined) {
|
|
281
|
+
delete currentParams[key]; //we want to use the default value if any of these are undefined
|
|
302
282
|
}
|
|
303
283
|
});
|
|
304
|
-
|
|
284
|
+
const tableQueryParams = {
|
|
285
|
+
...defaults,
|
|
286
|
+
...currentParams
|
|
287
|
+
};
|
|
288
|
+
let { page, pageSize, searchTerm, filters, order } = tableQueryParams;
|
|
289
|
+
const ccFields = getFieldsMappedByCCDisplayName(schema);
|
|
305
290
|
|
|
306
|
-
|
|
307
|
-
//these are values that might be generally useful for the wrapped component
|
|
308
|
-
page,
|
|
309
|
-
pageSize: ownProps.controlled_pageSize || pageSize,
|
|
310
|
-
order: cleanedOrder,
|
|
311
|
-
filters,
|
|
312
|
-
searchTerm
|
|
313
|
-
};
|
|
291
|
+
cleanupFilters({ filters, ccFields });
|
|
314
292
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
293
|
+
if (page <= 0 || isNaN(page)) {
|
|
294
|
+
page = undefined;
|
|
295
|
+
}
|
|
296
|
+
if (isInfinite) {
|
|
297
|
+
page = undefined;
|
|
298
|
+
pageSize = undefined;
|
|
299
|
+
}
|
|
300
|
+
if (pageSize !== undefined && !doNotCoercePageSize) {
|
|
301
|
+
//pageSize might come in as an unexpected number so we coerce it to be one of the nums in our pageSizes array
|
|
302
|
+
const closest = clone(window.tgPageSizes || defaultPageSizes).sort(
|
|
303
|
+
(a, b) => Math.abs(pageSize - a) - Math.abs(pageSize - b)
|
|
304
|
+
)[0];
|
|
305
|
+
pageSize = closest;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const cleanedOrder = [];
|
|
309
|
+
if (order && order.length) {
|
|
310
|
+
order.forEach(orderVal => {
|
|
311
|
+
const ccDisplayName = orderVal.replace(/^-/gi, "");
|
|
312
|
+
const schemaForField = ccFields[ccDisplayName];
|
|
313
|
+
if (schemaForField) {
|
|
314
|
+
const { path } = schemaForField;
|
|
315
|
+
const reversed = ccDisplayName !== orderVal;
|
|
316
|
+
const prefix = reversed ? "-" : "";
|
|
317
|
+
cleanedOrder.push(prefix + path);
|
|
318
|
+
} else {
|
|
319
|
+
!noOrderError &&
|
|
320
|
+
console.error(
|
|
321
|
+
"No schema for field found!",
|
|
322
|
+
ccDisplayName,
|
|
323
|
+
JSON.stringify(schema.fields, null, 2)
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
let toRet = {
|
|
329
|
+
//these are values that might be generally useful for the wrapped component
|
|
330
|
+
page,
|
|
331
|
+
pageSize: ownProps.controlled_pageSize || pageSize,
|
|
332
|
+
order: cleanedOrder,
|
|
333
|
+
filters,
|
|
334
|
+
searchTerm
|
|
337
335
|
};
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
336
|
+
|
|
337
|
+
const { where, order_by, limit, offset } = tableQueryParamsToHasuraClauses({
|
|
338
|
+
page,
|
|
339
|
+
pageSize,
|
|
340
|
+
searchTerm,
|
|
341
|
+
filters,
|
|
342
|
+
order: cleanedOrder,
|
|
343
|
+
schema
|
|
344
|
+
});
|
|
345
|
+
initializeHasuraWhereAndFilter(additionalFilter, where, currentParams);
|
|
346
|
+
if (isLocalCall) {
|
|
347
|
+
//if the table is local (aka not directly connected to a db) then we need to
|
|
348
|
+
//handle filtering/paging/sorting all on the front end
|
|
349
|
+
const newEnts = filterLocalEntitiesToHasura(
|
|
350
|
+
prepEntitiesForLocalFilter({ entities, ccFields }),
|
|
351
|
+
{
|
|
352
|
+
where,
|
|
353
|
+
order_by: (Array.isArray(order_by) ? order_by : [order_by]).map(
|
|
354
|
+
obj => {
|
|
355
|
+
const path = Object.keys(obj)[0];
|
|
356
|
+
return {
|
|
357
|
+
path,
|
|
358
|
+
direction: obj[path],
|
|
359
|
+
ownProps,
|
|
360
|
+
...ccFields[path]
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
),
|
|
364
|
+
limit,
|
|
365
|
+
offset,
|
|
366
|
+
isInfinite
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
toRet = {
|
|
371
|
+
...toRet,
|
|
372
|
+
...newEnts
|
|
373
|
+
};
|
|
374
|
+
return toRet;
|
|
375
|
+
} else {
|
|
376
|
+
if (!order_by.length) {
|
|
377
|
+
// if no order by is specified, we will default to sorting by updatedAt
|
|
378
|
+
// this is useful for models that do not have a code field
|
|
379
|
+
order_by.push({ updatedAt: "desc" });
|
|
347
380
|
}
|
|
348
|
-
|
|
381
|
+
// in case entries that have the same value in the column being sorted on
|
|
382
|
+
// fall back to id as a secondary sort to make sure ordering happens correctly
|
|
383
|
+
order_by.push(
|
|
384
|
+
isCodeModel ? { code: "desc" } : { [window.__sortId || "id"]: "desc" }
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
return {
|
|
388
|
+
...toRet,
|
|
389
|
+
variables: {
|
|
390
|
+
where,
|
|
391
|
+
order_by,
|
|
392
|
+
limit,
|
|
393
|
+
offset
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
} catch (e) {
|
|
398
|
+
if (urlConnected) {
|
|
399
|
+
errorParsingUrlString = e;
|
|
400
|
+
console.error(
|
|
401
|
+
"The following error occurred when trying to build the query params. This is probably due to a malformed URL:",
|
|
402
|
+
e
|
|
403
|
+
);
|
|
404
|
+
return {
|
|
405
|
+
errorParsingUrlString,
|
|
406
|
+
variables: {
|
|
407
|
+
where: {},
|
|
408
|
+
order_by: [],
|
|
409
|
+
limit: 0,
|
|
410
|
+
offset: 0
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
} else {
|
|
414
|
+
console.error("Error building query params from filter:");
|
|
415
|
+
throw e;
|
|
416
|
+
}
|
|
349
417
|
}
|
|
350
418
|
}
|
|
419
|
+
|
|
420
|
+
function prepEntitiesForLocalFilter({ entities, ccFields }) {
|
|
421
|
+
// Prepare entities for local filtering by mapping over them and applying necessary transformations
|
|
422
|
+
const r = entities.map(entity => {
|
|
423
|
+
const newEnt = { ...entity };
|
|
424
|
+
// Apply any necessary transformations using ccFields
|
|
425
|
+
forEach(ccFields, ({ getValueToFilterOn, path }) => {
|
|
426
|
+
if (getValueToFilterOn) {
|
|
427
|
+
newEnt["___original___" + path] = newEnt[path];
|
|
428
|
+
const value = getValueToFilterOn(newEnt);
|
|
429
|
+
newEnt[path] = value;
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
return newEnt;
|
|
433
|
+
});
|
|
434
|
+
return r;
|
|
435
|
+
}
|