@nestledjs/data-browser 0.1.12 → 0.1.15

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.js CHANGED
@@ -16,6 +16,7 @@ import { RelationFilterField } from "./lib/components/filters/RelationFilterFiel
16
16
  import { AdminBreadcrumbs } from "./lib/components/shared/AdminBreadcrumbs.js";
17
17
  import { AdminEmptyState, AdminErrorState, AdminLoadingState } from "./lib/components/shared/AdminErrorStates.js";
18
18
  import { AdminStatusDisplay, AdminUserStatus } from "./lib/components/shared/AdminStatusDisplay.js";
19
+ import { RelationFieldWrapper } from "./lib/components/RelationFieldWrapper.js";
19
20
  import { buildFormFields, cleanFormInput, getAdminDocuments, getMutationName } from "./lib/utils/graphql-utils.js";
20
21
  import { AdminLocalStorage, SecureAdminLocalStorage } from "./lib/utils/secure-storage.js";
21
22
  import { formatFieldName, getItemDisplayName, getSmartSearchFields, kebabCase, normalizeModelNameForDocument, spacedWords } from "./lib/utils/string-utils.js";
@@ -40,6 +41,7 @@ export {
40
41
  NumberRangeFilter,
41
42
  RelationDropdownButton,
42
43
  RelationDropdownContent,
44
+ RelationFieldWrapper,
43
45
  RelationFilterField,
44
46
  RelationItem,
45
47
  RelationItemList,
@@ -0,0 +1,9 @@
1
+ interface RelationFieldWrapperProps {
2
+ readonly children?: React.ReactNode;
3
+ readonly relationType?: string;
4
+ readonly initialValue?: string;
5
+ readonly fieldName?: string;
6
+ readonly basePath?: string;
7
+ }
8
+ export declare function RelationFieldWrapper({ children, relationType, initialValue, fieldName, basePath }: RelationFieldWrapperProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,63 @@
1
+ import { Link } from "react-router";
2
+ import { useState, useEffect } from "react";
3
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/RelationFieldWrapper.tsx";
4
+ const toKebabCase = (str) => {
5
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
6
+ };
7
+ function RelationFieldWrapper({
8
+ children,
9
+ relationType,
10
+ initialValue,
11
+ fieldName,
12
+ basePath = "/admin/data"
13
+ }) {
14
+ const [currentValue, setCurrentValue] = useState(initialValue || "");
15
+ useEffect(() => {
16
+ if (initialValue && !currentValue) {
17
+ setCurrentValue(initialValue);
18
+ }
19
+ if (fieldName) {
20
+ const selectElement = document.querySelector(`[name="${fieldName}"]`);
21
+ if ((selectElement == null ? void 0 : selectElement.value) && selectElement.value !== currentValue) {
22
+ setCurrentValue(selectElement.value);
23
+ }
24
+ if (selectElement) {
25
+ const handleChange = (event) => {
26
+ const target = event.target;
27
+ if (target.value !== currentValue) {
28
+ setCurrentValue(target.value);
29
+ }
30
+ };
31
+ selectElement.addEventListener("change", handleChange);
32
+ return () => {
33
+ selectElement.removeEventListener("change", handleChange);
34
+ };
35
+ }
36
+ }
37
+ }, [fieldName, currentValue, initialValue]);
38
+ const showViewLink = !!(relationType && currentValue && currentValue !== "");
39
+ return /* @__PURE__ */ React.createElement("div", { className: "relative", __self: this, __source: {
40
+ fileName: _jsxFileName,
41
+ lineNumber: 64,
42
+ columnNumber: 5
43
+ } }, children, showViewLink && /* @__PURE__ */ React.createElement("div", { className: "mt-1", __self: this, __source: {
44
+ fileName: _jsxFileName,
45
+ lineNumber: 67,
46
+ columnNumber: 9
47
+ } }, /* @__PURE__ */ React.createElement(Link, { to: `${basePath}/${toKebabCase(relationType)}/${currentValue}`, className: "inline-flex items-center text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 hover:underline", __self: this, __source: {
48
+ fileName: _jsxFileName,
49
+ lineNumber: 68,
50
+ columnNumber: 11
51
+ } }, /* @__PURE__ */ React.createElement("svg", { className: "h-3 w-3 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", __self: this, __source: {
52
+ fileName: _jsxFileName,
53
+ lineNumber: 72,
54
+ columnNumber: 13
55
+ } }, /* @__PURE__ */ React.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z", __self: this, __source: {
56
+ fileName: _jsxFileName,
57
+ lineNumber: 79,
58
+ columnNumber: 15
59
+ } })), "View ", relationType, " record")));
60
+ }
61
+ export {
62
+ RelationFieldWrapper
63
+ };
@@ -3,5 +3,5 @@ interface DateRangeFilterProps {
3
3
  currentValue: any;
4
4
  onChange: (value: any) => void;
5
5
  }
