@teselagen/ui 0.8.6-beta.11 → 0.8.6-beta.12

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/index.cjs.js CHANGED
@@ -19422,34 +19422,37 @@ function tableQueryParamsToHasuraClauses({
19422
19422
  if (searchTerm) {
19423
19423
  const searchTermFilters = [];
19424
19424
  const uniqueFieldsByPath = {};
19425
+ const searchTerms = searchTerm.split(",");
19425
19426
  schema.fields.forEach((field) => {
19426
19427
  const { type: type2, path: path2, searchDisabled } = field;
19427
19428
  if (uniqueFieldsByPath[path2]) return;
19428
19429
  uniqueFieldsByPath[path2] = true;
19429
19430
  if (searchDisabled || field.filterDisabled || type2 === "color") return;
19430
- const filterValue = searchTerm;
19431
- if (type2 === "string" || type2 === "lookup") {
19432
- const o2 = set$1({}, path2, { _ilike: `%${filterValue}%` });
19433
- searchTermFilters.push(o2);
19434
- } else if (type2 === "boolean") {
19435
- let regex;
19436
- try {
19437
- regex = new RegExp("^" + searchTerm, "ig");
19438
- } catch (error) {
19439
- }
19440
- if (regex) {
19441
- if ("true".replace(regex, "") !== "true") {
19442
- const o2 = set$1({}, path2, { _eq: true });
19443
- searchTermFilters.push(o2);
19444
- } else if ("false".replace(regex, "") !== "false") {
19445
- const o2 = set$1({}, path2, { _eq: false });
19446
- searchTermFilters.push(o2);
19431
+ searchTerms.forEach((term) => {
19432
+ const filterValue = term.trim();
19433
+ if (type2 === "string" || type2 === "lookup") {
19434
+ const o2 = set$1({}, path2, { _ilike: `%${filterValue}%` });
19435
+ searchTermFilters.push(o2);
19436
+ } else if (type2 === "boolean") {
19437
+ let regex;
19438
+ try {
19439
+ regex = new RegExp("^" + filterValue, "ig");
19440
+ } catch (error) {
19447
19441
  }
19442
+ if (regex) {
19443
+ if ("true".replace(regex, "") !== "true") {
19444
+ const o2 = set$1({}, path2, { _eq: true });
19445
+ searchTermFilters.push(o2);
19446
+ } else if ("false".replace(regex, "") !== "false") {
19447
+ const o2 = set$1({}, path2, { _eq: false });
19448
+ searchTermFilters.push(o2);
19449
+ }
19450
+ }
19451
+ } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19452
+ const o2 = set$1({}, path2, { _eq: parseFloat(filterValue) });
19453
+ searchTermFilters.push(o2);
19448
19454
  }
19449
- } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19450
- const o2 = set$1({}, path2, { _eq: parseFloat(filterValue) });
19451
- searchTermFilters.push(o2);
19452
- }
19455
+ });
19453
19456
  });
19454
19457
  if (searchTermFilters.length > 0) {
19455
19458
  if (Object.keys(where).length > 0) {
@@ -19543,9 +19546,7 @@ function tableQueryParamsToHasuraClauses({
19543
19546
  },
19544
19547
  {
19545
19548
  [filterOn]: {
19546
- _gt: new Date(
19547
- new Date(arrayFilterValue[1]).setHours(23, 59)
19548
- )
19549
+ _gt: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
19549
19550
  }
19550
19551
  }
19551
19552
  ]
package/index.es.js CHANGED
@@ -19404,34 +19404,37 @@ function tableQueryParamsToHasuraClauses({
19404
19404
  if (searchTerm) {
19405
19405
  const searchTermFilters = [];
19406
19406
  const uniqueFieldsByPath = {};
19407
+ const searchTerms = searchTerm.split(",");
19407
19408
  schema.fields.forEach((field) => {
19408
19409
  const { type: type2, path: path2, searchDisabled } = field;
19409
19410
  if (uniqueFieldsByPath[path2]) return;
19410
19411
  uniqueFieldsByPath[path2] = true;
19411
19412
  if (searchDisabled || field.filterDisabled || type2 === "color") return;
19412
- const filterValue = searchTerm;
19413
- if (type2 === "string" || type2 === "lookup") {
19414
- const o2 = set$1({}, path2, { _ilike: `%${filterValue}%` });
19415
- searchTermFilters.push(o2);
19416
- } else if (type2 === "boolean") {
19417
- let regex;
19418
- try {
19419
- regex = new RegExp("^" + searchTerm, "ig");
19420
- } catch (error) {
19421
- }
19422
- if (regex) {
19423
- if ("true".replace(regex, "") !== "true") {
19424
- const o2 = set$1({}, path2, { _eq: true });
19425
- searchTermFilters.push(o2);
19426
- } else if ("false".replace(regex, "") !== "false") {
19427
- const o2 = set$1({}, path2, { _eq: false });
19428
- searchTermFilters.push(o2);
19413
+ searchTerms.forEach((term) => {
19414
+ const filterValue = term.trim();
19415
+ if (type2 === "string" || type2 === "lookup") {
19416
+ const o2 = set$1({}, path2, { _ilike: `%${filterValue}%` });
19417
+ searchTermFilters.push(o2);
19418
+ } else if (type2 === "boolean") {
19419
+ let regex;
19420
+ try {
19421
+ regex = new RegExp("^" + filterValue, "ig");
19422
+ } catch (error) {
19429
19423
  }
19424
+ if (regex) {
19425
+ if ("true".replace(regex, "") !== "true") {
19426
+ const o2 = set$1({}, path2, { _eq: true });
19427
+ searchTermFilters.push(o2);
19428
+ } else if ("false".replace(regex, "") !== "false") {
19429
+ const o2 = set$1({}, path2, { _eq: false });
19430
+ searchTermFilters.push(o2);
19431
+ }
19432
+ }
19433
+ } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19434
+ const o2 = set$1({}, path2, { _eq: parseFloat(filterValue) });
19435
+ searchTermFilters.push(o2);
19430
19436
  }
19431
- } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19432
- const o2 = set$1({}, path2, { _eq: parseFloat(filterValue) });
19433
- searchTermFilters.push(o2);
19434
- }
19437
+ });
19435
19438
  });
19436
19439
  if (searchTermFilters.length > 0) {
19437
19440
  if (Object.keys(where).length > 0) {
@@ -19525,9 +19528,7 @@ function tableQueryParamsToHasuraClauses({
19525
19528
  },
19526
19529
  {
19527
19530
  [filterOn]: {
19528
- _gt: new Date(
19529
- new Date(arrayFilterValue[1]).setHours(23, 59)
19530
- )
19531
+ _gt: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
19531
19532
  }
19532
19533
  }
19533
19534
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ui",
3
- "version": "0.8.6-beta.11",
3
+ "version": "0.8.6-beta.12",
4
4
  "main": "./src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,7 +17,6 @@
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",
21
20
  "classnames": "^2.3.2",
22
21
  "color": "^3.2.1",
23
22
  "copy-to-clipboard": "^3.3.1",
@@ -12,4 +12,4 @@ export function initializeHasuraWhereAndFilter(
12
12
  }
13
13
  } else if (typeof additionalFilter === "object")
14
14
  where._and.push(additionalFilter);
15
- }
15
+ }
@@ -5,9 +5,7 @@ import {
5
5
  tableQueryParamsToHasuraClauses
6
6
  } from "./tableQueryParamsToHasuraClauses";
7
7
  import { filterLocalEntitiesToHasura } from "./filterLocalEntitiesToHasura";
8
- import {
9
- initializeHasuraWhereAndFilter
10
- } from "./initializeHasuraWhereAndFilter";
8
+ import { initializeHasuraWhereAndFilter } from "./initializeHasuraWhereAndFilter";
11
9
 
12
10
  const defaultPageSizes = [5, 10, 15, 25, 50, 100, 200, 400];
13
11
 
@@ -20,39 +20,46 @@ export function tableQueryParamsToHasuraClauses({
20
20
  // Create a map to deduplicate fields by path
21
21
  const uniqueFieldsByPath = {};
22
22
 
23
+ // Split the search term by comma to support multi-term searching
24
+ const searchTerms = searchTerm.split(',');
25
+
23
26
  schema.fields.forEach(field => {
24
27
  const { type, path, searchDisabled } = field;
25
28
  if (uniqueFieldsByPath[path]) return; // Skip if already added
26
29
  uniqueFieldsByPath[path] = true;
27
30
  if (searchDisabled || field.filterDisabled || type === "color") return;
28
- const filterValue = searchTerm; // No cleaning needed here, we're using _ilike
29
-
30
- if (type === "string" || type === "lookup") {
31
- const o = set({}, path, { _ilike: `%${filterValue}%` });
32
- searchTermFilters.push(o);
33
- } else if (type === "boolean") {
34
- let regex;
35
- try {
36
- regex = new RegExp("^" + searchTerm, "ig");
37
- } catch (error) {
38
- //ignore
39
- }
40
- if (regex) {
41
- if ("true".replace(regex, "") !== "true") {
42
- const o = set({}, path, { _eq: true });
43
- searchTermFilters.push(o);
44
- } else if ("false".replace(regex, "") !== "false") {
45
- const o = set({}, path, { _eq: false });
46
- searchTermFilters.push(o);
31
+
32
+ // Process each search term
33
+ searchTerms.forEach(term => {
34
+ const filterValue = term.trim(); // Trim the term to handle spaces after commas
35
+
36
+ if (type === "string" || type === "lookup") {
37
+ const o = set({}, path, { _ilike: `%${filterValue}%` });
38
+ searchTermFilters.push(o);
39
+ } else if (type === "boolean") {
40
+ let regex;
41
+ try {
42
+ regex = new RegExp("^" + filterValue, "ig");
43
+ } catch (error) {
44
+ //ignore
47
45
  }
46
+ if (regex) {
47
+ if ("true".replace(regex, "") !== "true") {
48
+ const o = set({}, path, { _eq: true });
49
+ searchTermFilters.push(o);
50
+ } else if ("false".replace(regex, "") !== "false") {
51
+ const o = set({}, path, { _eq: false });
52
+ searchTermFilters.push(o);
53
+ }
54
+ }
55
+ } else if (
56
+ (type === "number" || type === "integer") &&
57
+ !isNaN(filterValue)
58
+ ) {
59
+ const o = set({}, path, { _eq: parseFloat(filterValue) });
60
+ searchTermFilters.push(o);
48
61
  }
49
- } else if (
50
- (type === "number" || type === "integer") &&
51
- !isNaN(filterValue)
52
- ) {
53
- const o = set({}, path, { _eq: parseFloat(filterValue) });
54
- searchTermFilters.push(o);
55
- }
62
+ });
56
63
  });
57
64
 
58
65
  if (searchTermFilters.length > 0) {
@@ -65,164 +72,161 @@ export function tableQueryParamsToHasuraClauses({
65
72
  }
66
73
 
67
74
  if (filters && filters.length > 0) {
68
- const filterClauses = filters
69
- .map(filter => {
70
- let { selectedFilter, filterOn, filterValue } = filter;
71
- const fieldSchema = ccFields[filterOn] || {};
75
+ const filterClauses = filters.map(filter => {
76
+ let { selectedFilter, filterOn, filterValue } = filter;
77
+ const fieldSchema = ccFields[filterOn] || {};
72
78
 
73
- const { path, reference, type, customColumnFilter } = fieldSchema;
74
- if (customColumnFilter) {
75
- return customColumnFilter(filterValue);
76
- }
77
- let stringFilterValue =
78
- filterValue && filterValue.toString
79
- ? filterValue.toString()
80
- : filterValue;
81
- if (stringFilterValue === false) {
82
- // we still want to be able to search for the string "false" which will get parsed to false
83
- stringFilterValue = "false";
84
- } else {
85
- stringFilterValue = stringFilterValue || "";
86
- }
87
- const arrayFilterValue = Array.isArray(filterValue)
88
- ? filterValue
89
- : stringFilterValue.split(";");
79
+ const { path, reference, type, customColumnFilter } = fieldSchema;
80
+ if (customColumnFilter) {
81
+ return customColumnFilter(filterValue);
82
+ }
83
+ let stringFilterValue =
84
+ filterValue && filterValue.toString
85
+ ? filterValue.toString()
86
+ : filterValue;
87
+ if (stringFilterValue === false) {
88
+ // we still want to be able to search for the string "false" which will get parsed to false
89
+ stringFilterValue = "false";
90
+ } else {
91
+ stringFilterValue = stringFilterValue || "";
92
+ }
93
+ const arrayFilterValue = Array.isArray(filterValue)
94
+ ? filterValue
95
+ : stringFilterValue.split(";");
90
96
 
91
- if (type === "number" || type === "integer") {
92
- filterValue = Array.isArray(filterValue)
93
- ? filterValue.map(val => Number(val))
94
- : Number(filterValue);
95
- }
97
+ if (type === "number" || type === "integer") {
98
+ filterValue = Array.isArray(filterValue)
99
+ ? filterValue.map(val => Number(val))
100
+ : Number(filterValue);
101
+ }
96
102
 
97
- if (fieldSchema.normalizeFilter) {
98
- filterValue = fieldSchema.normalizeFilter(
99
- filterValue,
100
- selectedFilter,
101
- filterOn
102
- );
103
- }
103
+ if (fieldSchema.normalizeFilter) {
104
+ filterValue = fieldSchema.normalizeFilter(
105
+ filterValue,
106
+ selectedFilter,
107
+ filterOn
108
+ );
109
+ }
104
110
 
105
- if (reference) {
106
- filterOn = reference.sourceField;
107
- } else {
108
- filterOn = path || filterOn;
109
- }
110
- switch (selectedFilter) {
111
- case "none":
112
- return {};
113
- case "startsWith":
114
- return { [filterOn]: { _ilike: `${filterValue}%` } };
115
- case "endsWith":
116
- return { [filterOn]: { _ilike: `%${filterValue}` } };
117
- case "contains":
118
- return { [filterOn]: { _ilike: `%${filterValue}%` } };
119
- case "notContains":
120
- return { [filterOn]: { _nilike: `%${filterValue}%` } };
121
- case "isExactly":
122
- return { [filterOn]: { _eq: filterValue } };
123
- case "isEmpty":
124
- if (filterOn.includes(".")) {
125
- // if we're filtering on a nested field, like a sequence table with parts.name
126
- // we really want to just query on the top level field's existence
127
- return {
128
- _not: {
129
- [filterOn.split(".")[0]]: {}
130
- }
131
- };
132
- }
133
- return {
134
- _or: [
135
- { [filterOn]: { _eq: "" } },
136
- { [filterOn]: { _is_null: true } }
137
- ]
138
- };
139
- case "notEmpty":
140
- return {
141
- _and: [
142
- { [filterOn]: { _neq: "" } },
143
- { [filterOn]: { _is_null: false } }
144
- ]
145
- };
146
- case "inList":
147
- return { [filterOn]: { _in: filterValue } };
148
- case "notInList":
149
- return { [filterOn]: { _nin: filterValue } };
150
- case "true":
151
- return { [filterOn]: { _eq: true } };
152
- case "false":
153
- return { [filterOn]: { _eq: false } };
154
- case "dateIs":
155
- return { [filterOn]: { _eq: filterValue } };
156
- case "notBetween":
157
- return {
158
- _or: [
159
- {
160
- [filterOn]: {
161
- _lt: new Date(arrayFilterValue[0])
162
- }
163
- },
164
- {
165
- [filterOn]: {
166
- _gt: new Date(
167
- new Date(arrayFilterValue[1]).setHours(23, 59)
168
- )
169
- }
170
- }
171
- ]
172
- };
173
- case "isBetween":
111
+ if (reference) {
112
+ filterOn = reference.sourceField;
113
+ } else {
114
+ filterOn = path || filterOn;
115
+ }
116
+ switch (selectedFilter) {
117
+ case "none":
118
+ return {};
119
+ case "startsWith":
120
+ return { [filterOn]: { _ilike: `${filterValue}%` } };
121
+ case "endsWith":
122
+ return { [filterOn]: { _ilike: `%${filterValue}` } };
123
+ case "contains":
124
+ return { [filterOn]: { _ilike: `%${filterValue}%` } };
125
+ case "notContains":
126
+ return { [filterOn]: { _nilike: `%${filterValue}%` } };
127
+ case "isExactly":
128
+ return { [filterOn]: { _eq: filterValue } };
129
+ case "isEmpty":
130
+ if (filterOn.includes(".")) {
131
+ // if we're filtering on a nested field, like a sequence table with parts.name
132
+ // we really want to just query on the top level field's existence
174
133
  return {
175
- [filterOn]: {
176
- _gte: new Date(arrayFilterValue[0]),
177
- _lte: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
134
+ _not: {
135
+ [filterOn.split(".")[0]]: {}
178
136
  }
179
137
  };
180
- case "isBefore":
181
- return { [filterOn]: { _lt: new Date(filterValue) } };
182
- case "isAfter":
183
- return { [filterOn]: { _gt: new Date(filterValue) } };
184
- case "greaterThan":
185
- return { [filterOn]: { _gt: parseFloat(filterValue) } };
186
- case "lessThan":
187
- return { [filterOn]: { _lt: parseFloat(filterValue) } };
188
- case "inRange":
189
- return {
190
- [filterOn]: {
191
- _gte: parseFloat(arrayFilterValue[0]),
192
- _lte: parseFloat(arrayFilterValue[1])
138
+ }
139
+ return {
140
+ _or: [
141
+ { [filterOn]: { _eq: "" } },
142
+ { [filterOn]: { _is_null: true } }
143
+ ]
144
+ };
145
+ case "notEmpty":
146
+ return {
147
+ _and: [
148
+ { [filterOn]: { _neq: "" } },
149
+ { [filterOn]: { _is_null: false } }
150
+ ]
151
+ };
152
+ case "inList":
153
+ return { [filterOn]: { _in: filterValue } };
154
+ case "notInList":
155
+ return { [filterOn]: { _nin: filterValue } };
156
+ case "true":
157
+ return { [filterOn]: { _eq: true } };
158
+ case "false":
159
+ return { [filterOn]: { _eq: false } };
160
+ case "dateIs":
161
+ return { [filterOn]: { _eq: filterValue } };
162
+ case "notBetween":
163
+ return {
164
+ _or: [
165
+ {
166
+ [filterOn]: {
167
+ _lt: new Date(arrayFilterValue[0])
168
+ }
169
+ },
170
+ {
171
+ [filterOn]: {
172
+ _gt: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
173
+ }
193
174
  }
194
- };
195
- case "outsideRange":
196
- return {
197
- _or: [
198
- {
199
- [filterOn]: {
200
- _lt: parseFloat(arrayFilterValue[0])
201
- }
202
- },
203
- {
204
- [filterOn]: {
205
- _gt: parseFloat(arrayFilterValue[1])
206
- }
175
+ ]
176
+ };
177
+ case "isBetween":
178
+ return {
179
+ [filterOn]: {
180
+ _gte: new Date(arrayFilterValue[0]),
181
+ _lte: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
182
+ }
183
+ };
184
+ case "isBefore":
185
+ return { [filterOn]: { _lt: new Date(filterValue) } };
186
+ case "isAfter":
187
+ return { [filterOn]: { _gt: new Date(filterValue) } };
188
+ case "greaterThan":
189
+ return { [filterOn]: { _gt: parseFloat(filterValue) } };
190
+ case "lessThan":
191
+ return { [filterOn]: { _lt: parseFloat(filterValue) } };
192
+ case "inRange":
193
+ return {
194
+ [filterOn]: {
195
+ _gte: parseFloat(arrayFilterValue[0]),
196
+ _lte: parseFloat(arrayFilterValue[1])
197
+ }
198
+ };
199
+ case "outsideRange":
200
+ return {
201
+ _or: [
202
+ {
203
+ [filterOn]: {
204
+ _lt: parseFloat(arrayFilterValue[0])
205
+ }
206
+ },
207
+ {
208
+ [filterOn]: {
209
+ _gt: parseFloat(arrayFilterValue[1])
207
210
  }
208
- ]
209
- };
210
- case "equalTo":
211
- return {
212
- [filterOn]: {
213
- _eq:
214
- type === "number" || type === "integer"
215
- ? parseFloat(filterValue)
216
- : filterValue
217
211
  }
218
- };
219
- case "regex":
220
- return { [filterOn]: { _regex: filterValue } };
221
- default:
222
- console.warn(`Unsupported filter type: ${selectedFilter}`);
223
- return {};
224
- }
225
- })
212
+ ]
213
+ };
214
+ case "equalTo":
215
+ return {
216
+ [filterOn]: {
217
+ _eq:
218
+ type === "number" || type === "integer"
219
+ ? parseFloat(filterValue)
220
+ : filterValue
221
+ }
222
+ };
223
+ case "regex":
224
+ return { [filterOn]: { _regex: filterValue } };
225
+ default:
226
+ console.warn(`Unsupported filter type: ${selectedFilter}`);
227
+ return {};
228
+ }
229
+ });
226
230
 
227
231
  if (filterClauses.length > 0) {
228
232
  if (Object.keys(where).length > 0) {
@@ -44,6 +44,25 @@ describe("tableQueryParamsToHasuraClauses", () => {
44
44
  offset: 0
45
45
  });
46
46
  });
47
+ it("should handle searchTerm with string fields with a comma in them", () => {
48
+ const result = tableQueryParamsToHasuraClauses({
49
+ searchTerm: "test,test2",
50
+ schema
51
+ });
52
+ expect(result).toEqual({
53
+ where: {
54
+ _or: [
55
+ { name: { _ilike: "%test%" } },
56
+ { name: { _ilike: "%test2%" } },
57
+ { email: { _ilike: "%test%" } },
58
+ { email: { _ilike: "%test2%" } }
59
+ ]
60
+ },
61
+ order_by: [],
62
+ limit: 25,
63
+ offset: 0
64
+ });
65
+ });
47
66
  it("should flatten queries with dup paths", () => {
48
67
  const result = tableQueryParamsToHasuraClauses({
49
68
  searchTerm: "test",