@teselagen/ui 0.7.33-beta.3 → 0.7.33-beta.4

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.
Files changed (137) hide show
  1. package/package.json +1 -1
  2. package/src/AdvancedOptions.spec.js +26 -0
  3. package/src/AsyncValidateFieldSpinner/index.js +12 -0
  4. package/src/BlueprintError/index.js +14 -0
  5. package/src/BounceLoader/index.js +16 -0
  6. package/src/BounceLoader/style.css +45 -0
  7. package/src/CollapsibleCard/index.js +68 -0
  8. package/src/CollapsibleCard/style.css +23 -0
  9. package/src/DNALoader/index.js +20 -0
  10. package/src/DNALoader/style.css +251 -0
  11. package/src/DataTable/index.js +3209 -0
  12. package/src/DataTable/style.css +608 -0
  13. package/src/DataTable/utils/filterLocalEntitiesToHasura.test.js +515 -0
  14. package/src/DataTable/utils/index.js +55 -0
  15. package/src/DataTable/utils/simplifyHasuraWhere.test.js +73 -0
  16. package/src/DataTable/utils/tableQueryParamsToHasuraClauses.test.js +219 -0
  17. package/src/DialogFooter/index.js +86 -0
  18. package/src/DialogFooter/style.css +9 -0
  19. package/src/FormComponents/index.js +1266 -0
  20. package/src/FormComponents/style.css +275 -0
  21. package/src/FormComponents/utils.js +6 -0
  22. package/src/HotkeysDialog/index.js +79 -0
  23. package/src/HotkeysDialog/style.css +54 -0
  24. package/src/InfoHelper/index.js +78 -0
  25. package/src/InfoHelper/style.css +7 -0
  26. package/src/IntentText/index.js +18 -0
  27. package/src/Loading/index.js +70 -0
  28. package/src/Loading/style.css +4 -0
  29. package/src/MenuBar/index.js +423 -0
  30. package/src/MenuBar/style.css +45 -0
  31. package/src/PromptUnsavedChanges/index.js +38 -0
  32. package/src/ResizableDraggableDialog/index.js +141 -0
  33. package/src/ResizableDraggableDialog/style.css +42 -0
  34. package/src/ScrollToTop/index.js +72 -0
  35. package/src/TagSelect/index.js +69 -0
  36. package/src/TagSelect/style.css +13 -0
  37. package/src/TgHtmlSelect/index.js +20 -0
  38. package/src/TgSelect/index.js +537 -0
  39. package/src/TgSelect/style.css +61 -0
  40. package/src/TgSuggest/index.js +124 -0
  41. package/src/Timeline/index.js +15 -0
  42. package/src/Timeline/style.css +29 -0
  43. package/src/enhancers/withDialog/index.js +196 -0
  44. package/src/index.js +88 -1
  45. package/src/showConfirmationDialog/index.js +148 -0
  46. package/src/style.css +261 -9
  47. package/src/utils/hooks/index.js +1 -0
  48. /package/src/{CellDragHandle.js → DataTable/CellDragHandle.js} +0 -0
  49. /package/src/{ColumnFilterMenu.js → DataTable/ColumnFilterMenu.js} +0 -0
  50. /package/src/{Columns.js → DataTable/Columns.js} +0 -0
  51. /package/src/{DisabledLoadingComponent.js → DataTable/DisabledLoadingComponent.js} +0 -0
  52. /package/src/{DisplayOptions.js → DataTable/DisplayOptions.js} +0 -0
  53. /package/src/{DropdownCell.js → DataTable/DropdownCell.js} +0 -0
  54. /package/src/{EditableCell.js → DataTable/EditableCell.js} +0 -0
  55. /package/src/{FilterAndSortMenu.js → DataTable/FilterAndSortMenu.js} +0 -0
  56. /package/src/{PagingTool.js → DataTable/PagingTool.js} +0 -0
  57. /package/src/{RenderCell.js → DataTable/RenderCell.js} +0 -0
  58. /package/src/{SearchBar.js → DataTable/SearchBar.js} +0 -0
  59. /package/src/{SortableColumns.js → DataTable/SortableColumns.js} +0 -0
  60. /package/src/{TableFormTrackerContext.js → DataTable/TableFormTrackerContext.js} +0 -0
  61. /package/src/{ThComponent.js → DataTable/ThComponent.js} +0 -0
  62. /package/src/{dataTableEnhancer.js → DataTable/dataTableEnhancer.js} +0 -0
  63. /package/src/{defaultFormatters.js → DataTable/defaultFormatters.js} +0 -0
  64. /package/src/{defaultValidators.js → DataTable/defaultValidators.js} +0 -0
  65. /package/src/{editCellHelper.js → DataTable/editCellHelper.js} +0 -0
  66. /package/src/{getCellVal.js → DataTable/getCellVal.js} +0 -0
  67. /package/src/{getVals.js → DataTable/getVals.js} +0 -0
  68. /package/src/{isTruthy.js → DataTable/isTruthy.js} +0 -0
  69. /package/src/{isValueEmpty.js → DataTable/isValueEmpty.js} +0 -0
  70. /package/src/{convertSchema.js → DataTable/utils/convertSchema.js} +0 -0
  71. /package/src/{filterLocalEntitiesToHasura.js → DataTable/utils/filterLocalEntitiesToHasura.js} +0 -0
  72. /package/src/{formatPasteData.js → DataTable/utils/formatPasteData.js} +0 -0
  73. /package/src/{getAllRows.js → DataTable/utils/getAllRows.js} +0 -0
  74. /package/src/{getCellCopyText.js → DataTable/utils/getCellCopyText.js} +0 -0
  75. /package/src/{getCellInfo.js → DataTable/utils/getCellInfo.js} +0 -0
  76. /package/src/{getFieldPathToField.js → DataTable/utils/getFieldPathToField.js} +0 -0
  77. /package/src/{getIdOrCodeOrIndex.js → DataTable/utils/getIdOrCodeOrIndex.js} +0 -0
  78. /package/src/{getLastSelectedEntity.js → DataTable/utils/getLastSelectedEntity.js} +0 -0
  79. /package/src/{getNewEntToSelect.js → DataTable/utils/getNewEntToSelect.js} +0 -0
  80. /package/src/{getRowCopyText.js → DataTable/utils/getRowCopyText.js} +0 -0
  81. /package/src/{getTableConfigFromStorage.js → DataTable/utils/getTableConfigFromStorage.js} +0 -0
  82. /package/src/{handleCopyColumn.js → DataTable/utils/handleCopyColumn.js} +0 -0
  83. /package/src/{handleCopyHelper.js → DataTable/utils/handleCopyHelper.js} +0 -0
  84. /package/src/{handleCopyRows.js → DataTable/utils/handleCopyRows.js} +0 -0
  85. /package/src/{handleCopyTable.js → DataTable/utils/handleCopyTable.js} +0 -0
  86. /package/src/{initializeHasuraWhereAndFilter.js → DataTable/utils/initializeHasuraWhereAndFilter.js} +0 -0
  87. /package/src/{isBottomRightCornerOfRectangle.js → DataTable/utils/isBottomRightCornerOfRectangle.js} +0 -0
  88. /package/src/{isEntityClean.js → DataTable/utils/isEntityClean.js} +0 -0
  89. /package/src/{primarySelectedValue.js → DataTable/utils/primarySelectedValue.js} +0 -0
  90. /package/src/{queryParams.js → DataTable/utils/queryParams.js} +0 -0
  91. /package/src/{removeCleanRows.js → DataTable/utils/removeCleanRows.js} +0 -0
  92. /package/src/{rowClick.js → DataTable/utils/rowClick.js} +0 -0
  93. /package/src/{selection.js → DataTable/utils/selection.js} +0 -0
  94. /package/src/{simplifyHasuraWhere.js → DataTable/utils/simplifyHasuraWhere.js} +0 -0
  95. /package/src/{tableQueryParamsToHasuraClauses.js → DataTable/utils/tableQueryParamsToHasuraClauses.js} +0 -0
  96. /package/src/{useTableEntities.js → DataTable/utils/useTableEntities.js} +0 -0
  97. /package/src/{utils.js → DataTable/utils/utils.js} +0 -0
  98. /package/src/{withSelectedEntities.js → DataTable/utils/withSelectedEntities.js} +0 -0
  99. /package/src/{withTableParams.js → DataTable/utils/withTableParams.js} +0 -0
  100. /package/src/{validateTableWideErrors.js → DataTable/validateTableWideErrors.js} +0 -0
  101. /package/src/{viewColumn.js → DataTable/viewColumn.js} +0 -0
  102. /package/src/{FormSeparator.js → FormComponents/FormSeparator.js} +0 -0
  103. /package/src/{LoadingDots.js → FormComponents/LoadingDots.js} +0 -0
  104. /package/src/{Uploader.js → FormComponents/Uploader.js} +0 -0
  105. /package/src/{getNewName.js → FormComponents/getNewName.js} +0 -0
  106. /package/src/{itemUpload.js → FormComponents/itemUpload.js} +0 -0
  107. /package/src/{sortify.js → FormComponents/sortify.js} +0 -0
  108. /package/src/{tryToMatchSchemas.js → FormComponents/tryToMatchSchemas.js} +0 -0
  109. /package/src/{TimelineEvent.js → Timeline/TimelineEvent.js} +0 -0
  110. /package/src/{tg_modalState.js → enhancers/withDialog/tg_modalState.js} +0 -0
  111. /package/src/{withField.js → enhancers/withField.js} +0 -0
  112. /package/src/{withFields.js → enhancers/withFields.js} +0 -0
  113. /package/src/{withLocalStorage.js → enhancers/withLocalStorage.js} +0 -0
  114. /package/src/{adHoc.js → utils/adHoc.js} +0 -0
  115. /package/src/{basicHandleActionsWithFullState.js → utils/basicHandleActionsWithFullState.js} +0 -0
  116. /package/src/{browserUtils.js → utils/browserUtils.js} +0 -0
  117. /package/src/{combineReducersWithFullState.js → utils/combineReducersWithFullState.js} +0 -0
  118. /package/src/{commandControls.js → utils/commandControls.js} +0 -0
  119. /package/src/{commandUtils.js → utils/commandUtils.js} +0 -0
  120. /package/src/{determineBlackOrWhiteTextColor.js → utils/determineBlackOrWhiteTextColor.js} +0 -0
  121. /package/src/{getDayjsFormatter.js → utils/getDayjsFormatter.js} +0 -0
  122. /package/src/{getTextFromEl.js → utils/getTextFromEl.js} +0 -0
  123. /package/src/{handlerHelpers.js → utils/handlerHelpers.js} +0 -0
  124. /package/src/{useDeepEqualMemo.js → utils/hooks/useDeepEqualMemo.js} +0 -0
  125. /package/src/{useStableReference.js → utils/hooks/useStableReference.js} +0 -0
  126. /package/src/{hotkeyUtils.js → utils/hotkeyUtils.js} +0 -0
  127. /package/src/{isBeingCalledExcessively.js → utils/isBeingCalledExcessively.js} +0 -0
  128. /package/src/{menuUtils.js → utils/menuUtils.js} +0 -0
  129. /package/src/{popoverOverflowModifiers.js → utils/popoverOverflowModifiers.js} +0 -0
  130. /package/src/{pureNoFunc.js → utils/pureNoFunc.js} +0 -0
  131. /package/src/{renderOnDoc.js → utils/renderOnDoc.js} +0 -0
  132. /package/src/{showProgressToast.js → utils/showProgressToast.js} +0 -0
  133. /package/src/{tagUtils.js → utils/tagUtils.js} +0 -0
  134. /package/src/{tgFormValues.js → utils/tgFormValues.js} +0 -0
  135. /package/src/{useTraceUpdate.js → utils/useTraceUpdate.js} +0 -0
  136. /package/src/{withSelectTableRecords.js → utils/withSelectTableRecords.js} +0 -0
  137. /package/src/{withStore.js → utils/withStore.js} +0 -0