6
- export declare function DateRangeFilter({ fieldName, currentValue, onChange }: DateRangeFilterProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function DateRangeFilter({ fieldName, currentValue, onChange }: Readonly<DateRangeFilterProps>): import("react/jsx-runtime").JSX.Element;
7
7
  export {};
@@ -1,5 +1,5 @@
1
1
  import { formatFieldName } from "../../utils/string-utils.js";
2
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/filters/DateRangeFilter.tsx";
2
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/filters/DateRangeFilter.tsx";
3
3
  function DateRangeFilter({
4
4
  fieldName,
5
5
  currentValue,
@@ -55,29 +55,29 @@ function DateRangeFilter({
55
55
  fileName: _jsxFileName,
56
56
  lineNumber: 60,
57
57
  columnNumber: 9
58
- } }, /* @__PURE__ */ React.createElement("label", { className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
58
+ } }, /* @__PURE__ */ React.createElement("label", { htmlFor: `${fieldName}-from`, className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
59
59
  fileName: _jsxFileName,
60
60
  lineNumber: 61,
61
61
  columnNumber: 11
62
- } }, "From"), /* @__PURE__ */ React.createElement("input", { type: "date", value: fromDate, onChange: (e) => handleFromChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
62
+ } }, "From"), /* @__PURE__ */ React.createElement("input", { id: `${fieldName}-from`, type: "date", value: fromDate, onChange: (e) => handleFromChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
63
63
  fileName: _jsxFileName,
64
64
  lineNumber: 62,
65
65
  columnNumber: 11
66
66
  } })), /* @__PURE__ */ React.createElement("div", { __self: this, __source: {
67
67
  fileName: _jsxFileName,
68
- lineNumber: 69,
68
+ lineNumber: 70,
69
69
  columnNumber: 9
70
- } }, /* @__PURE__ */ React.createElement("label", { className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
70
+ } }, /* @__PURE__ */ React.createElement("label", { htmlFor: `${fieldName}-to`, className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
71
71
  fileName: _jsxFileName,
72
- lineNumber: 70,
72
+ lineNumber: 71,
73
73
  columnNumber: 11
74
- } }, "To"), /* @__PURE__ */ React.createElement("input", { type: "date", value: toDate, onChange: (e) => handleToChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
74
+ } }, "To"), /* @__PURE__ */ React.createElement("input", { id: `${fieldName}-to`, type: "date", value: toDate, onChange: (e) => handleToChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
75
75
  fileName: _jsxFileName,
76
- lineNumber: 71,
76
+ lineNumber: 72,
77
77
  columnNumber: 11
78
78
  } }))), (fromDate || toDate) && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-gray-500", __self: this, __source: {
79
79
  fileName: _jsxFileName,
80
- lineNumber: 80,
80
+ lineNumber: 82,
81
81
  columnNumber: 9
82
82
  } }, fromDate && toDate && `${fromDate} to ${toDate}`, fromDate && !toDate && `From ${fromDate}`, !fromDate && toDate && `Until ${toDate}`));
83
83
  }
@@ -1,21 +1,21 @@
1
1
  import { formatFieldName } from "../../utils/string-utils.js";
