@nestledjs/data-browser 0.1.13 → 0.1.16

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/README.md CHANGED
@@ -30,7 +30,6 @@ This package requires a Nestled framework project with:
30
30
  - **Apollo Client v4+** for GraphQL operations
31
31
  - **React Router v7+** for routing
32
32
  - **@nestledjs/forms** for form generation
33
- - **@nestledjs/helpers** for utility functions
34
33
  - **Prisma** for database models
35
34
  - **Generated GraphQL SDK** with admin CRUD operations
36
35
 
@@ -40,7 +39,6 @@ This package requires a Nestled framework project with:
40
39
  {
41
40
  "@apollo/client": "^4.0.0",
42
41
  "@nestledjs/forms": "^0.5.0",
43
- "@nestledjs/helpers": "^0.1.0",
44
42
  "react": "^19.0.0",
45
43
  "react-router": "^7.0.0"
46
44
  }
package/index.d.ts CHANGED
@@ -13,3 +13,4 @@ export * from './lib/components';
13
13
  export * from './lib/utils/graphql-utils';
14
14
  export * from './lib/utils/secure-storage';
15
15
  export * from './lib/utils/string-utils';
16
+ export * from './lib/utils/get-plural-names';
package/index.js CHANGED
@@ -20,6 +20,7 @@ import { RelationFieldWrapper } from "./lib/components/RelationFieldWrapper.js";
20
20
  import { buildFormFields, cleanFormInput, getAdminDocuments, getMutationName } from "./lib/utils/graphql-utils.js";
21
21
  import { AdminLocalStorage, SecureAdminLocalStorage } from "./lib/utils/secure-storage.js";
22
22
  import { formatFieldName, getItemDisplayName, getSmartSearchFields, kebabCase, normalizeModelNameForDocument, spacedWords } from "./lib/utils/string-utils.js";
