@mdxui/do 4.0.0 → 4.0.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.
- package/dist/app/index.d.ts +32 -186
- package/dist/app/index.js +19 -11
- package/dist/auth/index.d.ts +48 -0
- package/dist/auth/index.js +4 -0
- package/dist/{breadcrumbs-C9Qn3S7d.d.ts → breadcrumbs-DltlCiHt.d.ts} +3 -3
- package/dist/chunk-2FWXT4HH.js +576 -0
- package/dist/chunk-2FWXT4HH.js.map +1 -0
- package/dist/chunk-5PC6U46L.js +604 -0
- package/dist/chunk-5PC6U46L.js.map +1 -0
- package/dist/chunk-63VCRTDQ.js +2505 -0
- package/dist/chunk-63VCRTDQ.js.map +1 -0
- package/dist/chunk-7J3RSIG4.js +178 -0
- package/dist/chunk-7J3RSIG4.js.map +1 -0
- package/dist/chunk-7QCTRNEJ.js +173 -0
- package/dist/chunk-7QCTRNEJ.js.map +1 -0
- package/dist/chunk-7TFHUKS7.js +66 -0
- package/dist/chunk-7TFHUKS7.js.map +1 -0
- package/dist/{chunk-LJIWB7KE.js → chunk-BU5HMHGQ.js} +3 -3
- package/dist/chunk-BU5HMHGQ.js.map +1 -0
- package/dist/{chunk-GGO5GW72.js → chunk-BZURBNFD.js} +305 -51
- package/dist/chunk-BZURBNFD.js.map +1 -0
- package/dist/{chunk-NA652ART.js → chunk-FM2RTAHV.js} +5 -65
- package/dist/chunk-FM2RTAHV.js.map +1 -0
- package/dist/{chunk-WMNT4OIE.js → chunk-HC4PBXV4.js} +131 -58
- package/dist/chunk-HC4PBXV4.js.map +1 -0
- package/dist/{chunk-Y52IEYVM.js → chunk-JPZ6RZJE.js} +78 -45
- package/dist/chunk-JPZ6RZJE.js.map +1 -0
- package/dist/{chunk-OVLO7UOH.js → chunk-KLN5OTQH.js} +168 -361
- package/dist/chunk-KLN5OTQH.js.map +1 -0
- package/dist/chunk-LCYBQR35.js +79 -0
- package/dist/chunk-LCYBQR35.js.map +1 -0
- package/dist/chunk-PJYGRD7N.js +216 -0
- package/dist/chunk-PJYGRD7N.js.map +1 -0
- package/dist/chunk-QEXY4FZV.js +292 -0
- package/dist/chunk-QEXY4FZV.js.map +1 -0
- package/dist/chunk-SX4IIE2R.js +53 -0
- package/dist/chunk-SX4IIE2R.js.map +1 -0
- package/dist/chunk-UCWMSKCW.js +901 -0
- package/dist/chunk-UCWMSKCW.js.map +1 -0
- package/dist/{chunk-5SHZZC7L.js → chunk-WC6SFBAF.js} +59 -6
- package/dist/chunk-WC6SFBAF.js.map +1 -0
- package/dist/chunk-WIKU77ZY.js +18 -0
- package/dist/chunk-WIKU77ZY.js.map +1 -0
- package/dist/chunk-X3AWNFBF.js +47 -0
- package/dist/chunk-X3AWNFBF.js.map +1 -0
- package/dist/chunk-ZZTQGMLX.js +23 -0
- package/dist/chunk-ZZTQGMLX.js.map +1 -0
- package/dist/{lib → client}/index.d.ts +97 -345
- package/dist/client/index.js +3 -0
- package/dist/common-DW_JM2dW.d.ts +454 -0
- package/dist/components/index.d.ts +11 -2
- package/dist/components/index.js +8 -3
- package/dist/{config-CxvpD8Y6.d.ts → config-DB14_LhF.d.ts} +1 -1
- package/dist/{do-D27i5bU0.d.ts → do-D37hbmL9.d.ts} +6 -14
- package/dist/dotdo-client-2DkwXHM2.d.ts +344 -0
- package/dist/errors-BOY11CJs.d.ts +373 -0
- package/dist/features/data-browser/index.d.ts +51 -0
- package/dist/features/data-browser/index.js +12 -0
- package/dist/features/data-browser/index.js.map +1 -0
- package/dist/features/data-grid/index.d.ts +22 -0
- package/dist/features/data-grid/index.js +12 -0
- package/dist/features/data-grid/index.js.map +1 -0
- package/dist/features/document-editor/index.d.ts +26 -0
- package/dist/features/document-editor/index.js +12 -0
- package/dist/features/document-editor/index.js.map +1 -0
- package/dist/features/function-editor/index.d.ts +215 -0
- package/dist/features/function-editor/index.js +7 -0
- package/dist/features/function-editor/index.js.map +1 -0
- package/dist/hooks/index.d.ts +64 -7
- package/dist/hooks/index.js +8 -7
- package/dist/hooks/things/index.d.ts +5 -297
- package/dist/hooks/things/index.js +6 -6
- package/dist/index-C0m9UI6W.d.ts +444 -0
- package/dist/index.d.ts +42 -32
- package/dist/index.js +21 -13
- package/dist/providers/index.d.ts +16 -28
- package/dist/providers/index.js +3 -3
- package/dist/schemas/index.d.ts +4551 -109
- package/dist/schemas/index.js +2 -260
- package/dist/schemas/index.js.map +1 -1
- package/dist/shell/index.d.ts +92 -0
- package/dist/shell/index.js +6 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/{thing-BF25aUtJ.d.ts → thing-Dc3AE2XI.d.ts} +22 -22
- package/dist/thing-adapters-aMjF0h9u.d.ts +1214 -0
- package/dist/types/index.d.ts +954 -7521
- package/dist/types/index.js +2 -2
- package/dist/ui-filters-BvrjMP_U.d.ts +108 -0
- package/dist/{errors-DratdVIz.d.ts → utils/index.d.ts} +38 -77
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist-app/assets/index-DWX3479M.js +7 -0
- package/dist-app/assets/index-DWX3479M.js.map +1 -0
- package/dist-app/assets/main-BptePr_C.js +318 -0
- package/dist-app/assets/main-BptePr_C.js.map +1 -0
- package/dist-app/assets/main-CS9jgKzj.css +1 -0
- package/dist-app/index.html +38 -0
- package/package.json +32 -19
- package/dist/agents-2_r9e9i7.d.ts +0 -1043
- package/dist/capnweb-client-Bq78FtEA.d.ts +0 -229
- package/dist/chunk-3XKYQRXY.js +0 -192
- package/dist/chunk-3XKYQRXY.js.map +0 -1
- package/dist/chunk-4KXVN3EQ.js +0 -56
- package/dist/chunk-4KXVN3EQ.js.map +0 -1
- package/dist/chunk-5SHZZC7L.js.map +0 -1
- package/dist/chunk-7UFINK3Q.js +0 -1994
- package/dist/chunk-7UFINK3Q.js.map +0 -1
- package/dist/chunk-GGO5GW72.js.map +0 -1
- package/dist/chunk-JJLAES6W.js +0 -76
- package/dist/chunk-JJLAES6W.js.map +0 -1
- package/dist/chunk-KT52UU3U.js +0 -985
- package/dist/chunk-KT52UU3U.js.map +0 -1
- package/dist/chunk-LJIWB7KE.js.map +0 -1
- package/dist/chunk-NA652ART.js.map +0 -1
- package/dist/chunk-OVLO7UOH.js.map +0 -1
- package/dist/chunk-VRLUXCLD.js +0 -31
- package/dist/chunk-VRLUXCLD.js.map +0 -1
- package/dist/chunk-WMNT4OIE.js.map +0 -1
- package/dist/chunk-Y52IEYVM.js.map +0 -1
- package/dist/lib/index.js +0 -6
- package/dist/query-keys-CZNFikIi.d.ts +0 -153
- package/dist/views/index.d.ts +0 -131
- package/dist/views/index.js +0 -11
- /package/dist/{lib → auth}/index.js.map +0 -0
- /package/dist/{views → client}/index.js.map +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { useTypes } from './chunk-FM2RTAHV.js';
|
|
2
|
+
import { useThings, useThing, useUpdateThing, useDeleteThing } from './chunk-WC6SFBAF.js';
|
|
3
|
+
import { useDO } from './chunk-HC4PBXV4.js';
|
|
4
|
+
import { cn } from './chunk-JPZ6RZJE.js';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { DocumentSidebar, DocumentViewToolbar, DocumentEditor } from '@mdxui/admin';
|
|
7
|
+
import { Database } from 'lucide-react';
|
|
8
|
+
import { TooltipProvider } from '@mdxui/primitives';
|
|
9
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
|
|
11
|
+
function toDocumentType(type) {
|
|
12
|
+
return {
|
|
13
|
+
id: type.id,
|
|
14
|
+
name: type.name,
|
|
15
|
+
label: type.label
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function toDocumentTypeOption(type) {
|
|
19
|
+
return {
|
|
20
|
+
id: type.id,
|
|
21
|
+
name: type.name,
|
|
22
|
+
label: type.label
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function toDocumentItem(thing) {
|
|
26
|
+
return {
|
|
27
|
+
id: thing.id,
|
|
28
|
+
name: thing.name,
|
|
29
|
+
type: thing.type
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function DocumentEditorView({
|
|
33
|
+
initialNamespace,
|
|
34
|
+
initialType,
|
|
35
|
+
initialId,
|
|
36
|
+
onSave,
|
|
37
|
+
onDelete,
|
|
38
|
+
onBack: _onBack,
|
|
39
|
+
className
|
|
40
|
+
}) {
|
|
41
|
+
const { namespace: contextNamespace } = useDO();
|
|
42
|
+
const [selectedNamespace] = React.useState(initialNamespace ?? contextNamespace);
|
|
43
|
+
const [selectedType, setSelectedType] = React.useState(initialType);
|
|
44
|
+
const [selectedThingId, setSelectedThingId] = React.useState(initialId);
|
|
45
|
+
const [sidebarCollapsed, setSidebarCollapsed] = React.useState(false);
|
|
46
|
+
const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false);
|
|
47
|
+
const [isSaving, setIsSaving] = React.useState(false);
|
|
48
|
+
const [localDocument, setLocalDocument] = React.useState(null);
|
|
49
|
+
const fileInputRef = React.useRef(null);
|
|
50
|
+
const { data: types } = useTypes({ ns: selectedNamespace });
|
|
51
|
+
const { data: thingsResult, refetch: refetchThings } = useThings({
|
|
52
|
+
ns: selectedNamespace,
|
|
53
|
+
type: selectedType
|
|
54
|
+
});
|
|
55
|
+
const thingParams = selectedType && selectedThingId ? { ns: selectedNamespace, type: selectedType, id: selectedThingId } : { ns: "", type: "", id: "" };
|
|
56
|
+
const { data: currentThing, isLoading: isLoadingThing } = useThing(thingParams);
|
|
57
|
+
const updateThing = useUpdateThing(
|
|
58
|
+
selectedType && selectedThingId ? { ns: selectedNamespace, type: selectedType, id: selectedThingId } : { ns: "temp", type: "temp", id: "temp" }
|
|
59
|
+
);
|
|
60
|
+
const deleteThing = useDeleteThing(
|
|
61
|
+
selectedType && selectedThingId ? { ns: selectedNamespace, type: selectedType, id: selectedThingId } : { ns: "temp", type: "temp", id: "temp" }
|
|
62
|
+
);
|
|
63
|
+
const documentTypes = React.useMemo(
|
|
64
|
+
() => types?.map(toDocumentType) ?? [],
|
|
65
|
+
[types]
|
|
66
|
+
);
|
|
67
|
+
const documentTypeOptions = React.useMemo(
|
|
68
|
+
() => types?.map(toDocumentTypeOption) ?? [],
|
|
69
|
+
[types]
|
|
70
|
+
);
|
|
71
|
+
const documentItems = React.useMemo(
|
|
72
|
+
() => thingsResult?.data?.map(toDocumentItem) ?? [],
|
|
73
|
+
[thingsResult]
|
|
74
|
+
);
|
|
75
|
+
React.useEffect(() => {
|
|
76
|
+
if (currentThing) {
|
|
77
|
+
setLocalDocument({
|
|
78
|
+
_id: currentThing.id,
|
|
79
|
+
_ns: currentThing.ns,
|
|
80
|
+
_type: currentThing.type,
|
|
81
|
+
name: currentThing.name,
|
|
82
|
+
createdAt: currentThing.createdAt instanceof Date ? currentThing.createdAt.toISOString() : currentThing.createdAt,
|
|
83
|
+
updatedAt: currentThing.updatedAt instanceof Date ? currentThing.updatedAt.toISOString() : currentThing.updatedAt,
|
|
84
|
+
...currentThing.data
|
|
85
|
+
});
|
|
86
|
+
setHasUnsavedChanges(false);
|
|
87
|
+
} else {
|
|
88
|
+
setLocalDocument(null);
|
|
89
|
+
}
|
|
90
|
+
}, [currentThing]);
|
|
91
|
+
const handleSelectDocument = React.useCallback((type, documentId) => {
|
|
92
|
+
setSelectedType(type);
|
|
93
|
+
setSelectedThingId(documentId);
|
|
94
|
+
setHasUnsavedChanges(false);
|
|
95
|
+
}, []);
|
|
96
|
+
const handleDocumentChange = React.useCallback((updatedDoc) => {
|
|
97
|
+
setLocalDocument(updatedDoc);
|
|
98
|
+
setHasUnsavedChanges(true);
|
|
99
|
+
}, []);
|
|
100
|
+
const handleCreateDocument = React.useCallback((type) => {
|
|
101
|
+
const newId = `${Date.now()}`;
|
|
102
|
+
setSelectedType(type);
|
|
103
|
+
setSelectedThingId(newId);
|
|
104
|
+
setLocalDocument({
|
|
105
|
+
_id: newId,
|
|
106
|
+
_type: type,
|
|
107
|
+
_ns: selectedNamespace,
|
|
108
|
+
name: "New Thing",
|
|
109
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
110
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
|
+
});
|
|
112
|
+
setHasUnsavedChanges(true);
|
|
113
|
+
}, [selectedNamespace]);
|
|
114
|
+
const handleSave = React.useCallback(async () => {
|
|
115
|
+
if (!localDocument || !selectedType || !selectedThingId) return;
|
|
116
|
+
setIsSaving(true);
|
|
117
|
+
try {
|
|
118
|
+
const { _id, _ns, _type, createdAt, updatedAt, name, ...data } = localDocument;
|
|
119
|
+
await updateThing.mutateAsync({
|
|
120
|
+
name,
|
|
121
|
+
data
|
|
122
|
+
});
|
|
123
|
+
setHasUnsavedChanges(false);
|
|
124
|
+
await refetchThings();
|
|
125
|
+
if (onSave && currentThing) {
|
|
126
|
+
onSave({ ...currentThing, name, data });
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error("Failed to save:", err);
|
|
130
|
+
} finally {
|
|
131
|
+
setIsSaving(false);
|
|
132
|
+
}
|
|
133
|
+
}, [localDocument, selectedType, selectedThingId, updateThing, refetchThings, onSave, currentThing]);
|
|
134
|
+
const handleDelete = React.useCallback(async () => {
|
|
135
|
+
if (!selectedType || !selectedThingId) return;
|
|
136
|
+
try {
|
|
137
|
+
await deleteThing.mutateAsync();
|
|
138
|
+
const remainingThings = thingsResult?.data?.filter((t) => t.id !== selectedThingId) ?? [];
|
|
139
|
+
if (remainingThings.length > 0) {
|
|
140
|
+
setSelectedThingId(remainingThings[0].id);
|
|
141
|
+
setSelectedType(remainingThings[0].type);
|
|
142
|
+
} else {
|
|
143
|
+
setSelectedThingId(void 0);
|
|
144
|
+
}
|
|
145
|
+
setHasUnsavedChanges(false);
|
|
146
|
+
await refetchThings();
|
|
147
|
+
onDelete?.();
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.error("Failed to delete:", err);
|
|
150
|
+
}
|
|
151
|
+
}, [selectedType, selectedThingId, deleteThing, thingsResult, refetchThings, onDelete]);
|
|
152
|
+
const handleExport = React.useCallback(() => {
|
|
153
|
+
if (!localDocument) return;
|
|
154
|
+
const json = JSON.stringify(localDocument, null, 2);
|
|
155
|
+
const blob = new Blob([json], { type: "application/json" });
|
|
156
|
+
const url = URL.createObjectURL(blob);
|
|
157
|
+
const link = document.createElement("a");
|
|
158
|
+
link.href = url;
|
|
159
|
+
link.download = `${selectedThingId}.json`;
|
|
160
|
+
document.body.appendChild(link);
|
|
161
|
+
link.click();
|
|
162
|
+
document.body.removeChild(link);
|
|
163
|
+
URL.revokeObjectURL(url);
|
|
164
|
+
}, [localDocument, selectedThingId]);
|
|
165
|
+
const handleImport = React.useCallback(() => {
|
|
166
|
+
fileInputRef.current?.click();
|
|
167
|
+
}, []);
|
|
168
|
+
const handleFileChange = React.useCallback(
|
|
169
|
+
(event) => {
|
|
170
|
+
const file = event.target.files?.[0];
|
|
171
|
+
if (!file || !selectedType) return;
|
|
172
|
+
const reader = new FileReader();
|
|
173
|
+
reader.onload = (e) => {
|
|
174
|
+
try {
|
|
175
|
+
const content = e.target?.result;
|
|
176
|
+
const parsed = JSON.parse(content);
|
|
177
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
178
|
+
throw new Error("Invalid JSON: root must be an object");
|
|
179
|
+
}
|
|
180
|
+
const newId = `${Date.now()}`;
|
|
181
|
+
setSelectedThingId(newId);
|
|
182
|
+
setLocalDocument({
|
|
183
|
+
...parsed,
|
|
184
|
+
_id: newId,
|
|
185
|
+
_type: selectedType,
|
|
186
|
+
_ns: selectedNamespace
|
|
187
|
+
});
|
|
188
|
+
setHasUnsavedChanges(true);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
console.error("Failed to import document:", err);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
reader.readAsText(file);
|
|
194
|
+
event.target.value = "";
|
|
195
|
+
},
|
|
196
|
+
[selectedType, selectedNamespace]
|
|
197
|
+
);
|
|
198
|
+
const handleRefresh = React.useCallback(async () => {
|
|
199
|
+
await refetchThings();
|
|
200
|
+
setHasUnsavedChanges(false);
|
|
201
|
+
}, [refetchThings]);
|
|
202
|
+
React.useEffect(() => {
|
|
203
|
+
const mediaQuery = window.matchMedia("(max-width: 768px)");
|
|
204
|
+
const handleMediaChange = (e) => {
|
|
205
|
+
if (e.matches) {
|
|
206
|
+
setSidebarCollapsed(true);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
handleMediaChange(mediaQuery);
|
|
210
|
+
mediaQuery.addEventListener("change", handleMediaChange);
|
|
211
|
+
return () => mediaQuery.removeEventListener("change", handleMediaChange);
|
|
212
|
+
}, []);
|
|
213
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: cn("flex h-full overflow-x-auto bg-background", className), children: [
|
|
214
|
+
/* @__PURE__ */ jsx(
|
|
215
|
+
"input",
|
|
216
|
+
{
|
|
217
|
+
ref: fileInputRef,
|
|
218
|
+
type: "file",
|
|
219
|
+
accept: ".json,application/json",
|
|
220
|
+
className: "hidden",
|
|
221
|
+
onChange: handleFileChange
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
/* @__PURE__ */ jsx(
|
|
225
|
+
DocumentSidebar,
|
|
226
|
+
{
|
|
227
|
+
types: documentTypes,
|
|
228
|
+
documents: documentItems,
|
|
229
|
+
selectedType,
|
|
230
|
+
selectedDocumentId: selectedThingId,
|
|
231
|
+
onSelectDocument: handleSelectDocument,
|
|
232
|
+
onCreateDocument: handleCreateDocument,
|
|
233
|
+
collapsed: sidebarCollapsed
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden min-w-[320px]", children: [
|
|
237
|
+
/* @__PURE__ */ jsx(
|
|
238
|
+
DocumentViewToolbar,
|
|
239
|
+
{
|
|
240
|
+
typeName: selectedType,
|
|
241
|
+
documentName: localDocument ? localDocument.name : void 0,
|
|
242
|
+
documentId: selectedThingId,
|
|
243
|
+
hasUnsavedChanges,
|
|
244
|
+
isSaving,
|
|
245
|
+
hasDocument: !!localDocument,
|
|
246
|
+
types: documentTypeOptions,
|
|
247
|
+
sidebarCollapsed,
|
|
248
|
+
onSidebarToggle: () => setSidebarCollapsed(!sidebarCollapsed),
|
|
249
|
+
onSave: handleSave,
|
|
250
|
+
onRefresh: handleRefresh,
|
|
251
|
+
onImport: handleImport,
|
|
252
|
+
onExport: handleExport,
|
|
253
|
+
onDelete: handleDelete,
|
|
254
|
+
onCreateNew: handleCreateDocument
|
|
255
|
+
}
|
|
256
|
+
),
|
|
257
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: isLoadingThing ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
258
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }),
|
|
259
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Loading..." })
|
|
260
|
+
] }) }) : localDocument ? /* @__PURE__ */ jsx(
|
|
261
|
+
DocumentEditor,
|
|
262
|
+
{
|
|
263
|
+
document: localDocument,
|
|
264
|
+
onChange: handleDocumentChange,
|
|
265
|
+
className: "h-full"
|
|
266
|
+
}
|
|
267
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center text-muted-foreground", children: [
|
|
268
|
+
/* @__PURE__ */ jsx(Database, { className: "mb-4 h-12 w-12 opacity-20" }),
|
|
269
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No document selected" }),
|
|
270
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-xs", children: "Select a document from the sidebar or create a new one" })
|
|
271
|
+
] }) }),
|
|
272
|
+
/* @__PURE__ */ jsxs("footer", { className: "flex h-10 shrink-0 items-center justify-between border-t bg-muted/30 px-2 sm:px-4 gap-4", children: [
|
|
273
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground whitespace-nowrap shrink-0", children: selectedType && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
274
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: thingsResult?.data?.filter((t) => t.type === selectedType).length ?? 0 }),
|
|
275
|
+
" ",
|
|
276
|
+
"documents in ",
|
|
277
|
+
selectedType
|
|
278
|
+
] }) }),
|
|
279
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: localDocument && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
280
|
+
"ID:",
|
|
281
|
+
" ",
|
|
282
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-foreground", children: selectedThingId })
|
|
283
|
+
] }) })
|
|
284
|
+
] })
|
|
285
|
+
] })
|
|
286
|
+
] }) });
|
|
287
|
+
}
|
|
288
|
+
DocumentEditorView.displayName = "DocumentEditorView";
|
|
289
|
+
|
|
290
|
+
export { DocumentEditorView };
|
|
291
|
+
//# sourceMappingURL=chunk-QEXY4FZV.js.map
|
|
292
|
+
//# sourceMappingURL=chunk-QEXY4FZV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/document-editor/DocumentEditorView.tsx"],"names":[],"mappings":"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","file":"chunk-QEXY4FZV.js","sourcesContent":["'use client'\n\n/**\n * DocumentEditorView\n *\n * Edit individual Things with a document-based interface.\n * Uses @mdxui/admin DocumentEditor component for tree view + format editing.\n *\n * Matches the composable pattern from DataGridView.\n */\n\nimport * as React from 'react'\nimport {\n DocumentEditor,\n DocumentSidebar,\n DocumentViewToolbar,\n type DocumentItem,\n type DocumentType as DocumentTypeComponent,\n type DocumentTypeOption,\n} from '@mdxui/admin'\nimport { Database } from 'lucide-react'\nimport { TooltipProvider } from '@mdxui/primitives'\nimport { cn } from '../../utils'\nimport { useDO } from '../../providers/do-provider'\nimport { useThing, useThings, useTypes, useUpdateThing, useDeleteThing } from '../../hooks'\nimport type { Thing, SemanticType } from '../../types'\n\n// JSON types (local definition matching @mdxui/admin/editors/types)\ntype JsonPrimitive = string | number | boolean | null\ntype JsonArray = JsonValue[]\ntype JsonObject = { [key: string]: JsonValue }\ntype JsonValue = JsonPrimitive | JsonArray | JsonObject\n\n\nexport interface DocumentEditorViewProps {\n /** Initial namespace */\n initialNamespace?: string\n /** Initial type */\n initialType?: string\n /** Initial thing ID */\n initialId?: string\n /** Callback when save completes */\n onSave?: (thing: Thing) => void\n /** Callback when delete completes */\n onDelete?: () => void\n /** Callback when back is clicked */\n onBack?: () => void\n /** Custom className */\n className?: string\n}\n\n\n/** Convert SemanticType to DocumentType for sidebar */\nfunction toDocumentType(type: SemanticType): DocumentTypeComponent {\n return {\n id: type.id,\n name: type.name,\n label: type.label,\n }\n}\n\n/** Convert SemanticType to DocumentTypeOption for toolbar */\nfunction toDocumentTypeOption(type: SemanticType): DocumentTypeOption {\n return {\n id: type.id,\n name: type.name,\n label: type.label,\n }\n}\n\n/** Convert Thing to DocumentItem for sidebar */\nfunction toDocumentItem(thing: Thing): DocumentItem {\n return {\n id: thing.id,\n name: thing.name,\n type: thing.type,\n }\n}\n\n\nexport function DocumentEditorView({\n initialNamespace,\n initialType,\n initialId,\n onSave,\n onDelete,\n onBack: _onBack,\n className,\n}: DocumentEditorViewProps) {\n const { namespace: contextNamespace } = useDO()\n\n // State\n const [selectedNamespace] = React.useState(initialNamespace ?? contextNamespace)\n const [selectedType, setSelectedType] = React.useState<string | undefined>(initialType)\n const [selectedThingId, setSelectedThingId] = React.useState<string | undefined>(initialId)\n const [sidebarCollapsed, setSidebarCollapsed] = React.useState(false)\n const [hasUnsavedChanges, setHasUnsavedChanges] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n const [localDocument, setLocalDocument] = React.useState<JsonObject | null>(null)\n const fileInputRef = React.useRef<HTMLInputElement>(null)\n\n // Data fetching\n const { data: types } = useTypes({ ns: selectedNamespace })\n const { data: thingsResult, refetch: refetchThings } = useThings({\n ns: selectedNamespace,\n type: selectedType,\n })\n\n // Fetch selected thing\n const thingParams = selectedType && selectedThingId\n ? { ns: selectedNamespace, type: selectedType, id: selectedThingId }\n : { ns: '', type: '', id: '' }\n const { data: currentThing, isLoading: isLoadingThing } = useThing(thingParams)\n\n // Mutations\n const updateThing = useUpdateThing(\n selectedType && selectedThingId\n ? { ns: selectedNamespace, type: selectedType, id: selectedThingId }\n : { ns: 'temp', type: 'temp', id: 'temp' }\n )\n const deleteThing = useDeleteThing(\n selectedType && selectedThingId\n ? { ns: selectedNamespace, type: selectedType, id: selectedThingId }\n : { ns: 'temp', type: 'temp', id: 'temp' }\n )\n\n // Convert types for components\n const documentTypes = React.useMemo(\n () => types?.map(toDocumentType) ?? [],\n [types]\n )\n\n const documentTypeOptions = React.useMemo(\n () => types?.map(toDocumentTypeOption) ?? [],\n [types]\n )\n\n const documentItems = React.useMemo(\n () => thingsResult?.data?.map(toDocumentItem) ?? [],\n [thingsResult]\n )\n\n // Sync local document with fetched thing\n React.useEffect(() => {\n if (currentThing) {\n setLocalDocument({\n _id: currentThing.id,\n _ns: currentThing.ns,\n _type: currentThing.type,\n name: currentThing.name,\n createdAt: currentThing.createdAt instanceof Date\n ? currentThing.createdAt.toISOString()\n : currentThing.createdAt,\n updatedAt: currentThing.updatedAt instanceof Date\n ? currentThing.updatedAt.toISOString()\n : currentThing.updatedAt,\n ...(currentThing.data as JsonObject),\n })\n setHasUnsavedChanges(false)\n } else {\n setLocalDocument(null)\n }\n }, [currentThing])\n\n // Handlers\n const handleSelectDocument = React.useCallback((type: string, documentId: string) => {\n setSelectedType(type)\n setSelectedThingId(documentId)\n setHasUnsavedChanges(false)\n }, [])\n\n const handleDocumentChange = React.useCallback((updatedDoc: JsonObject) => {\n setLocalDocument(updatedDoc)\n setHasUnsavedChanges(true)\n }, [])\n\n const handleCreateDocument = React.useCallback((type: string) => {\n const newId = `${Date.now()}`\n setSelectedType(type)\n setSelectedThingId(newId)\n setLocalDocument({\n _id: newId,\n _type: type,\n _ns: selectedNamespace,\n name: 'New Thing',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })\n setHasUnsavedChanges(true)\n }, [selectedNamespace])\n\n const handleSave = React.useCallback(async () => {\n if (!localDocument || !selectedType || !selectedThingId) return\n\n setIsSaving(true)\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { _id, _ns, _type, createdAt, updatedAt, name, ...data } = localDocument\n await updateThing.mutateAsync({\n name: name as string,\n data,\n })\n setHasUnsavedChanges(false)\n await refetchThings()\n if (onSave && currentThing) {\n onSave({ ...currentThing, name: name as string, data })\n }\n } catch (err) {\n console.error('Failed to save:', err)\n } finally {\n setIsSaving(false)\n }\n }, [localDocument, selectedType, selectedThingId, updateThing, refetchThings, onSave, currentThing])\n\n const handleDelete = React.useCallback(async () => {\n if (!selectedType || !selectedThingId) return\n\n try {\n await deleteThing.mutateAsync()\n\n // Select another thing or clear selection\n const remainingThings = thingsResult?.data?.filter((t) => t.id !== selectedThingId) ?? []\n if (remainingThings.length > 0) {\n setSelectedThingId(remainingThings[0].id)\n setSelectedType(remainingThings[0].type)\n } else {\n setSelectedThingId(undefined)\n }\n\n setHasUnsavedChanges(false)\n await refetchThings()\n onDelete?.()\n } catch (err) {\n console.error('Failed to delete:', err)\n }\n }, [selectedType, selectedThingId, deleteThing, thingsResult, refetchThings, onDelete])\n\n const handleExport = React.useCallback(() => {\n if (!localDocument) return\n\n const json = JSON.stringify(localDocument, null, 2)\n const blob = new Blob([json], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const link = document.createElement('a')\n link.href = url\n link.download = `${selectedThingId}.json`\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n URL.revokeObjectURL(url)\n }, [localDocument, selectedThingId])\n\n const handleImport = React.useCallback(() => {\n fileInputRef.current?.click()\n }, [])\n\n const handleFileChange = React.useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0]\n if (!file || !selectedType) return\n\n const reader = new FileReader()\n reader.onload = (e) => {\n try {\n const content = e.target?.result as string\n const parsed = JSON.parse(content)\n\n if (typeof parsed !== 'object' || parsed === null) {\n throw new Error('Invalid JSON: root must be an object')\n }\n\n const newId = `${Date.now()}`\n setSelectedThingId(newId)\n setLocalDocument({\n ...parsed,\n _id: newId,\n _type: selectedType,\n _ns: selectedNamespace,\n })\n setHasUnsavedChanges(true)\n } catch (err) {\n console.error('Failed to import document:', err)\n }\n }\n reader.readAsText(file)\n event.target.value = ''\n },\n [selectedType, selectedNamespace]\n )\n\n const handleRefresh = React.useCallback(async () => {\n await refetchThings()\n setHasUnsavedChanges(false)\n }, [refetchThings])\n\n // Auto-collapse sidebar on medium screens\n React.useEffect(() => {\n const mediaQuery = window.matchMedia('(max-width: 768px)')\n const handleMediaChange = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) {\n setSidebarCollapsed(true)\n }\n }\n handleMediaChange(mediaQuery)\n mediaQuery.addEventListener('change', handleMediaChange)\n return () => mediaQuery.removeEventListener('change', handleMediaChange)\n }, [])\n\n return (\n <TooltipProvider>\n <div className={cn('flex h-full overflow-x-auto bg-background', className)}>\n {/* Hidden file input for import */}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".json,application/json\"\n className=\"hidden\"\n onChange={handleFileChange}\n />\n\n {/* Sidebar */}\n <DocumentSidebar\n types={documentTypes}\n documents={documentItems}\n selectedType={selectedType}\n selectedDocumentId={selectedThingId}\n onSelectDocument={handleSelectDocument}\n onCreateDocument={handleCreateDocument}\n collapsed={sidebarCollapsed}\n />\n\n {/* Main Content */}\n <div className=\"flex flex-1 flex-col overflow-hidden min-w-[320px]\">\n {/* Toolbar */}\n <DocumentViewToolbar\n typeName={selectedType}\n documentName={localDocument ? (localDocument.name as string) : undefined}\n documentId={selectedThingId}\n hasUnsavedChanges={hasUnsavedChanges}\n isSaving={isSaving}\n hasDocument={!!localDocument}\n types={documentTypeOptions}\n sidebarCollapsed={sidebarCollapsed}\n onSidebarToggle={() => setSidebarCollapsed(!sidebarCollapsed)}\n onSave={handleSave}\n onRefresh={handleRefresh}\n onImport={handleImport}\n onExport={handleExport}\n onDelete={handleDelete}\n onCreateNew={handleCreateDocument}\n />\n\n {/* Editor */}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n {isLoadingThing ? (\n <div className=\"flex h-full items-center justify-center\">\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent\" />\n <span className=\"text-sm text-muted-foreground\">Loading...</span>\n </div>\n </div>\n ) : localDocument ? (\n <DocumentEditor\n document={localDocument}\n onChange={handleDocumentChange}\n className=\"h-full\"\n />\n ) : (\n <div className=\"flex h-full flex-col items-center justify-center text-muted-foreground\">\n <Database className=\"mb-4 h-12 w-12 opacity-20\" />\n <p className=\"text-sm\">No document selected</p>\n <p className=\"mt-1 text-xs\">\n Select a document from the sidebar or create a new one\n </p>\n </div>\n )}\n </div>\n\n {/* Footer */}\n <footer className=\"flex h-10 shrink-0 items-center justify-between border-t bg-muted/30 px-2 sm:px-4 gap-4\">\n <div className=\"text-xs text-muted-foreground whitespace-nowrap shrink-0\">\n {selectedType && (\n <>\n <span className=\"font-medium text-foreground\">\n {thingsResult?.data?.filter((t) => t.type === selectedType).length ?? 0}\n </span>{' '}\n documents in {selectedType}\n </>\n )}\n </div>\n <div className=\"text-xs text-muted-foreground truncate\">\n {localDocument && (\n <>\n ID:{' '}\n <span className=\"font-mono text-foreground\">\n {selectedThingId}\n </span>\n </>\n )}\n </div>\n </footer>\n </div>\n </div>\n </TooltipProvider>\n )\n}\n\nDocumentEditorView.displayName = 'DocumentEditorView'\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, DropdownMenu, DropdownMenuTrigger, BreadcrumbEllipsis, DropdownMenuContent, DropdownMenuItem } from '@mdxui/primitives';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/components/breadcrumbs.tsx
|
|
6
|
+
function DefaultLink({ href, children, className, onClick }) {
|
|
7
|
+
return /* @__PURE__ */ jsx("a", { href, className, onClick, children });
|
|
8
|
+
}
|
|
9
|
+
function Breadcrumbs({
|
|
10
|
+
items,
|
|
11
|
+
LinkComponent = DefaultLink,
|
|
12
|
+
className,
|
|
13
|
+
maxItems = 4,
|
|
14
|
+
separator
|
|
15
|
+
}) {
|
|
16
|
+
if (!items || items.length === 0) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const shouldCollapse = items.length > maxItems;
|
|
20
|
+
const visibleItems = shouldCollapse ? [items[0], ...items.slice(-(maxItems - 1))] : items;
|
|
21
|
+
const hiddenItems = shouldCollapse ? items.slice(1, -(maxItems - 1)) : [];
|
|
22
|
+
return /* @__PURE__ */ jsx(Breadcrumb, { className, children: /* @__PURE__ */ jsx(BreadcrumbList, { children: visibleItems.map((item, index) => {
|
|
23
|
+
const isLast = index === visibleItems.length - 1;
|
|
24
|
+
const isFirst = index === 0;
|
|
25
|
+
if (shouldCollapse && isFirst) {
|
|
26
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
27
|
+
/* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) }),
|
|
28
|
+
/* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator }),
|
|
29
|
+
/* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
30
|
+
/* @__PURE__ */ jsx(
|
|
31
|
+
DropdownMenuTrigger,
|
|
32
|
+
{
|
|
33
|
+
className: "flex items-center gap-1 hover:text-foreground",
|
|
34
|
+
"aria-label": "Show hidden breadcrumbs",
|
|
35
|
+
children: /* @__PURE__ */ jsx(BreadcrumbEllipsis, { className: "size-4" })
|
|
36
|
+
}
|
|
37
|
+
),
|
|
38
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", children: hiddenItems.map((hiddenItem) => /* @__PURE__ */ jsx(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: hiddenItem.href || "#", children: hiddenItem.label }) }, hiddenItem.label)) })
|
|
39
|
+
] }) }),
|
|
40
|
+
/* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator })
|
|
41
|
+
] }, item.label);
|
|
42
|
+
}
|
|
43
|
+
return /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
44
|
+
/* @__PURE__ */ jsx(BreadcrumbItem, { children: isLast ? /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) : item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx(LinkComponent, { href: item.href, children: item.label }) }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) }),
|
|
45
|
+
!isLast && /* @__PURE__ */ jsx(BreadcrumbSeparator, { children: separator })
|
|
46
|
+
] }, item.label);
|
|
47
|
+
}) }) });
|
|
48
|
+
}
|
|
49
|
+
Breadcrumbs.displayName = "Breadcrumbs";
|
|
50
|
+
|
|
51
|
+
export { Breadcrumbs };
|
|
52
|
+
//# sourceMappingURL=chunk-SX4IIE2R.js.map
|
|
53
|
+
//# sourceMappingURL=chunk-SX4IIE2R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/breadcrumbs.tsx"],"names":[],"mappings":"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","file":"chunk-SX4IIE2R.js","sourcesContent":["'use client'\n\n/**\n * Breadcrumbs Component\n *\n * Router-agnostic breadcrumbs that can work with any Link component.\n * Uses @mdxui/primitives breadcrumb components under the hood.\n */\n\nimport {\n Breadcrumb,\n BreadcrumbEllipsis,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@mdxui/primitives'\nimport * as React from 'react'\n\n/**\n * Props for the Link component\n */\nexport interface BreadcrumbLinkProps {\n href: string\n children: React.ReactNode\n className?: string\n onClick?: () => void\n}\n\n/**\n * Single breadcrumb item configuration\n */\nexport interface BreadcrumbItemConfig {\n /** Display label */\n label: string\n /** Route path - last item should not have href */\n href?: string\n}\n\n/**\n * Props for the Breadcrumbs component\n */\nexport interface BreadcrumbsProps {\n /** Array of breadcrumb items */\n items: BreadcrumbItemConfig[]\n /** Custom link component (e.g., Next.js Link, TanStack Link) */\n LinkComponent?: React.ComponentType<BreadcrumbLinkProps>\n /** Additional class names */\n className?: string\n /** Maximum items to show before collapsing */\n maxItems?: number\n /** Custom separator element */\n separator?: React.ReactNode\n}\n\n/**\n * Default link component using a plain anchor tag\n */\nfunction DefaultLink({ href, children, className, onClick }: BreadcrumbLinkProps) {\n return (\n <a href={href} className={className} onClick={onClick}>\n {children}\n </a>\n )\n}\n\n/**\n * Breadcrumbs provides navigation context showing the user's location.\n *\n * Features:\n * - Router-agnostic - works with any Link component\n * - Automatic collapse with dropdown for long paths\n * - Accessible breadcrumb semantics\n * - Custom separator support\n *\n * @example\n * ```tsx\n * // With default anchor tags\n * <Breadcrumbs\n * items={[\n * { label: 'Home', href: '/' },\n * { label: 'Users', href: '/users' },\n * { label: 'John Doe' },\n * ]}\n * />\n *\n * // With @mdxui/navigation WebLink\n * import { WebLink } from '@mdxui/navigation/web'\n *\n * <Breadcrumbs\n * items={breadcrumbItems}\n * LinkComponent={({ href, children, className }) => (\n * <WebLink to={href} className={className}>{children}</WebLink>\n * )}\n * />\n *\n * // With Next.js Link\n * import NextLink from 'next/link'\n *\n * <Breadcrumbs\n * items={breadcrumbItems}\n * LinkComponent={NextLink}\n * />\n * ```\n */\nexport function Breadcrumbs({\n items,\n LinkComponent = DefaultLink,\n className,\n maxItems = 4,\n separator,\n}: BreadcrumbsProps) {\n // Handle empty items\n if (!items || items.length === 0) {\n return null\n }\n\n // Determine if we need to collapse items\n const shouldCollapse = items.length > maxItems\n const visibleItems = shouldCollapse\n ? [items[0], ...items.slice(-(maxItems - 1))]\n : items\n const hiddenItems = shouldCollapse\n ? items.slice(1, -(maxItems - 1))\n : []\n\n return (\n <Breadcrumb className={className}>\n <BreadcrumbList>\n {visibleItems.map((item, index) => {\n const isLast = index === visibleItems.length - 1\n const isFirst = index === 0\n\n // Insert ellipsis after first item if collapsing\n if (shouldCollapse && isFirst) {\n return (\n <React.Fragment key={item.label}>\n <BreadcrumbItem>\n {item.href ? (\n <BreadcrumbLink asChild>\n <LinkComponent href={item.href}>{item.label}</LinkComponent>\n </BreadcrumbLink>\n ) : (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>\n <BreadcrumbItem>\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex items-center gap-1 hover:text-foreground\"\n aria-label=\"Show hidden breadcrumbs\"\n >\n <BreadcrumbEllipsis className=\"size-4\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {hiddenItems.map((hiddenItem) => (\n <DropdownMenuItem key={hiddenItem.label} asChild>\n <LinkComponent href={hiddenItem.href || '#'}>\n {hiddenItem.label}\n </LinkComponent>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </BreadcrumbItem>\n <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>\n </React.Fragment>\n )\n }\n\n return (\n <React.Fragment key={item.label}>\n <BreadcrumbItem>\n {isLast ? (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n ) : item.href ? (\n <BreadcrumbLink asChild>\n <LinkComponent href={item.href}>{item.label}</LinkComponent>\n </BreadcrumbLink>\n ) : (\n <BreadcrumbPage>{item.label}</BreadcrumbPage>\n )}\n </BreadcrumbItem>\n {!isLast && <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>}\n </React.Fragment>\n )\n })}\n </BreadcrumbList>\n </Breadcrumb>\n )\n}\n\nBreadcrumbs.displayName = 'Breadcrumbs'\n"]}
|