2
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/filters/NumberRangeFilter.tsx";
2
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/filters/NumberRangeFilter.tsx";
3
3
  function NumberRangeFilter({
4
4
  fieldName,
5
5
  fieldType,
6
6
  currentValue,
7
7
  onChange
8
8
  }) {
9
- const minValue = (currentValue == null ? void 0 : currentValue.gte) !== void 0 ? currentValue.gte.toString() : "";
10
- const maxValue = (currentValue == null ? void 0 : currentValue.lte) !== void 0 ? currentValue.lte.toString() : "";
9
+ const minValue = (currentValue == null ? void 0 : currentValue.gte) === void 0 ? "" : currentValue.gte.toString();
10
+ const maxValue = (currentValue == null ? void 0 : currentValue.lte) === void 0 ? "" : currentValue.lte.toString();
11
11
  const parseNumber = (value) => {
12
12
  if (!value) return void 0;
13
13
  if (fieldType === "int" || fieldType === "bigint") {
14
- const parsed = parseInt(value, 10);
15
- return isNaN(parsed) ? void 0 : parsed;
14
+ const parsed = Number.parseInt(value, 10);
15
+ return Number.isNaN(parsed) ? void 0 : parsed;
16
16
  } else if (fieldType === "float" || fieldType === "decimal") {
17
- const parsed = parseFloat(value);
18
- return isNaN(parsed) ? void 0 : parsed;
17
+ const parsed = Number.parseFloat(value);
18
+ return Number.isNaN(parsed) ? void 0 : parsed;
19
19
  }
20
20
  return void 0;
21
21
  };
@@ -24,10 +24,10 @@ function NumberRangeFilter({
24
24
  ...currentValue
25
25
  };
26
26
  const parsedValue = parseNumber(value);
27
- if (parsedValue !== void 0) {
28
- newValue.gte = parsedValue;
29
- } else {
27
+ if (parsedValue === void 0) {
30
28
  delete newValue.gte;
29
+ } else {
30
+ newValue.gte = parsedValue;
31
31
  }
32
32
  if (newValue.gte === void 0 && newValue.lte === void 0) {
33
33
  onChange(void 0);
@@ -40,10 +40,10 @@ function NumberRangeFilter({
40
40
  ...currentValue
41
41
  };
42
42
  const parsedValue = parseNumber(value);
43
- if (parsedValue !== void 0) {
44
- newValue.lte = parsedValue;
45
- } else {
43
+ if (parsedValue === void 0) {
46
44
  delete newValue.lte;
45
+ } else {
46
+ newValue.lte = parsedValue;
47
47
  }
48
48
  if (newValue.gte === void 0 && newValue.lte === void 0) {
49
49
  onChange(void 0);
@@ -68,29 +68,29 @@ function NumberRangeFilter({
68
68
  fileName: _jsxFileName,
69
69
  lineNumber: 79,
70
70
  columnNumber: 9
71
- } }, /* @__PURE__ */ React.createElement("label", { className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
71
+ } }, /* @__PURE__ */ React.createElement("label", { htmlFor: `${fieldName}-min`, className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
72
72
  fileName: _jsxFileName,
73
73
  lineNumber: 80,
74
74
  columnNumber: 11
75
- } }, "Min"), /* @__PURE__ */ React.createElement("input", { type: "number", step, value: minValue, onChange: (e) => handleMinChange(e.target.value), placeholder: "No minimum", className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
75
+ } }, "Min"), /* @__PURE__ */ React.createElement("input", { id: `${fieldName}-min`, type: "number", step, value: minValue, onChange: (e) => handleMinChange(e.target.value), placeholder: "No minimum", className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
76
76
  fileName: _jsxFileName,
77
77
  lineNumber: 81,
78
78
  columnNumber: 11
79
79
  } })), /* @__PURE__ */ React.createElement("div", { __self: this, __source: {
80
80
  fileName: _jsxFileName,
81
- lineNumber: 90,
81
+ lineNumber: 91,
82
82
  columnNumber: 9
83
- } }, /* @__PURE__ */ React.createElement("label", { className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
83
+ } }, /* @__PURE__ */ React.createElement("label", { htmlFor: `${fieldName}-max`, className: "block text-xs text-gray-500 mb-1", __self: this, __source: {
84
84
  fileName: _jsxFileName,
85
- lineNumber: 91,
85
+ lineNumber: 92,
86
86
  columnNumber: 11
87
- } }, "Max"), /* @__PURE__ */ React.createElement("input", { type: "number", step, value: maxValue, onChange: (e) => handleMaxChange(e.target.value), placeholder: "No maximum", className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
87
+ } }, "Max"), /* @__PURE__ */ React.createElement("input", { id: `${fieldName}-max`, type: "number", step, value: maxValue, onChange: (e) => handleMaxChange(e.target.value), placeholder: "No maximum", className: "w-full px-2 py-1 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-1 focus:ring-green-web focus:border-green-web", __self: this, __source: {
88
88
  fileName: _jsxFileName,
89
- lineNumber: 92,
89
+ lineNumber: 93,
90
90
  columnNumber: 11
91
91
  } }))), (minValue || maxValue) && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-gray-500", __self: this, __source: {
92
92
  fileName: _jsxFileName,
93
- lineNumber: 103,
93
+ lineNumber: 105,
94
94
  columnNumber: 9
95
95
  } }, minValue && maxValue && `${minValue} to ${maxValue}`, minValue && !maxValue && `≥ ${minValue}`, !minValue && maxValue && `≤ ${maxValue}`));
