@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.
Files changed (125) hide show
  1. package/dist/app/index.d.ts +32 -186
  2. package/dist/app/index.js +19 -11
  3. package/dist/auth/index.d.ts +48 -0
  4. package/dist/auth/index.js +4 -0
  5. package/dist/{breadcrumbs-C9Qn3S7d.d.ts → breadcrumbs-DltlCiHt.d.ts} +3 -3
  6. package/dist/chunk-2FWXT4HH.js +576 -0
  7. package/dist/chunk-2FWXT4HH.js.map +1 -0
  8. package/dist/chunk-5PC6U46L.js +604 -0
  9. package/dist/chunk-5PC6U46L.js.map +1 -0
  10. package/dist/chunk-63VCRTDQ.js +2505 -0
  11. package/dist/chunk-63VCRTDQ.js.map +1 -0
  12. package/dist/chunk-7J3RSIG4.js +178 -0
  13. package/dist/chunk-7J3RSIG4.js.map +1 -0
  14. package/dist/chunk-7QCTRNEJ.js +173 -0
  15. package/dist/chunk-7QCTRNEJ.js.map +1 -0
  16. package/dist/chunk-7TFHUKS7.js +66 -0
  17. package/dist/chunk-7TFHUKS7.js.map +1 -0
  18. package/dist/{chunk-LJIWB7KE.js → chunk-BU5HMHGQ.js} +3 -3
  19. package/dist/chunk-BU5HMHGQ.js.map +1 -0
  20. package/dist/{chunk-GGO5GW72.js → chunk-BZURBNFD.js} +305 -51
  21. package/dist/chunk-BZURBNFD.js.map +1 -0
  22. package/dist/{chunk-NA652ART.js → chunk-FM2RTAHV.js} +5 -65
  23. package/dist/chunk-FM2RTAHV.js.map +1 -0
  24. package/dist/{chunk-WMNT4OIE.js → chunk-HC4PBXV4.js} +131 -58
  25. package/dist/chunk-HC4PBXV4.js.map +1 -0
  26. package/dist/{chunk-Y52IEYVM.js → chunk-JPZ6RZJE.js} +78 -45
  27. package/dist/chunk-JPZ6RZJE.js.map +1 -0
  28. package/dist/{chunk-OVLO7UOH.js → chunk-KLN5OTQH.js} +168 -361
  29. package/dist/chunk-KLN5OTQH.js.map +1 -0
  30. package/dist/chunk-LCYBQR35.js +79 -0
  31. package/dist/chunk-LCYBQR35.js.map +1 -0
  32. package/dist/chunk-PJYGRD7N.js +216 -0
  33. package/dist/chunk-PJYGRD7N.js.map +1 -0
  34. package/dist/chunk-QEXY4FZV.js +292 -0
  35. package/dist/chunk-QEXY4FZV.js.map +1 -0
  36. package/dist/chunk-SX4IIE2R.js +53 -0
  37. package/dist/chunk-SX4IIE2R.js.map +1 -0
  38. package/dist/chunk-UCWMSKCW.js +901 -0
  39. package/dist/chunk-UCWMSKCW.js.map +1 -0
  40. package/dist/{chunk-5SHZZC7L.js → chunk-WC6SFBAF.js} +59 -6
  41. package/dist/chunk-WC6SFBAF.js.map +1 -0
  42. package/dist/chunk-WIKU77ZY.js +18 -0
  43. package/dist/chunk-WIKU77ZY.js.map +1 -0
  44. package/dist/chunk-X3AWNFBF.js +47 -0
  45. package/dist/chunk-X3AWNFBF.js.map +1 -0
  46. package/dist/chunk-ZZTQGMLX.js +23 -0
  47. package/dist/chunk-ZZTQGMLX.js.map +1 -0
  48. package/dist/{lib → client}/index.d.ts +97 -345
  49. package/dist/client/index.js +3 -0
  50. package/dist/common-DW_JM2dW.d.ts +454 -0
  51. package/dist/components/index.d.ts +11 -2
  52. package/dist/components/index.js +8 -3
  53. package/dist/{config-CxvpD8Y6.d.ts → config-DB14_LhF.d.ts} +1 -1
  54. package/dist/{do-D27i5bU0.d.ts → do-D37hbmL9.d.ts} +6 -14
  55. package/dist/dotdo-client-2DkwXHM2.d.ts +344 -0
  56. package/dist/errors-BOY11CJs.d.ts +373 -0
  57. package/dist/features/data-browser/index.d.ts +51 -0
  58. package/dist/features/data-browser/index.js +12 -0
  59. package/dist/features/data-browser/index.js.map +1 -0
  60. package/dist/features/data-grid/index.d.ts +22 -0
  61. package/dist/features/data-grid/index.js +12 -0
  62. package/dist/features/data-grid/index.js.map +1 -0
  63. package/dist/features/document-editor/index.d.ts +26 -0
  64. package/dist/features/document-editor/index.js +12 -0
  65. package/dist/features/document-editor/index.js.map +1 -0
  66. package/dist/features/function-editor/index.d.ts +215 -0
  67. package/dist/features/function-editor/index.js +7 -0
  68. package/dist/features/function-editor/index.js.map +1 -0
  69. package/dist/hooks/index.d.ts +64 -7
  70. package/dist/hooks/index.js +8 -7
  71. package/dist/hooks/things/index.d.ts +5 -297
  72. package/dist/hooks/things/index.js +6 -6
  73. package/dist/index-C0m9UI6W.d.ts +444 -0
  74. package/dist/index.d.ts +42 -32
  75. package/dist/index.js +21 -13
  76. package/dist/providers/index.d.ts +16 -28
  77. package/dist/providers/index.js +3 -3
  78. package/dist/schemas/index.d.ts +4551 -109
  79. package/dist/schemas/index.js +2 -260
  80. package/dist/schemas/index.js.map +1 -1
  81. package/dist/shell/index.d.ts +92 -0
  82. package/dist/shell/index.js +6 -0
  83. package/dist/shell/index.js.map +1 -0
  84. package/dist/{thing-BF25aUtJ.d.ts → thing-Dc3AE2XI.d.ts} +22 -22
  85. package/dist/thing-adapters-aMjF0h9u.d.ts +1214 -0
  86. package/dist/types/index.d.ts +954 -7521
  87. package/dist/types/index.js +2 -2
  88. package/dist/ui-filters-BvrjMP_U.d.ts +108 -0
  89. package/dist/{errors-DratdVIz.d.ts → utils/index.d.ts} +38 -77
  90. package/dist/utils/index.js +4 -0
  91. package/dist/utils/index.js.map +1 -0
  92. package/dist-app/assets/index-DWX3479M.js +7 -0
  93. package/dist-app/assets/index-DWX3479M.js.map +1 -0
  94. package/dist-app/assets/main-BptePr_C.js +318 -0
  95. package/dist-app/assets/main-BptePr_C.js.map +1 -0
  96. package/dist-app/assets/main-CS9jgKzj.css +1 -0
  97. package/dist-app/index.html +38 -0
  98. package/package.json +32 -19
  99. package/dist/agents-2_r9e9i7.d.ts +0 -1043
  100. package/dist/capnweb-client-Bq78FtEA.d.ts +0 -229
  101. package/dist/chunk-3XKYQRXY.js +0 -192
  102. package/dist/chunk-3XKYQRXY.js.map +0 -1
  103. package/dist/chunk-4KXVN3EQ.js +0 -56
  104. package/dist/chunk-4KXVN3EQ.js.map +0 -1
  105. package/dist/chunk-5SHZZC7L.js.map +0 -1
  106. package/dist/chunk-7UFINK3Q.js +0 -1994
  107. package/dist/chunk-7UFINK3Q.js.map +0 -1
  108. package/dist/chunk-GGO5GW72.js.map +0 -1
  109. package/dist/chunk-JJLAES6W.js +0 -76
  110. package/dist/chunk-JJLAES6W.js.map +0 -1
  111. package/dist/chunk-KT52UU3U.js +0 -985
  112. package/dist/chunk-KT52UU3U.js.map +0 -1
  113. package/dist/chunk-LJIWB7KE.js.map +0 -1
  114. package/dist/chunk-NA652ART.js.map +0 -1
  115. package/dist/chunk-OVLO7UOH.js.map +0 -1
  116. package/dist/chunk-VRLUXCLD.js +0 -31
  117. package/dist/chunk-VRLUXCLD.js.map +0 -1
  118. package/dist/chunk-WMNT4OIE.js.map +0 -1
  119. package/dist/chunk-Y52IEYVM.js.map +0 -1
  120. package/dist/lib/index.js +0 -6
  121. package/dist/query-keys-CZNFikIi.d.ts +0 -153
  122. package/dist/views/index.d.ts +0 -131
  123. package/dist/views/index.js +0 -11
  124. /package/dist/{lib → auth}/index.js.map +0 -0
  125. /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"]}