23
+ import { getPluralName } from "./lib/utils/get-plural-names.js";
23
24
  export {
24
25
  AdminBreadcrumbs,
25
26
  AdminDataCreateErrorBoundary,
@@ -53,6 +54,7 @@ export {
53
54
  getAdminDocuments,
54
55
  getItemDisplayName,
55
56
  getMutationName,
57
+ getPluralName,
56
58
  getSmartSearchFields,
57
59
  initialState,
58
60
  kebabCase,
@@ -24,6 +24,8 @@ function adminListReducer(state, action) {
24
24
  return { ...state, filters: action.payload };
25
25
  case "TOGGLE_FILTERS":
26
26
  return { ...state, showFilters: !state.showFilters };
27
+ case "SET_SHOW_FILTERS":
28
+ return { ...state, showFilters: action.payload };
27
29
  case "RESET_PAGINATION":
28
30
  return { ...state, skip: 0 };
29
31
  case "RESET_FILTERS":
@@ -55,14 +55,12 @@ function useRelationData(relatedModelName, searchTerm, isOpen, currentValueId) {
55
55
  });
56
56
  const relatedItems = useMemo(() => {
57
57
  if (relationError) {
58
- console.warn("[RelationData] GraphQL error:", relationError.message);
59
58
  return [];
60
59
  }
61
60
  if (!relatedData) return [];
62
61
  try {
63
62
  const items = relatedData[relatedDataPath] || [];
64
63
  if (!Array.isArray(items)) {
65
- console.warn("[RelationData] Expected array but got:", typeof items);
66
64
  return [];
67
65
  }
68
66
  return items.filter((item) => {
@@ -71,7 +69,6 @@ function useRelationData(relatedModelName, searchTerm, isOpen, currentValueId) {
71
69
  return true;
72
70
  });
73
71
  } catch (error) {
74
- console.error("[RelationData] Error processing relation data:", error);
75
72
  return [];
76
73
  }
77
74
  }, [relatedData, relatedDataPath, relationError]);
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useMemo } from "react";
2
- import { getPluralName } from "@nestledjs/helpers";
2
+ import { getPluralName } from "../utils/get-plural-names.js";
3
3
  import { useNavigate, useParams, Outlet } from "react-router";
4
4
  import { AdminLocalStorage } from "../utils/secure-storage.js";
5
5
  import { spacedWords, kebabCase } from "../utils/string-utils.js";
@@ -132,7 +132,8 @@ function AdminDataCreatePageContent({
132
132
  }) {
133
133
  const navigate = useNavigate();
134
134
  const {
135
- sdk
135
+ sdk,
136
+ databaseModels
136
137
  } = useAdminDataContext();
137
138
  const [submissionState, setSubmissionState] = useState({
138
139
  status: "idle"
@@ -141,7 +142,6 @@ function AdminDataCreatePageContent({
141
142
  try {
142
143
  return getAdminDocuments(sdk, model);
143
144
  } catch (error) {
144
- console.error("[AdminDataCreatePage] Error getting documents:", error);
145
145
  return null;
146
146
  }
147
147
  }, [sdk, model]);
@@ -154,7 +154,6 @@ function AdminDataCreatePageContent({
154
154
  }
155
155
  return gql(documents.create);
156
156
  } catch (error) {
157
- console.error("[AdminDataCreatePage] Error parsing CREATE mutation:", error);
158
157
  return null;
159
158
  }
160
159
  }, [documents]);
@@ -166,43 +165,43 @@ function AdminDataCreatePageContent({
166
165
  if (!documents || !CREATE_MUTATION) {
167
166
  return /* @__PURE__ */ React.createElement("div", { className: "min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col justify-center py-12 sm:px-6 lg:px-8", __self: this, __source: {
168
167
  fileName: _jsxFileName,
169
- lineNumber: 222,
168
+ lineNumber: 220,
170
169
  columnNumber: 7
171
170
  } }, /* @__PURE__ */ React.createElement("div", { className: "mt-8 sm:mx-auto sm:w-full sm:max-w-2xl", __self: this, __source: {
172
171
  fileName: _jsxFileName,
173
- lineNumber: 223,
172
+ lineNumber: 221,
174
173
  columnNumber: 9
175
174
  } }, /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 py-8 px-4 shadow sm:rounded-lg sm:px-10", __self: this, __source: {
176
175
  fileName: _jsxFileName,
177
- lineNumber: 224,
176
+ lineNumber: 222,
178
177
  columnNumber: 11
179
178
  } }, /* @__PURE__ */ React.createElement("div", { className: "text-center", __self: this, __source: {
180
179
  fileName: _jsxFileName,
181
- lineNumber: 225,
180
+ lineNumber: 223,
182
181
  columnNumber: 13
183
182
  } }, /* @__PURE__ */ React.createElement(ExclamationCircleIcon, { className: "mx-auto h-12 w-12 text-red-400", __self: this, __source: {
184
183
  fileName: _jsxFileName,
185
- lineNumber: 226,
184
+ lineNumber: 224,
186
185
  columnNumber: 15
187
186
  } }), /* @__PURE__ */ React.createElement("h2", { className: "mt-4 text-lg font-medium text-gray-900 dark:text-gray-100", __self: this, __source: {
188
187
  fileName: _jsxFileName,
189
- lineNumber: 227,
188
+ lineNumber: 225,
190
189
  columnNumber: 15
191
190
  } }, "GraphQL Schema Error"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-gray-600 dark:text-gray-400", __self: this, __source: {
192
191
  fileName: _jsxFileName,
193
- lineNumber: 228,
192
+ lineNumber: 226,
194
193
  columnNumber: 15
195
194
  } }, "Unable to load GraphQL documents for this model. Please ensure the API server is running and the GraphQL schema is up to date."), /* @__PURE__ */ React.createElement("div", { className: "mt-6", __self: this, __source: {
196
195
  fileName: _jsxFileName,
197
- lineNumber: 232,
196
+ lineNumber: 230,
198
197
  columnNumber: 15
199
198
  } }, /* @__PURE__ */ React.createElement(Link, { to: basePath, className: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-green-web hover:bg-green-web-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-web", __self: this, __source: {
200
199
  fileName: _jsxFileName,
201
- lineNumber: 233,
200
+ lineNumber: 231,
202
201
  columnNumber: 17
203
202
  } }, "Return to Data Browser"))))));
204
203
  }