96
96
  }
@@ -9,10 +9,10 @@ export declare function RelationSearchInput({ searchTerm, onSearchChange, relate
9
9
  onSearchChange: (value: string) => void;
10
10
  relatedModelName: string;
11
11
  }>): import("react/jsx-runtime").JSX.Element;
12
- export declare function RelationItem({ item, onSelect }: {
12
+ export declare function RelationItem({ item, onSelect }: Readonly<{
13
13
  item: any;
14
14
  onSelect: (item: any) => void;
15
- }): import("react/jsx-runtime").JSX.Element;
15
+ }>): import("react/jsx-runtime").JSX.Element;
16
16
  export declare function RelationItemList({ items, loading, error, onSelect, onClear }: Readonly<{
17
17
  items: any[];
18
18
  loading: boolean;
@@ -20,7 +20,7 @@ export declare function RelationItemList({ items, loading, error, onSelect, onCl
20
20
  onSelect: (item: any) => void;
21
21
  onClear: () => void;
22
22
  }>): import("react/jsx-runtime").JSX.Element;
23
- export declare function RelationDropdownContent({ searchTerm, onSearchChange, relatedModelName, items, loading, error, onSelect, onClear }: {
23
+ export declare function RelationDropdownContent({ searchTerm, onSearchChange, relatedModelName, items, loading, error, onSelect, onClear }: Readonly<{
24
24
  searchTerm: string;
25
25
  onSearchChange: (value: string) => void;
26
26
  relatedModelName: string;
@@ -29,4 +29,4 @@ export declare function RelationDropdownContent({ searchTerm, onSearchChange, re
29
29
  error?: any;
30
30
  onSelect: (item: any) => void;
31
31
  onClear: () => void;
32
- }): import("react/jsx-runtime").JSX.Element;
32
+ }>): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { getItemDisplayName } from "../../utils/string-utils.js";
2
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/filters/RelationComponents.tsx";
2
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/filters/RelationComponents.tsx";
3
3
  function RelationDropdownButton({
4
4
  currentItem,
5
5
  relatedModelName,
@@ -64,7 +64,7 @@ function RelationItemList({
64
64
  fileName: _jsxFileName,
65
65
  lineNumber: 95,
66
66
  columnNumber: 15
67
- } }, "Clear selection"), error ? /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-red-600", __self: this, __source: {
67
+ } }, "Clear selection"), error && /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-red-600", __self: this, __source: {
68
68
  fileName: _jsxFileName,
69
69
  lineNumber: 104,
70
70
  columnNumber: 9
@@ -84,33 +84,33 @@ function RelationItemList({
84
84
  fileName: _jsxFileName,
85
85
  lineNumber: 111,
86
86
  columnNumber: 11
87
- } }, error.networkError ? "Network error" : "Please try again")) : loading ? /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-gray-500", __self: this, __source: {
87
+ } }, error.networkError ? "Network error" : "Please try again")), !error && loading && /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-gray-500", __self: this, __source: {
88
88
  fileName: _jsxFileName,
89
- lineNumber: 116,
89
+ lineNumber: 117,
90
90
  columnNumber: 9
91
91
  } }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center", __self: this, __source: {
92
92
  fileName: _jsxFileName,
93
- lineNumber: 117,
93
+ lineNumber: 118,
94
94
  columnNumber: 11
