@teselagen/ui 0.8.4 → 0.8.6
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/filterLocalEntitiesToHasura.d.ts +5 -0
- package/DataTable/utils/initializeHasuraWhereAndFilter.d.ts +2 -0
- package/DataTable/utils/tableQueryParamsToHasuraClauses.d.ts +26 -0
- package/autoTooltip.d.ts +1 -1
- package/index.cjs.js +1 -78
- package/index.es.js +1 -78
- package/package.json +1 -1
- package/src/DataTable/utils/filterLocalEntitiesToHasura.js +236 -0
- package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +587 -0
- package/src/DataTable/utils/initializeHasuraWhereAndFilter.js +26 -0
- package/src/DataTable/utils/tableQueryParamsToHasuraClauses.js +260 -0
- package/src/DataTable/utils/tableQueryParamsToHasuraClauses.test.js +206 -0
- package/src/autoTooltip.js +3 -115
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function tableQueryParamsToHasuraClauses({ page, pageSize, searchTerm, filters, order, schema, additionalFilter }: {
|
|
2
|
+
page: any;
|
|
3
|
+
pageSize: any;
|
|
4
|
+
searchTerm: any;
|
|
5
|
+
filters: any;
|
|
6
|
+
order: any;
|
|
7
|
+
schema: any;
|
|
8
|
+
additionalFilter: any;
|
|
9
|
+
}): {
|
|
10
|
+
where: {};
|
|
11
|
+
order_by: {};
|
|
12
|
+
limit: any;
|
|
13
|
+
offset: number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Takes a schema and returns an object with the fields mapped by their camelCased display name.
|
|
17
|
+
* If the displayName is not set or is a jsx element, the path is used instead.
|
|
18
|
+
* The same conversion must be done when using the result of this method
|
|
19
|
+
*/
|
|
20
|
+
export function getFieldsMappedByCCDisplayName(schema: any): any;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {object} field
|
|
24
|
+
* @returns the camelCase display name of the field, to be used for filters, sorting, etc
|
|
25
|
+
*/
|
|
26
|
+
export function getCCDisplayName(field: object): string;
|
package/autoTooltip.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
package/index.cjs.js
CHANGED
|
@@ -2922,77 +2922,6 @@ document.addEventListener("mouseup", () => {
|
|
|
2922
2922
|
canSetDragging = false;
|
|
2923
2923
|
isDragging = false;
|
|
2924
2924
|
});
|
|
2925
|
-
const processedDisabledElements = /* @__PURE__ */ new WeakMap();
|
|
2926
|
-
function moveTooltipToParent(element2) {
|
|
2927
|
-
var _a, _b;
|
|
2928
|
-
if (processedDisabledElements.has(element2)) {
|
|
2929
|
-
return;
|
|
2930
|
-
}
|
|
2931
|
-
const isDisabled = element2.disabled === true || element2.getAttribute("disabled") !== null;
|
|
2932
|
-
const hasTipData = element2.getAttribute("data-tip") || element2.getAttribute("data-title") || element2.offsetWidth < element2.scrollWidth && ((_a = element2.textContent) == null ? void 0 : _a.trim().length) > 0;
|
|
2933
|
-
if (!isDisabled || !hasTipData) {
|
|
2934
|
-
return;
|
|
2935
|
-
}
|
|
2936
|
-
const parent2 = element2.parentElement;
|
|
2937
|
-
if (!parent2) {
|
|
2938
|
-
return;
|
|
2939
|
-
}
|
|
2940
|
-
const tooltipAttrs = ["data-tip", "data-title", "data-avoid", "data-avoid-backup"];
|
|
2941
|
-
let attrsMoved = false;
|
|
2942
|
-
const movedAttrs = [];
|
|
2943
|
-
tooltipAttrs.forEach((attr) => {
|
|
2944
|
-
const value = element2.getAttribute(attr);
|
|
2945
|
-
if (value) {
|
|
2946
|
-
if (!parent2.hasAttribute(attr)) {
|
|
2947
|
-
parent2.setAttribute(attr, value);
|
|
2948
|
-
movedAttrs.push(attr);
|
|
2949
|
-
attrsMoved = true;
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
});
|
|
2953
|
-
if (element2.offsetWidth < element2.scrollWidth && ((_b = element2.textContent) == null ? void 0 : _b.trim().length) > 0) {
|
|
2954
|
-
if (!parent2.hasAttribute("data-tip")) {
|
|
2955
|
-
parent2.setAttribute("data-tip", element2.textContent);
|
|
2956
|
-
movedAttrs.push("data-tip");
|
|
2957
|
-
attrsMoved = true;
|
|
2958
|
-
}
|
|
2959
|
-
}
|
|
2960
|
-
if (attrsMoved) {
|
|
2961
|
-
processedDisabledElements.set(element2, {
|
|
2962
|
-
parent: parent2,
|
|
2963
|
-
movedAttrs
|
|
2964
|
-
});
|
|
2965
|
-
}
|
|
2966
|
-
}
|
|
2967
|
-
__name(moveTooltipToParent, "moveTooltipToParent");
|
|
2968
|
-
function clearParentTooltips(element2) {
|
|
2969
|
-
if (!processedDisabledElements.has(element2)) {
|
|
2970
|
-
return;
|
|
2971
|
-
}
|
|
2972
|
-
const { parent: parent2, movedAttrs } = processedDisabledElements.get(element2);
|
|
2973
|
-
if (parent2 && movedAttrs) {
|
|
2974
|
-
movedAttrs.forEach((attr) => {
|
|
2975
|
-
parent2.removeAttribute(attr);
|
|
2976
|
-
});
|
|
2977
|
-
processedDisabledElements.delete(element2);
|
|
2978
|
-
}
|
|
2979
|
-
}
|
|
2980
|
-
__name(clearParentTooltips, "clearParentTooltips");
|
|
2981
|
-
function scanForDisabledElements() {
|
|
2982
|
-
processedDisabledElements.forEach((value, element2) => {
|
|
2983
|
-
const isStillDisabled = element2.disabled === true || element2.getAttribute("disabled") !== null;
|
|
2984
|
-
const isConnected = element2.isConnected;
|
|
2985
|
-
if (!isStillDisabled || !isConnected) {
|
|
2986
|
-
clearParentTooltips(element2);
|
|
2987
|
-
}
|
|
2988
|
-
});
|
|
2989
|
-
document.querySelectorAll("[disabled][data-tip], [disabled][data-title], button[disabled], input[disabled]").forEach((el) => {
|
|
2990
|
-
moveTooltipToParent(el);
|
|
2991
|
-
});
|
|
2992
|
-
}
|
|
2993
|
-
__name(scanForDisabledElements, "scanForDisabledElements");
|
|
2994
|
-
window.addEventListener("DOMContentLoaded", scanForDisabledElements);
|
|
2995
|
-
setInterval(scanForDisabledElements, 2e3);
|
|
2996
2925
|
let tippys = [];
|
|
2997
2926
|
let recentlyHidden = false;
|
|
2998
2927
|
let clearMe;
|
|
@@ -3000,13 +2929,7 @@ let clearMe;
|
|
|
3000
2929
|
let lastMouseOverElement = null;
|
|
3001
2930
|
document.addEventListener("mouseover", function(event) {
|
|
3002
2931
|
var _a, _b;
|
|
3003
|
-
|
|
3004
|
-
if (element2 instanceof Element && (element2.disabled === true || element2.getAttribute("disabled") !== null)) {
|
|
3005
|
-
const parent2 = element2.parentElement;
|
|
3006
|
-
if (parent2 && processedDisabledElements.has(element2)) {
|
|
3007
|
-
element2 = parent2;
|
|
3008
|
-
}
|
|
3009
|
-
}
|
|
2932
|
+
const element2 = event.target;
|
|
3010
2933
|
if (element2 instanceof Element && element2 !== lastMouseOverElement) {
|
|
3011
2934
|
let clearOldTippys = /* @__PURE__ */ __name(function(maybeInst) {
|
|
3012
2935
|
tippys = tippys.filter((t2) => {
|
package/index.es.js
CHANGED
|
@@ -2904,77 +2904,6 @@ document.addEventListener("mouseup", () => {
|
|
|
2904
2904
|
canSetDragging = false;
|
|
2905
2905
|
isDragging = false;
|
|
2906
2906
|
});
|
|
2907
|
-
const processedDisabledElements = /* @__PURE__ */ new WeakMap();
|
|
2908
|
-
function moveTooltipToParent(element2) {
|
|
2909
|
-
var _a, _b;
|
|
2910
|
-
if (processedDisabledElements.has(element2)) {
|
|
2911
|
-
return;
|
|
2912
|
-
}
|
|
2913
|
-
const isDisabled = element2.disabled === true || element2.getAttribute("disabled") !== null;
|
|
2914
|
-
const hasTipData = element2.getAttribute("data-tip") || element2.getAttribute("data-title") || element2.offsetWidth < element2.scrollWidth && ((_a = element2.textContent) == null ? void 0 : _a.trim().length) > 0;
|
|
2915
|
-
if (!isDisabled || !hasTipData) {
|
|
2916
|
-
return;
|
|
2917
|
-
}
|
|
2918
|
-
const parent2 = element2.parentElement;
|
|
2919
|
-
if (!parent2) {
|
|
2920
|
-
return;
|
|
2921
|
-
}
|
|
2922
|
-
const tooltipAttrs = ["data-tip", "data-title", "data-avoid", "data-avoid-backup"];
|
|
2923
|
-
let attrsMoved = false;
|
|
2924
|
-
const movedAttrs = [];
|
|
2925
|
-
tooltipAttrs.forEach((attr) => {
|
|
2926
|
-
const value = element2.getAttribute(attr);
|
|
2927
|
-
if (value) {
|
|
2928
|
-
if (!parent2.hasAttribute(attr)) {
|
|
2929
|
-
parent2.setAttribute(attr, value);
|
|
2930
|
-
movedAttrs.push(attr);
|
|
2931
|
-
attrsMoved = true;
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
});
|
|
2935
|
-
if (element2.offsetWidth < element2.scrollWidth && ((_b = element2.textContent) == null ? void 0 : _b.trim().length) > 0) {
|
|
2936
|
-
if (!parent2.hasAttribute("data-tip")) {
|
|
2937
|
-
parent2.setAttribute("data-tip", element2.textContent);
|
|
2938
|
-
movedAttrs.push("data-tip");
|
|
2939
|
-
attrsMoved = true;
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
if (attrsMoved) {
|
|
2943
|
-
processedDisabledElements.set(element2, {
|
|
2944
|
-
parent: parent2,
|
|
2945
|
-
movedAttrs
|
|
2946
|
-
});
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
__name(moveTooltipToParent, "moveTooltipToParent");
|
|
2950
|
-
function clearParentTooltips(element2) {
|
|
2951
|
-
if (!processedDisabledElements.has(element2)) {
|
|
2952
|
-
return;
|
|
2953
|
-
}
|
|
2954
|
-
const { parent: parent2, movedAttrs } = processedDisabledElements.get(element2);
|
|
2955
|
-
if (parent2 && movedAttrs) {
|
|
2956
|
-
movedAttrs.forEach((attr) => {
|
|
2957
|
-
parent2.removeAttribute(attr);
|
|
2958
|
-
});
|
|
2959
|
-
processedDisabledElements.delete(element2);
|
|
2960
|
-
}
|
|
2961
|
-
}
|
|
2962
|
-
__name(clearParentTooltips, "clearParentTooltips");
|
|
2963
|
-
function scanForDisabledElements() {
|
|
2964
|
-
processedDisabledElements.forEach((value, element2) => {
|
|
2965
|
-
const isStillDisabled = element2.disabled === true || element2.getAttribute("disabled") !== null;
|
|
2966
|
-
const isConnected = element2.isConnected;
|
|
2967
|
-
if (!isStillDisabled || !isConnected) {
|
|
2968
|
-
clearParentTooltips(element2);
|
|
2969
|
-
}
|
|
2970
|
-
});
|
|
2971
|
-
document.querySelectorAll("[disabled][data-tip], [disabled][data-title], button[disabled], input[disabled]").forEach((el) => {
|
|
2972
|
-
moveTooltipToParent(el);
|
|
2973
|
-
});
|
|
2974
|
-
}
|
|
2975
|
-
__name(scanForDisabledElements, "scanForDisabledElements");
|
|
2976
|
-
window.addEventListener("DOMContentLoaded", scanForDisabledElements);
|
|
2977
|
-
setInterval(scanForDisabledElements, 2e3);
|
|
2978
2907
|
let tippys = [];
|
|
2979
2908
|
let recentlyHidden = false;
|
|
2980
2909
|
let clearMe;
|
|
@@ -2982,13 +2911,7 @@ let clearMe;
|
|
|
2982
2911
|
let lastMouseOverElement = null;
|
|
2983
2912
|
document.addEventListener("mouseover", function(event) {
|
|
2984
2913
|
var _a, _b;
|
|
2985
|
-
|
|
2986
|
-
if (element2 instanceof Element && (element2.disabled === true || element2.getAttribute("disabled") !== null)) {
|
|
2987
|
-
const parent2 = element2.parentElement;
|
|
2988
|
-
if (parent2 && processedDisabledElements.has(element2)) {
|
|
2989
|
-
element2 = parent2;
|
|
2990
|
-
}
|
|
2991
|
-
}
|
|
2914
|
+
const element2 = event.target;
|
|
2992
2915
|
if (element2 instanceof Element && element2 !== lastMouseOverElement) {
|
|
2993
2916
|
let clearOldTippys = /* @__PURE__ */ __name(function(maybeInst) {
|
|
2994
2917
|
tippys = tippys.filter((t2) => {
|
package/package.json
CHANGED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isEmpty,
|
|
3
|
+
every,
|
|
4
|
+
some,
|
|
5
|
+
isEqual,
|
|
6
|
+
isString,
|
|
7
|
+
isNull,
|
|
8
|
+
isArray,
|
|
9
|
+
includes,
|
|
10
|
+
isObject,
|
|
11
|
+
has,
|
|
12
|
+
orderBy
|
|
13
|
+
} from "lodash-es";
|
|
14
|
+
|
|
15
|
+
export function filterLocalEntitiesToHasura(
|
|
16
|
+
records,
|
|
17
|
+
{ where, order_by, limit, offset, isInfinite } = {}
|
|
18
|
+
) {
|
|
19
|
+
let filteredRecords = [...records];
|
|
20
|
+
|
|
21
|
+
// Apply where clause if it exists
|
|
22
|
+
if (where) {
|
|
23
|
+
filteredRecords = applyWhereClause(filteredRecords, where);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Apply order_by if it exists
|
|
27
|
+
if (order_by) {
|
|
28
|
+
filteredRecords = applyOrderBy(filteredRecords, order_by);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Store the complete filtered and ordered records for pagination info
|
|
32
|
+
const allFilteredRecords = [...filteredRecords];
|
|
33
|
+
|
|
34
|
+
// Apply limit and offset
|
|
35
|
+
if (!isInfinite && offset !== undefined) {
|
|
36
|
+
filteredRecords = filteredRecords.slice(offset);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!isInfinite && limit !== undefined) {
|
|
40
|
+
filteredRecords = filteredRecords.slice(0, limit);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// For consistency, always return an object with entities, entitiesAcrossPages, and entityCount
|
|
44
|
+
return {
|
|
45
|
+
entities: filteredRecords,
|
|
46
|
+
entitiesAcrossPages: allFilteredRecords,
|
|
47
|
+
entityCount: allFilteredRecords.length
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function applyWhereClause(records, where) {
|
|
52
|
+
function applyFilter(record, filter) {
|
|
53
|
+
if (isEmpty(filter)) {
|
|
54
|
+
return true; // No filter, all records pass
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (const key in filter) {
|
|
58
|
+
if (key === "_and") {
|
|
59
|
+
if (isEmpty(filter[key])) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (!every(filter[key], subFilter => applyFilter(record, subFilter))) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
} else if (key === "_or") {
|
|
66
|
+
if (isEmpty(filter[key])) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (!some(filter[key], subFilter => applyFilter(record, subFilter))) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
} else if (key === "_not") {
|
|
73
|
+
if (applyFilter(record, filter[key])) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
const value = record[key];
|
|
78
|
+
const conditions = filter[key];
|
|
79
|
+
|
|
80
|
+
// Handle nested object properties
|
|
81
|
+
if (
|
|
82
|
+
isObject(value) &&
|
|
83
|
+
isObject(conditions) &&
|
|
84
|
+
!hasOperator(conditions)
|
|
85
|
+
) {
|
|
86
|
+
return applyFilter(value, conditions);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
for (const operator in conditions) {
|
|
90
|
+
const conditionValue = conditions[operator];
|
|
91
|
+
|
|
92
|
+
// Handle range conditions (_gt/_lt or _gte/_lte combinations)
|
|
93
|
+
if (operator === "_gt" && conditions._lt) {
|
|
94
|
+
if (!(value > conditionValue && value < conditions._lt))
|
|
95
|
+
return false;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (operator === "_gte" && conditions._lte) {
|
|
99
|
+
if (!(value >= conditionValue && value <= conditions._lte))
|
|
100
|
+
return false;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
switch (operator) {
|
|
105
|
+
case "_eq":
|
|
106
|
+
if (!isEqual(value, conditionValue)) return false;
|
|
107
|
+
break;
|
|
108
|
+
case "_neq":
|
|
109
|
+
if (isEqual(value, conditionValue)) return false;
|
|
110
|
+
break;
|
|
111
|
+
case "_gt":
|
|
112
|
+
if (!(value > conditionValue)) return false;
|
|
113
|
+
break;
|
|
114
|
+
case "_gte":
|
|
115
|
+
if (!(value >= conditionValue)) return false;
|
|
116
|
+
break;
|
|
117
|
+
case "_lt":
|
|
118
|
+
if (!(value < conditionValue)) return false;
|
|
119
|
+
break;
|
|
120
|
+
case "_lte":
|
|
121
|
+
if (!(value <= conditionValue)) return false;
|
|
122
|
+
break;
|
|
123
|
+
case "_like":
|
|
124
|
+
if (
|
|
125
|
+
!isString(value) ||
|
|
126
|
+
!new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
|
|
127
|
+
)
|
|
128
|
+
return false;
|
|
129
|
+
break;
|
|
130
|
+
case "_ilike":
|
|
131
|
+
if (
|
|
132
|
+
!isString(value) ||
|
|
133
|
+
!new RegExp(conditionValue.replace(/%/g, ".*"), "i").test(value)
|
|
134
|
+
)
|
|
135
|
+
return false;
|
|
136
|
+
break;
|
|
137
|
+
case "_nlike":
|
|
138
|
+
if (
|
|
139
|
+
!isString(value) ||
|
|
140
|
+
new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
|
|
141
|
+
)
|
|
142
|
+
return false;
|
|
143
|
+
break;
|
|
144
|
+
case "_nilike":
|
|
145
|
+
if (
|
|
146
|
+
!isString(value) ||
|
|
147
|
+
new RegExp(conditionValue.replace(/%/g, ".*"), "i").test(value)
|
|
148
|
+
)
|
|
149
|
+
return false;
|
|
150
|
+
break;
|
|
151
|
+
case "_starts_with":
|
|
152
|
+
if (!isString(value) || !value.startsWith(conditionValue))
|
|
153
|
+
return false;
|
|
154
|
+
break;
|
|
155
|
+
case "_ends_with":
|
|
156
|
+
if (!isString(value) || !value.endsWith(conditionValue))
|
|
157
|
+
return false;
|
|
158
|
+
break;
|
|
159
|
+
case "_is_null":
|
|
160
|
+
if (
|
|
161
|
+
(conditionValue && !isNull(value)) ||
|
|
162
|
+
(!conditionValue && isNull(value))
|
|
163
|
+
)
|
|
164
|
+
return false;
|
|
165
|
+
break;
|
|
166
|
+
case "_contains":
|
|
167
|
+
if (
|
|
168
|
+
!isArray(value) ||
|
|
169
|
+
!every(conditionValue, item => includes(value, item))
|
|
170
|
+
)
|
|
171
|
+
return false;
|
|
172
|
+
break;
|
|
173
|
+
case "_contained_in":
|
|
174
|
+
if (
|
|
175
|
+
!isArray(value) ||
|
|
176
|
+
!every(value, item => includes(conditionValue, item))
|
|
177
|
+
)
|
|
178
|
+
return false;
|
|
179
|
+
break;
|
|
180
|
+
case "_has_key":
|
|
181
|
+
if (!isObject(value) || !has(value, conditionValue)) return false;
|
|
182
|
+
break;
|
|
183
|
+
case "_has_keys_any":
|
|
184
|
+
if (
|
|
185
|
+
!isObject(value) ||
|
|
186
|
+
!some(conditionValue, item => has(value, item))
|
|
187
|
+
)
|
|
188
|
+
return false;
|
|
189
|
+
break;
|
|
190
|
+
case "_has_keys_all":
|
|
191
|
+
if (
|
|
192
|
+
!isObject(value) ||
|
|
193
|
+
!every(conditionValue, item => has(value, item))
|
|
194
|
+
)
|
|
195
|
+
return false;
|
|
196
|
+
break;
|
|
197
|
+
case "_similar":
|
|
198
|
+
if (
|
|
199
|
+
!isString(value) ||
|
|
200
|
+
!new RegExp(conditionValue.replace(/%/g, ".*")).test(value)
|
|
201
|
+
)
|
|
202
|
+
return false;
|
|
203
|
+
break;
|
|
204
|
+
default:
|
|
205
|
+
if (operator.startsWith("_")) {
|
|
206
|
+
console.warn(`Unsupported operator: ${operator}`);
|
|
207
|
+
return false;
|
|
208
|
+
} else {
|
|
209
|
+
console.warn(`Unsupported operator: ${operator}`);
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Helper to check if an object contains any Hasura operators
|
|
221
|
+
function hasOperator(obj) {
|
|
222
|
+
return Object.keys(obj).some(key => key.startsWith("_"));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return records.filter(record => applyFilter(record, where));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function applyOrderBy(records, order_by) {
|
|
229
|
+
const keys = Object.keys(order_by);
|
|
230
|
+
if (keys.length > 0) {
|
|
231
|
+
const field = keys[0];
|
|
232
|
+
const direction = order_by[field] === "asc" ? "asc" : "desc";
|
|
233
|
+
return orderBy(records, [field], [direction]);
|
|
234
|
+
}
|
|
235
|
+
return records;
|
|
236
|
+
}
|