205
- const formFields = buildFormFields(sdk, model, "create", void 0, submissionState.status === "loading", basePath);
204
+ const formFields = buildFormFields(sdk, model, "create", void 0, submissionState.status === "loading", basePath, databaseModels);
206
205
  const handleSubmit = async (formData) => {
207
206
  try {
208
207
  setSubmissionState({
@@ -215,7 +214,6 @@ function AdminDataCreatePageContent({
215
214
  }
216
215
  });
217
216
  if (result.errors) {
218
- console.error("GraphQL errors:", result.errors);
219
217
  setSubmissionState({
220
218
  status: "error",
221
219
  message: result.errors.map((err) => err.message).join(", ")
@@ -230,7 +228,6 @@ function AdminDataCreatePageContent({
230
228
  navigate(`${basePath}/${toKebabCase(model.pluralName)}`);
231
229
  }, 1500);
232
230
  } catch (error) {
233
- console.error("Error creating record:", error);
234
231
  setSubmissionState({
235
232
  status: "error",
236
233
  message: error instanceof Error ? error.message : "An unexpected error occurred"
@@ -249,115 +246,115 @@ function AdminDataCreatePageContent({
249
246
  }, [submissionState.status]);
250
247
  return /* @__PURE__ */ React.createElement("div", { className: "space-y-6", __self: this, __source: {
251
248
  fileName: _jsxFileName,
252
- lineNumber: 303,
249
+ lineNumber: 299,
253
250
  columnNumber: 5
254
251
  } }, /* @__PURE__ */ React.createElement("div", { className: "mb-8", __self: this, __source: {
255
252
  fileName: _jsxFileName,
256
- lineNumber: 305,
253
+ lineNumber: 301,
257
254
  columnNumber: 7
258
255
  } }, /* @__PURE__ */ React.createElement("nav", { className: "flex mb-6", "aria-label": "Breadcrumb", __self: this, __source: {
259
256
  fileName: _jsxFileName,
260
- lineNumber: 306,
257
+ lineNumber: 302,
261
258
  columnNumber: 11
262
259
  } }, /* @__PURE__ */ React.createElement("ol", { className: "flex items-center space-x-4", __self: this, __source: {
263
260
  fileName: _jsxFileName,
264
- lineNumber: 307,
261
+ lineNumber: 303,
265
262
  columnNumber: 13
266
263
  } }, /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
267
264
  fileName: _jsxFileName,
268
- lineNumber: 308,
265
+ lineNumber: 304,
269
266
  columnNumber: 15
270
267
  } }, /* @__PURE__ */ React.createElement(Link, { to: basePath, className: "text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400", __self: this, __source: {
271
268
  fileName: _jsxFileName,
272
- lineNumber: 309,
269
+ lineNumber: 305,
273
270
  columnNumber: 17
274
271
  } }, "Data Browser")), /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
275
272
  fileName: _jsxFileName,
276
- lineNumber: 313,
273
+ lineNumber: 309,
277
274
  columnNumber: 15
278
275
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center", __self: this, __source: {
279
276
  fileName: _jsxFileName,
280
- lineNumber: 314,
277
+ lineNumber: 310,
281
278
  columnNumber: 17
282
279
  } }, /* @__PURE__ */ React.createElement("svg", { className: "flex-shrink-0 h-5 w-5 text-gray-300 dark:text-gray-600", fill: "currentColor", viewBox: "0 0 20 20", __self: this, __source: {
283
280
  fileName: _jsxFileName,
284
- lineNumber: 315,
281
+ lineNumber: 311,
285
282
  columnNumber: 19
286
283
  } }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 111.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z", clipRule: "evenodd", __self: this, __source: {
287
284
  fileName: _jsxFileName,
288
- lineNumber: 320,
285
+ lineNumber: 316,
289
286
  columnNumber: 21
290
287
  } })), /* @__PURE__ */ React.createElement(Link, { to: `${basePath}/${toKebabCase(model.pluralName)}`, className: "ml-4 text-gray-400 dark:text-gray-500 hover:text-gray-500 dark:hover:text-gray-400", __self: this, __source: {
291
288
  fileName: _jsxFileName,
292
- lineNumber: 326,
289
+ lineNumber: 322,
293
290
  columnNumber: 19
294
291
  } }, toReadableText(model.pluralName)))), /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
295
292
  fileName: _jsxFileName,
296
- lineNumber: 334,
293
+ lineNumber: 330,
297
294
  columnNumber: 15
298
295
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center", __self: this, __source: {
299
296
  fileName: _jsxFileName,
300
- lineNumber: 335,
297
+ lineNumber: 331,
301
298
  columnNumber: 17
302
299
  } }, /* @__PURE__ */ React.createElement("svg", { className: "flex-shrink-0 h-5 w-5 text-gray-300 dark:text-gray-600", fill: "currentColor", viewBox: "0 0 20 20", __self: this, __source: {
303
300
  fileName: _jsxFileName,
304
- lineNumber: 336,
301
+ lineNumber: 332,
305
302
  columnNumber: 19
306
303
  } }, /* @__PURE__ */ React.createElement("path", { fillRule: "evenodd", d: "M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 111.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z", clipRule: "evenodd", __self: this, __source: {
307
304
  fileName: _jsxFileName,
308
- lineNumber: 341,
305
+ lineNumber: 337,
309
306
  columnNumber: 21
310
307
  } })), /* @__PURE__ */ React.createElement("span", { className: "ml-4 text-gray-500 dark:text-gray-400", __self: this, __source: {
311
308
  fileName: _jsxFileName,
312
- lineNumber: 347,
309
+ lineNumber: 343,
313
310
  columnNumber: 19
314
311
  } }, "Create New"))))), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-3xl font-bold text-gray-900 dark:text-gray-100", __self: this, __source: {