95
95
  } }, /* @__PURE__ */ React.createElement("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-gray-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", __self: this, __source: {
96
96
  fileName: _jsxFileName,
97
- lineNumber: 118,
97
+ lineNumber: 119,
98
98
  columnNumber: 13
99
99
  } }, /* @__PURE__ */ React.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", __self: this, __source: {
100
100
  fileName: _jsxFileName,
101
- lineNumber: 119,
101
+ lineNumber: 120,
102
102
  columnNumber: 15
103
103
  } }), /* @__PURE__ */ React.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z", __self: this, __source: {
104
104
  fileName: _jsxFileName,
105
- lineNumber: 120,
105
+ lineNumber: 121,
106
106
  columnNumber: 15
107
- } })), "Loading...")) : items.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-gray-500", __self: this, __source: {
107
+ } })), "Loading...")), !error && !loading && items.length === 0 && /* @__PURE__ */ React.createElement("div", { className: "px-3 py-2 text-sm text-gray-500", __self: this, __source: {
108
108
  fileName: _jsxFileName,
109
- lineNumber: 126,
110
- columnNumber: 17
111
- } }, "No items found") : items.map((item) => /* @__PURE__ */ React.createElement(RelationItem, { key: item.id, item, onSelect, __self: this, __source: {
109
+ lineNumber: 128,
110
+ columnNumber: 9
111
+ } }, "No items found"), !error && !loading && items.length > 0 && items.map((item) => /* @__PURE__ */ React.createElement(RelationItem, { key: item.id, item, onSelect, __self: this, __source: {
112
112
  fileName: _jsxFileName,
113
- lineNumber: 129,
113
+ lineNumber: 132,
114
114
  columnNumber: 11
115
115
  } })));
116
116
  }
@@ -126,15 +126,15 @@ function RelationDropdownContent({
126
126
  }) {
127
127
  return /* @__PURE__ */ React.createElement("div", { className: "absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-md shadow-lg", __self: this, __source: {
128
128
  fileName: _jsxFileName,
129
- lineNumber: 161,
129
+ lineNumber: 164,
130
130
  columnNumber: 5
131
131
  } }, /* @__PURE__ */ React.createElement(RelationSearchInput, { searchTerm, onSearchChange, relatedModelName, __self: this, __source: {
132
132
  fileName: _jsxFileName,
133
- lineNumber: 162,
133
+ lineNumber: 165,
134
134
  columnNumber: 7
135
135
  } }), /* @__PURE__ */ React.createElement(RelationItemList, { items, loading, error, onSelect, onClear, __self: this, __source: {
136
136
  fileName: _jsxFileName,
137
- lineNumber: 167,
137
+ lineNumber: 170,
138
138
  columnNumber: 7
139
139
  } }));
140
140
  }
@@ -3,7 +3,7 @@ import { useClickOutside } from "../../hooks/useClickOutside.js";
3
3
  import { useRelationData } from "../../hooks/useRelationData.js";
4
4
  import { formatFieldName } from "../../utils/string-utils.js";
5
5
  import { RelationDropdownButton, RelationDropdownContent } from "./RelationComponents.js";
