@nestledjs/data-browser 0.1.15 → 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";
@@ -142,7 +142,6 @@ function AdminDataCreatePageContent({
142
142
  try {
143
143
  return getAdminDocuments(sdk, model);
144
144
  } catch (error) {
145
- console.error("[AdminDataCreatePage] Error getting documents:", error);
146
145
  return null;
147
146
  }
148
147
  }, [sdk, model]);
@@ -155,7 +154,6 @@ function AdminDataCreatePageContent({
155
154
  }
156
155
  return gql(documents.create);
157
156
  } catch (error) {
158
- console.error("[AdminDataCreatePage] Error parsing CREATE mutation:", error);
159
157
  return null;
160
158
  }
161
159
  }, [documents]);
@@ -167,39 +165,39 @@ function AdminDataCreatePageContent({
167
165
  if (!documents || !CREATE_MUTATION) {
168
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: {
169
167
  fileName: _jsxFileName,
170
- lineNumber: 222,
168
+ lineNumber: 220,
171
169
  columnNumber: 7
172
170
  } }, /* @__PURE__ */ React.createElement("div", { className: "mt-8 sm:mx-auto sm:w-full sm:max-w-2xl", __self: this, __source: {
173
171
  fileName: _jsxFileName,
174
- lineNumber: 223,
172
+ lineNumber: 221,
175
173
  columnNumber: 9
176
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: {
177
175
  fileName: _jsxFileName,
178
- lineNumber: 224,
176
+ lineNumber: 222,
179
177
  columnNumber: 11
180
178
  } }, /* @__PURE__ */ React.createElement("div", { className: "text-center", __self: this, __source: {
181
179
  fileName: _jsxFileName,
182
- lineNumber: 225,
180
+ lineNumber: 223,
183
181
  columnNumber: 13
184
182
  } }, /* @__PURE__ */ React.createElement(ExclamationCircleIcon, { className: "mx-auto h-12 w-12 text-red-400", __self: this, __source: {
185
183
  fileName: _jsxFileName,
186
- lineNumber: 226,
184
+ lineNumber: 224,
187
185
  columnNumber: 15
188
186
  } }), /* @__PURE__ */ React.createElement("h2", { className: "mt-4 text-lg font-medium text-gray-900 dark:text-gray-100", __self: this, __source: {
189
187
  fileName: _jsxFileName,
190
- lineNumber: 227,
188
+ lineNumber: 225,
191
189
  columnNumber: 15
192
190
  } }, "GraphQL Schema Error"), /* @__PURE__ */ React.createElement("p", { className: "mt-2 text-sm text-gray-600 dark:text-gray-400", __self: this, __source: {
193
191
  fileName: _jsxFileName,
194
- lineNumber: 228,
192
+ lineNumber: 226,
195
193
  columnNumber: 15
196
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: {
197
195
  fileName: _jsxFileName,
198
- lineNumber: 232,
196
+ lineNumber: 230,
199
197
  columnNumber: 15
200
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: {
201
199
  fileName: _jsxFileName,
202
- lineNumber: 233,
200
+ lineNumber: 231,
203
201
  columnNumber: 17
204
202
  } }, "Return to Data Browser"))))));
205
203
  }
@@ -216,7 +214,6 @@ function AdminDataCreatePageContent({
216
214
  }
217
215
  });
