@nestledjs/data-browser 0.1.7 → 0.1.8

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.
@@ -1,16 +1,16 @@
1
- const e = {
1
+ const initialState = {
2
2
  search: "",
3
3
  debouncedSearch: "",
4
4
  skip: 0,
5
5
  pageSize: 20,
6
6
  sort: { orderBy: "id", orderDirection: "desc" },
7
7
  visibleColumns: [],
8
- showColumnSelector: !1,
8
+ showColumnSelector: false,
9
9
  searchFields: [],
10
- showSearchFieldSelector: !1,
10
+ showSearchFieldSelector: false,
11
11
  filters: {},
12
- showFilters: !1
12
+ showFilters: false
13
13
  };
14
14
  export {
15
- e as initialState
15
+ initialState
16
16
  };
@@ -1,193 +1,269 @@
1
- import { FormFieldClass as u } from "@nestledjs/forms";
2
- import { getPluralName as j } from "@nestledjs/helpers";
3
- function S(t, a) {
1
+ import { FormFieldClass } from "@nestledjs/forms";
2
+ import { getPluralName } from "@nestledjs/helpers";
3
+ function getEnumValues(sdk, enumType) {
4
4
  try {
5
- const n = t[a];
6
- if (!n || typeof n != "object")
5
+ const enumObject = sdk[enumType];
6
+ if (!enumObject || typeof enumObject !== "object") {
7
7
  return null;
8
- const r = Object.values(n).filter((l) => typeof l == "string");
9
- if (r.length === 0) {
10
- const l = Object.keys(n).filter((b) => isNaN(Number(b)));
11
- return l.length > 0 ? l : null;
12
8
  }
13
- return r;
14
- } catch (n) {
15
- return console.warn(`Failed to get enum values for type ${a}:`, n), null;
9
+ const values = Object.values(enumObject).filter((value) => typeof value === "string");
10
+ if (values.length === 0) {
11
+ const keys = Object.keys(enumObject).filter((key) => isNaN(Number(key)));
12
+ return keys.length > 0 ? keys : null;
13
+ }
14
+ return values;
15
+ } catch (error) {
16
+ console.warn(`Failed to get enum values for type ${enumType}:`, error);
17
+ return null;
16
18
  }
17
19
  }
18
- function O(t) {
19
- return t === t.toUpperCase() && t.length > 1 ? t.charAt(0).toUpperCase() + t.slice(1).toLowerCase() : t;
20
+ function normalizeModelNameForDocument(modelName) {
21
+ if (modelName === modelName.toUpperCase() && modelName.length > 1) {
22
+ return modelName.charAt(0).toUpperCase() + modelName.slice(1).toLowerCase();
23
+ }
24
+ return modelName;
20
25
  }
21
- function G(t, a) {
22
- if (!a || !a.name)
26
+ function getAdminDocuments(sdk, model) {
27
+ if (!model || !model.name) {
23
28
  throw new Error("Invalid model provided to getAdminDocuments");
24
- const n = O(a.name), r = O(j(a.name)), l = `__Admin${n}Document`, b = `__Admin${r}Document`, g = `__AdminUpdate${n}Document`, i = `__AdminDelete${n}Document`, m = `__AdminCreate${n}Document`, c = {
25
- query: t[l],
29
+ }
30
+ const normalizedModelName = normalizeModelNameForDocument(model.name);
31
+ const normalizedPluralName = normalizeModelNameForDocument(getPluralName(model.name));
32
+ const singleQueryDocumentName = `__Admin${normalizedModelName}Document`;
33
+ const listQueryDocumentName = `__Admin${normalizedPluralName}Document`;
34
+ const updateDocumentName = `__AdminUpdate${normalizedModelName}Document`;
35
+ const deleteDocumentName = `__AdminDelete${normalizedModelName}Document`;
36
+ const createDocumentName = `__AdminCreate${normalizedModelName}Document`;
37
+ const documents = {
38
+ query: sdk[singleQueryDocumentName],
26
39
  // For single item
27
- listQuery: t[b],
40
+ listQuery: sdk[listQueryDocumentName],
28
41
  // For lists
29
- update: t[g],
30
- delete: t[i],
31
- create: t[m]
32
- }, e = [];
33
- if (c.query || e.push(l), c.listQuery || e.push(b), c.create || e.push(m), c.update || e.push(g), c.delete || e.push(i), e.length > 0)
34
- throw console.error(`[GraphQL Documents] Missing documents for model "${a.name}":`, {
35
- model: a.name,
36
- normalizedModelName: n,
37
- normalizedPluralName: r,
38
- missingDocuments: e,
39
- availableDocuments: Object.keys(t).filter(
40
- (h) => h.includes("Admin") && h.includes("Document")
42
+ update: sdk[updateDocumentName],
43
+ delete: sdk[deleteDocumentName],
44
+ create: sdk[createDocumentName]
45
+ };
46
+ const missingDocuments = [];
47
+ if (!documents.query) missingDocuments.push(singleQueryDocumentName);
48
+ if (!documents.listQuery) missingDocuments.push(listQueryDocumentName);
49
+ if (!documents.create) missingDocuments.push(createDocumentName);
50
+ if (!documents.update) missingDocuments.push(updateDocumentName);
51
+ if (!documents.delete) missingDocuments.push(deleteDocumentName);
52
+ if (missingDocuments.length > 0) {
53
+ console.error(`[GraphQL Documents] Missing documents for model "${model.name}":`, {
54
+ model: model.name,
55
+ normalizedModelName,
56
+ normalizedPluralName,
57
+ missingDocuments,
58
+ availableDocuments: Object.keys(sdk).filter(
59
+ (key) => key.includes("Admin") && key.includes("Document")
41
60
  )
42
- }), new Error(
43
- `Missing GraphQL documents for model "${a.name}": ${e.join(", ")}. Please ensure the API server is running and the GraphQL schema is up to date.`
61
+ });
62
+ throw new Error(
63
+ `Missing GraphQL documents for model "${model.name}": ${missingDocuments.join(", ")}. Please ensure the API server is running and the GraphQL schema is up to date.`
44
64
  );
45
- return c;
65
+ }
66
+ return documents;
46
67
  }
47
- function z(t, a) {
48
- const n = t.name.charAt(0).toLowerCase() + t.name.slice(1);
49
- switch (a) {
68
+ function getMutationName(model, operation) {
69
+ const modelName = model.name.charAt(0).toLowerCase() + model.name.slice(1);
70
+ switch (operation) {
50
71
  case "create":
51
- return `create${t.name}`;
72
+ return `create${model.name}`;
52
73
  case "update":
53
- return `update${t.name}`;
74
+ return `update${model.name}`;
54
75
  case "delete":
55
- return `delete${t.name}`;
76
+ return `delete${model.name}`;
56
77
  default:
57
- return n;
78
+ return modelName;
58
79
  }
59
80
  }
60
- function I(t, a, n, r, l) {
61
- const g = a.fields.filter((e) => !(n === "create" && e.isId || e.isReadOnly || e.isGenerated || e.isUpdatedAt || e.name === "createdAt" || e.relationName && e.isList)).map((e) => {
62
- var $;
63
- const h = e.name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (d) => d.toUpperCase());
64
- let o = r && n === "update" ? r[e.name] : void 0;
65
- if ((e.type.toLowerCase() === "datetime" || e.type.toLowerCase() === "date") && (o instanceof Date || o && typeof o == "string"))
66
- try {
67
- const d = o instanceof Date ? o : new Date(o);
68
- e.type.toLowerCase() === "date" ? o = d.toISOString().split("T")[0] : o = d.toISOString().substring(0, 16);
69
- } catch (d) {
70
- console.warn(`Failed to convert date value for field ${e.name}:`, d), o = "";
81
+ function buildFormFields(sdk, model, operation, currentItem, isSubmitting) {
82
+ const editableFields = model.fields.filter((field) => {
83
+ if (operation === "create" && field.isId) return false;
84
+ if (field.isReadOnly || field.isGenerated) return false;
85
+ if (field.isUpdatedAt || field.name === "createdAt") return false;
86
+ if (field.relationName && field.isList) return false;
87
+ return true;
88
+ });
89
+ const formFields = editableFields.map((field) => {
90
+ var _a;
91
+ const label = field.name.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, (str) => str.toUpperCase());
92
+ let initialValue = currentItem && operation === "update" ? currentItem[field.name] : void 0;
93
+ if (field.type.toLowerCase() === "datetime" || field.type.toLowerCase() === "date") {
94
+ if (initialValue instanceof Date || initialValue && typeof initialValue === "string") {
95
+ try {
96
+ const dateValue = initialValue instanceof Date ? initialValue : new Date(initialValue);
97
+ if (field.type.toLowerCase() === "date") {
98
+ initialValue = dateValue.toISOString().split("T")[0];
99
+ } else {
100
+ const isoString = dateValue.toISOString();
101
+ initialValue = isoString.substring(0, 16);
102
+ }
103
+ } catch (e) {
104
+ console.warn(`Failed to convert date value for field ${field.name}:`, e);
105
+ initialValue = "";
106
+ }
71
107
  }
72
- if (o && typeof o == "object" && !Array.isArray(o) && e.relationName) {
73
- const d = o;
74
- d.id && typeof d.id == "string" ? o = d.id : o = "";
75
108
  }
76
- o === null && e.type.toLowerCase() !== "boolean" && (o = "");
77
- const _ = !!e.isList ? !1 : !e.isOptional, p = {
78
- label: h,
79
- required: _,
80
- ...o !== void 0 && { value: o }
109
+ if (initialValue && typeof initialValue === "object" && !Array.isArray(initialValue) && field.relationName) {
110
+ const relationObj = initialValue;
111
+ if (relationObj.id && typeof relationObj.id === "string") {
112
+ initialValue = relationObj.id;
113
+ } else {
114
+ initialValue = "";
115
+ }
116
+ }
117
+ if (initialValue === null && field.type.toLowerCase() !== "boolean") {
118
+ initialValue = "";
119
+ }
120
+ const isArrayField = Boolean(field.isList);
121
+ const isRequired = isArrayField ? false : !field.isOptional;
122
+ const options = {
123
+ label,
124
+ required: isRequired,
125
+ ...initialValue !== void 0 && { value: initialValue }
81
126
  };
82
- switch (e.type.toLowerCase()) {
127
+ switch (field.type.toLowerCase()) {
83
128
  case "string":
84
- return e.name.toLowerCase().includes("email") ? u.email(e.name, p) : e.name.toLowerCase().includes("description") || e.name.toLowerCase().includes("content") || e.name.toLowerCase().includes("notes") ? u.textArea(e.name, p) : u.text(e.name, p);
129
+ if (field.name.toLowerCase().includes("email")) {
130
+ return FormFieldClass.email(field.name, options);
131
+ }
132
+ if (field.name.toLowerCase().includes("description") || field.name.toLowerCase().includes("content") || field.name.toLowerCase().includes("notes")) {
133
+ return FormFieldClass.textArea(field.name, options);
134
+ }
135
+ return FormFieldClass.text(field.name, options);
85
136
  case "int":
86
137
  case "bigint":
87
- return u.text(e.name, p);
138
+ return FormFieldClass.text(field.name, options);
88
139
  case "float":
89
140
  case "decimal":
90
- return u.text(e.name, p);
141
+ return FormFieldClass.text(field.name, options);
91
142
  case "boolean": {
92
- const f = r && n === "update" ? !!r[e.name] : !1;
93
- return u.checkbox(e.name, {
94
- ...p,
95
- required: !1,
96
- ...n === "update" && { value: f }
143
+ const booleanValue = currentItem && operation === "update" ? Boolean(currentItem[field.name]) : false;
144
+ return FormFieldClass.checkbox(field.name, {
145
+ ...options,
146
+ required: false,
147
+ ...operation === "update" && { value: booleanValue }
97
148
  });
98
149
  }
99
150
  case "datetime":
100
- return u.dateTimePicker(e.name, p);
151
+ return FormFieldClass.dateTimePicker(field.name, options);
101
152
  case "date":
102
- return u.datePicker(e.name, p);
153
+ return FormFieldClass.datePicker(field.name, options);
103
154
  default:
104
- const d = S(t, e.type);
105
- if (d) {
106
- const f = d.map((s) => ({
107
- value: s,
108
- label: s.replace(/_/g, " ").toLowerCase().replace(/^./, (C) => C.toUpperCase())
155
+ const enumValues = getEnumValues(sdk, field.type);
156
+ if (enumValues) {
157
+ const selectOptions = enumValues.map((value) => ({
158
+ value,
159
+ label: value.replace(/_/g, " ").toLowerCase().replace(/^./, (str) => str.toUpperCase())
109
160
  }));
110
- return u.select(e.name, {
111
- ...p,
112
- options: f
161
+ return FormFieldClass.select(field.name, {
162
+ ...options,
163
+ options: selectOptions
113
164
  });
114
165
  }
115
- if (e.relationName && !e.isList) {
116
- const f = (($ = e.relationFromFields) == null ? void 0 : $[0]) || e.name;
117
- let s = r && n === "update" ? r[f] : void 0;
118
- s && typeof s == "object" && s.id && (s = s.id), s === null && (s = "");
119
- const C = `__Admin${e.type}sDocument`, F = `${e.type}sDocument`, N = t[C] || t[F];
120
- if (N) {
121
- let w = "id";
122
- e.type === "Course" ? w = "title" : e.type === "User" || e.type === "Program" ? w = "name" : w = "title";
123
- let A = [];
124
- if (r && n === "update") {
125
- const y = r[e.name];
126
- if (y && typeof y == "object" && y.id) {
127
- const L = y[w] || y.title || y.name || y.id;
128
- A = [
166
+ if (field.relationName && !field.isList) {
167
+ const relationFieldName = ((_a = field.relationFromFields) == null ? void 0 : _a[0]) || field.name;
168
+ let relationValue = currentItem && operation === "update" ? currentItem[relationFieldName] : void 0;
169
+ if (relationValue && typeof relationValue === "object" && relationValue.id) {
170
+ relationValue = relationValue.id;
171
+ }
172
+ if (relationValue === null) {
173
+ relationValue = "";
174
+ }
175
+ const adminDocumentName = `__Admin${field.type}sDocument`;
176
+ const regularDocumentName = `${field.type}sDocument`;
177
+ const relationDocument = sdk[adminDocumentName] || sdk[regularDocumentName];
178
+ if (relationDocument) {
179
+ let searchField = "id";
180
+ if (field.type === "Course") {
181
+ searchField = "title";
182
+ } else if (field.type === "User") {
183
+ searchField = "name";
184
+ } else if (field.type === "Program") {
185
+ searchField = "name";
186
+ } else {
187
+ searchField = "title";
188
+ }
189
+ let initialOptions = [];
190
+ if (currentItem && operation === "update") {
191
+ const currentRelationData = currentItem[field.name];
192
+ if (currentRelationData && typeof currentRelationData === "object" && currentRelationData.id) {
193
+ const displayLabel = currentRelationData[searchField] || currentRelationData.title || currentRelationData.name || currentRelationData.id;
194
+ initialOptions = [
129
195
  {
130
- value: y.id,
131
- label: L
196
+ value: currentRelationData.id,
197
+ label: displayLabel
132
198
  }
133
199
  ];
134
200
  }
135
201
  }
136
- return u.searchSelectApollo(f, {
137
- label: h,
202
+ return FormFieldClass.searchSelectApollo(relationFieldName, {
203
+ label,
138
204
  // Remove "ID" suffix - just use the field name
139
- required: p.required,
140
- dataType: e.type.toLowerCase() + "s",
205
+ required: options.required,
206
+ dataType: field.type.toLowerCase() + "s",
141
207
  // e.g., Course → courses
142
- document: N,
143
- searchFields: [w],
208
+ document: relationDocument,
209
+ searchFields: [searchField],
144
210
  // For searching
145
- selectOptionsFunction: (y) => {
146
- const L = y.map((D) => ({
147
- value: D.id,
148
- label: D[w] || D.title || D.name || D.id
149
- })), v = [...A];
150
- return L.forEach((D) => {
151
- v.find((x) => x.value === D.value) || v.push(D);
152
- }), v;
211
+ selectOptionsFunction: (items) => {
212
+ const queryOptions = items.map((item) => ({
213
+ value: item.id,
214
+ label: item[searchField] || item.title || item.name || item.id
215
+ }));
216
+ const allOptions = [...initialOptions];
217
+ queryOptions.forEach((option) => {
218
+ if (!allOptions.find((existing) => existing.value === option.value)) {
219
+ allOptions.push(option);
220
+ }
221
+ });
222
+ return allOptions;
153
223
  },
154
- ...A.length > 0 && { initialOptions: A },
224
+ ...initialOptions.length > 0 && { initialOptions },
155
225
  // Provide initial options if available
156
- ...s !== void 0 && { value: s }
226
+ ...relationValue !== void 0 && { value: relationValue }
157
227
  });
158
- } else
159
- return console.warn(
160
- `GraphQL document ${C} or ${F} not found for relation ${e.type}. Using text input instead.`
161
- ), u.text(f, {
162
- label: `${h} ID`,
163
- required: p.required,
228
+ } else {
229
+ console.warn(
230
+ `GraphQL document ${adminDocumentName} or ${regularDocumentName} not found for relation ${field.type}. Using text input instead.`
231
+ );
232
+ return FormFieldClass.text(relationFieldName, {
233
+ label: `${label} ID`,
234
+ required: options.required,
164
235
  helpText: "Enter the ID of the related record",
165
- ...s !== void 0 && { value: s }
236
+ ...relationValue !== void 0 && { value: relationValue }
166
237
  });
238
+ }
167
239
  }
168
- if (e.kind === "enum" && e.enumValues) {
169
- const f = e.enumValues.map((s) => ({
170
- value: s,
171
- label: s.replace(/_/g, " ").toLowerCase().replace(/^./, (C) => C.toUpperCase())
240
+ if (field.kind === "enum" && field.enumValues) {
241
+ const selectOptions = field.enumValues.map((value) => ({
242
+ value,
243
+ label: value.replace(/_/g, " ").toLowerCase().replace(/^./, (str) => str.toUpperCase())
172
244
  }));
173
- return u.select(e.name, {
174
- ...p,
175
- options: f
245
+ return FormFieldClass.select(field.name, {
246
+ ...options,
247
+ options: selectOptions
176
248
  });
177
249
  }
178
- return u.text(e.name, p);
250
+ return FormFieldClass.text(field.name, options);
179
251
  }
180
- }), c = l ? n === "create" ? "Creating..." : "Updating..." : n === "create" ? "Create" : "Update";
181
- return g.push(
182
- u.button("submit", {
183
- text: c,
252
+ });
253
+ const loadingText = operation === "create" ? "Creating..." : "Updating...";
254
+ const defaultText = operation === "create" ? "Create" : "Update";
255
+ const buttonText = isSubmitting ? loadingText : defaultText;
256
+ formFields.push(
257
+ FormFieldClass.button("submit", {
258
+ text: buttonText,
184
259
  type: "submit",
185
260
  variant: "primary",
186
- disabled: l
261
+ disabled: isSubmitting
187
262
  })
188
- ), g;
263
+ );
264
+ return formFields;
189
265
  }
190
- const V = /* @__PURE__ */ new Set([
266
+ const SYSTEM_FIELDS = /* @__PURE__ */ new Set([
191
267
  "__typename",
192
268
  // Apollo type annotation
193
269
  "id",
@@ -201,65 +277,78 @@ const V = /* @__PURE__ */ new Set([
201
277
  "_meta"
202
278
  // Prisma metadata
203
279
  ]);
204
- function U(t, a) {
205
- return V.has(t) || a === void 0;
280
+ function shouldSkipValue(key, value) {
281
+ return SYSTEM_FIELDS.has(key) || value === void 0;
206
282
  }
207
- function q(t, a) {
208
- if (t === "")
283
+ function convertStringValue(value, field) {
284
+ if (value === "") {
209
285
  return null;
210
- if ((a == null ? void 0 : a.type.toLowerCase()) === "datetime" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(t))
286
+ }
287
+ if ((field == null ? void 0 : field.type.toLowerCase()) === "datetime" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/.test(value)) {
211
288
  try {
212
- return new Date(t).toISOString();
213
- } catch {
214
- return console.warn(`Failed to convert datetime-local value: ${t}`), t;
289
+ const date = new Date(value);
290
+ return date.toISOString();
291
+ } catch (e) {
292
+ console.warn(`Failed to convert datetime-local value: ${value}`);
293
+ return value;
294
+ }
295
+ }
296
+ if (value === "true") return true;
297
+ if (value === "false") return false;
298
+ const numericPattern = /^\d+(\.\d+)?$/;
299
+ if (numericPattern.test(value)) {
300
+ const numericValue = Number(value);
301
+ if (!isNaN(numericValue)) {
302
+ return numericValue;
215
303
  }
216
- if (t === "true") return !0;
217
- if (t === "false") return !1;
218
- if (/^\d+(\.\d+)?$/.test(t)) {
219
- const r = Number(t);
220
- if (!isNaN(r))
221
- return r;
222
304
  }
223
- return t;
305
+ return value;
224
306
  }
225
- function T(t, a) {
226
- const n = P(t, a);
227
- return Object.keys(n).length > 0 ? n : null;
307
+ function processNestedObject(value, model) {
308
+ const cleanedNested = cleanFormInput(value, model);
309
+ return Object.keys(cleanedNested).length > 0 ? cleanedNested : null;
228
310
  }
229
- function P(t, a) {
230
- var l, b, g;
231
- const n = {}, r = new Set(
232
- ((b = (l = a == null ? void 0 : a.fields) == null ? void 0 : l.filter((i) => i.type.toLowerCase() === "boolean")) == null ? void 0 : b.map((i) => i.name)) || []
311
+ function cleanFormInput(input, model) {
312
+ var _a, _b, _c;
313
+ const cleaned = {};
314
+ const booleanFields = new Set(
315
+ ((_b = (_a = model == null ? void 0 : model.fields) == null ? void 0 : _a.filter((field) => field.type.toLowerCase() === "boolean")) == null ? void 0 : _b.map((field) => field.name)) || []
233
316
  );
234
- for (const [i, m] of Object.entries(t)) {
235
- if (r.has(i) && m === void 0) {
236
- n[i] = !1;
317
+ for (const [key, value] of Object.entries(input)) {
318
+ if (booleanFields.has(key) && value === void 0) {
319
+ cleaned[key] = false;
237
320
  continue;
238
321
  }
239
- if (!U(i, m)) {
240
- if (typeof m == "string") {
241
- const c = (g = a == null ? void 0 : a.fields) == null ? void 0 : g.find((h) => h.name === i), e = q(m, c);
242
- e !== null && (n[i] = e);
243
- continue;
322
+ if (shouldSkipValue(key, value)) {
323
+ continue;
324
+ }
325
+ if (typeof value === "string") {
326
+ const field = (_c = model == null ? void 0 : model.fields) == null ? void 0 : _c.find((f) => f.name === key);
327
+ const convertedValue = convertStringValue(value, field);
328
+ if (convertedValue !== null) {
329
+ cleaned[key] = convertedValue;
244
330
  }
245
- if (typeof m == "object" && m !== null && !Array.isArray(m)) {
246
- const c = m;
247
- if (c.value !== void 0 && c.label !== void 0 && typeof c.value == "string") {
248
- n[i] = c.value;
249
- continue;
250
- }
251
- const e = T(c, a);
252
- e !== null && (n[i] = e);
331
+ continue;
332
+ }
333
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
334
+ const obj = value;
335
+ if (obj.value !== void 0 && obj.label !== void 0 && typeof obj.value === "string") {
336
+ cleaned[key] = obj.value;
253
337
  continue;
254
338
  }
255
- n[i] = m;
339
+ const processedNested = processNestedObject(obj, model);
340
+ if (processedNested !== null) {
341
+ cleaned[key] = processedNested;
342
+ }
343
+ continue;
256
344
  }
345
+ cleaned[key] = value;
257
346
  }
258
- return n;
347
+ return cleaned;
259
348
  }
260
349
  export {
261
- I as buildFormFields,
262
- P as cleanFormInput,
263
- G as getAdminDocuments,
264
- z as getMutationName
350
+ buildFormFields,
351
+ cleanFormInput,
352
+ getAdminDocuments,
353
+ getMutationName
265
354
  };