6
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/filters/RelationFilterField.tsx";
6
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/filters/RelationFilterField.tsx";
7
7
  function RelationFilterField({
8
8
  fieldName,
9
9
  relatedModelName,
@@ -22,7 +22,13 @@ function RelationFilterField({
22
22
  loading,
23
23
  error: relationError,
24
24
  hasDocument
25
- } = useRelationData(relatedModelName, searchTerm, isOpen);
25
+ } = useRelationData(
26
+ relatedModelName,
27
+ searchTerm,
28
+ isOpen,
29
+ currentValue == null ? void 0 : currentValue.id
30
+ // Pass current value ID so it can be loaded even when dropdown is closed
31
+ );
26
32
  const currentItem = useMemo(() => (currentValue == null ? void 0 : currentValue.id) ? relatedItems.find((item) => item.id === currentValue.id) : null, [currentValue == null ? void 0 : currentValue.id, relatedItems]);
27
33
  const handleSelect = useCallback((item) => {
28
34
  onChange({
@@ -45,39 +51,39 @@ function RelationFilterField({
45
51
  if (!hasDocument) {
46
52
  return /* @__PURE__ */ React.createElement("div", { className: "space-y-1", __self: this, __source: {
47
53
  fileName: _jsxFileName,
48
- lineNumber: 63,
54
+ lineNumber: 68,
49
55
  columnNumber: 7
50
56
  } }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm font-medium text-gray-700", __self: this, __source: {
51
57
  fileName: _jsxFileName,
52
- lineNumber: 64,
58
+ lineNumber: 69,
53
59
  columnNumber: 9
54
60
  } }, formatFieldName(fieldName), " ID"), /* @__PURE__ */ React.createElement("input", { type: "text", value: (currentValue == null ? void 0 : currentValue.id) || "", onChange: (e) => onChange(e.target.value ? {
55
61
  id: e.target.value
56
62
  } : void 0), placeholder: "Enter ID...", className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-web focus:border-green-web text-sm", __self: this, __source: {
57
63
  fileName: _jsxFileName,
58
- lineNumber: 67,
64
+ lineNumber: 72,
59
65
  columnNumber: 9
60
66
  } }));
61
67
  }
62
68
  return /* @__PURE__ */ React.createElement("div", { className: "space-y-1", ref: dropdownRef, __self: this, __source: {
63
69
  fileName: _jsxFileName,
64
- lineNumber: 79,
70
+ lineNumber: 84,
65
71
  columnNumber: 5
66
72
  } }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm font-medium text-gray-700", __self: this, __source: {
67
73
  fileName: _jsxFileName,
68
- lineNumber: 80,
74
+ lineNumber: 85,
69
75
  columnNumber: 7
70
76
  } }, formatFieldName(fieldName)), /* @__PURE__ */ React.createElement("div", { className: "relative", __self: this, __source: {
71
77
  fileName: _jsxFileName,
72
- lineNumber: 83,
78
+ lineNumber: 88,
73
79
  columnNumber: 7
74
80
  } }, /* @__PURE__ */ React.createElement(RelationDropdownButton, { currentItem, relatedModelName, isOpen, onClick: handleToggleOpen, __self: this, __source: {
75
81
  fileName: _jsxFileName,
76
- lineNumber: 84,
82
+ lineNumber: 89,
77
83
  columnNumber: 9
78
84
  } }), isOpen && /* @__PURE__ */ React.createElement(RelationDropdownContent, { searchTerm, onSearchChange: setSearchTerm, relatedModelName, items: relatedItems, loading, error: relationError, onSelect: handleSelect, onClear: handleClear, __self: this, __source: {
79
85
  fileName: _jsxFileName,
80
- lineNumber: 92,
86
+ lineNumber: 97,
81
87
  columnNumber: 11
82
88
  } })));
83
89
  }
@@ -1,2 +1,3 @@
1
1
  export * from './filters';
2
2
  export * from './shared';