218
216
  if (result.errors) {
219
- console.error("GraphQL errors:", result.errors);
220
217
  setSubmissionState({
221
218
  status: "error",
222
219
  message: result.errors.map((err) => err.message).join(", ")
@@ -231,7 +228,6 @@ function AdminDataCreatePageContent({
231
228
  navigate(`${basePath}/${toKebabCase(model.pluralName)}`);
232
229
  }, 1500);
233
230
  } catch (error) {
234
- console.error("Error creating record:", error);
235
231
  setSubmissionState({
236
232
  status: "error",
237
233
  message: error instanceof Error ? error.message : "An unexpected error occurred"
@@ -250,115 +246,115 @@ function AdminDataCreatePageContent({
250
246
  }, [submissionState.status]);
251
247
  return /* @__PURE__ */ React.createElement("div", { className: "space-y-6", __self: this, __source: {
252
248
  fileName: _jsxFileName,
253
- lineNumber: 303,
249
+ lineNumber: 299,
254
250
  columnNumber: 5
255
251
  } }, /* @__PURE__ */ React.createElement("div", { className: "mb-8", __self: this, __source: {
256
252
  fileName: _jsxFileName,
257
- lineNumber: 305,
253
+ lineNumber: 301,
258
254
  columnNumber: 7
259
255
  } }, /* @__PURE__ */ React.createElement("nav", { className: "flex mb-6", "aria-label": "Breadcrumb", __self: this, __source: {
260
256
  fileName: _jsxFileName,
261
- lineNumber: 306,
257
+ lineNumber: 302,
262
258
  columnNumber: 11
263
259
  } }, /* @__PURE__ */ React.createElement("ol", { className: "flex items-center space-x-4", __self: this, __source: {
264
260
  fileName: _jsxFileName,
265
- lineNumber: 307,
261
+ lineNumber: 303,
266
262
  columnNumber: 13
267
263
  } }, /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
268
264
  fileName: _jsxFileName,
269
- lineNumber: 308,
265
+ lineNumber: 304,
270
266
  columnNumber: 15
271
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: {
272
268
  fileName: _jsxFileName,
273
- lineNumber: 309,
269
+ lineNumber: 305,
274
270
  columnNumber: 17
275
271
  } }, "Data Browser")), /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
276
272
  fileName: _jsxFileName,
277
- lineNumber: 313,
273
+ lineNumber: 309,
278
274
  columnNumber: 15
279
275
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center", __self: this, __source: {
280
276
  fileName: _jsxFileName,
281
- lineNumber: 314,
277
+ lineNumber: 310,
282
278
  columnNumber: 17
283
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: {
284
280
  fileName: _jsxFileName,
285
- lineNumber: 315,
281
+ lineNumber: 311,
286
282
  columnNumber: 19
287
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: {
288
284
  fileName: _jsxFileName,
289
- lineNumber: 320,
285
+ lineNumber: 316,
290
286
  columnNumber: 21
291
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: {
292
288
  fileName: _jsxFileName,
293
- lineNumber: 326,
289
+ lineNumber: 322,
294
290
  columnNumber: 19
295
291
  } }, toReadableText(model.pluralName)))), /* @__PURE__ */ React.createElement("li", { __self: this, __source: {
296
292
  fileName: _jsxFileName,
297
- lineNumber: 334,
293
+ lineNumber: 330,
298
294
  columnNumber: 15
299
295
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center", __self: this, __source: {
300
296
  fileName: _jsxFileName,
301
- lineNumber: 335,
297
+ lineNumber: 331,
302
298
  columnNumber: 17
303
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: {
304
300
  fileName: _jsxFileName,
305
- lineNumber: 336,
301
+ lineNumber: 332,
306
302
  columnNumber: 19
307
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: {
308
304
  fileName: _jsxFileName,
309
- lineNumber: 341,
305
+ lineNumber: 337,
310
306
  columnNumber: 21
311
307
  } })), /* @__PURE__ */ React.createElement("span", { className: "ml-4 text-gray-500 dark:text-gray-400", __self: this, __source: {
312
308
  fileName: _jsxFileName,
313
- lineNumber: 347,
309
+ lineNumber: 343,
314
310
  columnNumber: 19
315
311
  } }, "Create New"))))), /* @__PURE__ */ React.createElement("h1", { className: "mt-4 text-3xl font-bold text-gray-900 dark:text-gray-100", __self: this, __source: {
316
312
  fileName: _jsxFileName,
317
- lineNumber: 352,
313
+ lineNumber: 348,
318
314
  columnNumber: 11
319
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: {
320
316
  fileName: _jsxFileName,
321
- lineNumber: 359,
317
+ lineNumber: 355,
322
318
  columnNumber: 11
323
319
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex", __self: this, __source: {
324
320
  fileName: _jsxFileName,
325
- lineNumber: 368,
321
+ lineNumber: 364,
326
322
  columnNumber: 13
327
323
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex-shrink-0", __self: this, __source: {
328
324
  fileName: _jsxFileName,
329
- lineNumber: 369,
325
+ lineNumber: 365,
330
326
  columnNumber: 15
331
327
  } }, submissionState.status === "success" ? /* @__PURE__ */ React.createElement(CheckCircleIcon, { className: "h-5 w-5 text-green-400", __self: this, __source: {
332
328
  fileName: _jsxFileName,
333
- lineNumber: 371,
329
+ lineNumber: 367,
334
330
  columnNumber: 19
335
331
  } }) : submissionState.status === "error" ? /* @__PURE__ */ React.createElement(ExclamationCircleIcon, { className: "h-5 w-5 text-red-400", __self: this, __source: {
336
332
  fileName: _jsxFileName,
337
- lineNumber: 373,
333
+ lineNumber: 369,
338
334
  columnNumber: 19
339
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: {
340
336
  fileName: _jsxFileName,
341
- lineNumber: 375,
337
+ lineNumber: 371,
342
338
  columnNumber: 19
343
339
  } })), /* @__PURE__ */ React.createElement("div", { className: "ml-3", __self: this, __source: {
344
340
  fileName: _jsxFileName,
345
- lineNumber: 378,
341
+ lineNumber: 374,
346
342
  columnNumber: 15
347
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: {
348
344
  fileName: _jsxFileName,
349
- lineNumber: 379,
345
+ lineNumber: 375,
350
346
  columnNumber: 17
351
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: {
352
348
  fileName: _jsxFileName,
353
- lineNumber: 398,
349
+ lineNumber: 394,
354
350
  columnNumber: 9
355
351
  } }, /* @__PURE__ */ React.createElement("div", { className: "px-6 py-8", __self: this, __source: {
356
352
  fileName: _jsxFileName,
357
- lineNumber: 399,
353
+ lineNumber: 395,
358
354
  columnNumber: 11
359
355
  } }, /* @__PURE__ */ React.createElement(Form, { id: `create-${model.name.toLowerCase()}-form`, fields: formFields, submit: handleSubmit, disabled: submissionState.status === "loading", theme: formTheme, __self: this, __source: {
360
356
  fileName: _jsxFileName,
361
- lineNumber: 400,
357
+ lineNumber: 396,
362
358
  columnNumber: 13
363
359
  } }))));
364
360
  }
@@ -367,7 +363,7 @@ function AdminDataCreateErrorBoundary({
367
363
  }) {
368
364
  return /* @__PURE__ */ React.createElement(ErrorBoundary, { error, __self: this, __source: {
369
365
  fileName: _jsxFileName,
370
- lineNumber: 414,
366
+ lineNumber: 410,
371
367
  columnNumber: 10
372
368
  } });
373
369
  }