@@ -0,0 +1,515 @@
1
+ import { filterLocalEntitiesToHasura as filterRecords } from "./filterLocalEntitiesToHasura";
2
+
3
+ describe("filterRecords", () => {
4
+ const records = [
5
+ {
6
+ id: 123,
7
+ name: "John Doe",
8
+ age: 30,
9
+ is_active: true,
10
+ city: "London",
11
+
12
+ tags: ["programming", "javascript"],
13
+ email: "john@example.com",
14
+ data: { category: "A", type: "X" },
15
+ username: "john123"
16
+ },
17
+ {
18
+ id: 456,
19
+ name: "Jane Smith",
20
+ age: 25,
21
+ is_active: false,
22
+ city: "Paris",
23
+ tags: ["javascript", "python"],
24
+ email: null,
25
+ data: { category: "B", type: "Y" },
26
+ username: "jane456"
27
+ },
28
+ {
29
+ id: 789,
30
+ name: "Alice Johnson",
31
+ age: 35,
32
+ is_active: true,
33
+ city: "London",
34
+ tags: ["programming", "python", "java"],
35
+ email: "alice@example.com",
36
+ data: { category: "A", type: "Z" },
37
+ username: "alice789"
38
+ },
39
+ {
40
+ id: 101,
41
+ name: "Bob Williams",
42
+ age: 20,
43
+ is_active: false,
44
+ city: "New York",
45
+ tags: ["java"],
46
+ email: "bob@example.com",
47
+ data: { category: "C", type: "X" },
48
+ username: "bob101"
49
+ }
50
+ ];
51
+
52
+ it("should filter by _eq", () => {
53
+ const result = filterRecords(records, { where: { id: { _eq: 123 } } });
54
+ expect(result.entities).toEqual([records[0]]);
55
+ expect(result.entitiesAcrossPages).toEqual([records[0]]);
56
+ expect(result.entityCount).toBe(1);
57
+ });
58
+
59
+ it("should filter by _neq", () => {
60
+ const result = filterRecords(records, { where: { id: { _neq: 123 } } });
61
+ expect(result.entities).toEqual(records.slice(1));
62
+ expect(result.entitiesAcrossPages).toEqual(records.slice(1));
63
+ expect(result.entityCount).toBe(3);
64
+ });
65
+
66
+ it("should filter by _gt", () => {
67
+ const result = filterRecords(records, { where: { age: { _gt: 30 } } });
68
+ expect(result.entities).toEqual([records[2]]);
69
+ expect(result.entitiesAcrossPages).toEqual([records[2]]);
70
+ expect(result.entityCount).toBe(1);
71
+ });
72
+
73
+ it("should filter by _gte", () => {
74
+ const result = filterRecords(records, { where: { age: { _gte: 30 } } });
75
+ expect(result.entities).toEqual([records[0], records[2]]);
76
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
77
+ expect(result.entityCount).toBe(2);
78
+ });
79
+
80
+ it("should filter by _lt", () => {
81
+ const result = filterRecords(records, { where: { age: { _lt: 25 } } });
82
+ expect(result.entities).toEqual([records[3]]);
83
+ expect(result.entitiesAcrossPages).toEqual([records[3]]);
84
+ expect(result.entityCount).toBe(1);
85
+ });
86
+
87
+ it("should filter by _lte", () => {
88
+ const result = filterRecords(records, { where: { age: { _lte: 25 } } });
89
+ expect(result.entities).toEqual([records[1], records[3]]);
90
+ expect(result.entitiesAcrossPages).toEqual([records[1], records[3]]);
91
+ expect(result.entityCount).toBe(2);
92
+ });
93
+
94
+ it("should filter by _like", () => {
95
+ const result = filterRecords(records, {
96
+ where: { name: { _like: "%John%" } }
97
+ });
98
+ expect(result.entities).toEqual([records[0], records[2]]);
99
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
100
+ expect(result.entityCount).toBe(2);
101
+ });
102
+
103
+ it("should filter by _ilike", () => {
104
+ const result = filterRecords(records, {
105
+ where: { name: { _ilike: "%john%" } }
106
+ });
107
+ expect(result.entities).toEqual([records[0], records[2]]);
108
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
109
+ expect(result.entityCount).toBe(2);
110
+ });
111
+
112
+ it("should filter by _nlike", () => {
113
+ const result = filterRecords(records, {
114
+ where: { name: { _nlike: "%John%" } }
115
+ });
116
+ expect(result.entities).toEqual([records[1], records[3]]);
117
+ expect(result.entitiesAcrossPages).toEqual([records[1], records[3]]);
118
+ expect(result.entityCount).toBe(2);
119
+ });
120
+
121
+ it("should filter by _nilike", () => {
122
+ const result = filterRecords(records, {
123
+ where: { name: { _nilike: "%john%" } }
124
+ });
125
+ expect(result.entities).toEqual([records[1], records[3]]);
126
+ expect(result.entitiesAcrossPages).toEqual([records[1], records[3]]);
127
+ expect(result.entityCount).toBe(2);
128
+ });
129
+
130
+ it("should filter by _starts_with", () => {
131
+ const result = filterRecords(records, {
132
+ where: { name: { _starts_with: "John" } }
133
+ });
134
+ expect(result.entities).toEqual([records[0]]);
135
+ expect(result.entitiesAcrossPages).toEqual([records[0]]);
136
+ expect(result.entityCount).toBe(1);
137
+ });
138
+
139
+ it("should filter by _ends_with", () => {
140
+ const result = filterRecords(records, {
141
+ where: { name: { _ends_with: "Doe" } }
142
+ });
143
+ expect(result.entities).toEqual([records[0]]);
144
+ expect(result.entitiesAcrossPages).toEqual([records[0]]);
145
+ expect(result.entityCount).toBe(1);
146
+ });
147
+
148
+ it("should filter by _is_null", () => {
149
+ const result = filterRecords(records, {
150
+ where: { email: { _is_null: true } }
151
+ });
152
+ expect(result.entities).toEqual([records[1]]);
153
+ expect(result.entitiesAcrossPages).toEqual([records[1]]);
154
+ expect(result.entityCount).toBe(1);
155
+ });
156
+
157
+ it("should filter by _is_null false", () => {
158
+ const result = filterRecords(records, {
159
+ where: { email: { _is_null: false } }
160
+ });
161
+ expect(result.entities).toEqual([records[0], records[2], records[3]]);
162
+ expect(result.entitiesAcrossPages).toEqual([
163
+ records[0],
164
+ records[2],
165
+ records[3]
166
+ ]);
167
+ expect(result.entityCount).toBe(3);
168
+ });
169
+
170
+ it("should filter by _and", () => {
171
+ const result = filterRecords(records, {
172
+ where: {
173
+ _and: [{ age: { _gt: 25 } }, { city: { _eq: "London" } }]
174
+ }
175
+ });
176
+ expect(result.entities).toEqual([records[0], records[2]]);
177
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
178
+ expect(result.entityCount).toBe(2);
179
+ });
180
+
181
+ it("should filter by _or", () => {
182
+ const result = filterRecords(records, {
183
+ where: {
184
+ _or: [{ city: { _eq: "London" } }, { city: { _eq: "Paris" } }]
185
+ }
186
+ });
187
+ expect(result.entities).toEqual([records[0], records[1], records[2]]);
188
+ expect(result.entitiesAcrossPages).toEqual([
189
+ records[0],
190
+ records[1],
191
+ records[2]
192
+ ]);
193
+ expect(result.entityCount).toBe(3);
194
+ });
195
+
196
+ it("should filter by _not", () => {
197
+ const result = filterRecords(records, {
198
+ where: {
199
+ _not: { is_active: { _eq: true } }
200
+ }
201
+ });
202
+ expect(result.entities).toEqual([records[1], records[3]]);
203
+ expect(result.entitiesAcrossPages).toEqual([records[1], records[3]]);
204
+ expect(result.entityCount).toBe(2);
205
+ });
206
+
207
+ it("should filter by _contains", () => {
208
+ const result = filterRecords(records, {
209
+ where: {
210
+ tags: { _contains: ["programming", "javascript"] }
211
+ }
212
+ });
213
+ expect(result.entities).toEqual([records[0]]);
214
+ expect(result.entitiesAcrossPages).toEqual([records[0]]);
215
+ expect(result.entityCount).toBe(1);
216
+ });
217
+
218
+ it("should filter by _contained_in", () => {
219
+ const result = filterRecords(records, {
220
+ where: {
221
+ tags: { _contained_in: ["programming", "javascript", "python", "java"] }
222
+ }
223
+ });
224
+ expect(result.entities).toEqual(records);
225
+ expect(result.entitiesAcrossPages).toEqual(records);
226
+ expect(result.entityCount).toBe(4);
227
+ });
228
+
229
+ it("should filter by _has_key", () => {
230
+ const result = filterRecords(records, {
231
+ where: { data: { _has_key: "category" } }
232
+ });
233
+ expect(result.entities).toEqual(records);
234
+ expect(result.entitiesAcrossPages).toEqual(records);
235
+ expect(result.entityCount).toBe(4);
236
+ });
237
+
238
+ it("should filter by _has_keys_any", () => {
239
+ const result = filterRecords(records, {
240
+ where: {
241
+ data: { _has_keys_any: ["category", "missingKey"] }
242
+ }
243
+ });
244
+ expect(result.entities).toEqual(records);
245
+ expect(result.entitiesAcrossPages).toEqual(records);
246
+ expect(result.entityCount).toBe(4);
247
+ });
248
+
249
+ it("should filter by _has_keys_all", () => {
250
+ const result = filterRecords(records, {
251
+ where: {
252
+ data: { _has_keys_all: ["category", "type"] }
253
+ }
254
+ });
255
+ expect(result.entities).toEqual(records);
256
+ expect(result.entitiesAcrossPages).toEqual(records);
257
+ expect(result.entityCount).toBe(4);
258
+ });
259
+
260
+ it("should filter by _similar", () => {
261
+ const result = filterRecords(records, {
262
+ where: {
263
+ username: { _similar: "(john|alice)%" }
264
+ }
265
+ });
266
+ expect(result.entities).toEqual([records[0], records[2]]);
267
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
268
+ expect(result.entityCount).toBe(2);
269
+ });
270
+
271
+ it("should filter by range _gte and _lte", () => {
272
+ const result = filterRecords(records, {
273
+ where: { age: { _gte: 25, _lte: 30 } }
274
+ });
275
+ expect(result.entities).toEqual([records[0], records[1]]);
276
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[1]]);
277
+ expect(result.entityCount).toBe(2);
278
+ });
279
+
280
+ it("should filter by range _gt and _lt", () => {
281
+ const result = filterRecords(records, {
282
+ where: { age: { _gt: 25, _lt: 35 } }
283
+ });
284
+ expect(result.entities).toEqual([records[0]]);
285
+ expect(result.entitiesAcrossPages).toEqual([records[0]]);
286
+ expect(result.entityCount).toBe(1);
287
+ });
288
+
289
+ it("should handle empty where clause", () => {
290
+ const result = filterRecords(records, {});
291
+ expect(result.entities).toEqual(records);
292
+ expect(result.entitiesAcrossPages).toEqual(records);
293
+ expect(result.entityCount).toBe(4);
294
+ });
295
+
296
+ it("should handle nested _and and _or", () => {
297
+ const result = filterRecords(records, {
298
+ where: {
299
+ _and: [
300
+ { _or: [{ city: { _eq: "London" } }, { city: { _eq: "Paris" } }] },
301
+ { age: { _gt: 20 } }
302
+ ]
303
+ }
304
+ });
305
+ expect(result.entities).toEqual([records[0], records[1], records[2]]);
306
+ expect(result.entitiesAcrossPages).toEqual([
307
+ records[0],
308
+ records[1],
309
+ records[2]
310
+ ]);
311
+ expect(result.entityCount).toBe(3);
312
+ });
313
+ it("should order by age ascending", () => {
314
+ const result = filterRecords(records, {
315
+ order_by: { age: "asc" }
316
+ });
317
+ expect(result.entities).toEqual([
318
+ records[3],
319
+ records[1],
320
+ records[0],
321
+ records[2]
322
+ ]);
323
+ expect(result.entitiesAcrossPages).toEqual([
324
+ records[3],
325
+ records[1],
326
+ records[0],
327
+ records[2]
328
+ ]);
329
+ expect(result.entityCount).toBe(4);
330
+ });
331
+
332
+ it("should order by age descending", () => {
333
+ const result = filterRecords(records, {
334
+ order_by: { age: "desc" }
335
+ });
336
+ expect(result.entities).toEqual([
337
+ records[2],
338
+ records[0],
339
+ records[1],
340
+ records[3]
341
+ ]);
342
+ expect(result.entitiesAcrossPages).toEqual([
343
+ records[2],
344
+ records[0],
345
+ records[1],
346
+ records[3]
347
+ ]);
348
+ expect(result.entityCount).toBe(4);
349
+ });
350
+
351
+ it("should order by name ascending", () => {
352
+ const result = filterRecords(records, {
353
+ order_by: { name: "asc" }
354
+ });
355
+ expect(result.entities).toEqual([
356
+ records[2],
357
+ records[3],
358
+ records[1],
359
+ records[0]
360
+ ]);
361
+ expect(result.entitiesAcrossPages).toEqual([
362
+ records[2],
363
+ records[3],
364
+ records[1],
365
+ records[0]
366
+ ]);
367
+ expect(result.entityCount).toBe(4);
368
+ });
369
+
370
+ it("should order by name descending", () => {
371
+ const result = filterRecords(records, {
372
+ order_by: { name: "desc" }
373
+ });
374
+ expect(result.entities).toEqual([
375
+ records[0],
376
+ records[1],
377
+ records[3],
378
+ records[2]
379
+ ]);
380
+ expect(result.entitiesAcrossPages).toEqual([
381
+ records[0],
382
+ records[1],
383
+ records[3],
384
+ records[2]
385
+ ]);
386
+ expect(result.entityCount).toBe(4);
387
+ });
388
+
389
+ it("should filter and order", () => {
390
+ const result = filterRecords(records, {
391
+ where: { city: { _eq: "London" } },
392
+ order_by: { age: "desc" }
393
+ });
394
+ expect(result.entities).toEqual([records[2], records[0]]);
395
+ expect(result.entitiesAcrossPages).toEqual([records[2], records[0]]);
396
+ expect(result.entityCount).toBe(2);
397
+ });
398
+
399
+ it("should handle empty order_by", () => {
400
+ const result = filterRecords(records, {
401
+ where: { city: { _eq: "London" } }
402
+ });
403
+ expect(result.entities).toEqual([records[0], records[2]]);
404
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
405
+ expect(result.entityCount).toBe(2);
406
+ });
407
+
408
+ it("should handle order_by with empty where", () => {
409
+ const result = filterRecords(records, {
410
+ order_by: { age: "asc" }
411
+ });
412
+ expect(result.entities).toEqual([
413
+ records[3],
414
+ records[1],
415
+ records[0],
416
+ records[2]
417
+ ]);
418
+ expect(result.entitiesAcrossPages).toEqual([
419
+ records[3],
420
+ records[1],
421
+ records[0],
422
+ records[2]
423
+ ]);
424
+ expect(result.entityCount).toBe(4);
425
+ });
426
+
427
+ it("should apply limit", () => {
428
+ const result = filterRecords(records, { limit: 2 });
429
+ expect(result.entities).toEqual([records[0], records[1]]);
430
+ expect(result.entitiesAcrossPages).toEqual(records);
431
+ expect(result.entityCount).toBe(4);
432
+ });
433
+
434
+ it("should apply offset", () => {
435
+ const result = filterRecords(records, { offset: 2 });
436
+ expect(result.entities).toEqual([records[2], records[3]]);
437
+ expect(result.entitiesAcrossPages).toEqual(records);
438
+ expect(result.entityCount).toBe(4);
439
+ });
440
+
441
+ it("should apply limit and offset", () => {
442
+ const result = filterRecords(records, { limit: 1, offset: 2 });
443
+ expect(result.entities).toEqual([records[2]]);
444
+ expect(result.entitiesAcrossPages).toEqual(records);
445
+ expect(result.entityCount).toBe(4);
446
+ });
447
+
448
+ it("should apply limit to filtered results", () => {
449
+ const result = filterRecords(records, {
450
+ where: { city: { _eq: "London" } },
451
+ limit: 1
452
+ });
453
+ expect(result.entities).toEqual([records[0]]);
454
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
455
+ expect(result.entityCount).toBe(2);
456
+ });
457
+
458
+ it("should apply offset to filtered results", () => {
459
+ const result = filterRecords(records, {
460
+ where: { city: { _eq: "London" } },
461
+ offset: 1
462
+ });
463
+ expect(result.entities).toEqual([records[2]]);
464
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
465
+ expect(result.entityCount).toBe(2);
466
+ });
467
+
468
+ it("should apply limit and offset to filtered and ordered results", () => {
469
+ const result = filterRecords(records, {
470
+ where: { city: { _eq: "London" } },
471
+ order_by: { age: "desc" },
472
+ limit: 1,
473
+ offset: 1
474
+ });
475
+ expect(result.entities).toEqual([records[0]]);
476
+ expect(result.entitiesAcrossPages).toEqual([records[2], records[0]]);
477
+ expect(result.entityCount).toBe(2);
478
+ });
479
+
480
+ it("should handle offset greater than array length", () => {
481
+ const result = filterRecords(records, { offset: 10 });
482
+ expect(result.entities).toEqual([]);
483
+ expect(result.entitiesAcrossPages).toEqual(records);
484
+ expect(result.entityCount).toBe(4);
485
+ });
486
+
487
+ it("should handle limit greater than array length", () => {
488
+ const result = filterRecords(records, { limit: 10 });
489
+ expect(result.entities).toEqual(records);
490
+ expect(result.entitiesAcrossPages).toEqual(records);
491
+ expect(result.entityCount).toBe(4);
492
+ });
493
+
494
+ it("should handle isInfinite option with filtering", () => {
495
+ const result = filterRecords(records, {
496
+ where: { city: { _eq: "London" } },
497
+ isInfinite: true
498
+ });
499
+ expect(result.entities).toEqual([records[0], records[2]]);
500
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
501
+ expect(result.entityCount).toBe(2);
502
+ });
503
+
504
+ it("should handle isInfinite option with filtering, limit, and offset", () => {
505
+ const result = filterRecords(records, {
506
+ where: { city: { _eq: "London" } },
507
+ limit: 1,
508
+ offset: 1,
509
+ isInfinite: true
510
+ });
511
+ expect(result.entities).toEqual([records[0], records[2]]);
512
+ expect(result.entitiesAcrossPages).toEqual([records[0], records[2]]);
513
+ expect(result.entityCount).toBe(2);
514
+ });
515
+ });
@@ -0,0 +1,55 @@
1
+ import { isEntityClean } from "./isEntityClean";
2
+ import { getSelectedRowsFromEntities } from "./selection";
3
+ import { removeCleanRows } from "./removeCleanRows";
4
+ import { getIdOrCodeOrIndex } from "./getIdOrCodeOrIndex";
5
+ import { getRecordsFromIdMap } from "./withSelectedEntities";
6
+ import { formatPasteData } from "./formatPasteData";
7
+ import { getFieldPathToField } from "./getFieldPathToField";
8
+ import {
9
+ defaultParsePaste,
10
+ getEntityIdToEntity,
11
+ getFieldPathToIndex,
12
+ getNumberStrAtEnd,
13
+ stripNumberAtEnd
14
+ } from "./utils";
15
+ import { getAllRows } from "./getAllRows";
16
+ import { getNewEntToSelect } from "./getNewEntToSelect";
17
+ import { getLastSelectedEntity } from "./getLastSelectedEntity";
18
+ import { getCellInfo } from "./getCellInfo";
19
+ import { getCellCopyText } from "./getCellCopyText";
20
+ import { getRowCopyText } from "./getRowCopyText";
21
+ import { handleCopyHelper } from "./handleCopyHelper";
22
+ import { handleCopyRows } from "./handleCopyRows";
23
+ import { handleCopyColumn } from "./handleCopyColumn";
24
+ import { isBottomRightCornerOfRectangle } from "./isBottomRightCornerOfRectangle";
25
+ import { handleCopyTable } from "./handleCopyTable";
26
+ import { PRIMARY_SELECTED_VAL } from "./primarySelectedValue";
27
+ import { useTableEntities } from "./useTableEntities";
28
+
29
+ export {
30
+ defaultParsePaste,
31
+ formatPasteData,
32
+ getAllRows,
33
+ getCellCopyText,
34
+ getCellInfo,
35
+ getEntityIdToEntity,
36
+ getFieldPathToIndex,
37
+ getFieldPathToField,
38
+ getIdOrCodeOrIndex,
39
+ getLastSelectedEntity,
40
+ getNewEntToSelect,
41
+ getNumberStrAtEnd,
42
+ getRecordsFromIdMap,
43
+ getRowCopyText,
44
+ getSelectedRowsFromEntities,
45
+ handleCopyColumn,
46
+ handleCopyHelper,
47
+ handleCopyRows,
48
+ handleCopyTable,
49
+ isBottomRightCornerOfRectangle,
50
+ isEntityClean,
51
+ PRIMARY_SELECTED_VAL,
52
+ removeCleanRows,
53
+ stripNumberAtEnd,
54
+ useTableEntities
55
+ };
@@ -0,0 +1,73 @@
1
+ import { simplifyHasuraWhere } from "./simplifyHasuraWhere";
2
+
3
+ describe("simplifyHasuraWhere", () => {
4
+ it("should handle empty where clause", () => {
5
+ expect(simplifyHasuraWhere({})).toEqual({});
6
+ });
7
+
8
+ it("should simplify simple _eq where clauses", () => {
9
+ const input = { id: 123, name: "John Doe" };
10
+ const expected = { id: { _eq: 123 }, name: { _eq: "John Doe" } };
11
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
12
+ });
13
+
14
+ it("should handle existing _eq where clauses without simplification", () => {
15
+ const input = { id: { _eq: 123 }, name: { _eq: "John Doe" } };
16
+ const expected = { id: { _eq: 123 }, name: { _eq: "John Doe" } };
17
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
18
+ });
19
+
20
+ it("should handle other Hasura operators", () => {
21
+ const input = { age: { _gt: 30 }, isActive: { _eq: true } };
22
+ const expected = { age: { _gt: 30 }, isActive: { _eq: true } };
23
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
24
+ });
25
+
26
+ it("should handle dot-nested where clauses", () => {
27
+ const input = { "address.city": { _eq: "New York" }, "address.zip": 10001 };
28
+ const expected = {
29
+ address: { city: { _eq: "New York" }, zip: { _eq: 10001 } }
30
+ };
31
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
32
+ });
33
+
34
+ it("should handle deeply nested dot-nested where clauses", () => {
35
+ const input = { "nested.prop.value": { _eq: "test" } };
36
+ const expected = { nested: { prop: { value: { _eq: "test" } } } };
37
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
38
+ });
39
+
40
+ it("should handle a mix of simple, nested, and operator clauses", () => {
41
+ const input = {
42
+ id: 123,
43
+ name: "John Doe",
44
+ "address.city": { _eq: "New York" },
45
+ age: { _gt: 30 },
46
+ "nested.prop.value": { _eq: "test" }
47
+ };
48
+ const expected = {
49
+ id: { _eq: 123 },
50
+ name: { _eq: "John Doe" },
51
+ address: { city: { _eq: "New York" } },
52
+ age: { _gt: 30 },
53
+ nested: { prop: { value: { _eq: "test" } } }
54
+ };
55
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
56
+ });
57
+
58
+ it("should handle already nested objects with operators", () => {
59
+ const input = {
60
+ address: {
61
+ city: { _eq: "London" },
62
+ country: "UK"
63
+ }
64
+ };
65
+ const expected = {
66
+ address: {
67
+ city: { _eq: "London" },
68
+ country: { _eq: "UK" }
69
+ }
70
+ };
71
+ expect(simplifyHasuraWhere(input)).toEqual(expected);
72
+ });
73
+ });