3
+ export * from './RelationFieldWrapper';
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Link } from "react-router";
3
3
  import { HomeIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
4
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/shared/AdminBreadcrumbs.tsx";
4
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/shared/AdminBreadcrumbs.tsx";
5
5
  function AdminBreadcrumbs({
6
6
  items,
7
7
  showHome = true,
@@ -46,11 +46,11 @@ function AdminBreadcrumbs({
46
46
  };
47
47
  return /* @__PURE__ */ React.createElement("nav", { className: `flex ${className}`, "aria-label": "Breadcrumb", __self: this, __source: {
48
48
  fileName: _jsxFileName,
49
- lineNumber: 78,
49
+ lineNumber: 74,
50
50
  columnNumber: 5
51
51
  } }, /* @__PURE__ */ React.createElement("ol", { className: "flex items-center space-x-4", __self: this, __source: {
52
52
  fileName: _jsxFileName,
53
- lineNumber: 79,
53
+ lineNumber: 75,
54
54
  columnNumber: 7
55
55
  } }, renderHomeLink(), items.map((item, index) => {
56
56
  index === items.length - 1;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { XCircleIcon, ExclamationCircleIcon, ExclamationTriangleIcon } from "@heroicons/react/24/outline";
3
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/shared/AdminErrorStates.tsx";
3
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/shared/AdminErrorStates.tsx";
4
4
  const getSeverityConfig = (severity) => {
5
5
  const configs = {
6
6
  warning: {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { QuestionMarkCircleIcon, PauseCircleIcon, CheckCircleIcon, XCircleIcon, ExclamationTriangleIcon, ClockIcon } from "@heroicons/react/24/solid";
3
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/components/shared/AdminStatusDisplay.tsx";
3
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/components/shared/AdminStatusDisplay.tsx";
4
4
  const getStatusConfig = (status) => {
5
5
  const configs = {
6
6
  active: {
@@ -39,7 +39,7 @@ export interface AdminDataProviderProps {
39
39
  * </AdminDataProvider>
40
40
  * ```
41
41
  */
42
- export declare function AdminDataProvider({ children, sdk, databaseModels, basePath, formTheme }: AdminDataProviderProps): import("react/jsx-runtime").JSX.Element;
42
+ export declare function AdminDataProvider({ children, sdk, databaseModels, basePath, formTheme }: Readonly<AdminDataProviderProps>): import("react/jsx-runtime").JSX.Element;
43
43
  /**
44
44
  * Hook to access the admin data context
45
45
  * @throws Error if used outside of AdminDataProvider
@@ -1,5 +1,5 @@
1
- import React, { createContext, useContext } from "react";
2
- var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/admin-data/src/lib/context/AdminDataContext.tsx";
1
+ import React, { createContext, useMemo, useContext } from "react";
2
+ var _jsxFileName = "/Users/justinhandley/IdeaProjects/nestled_template/libs/data-browser/src/lib/context/AdminDataContext.tsx";
3
3
  const AdminDataContext = createContext(null);
4
4
  function AdminDataProvider({
5
5
  children,
@@ -8,14 +8,15 @@ function AdminDataProvider({
8
8
  basePath = "/admin/data",
9
9
  formTheme
10
10
  }) {
11
- return /* @__PURE__ */ React.createElement(AdminDataContext.Provider, { value: {
11
+ const value = useMemo(() => ({
12
12
  sdk,
13
13
  databaseModels,
14
14
  basePath,
15
15
  formTheme
16
- }, __self: this, __source: {
16
+ }), [sdk, databaseModels, basePath, formTheme]);
17
+ return /* @__PURE__ */ React.createElement(AdminDataContext.Provider, { value, __self: this, __source: {
17
18
  fileName: _jsxFileName,
18
- lineNumber: 55,
19
+ lineNumber: 60,
19
20
  columnNumber: 5
20
21
  } }, children);
21
22
  }
@@ -1,4 +1,4 @@
1
- export declare function useRelationData(relatedModelName: string, searchTerm: string, isOpen: boolean): {
1
+ export declare function useRelationData(relatedModelName: string, searchTerm: string, isOpen: boolean, currentValueId?: string): {
2
2
  relatedModel: any;
3
3
  relatedItems: any[];
4
4
  loading: boolean;
@@ -4,7 +4,7 @@ import { useAdminDataContext } from "../context/AdminDataContext.js";
4
4
  import { getAdminDocuments } from "../utils/graphql-utils.js";
5
5
  import { getSmartSearchFields } from "../utils/string-utils.js";
6
6
  import { useDebounce } from "./useDebounce.js";
7
- function useRelationData(relatedModelName, searchTerm, isOpen) {
7
+ function useRelationData(relatedModelName, searchTerm, isOpen, currentValueId) {
8
8
  const { sdk, databaseModels } = useAdminDataContext();
9
9
  const debouncedSearchTerm = useDebounce(searchTerm, 300);
10
10
  const relatedModel = useMemo(
@@ -45,7 +45,8 @@ function useRelationData(relatedModelName, searchTerm, isOpen) {
45
45
  error: relationError
46
46
  } = useQuery(relatedDocuments.listQuery, {
47
47
  variables: queryVariables,
48
- skip: !relatedDocuments.listQuery || !isOpen,
48
+ // Don't skip if we have a currentValueId to display, even if dropdown is closed
49
+ skip: !relatedDocuments.listQuery || !isOpen && !currentValueId,
49
50
  errorPolicy: "all",
50
51
  // Continue processing even if there are GraphQL errors
51
52
  notifyOnNetworkStatusChange: true,