315
312
  fileName: _jsxFileName,
316
- lineNumber: 352,
313
+ lineNumber: 348,
317
314
  columnNumber: 11
318
315
  } }, "Create ", toReadableText(model.name))), submissionState.status !== "idle" && /* @__PURE__ */ React.createElement("div", { className: `mb-6 rounded-md p-4 ${submissionState.status === "success" ? "bg-green-50 border border-green-200" : submissionState.status === "error" ? "bg-red-50 border border-red-200" : "bg-blue-50 border border-blue-200"}`, __self: this, __source: {
319
316
  fileName: _jsxFileName,
320
- lineNumber: 359,
317
+ lineNumber: 355,
321
318
  columnNumber: 11
322
319
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex", __self: this, __source: {
323
320
  fileName: _jsxFileName,
324
- lineNumber: 368,
321
+ lineNumber: 364,
325
322
  columnNumber: 13
326
323
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex-shrink-0", __self: this, __source: {
327
324
  fileName: _jsxFileName,
328
- lineNumber: 369,
325
+ lineNumber: 365,
329
326
  columnNumber: 15
330
327
  } }, submissionState.status === "success" ? /* @__PURE__ */ React.createElement(CheckCircleIcon, { className: "h-5 w-5 text-green-400", __self: this, __source: {
331
328
  fileName: _jsxFileName,
332
- lineNumber: 371,
329
+ lineNumber: 367,
333
330
  columnNumber: 19
334
331
  } }) : submissionState.status === "error" ? /* @__PURE__ */ React.createElement(ExclamationCircleIcon, { className: "h-5 w-5 text-red-400", __self: this, __source: {
335
332
  fileName: _jsxFileName,
336
- lineNumber: 373,
333
+ lineNumber: 369,
337
334
  columnNumber: 19
338
335
  } }) : /* @__PURE__ */ React.createElement("div", { className: "h-5 w-5 border-2 border-blue-400 border-t-transparent rounded-full animate-spin", __self: this, __source: {
339
336
  fileName: _jsxFileName,
340
- lineNumber: 375,
337
+ lineNumber: 371,
341
338
  columnNumber: 19
342
339
  } })), /* @__PURE__ */ React.createElement("div", { className: "ml-3", __self: this, __source: {
343
340
  fileName: _jsxFileName,
344
- lineNumber: 378,
341
+ lineNumber: 374,
345
342
  columnNumber: 15
346
343
  } }, /* @__PURE__ */ React.createElement("p", { className: `text-sm font-medium ${submissionState.status === "success" ? "text-green-800" : submissionState.status === "error" ? "text-red-800" : "text-blue-800"}`, __self: this, __source: {
347
344
  fileName: _jsxFileName,
348
- lineNumber: 379,
345
+ lineNumber: 375,
349
346
  columnNumber: 17
350
347
  } }, submissionState.status === "loading" ? `Creating ${toReadableText(model.name)}...` : submissionState.message)))), /* @__PURE__ */ React.createElement("div", { className: "bg-white dark:bg-gray-800 shadow-sm rounded-lg", __self: this, __source: {
351
348
  fileName: _jsxFileName,
352
- lineNumber: 398,
349
+ lineNumber: 394,
353
350
  columnNumber: 9
354
351
  } }, /* @__PURE__ */ React.createElement("div", { className: "px-6 py-8", __self: this, __source: {
355
352
  fileName: _jsxFileName,
356
- lineNumber: 399,
353
+ lineNumber: 395,
357
354
  columnNumber: 11
358
355
  } }, /* @__PURE__ */ React.createElement(Form, { id: `create-${model.name.toLowerCase()}-form`, fields: formFields, submit: handleSubmit, disabled: submissionState.status === "loading", theme: formTheme, __self: this, __source: {
359
356
  fileName: _jsxFileName,
360
- lineNumber: 400,
357
+ lineNumber: 396,
361
358
  columnNumber: 13
362
359
  } }))));
363
360
  }
@@ -366,7 +363,7 @@ function AdminDataCreateErrorBoundary({
366
363
  }) {
367
364
  return /* @__PURE__ */ React.createElement(ErrorBoundary, { error, __self: this, __source: {
368
365
  fileName: _jsxFileName,
369
- lineNumber: 414,
366
+ lineNumber: 410,
370
367
  columnNumber: 10
371
368
  } });
372
369
  }