@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,901 @@
1
+ import { useNamespaces, useTypes } from './chunk-FM2RTAHV.js';
2
+ import { useCreateThing, useThings } from './chunk-WC6SFBAF.js';
3
+ import { useDO } from './chunk-HC4PBXV4.js';
4
+ import { cn } from './chunk-JPZ6RZJE.js';
5
+ import * as React3 from 'react';
6
+ import { parseQuery, applyQueryFilter, DataSidebar, DataSidebarTrigger, QuerySearch, ViewSwitcher, DataFilterPopover, DatabaseListView, DatabaseTableView, DatabaseCardView, DatabaseCodeView } from '@mdxui/admin';
7
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Input, Textarea, DialogFooter, Button, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, Badge, ScrollArea, SheetFooter, Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, AlertDialog, AlertDialogTrigger, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem, DropdownMenuItem } from '@mdxui/primitives';
8
+ import { Hash, Save, Pencil, Copy, Shapes, X, Trash2, Columns3, Plus, MoreVertical, Download, RefreshCw, ExternalLink, Calendar, Clock } from 'lucide-react';
9
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
+
11
+ function CreateDialog({
12
+ open,
13
+ onOpenChange,
14
+ namespace,
15
+ defaultType,
16
+ types,
17
+ onCreated
18
+ }) {
19
+ const [selectedType, setSelectedType] = React3.useState(defaultType ?? "");
20
+ const [name, setName] = React3.useState("");
21
+ const [dataJson, setDataJson] = React3.useState("{}");
22
+ const [jsonError, setJsonError] = React3.useState(null);
23
+ const createMutation = useCreateThing();
24
+ React3.useEffect(() => {
25
+ if (open) {
26
+ setSelectedType(defaultType ?? "");
27
+ setName("");
28
+ setDataJson("{}");
29
+ setJsonError(null);
30
+ }
31
+ }, [open, defaultType]);
32
+ const handleSubmit = async (e) => {
33
+ e.preventDefault();
34
+ setJsonError(null);
35
+ let parsedData;
36
+ try {
37
+ parsedData = JSON.parse(dataJson);
38
+ } catch {
39
+ setJsonError("Invalid JSON format");
40
+ return;
41
+ }
42
+ try {
43
+ const result = await createMutation.mutateAsync({
44
+ ns: namespace,
45
+ type: selectedType,
46
+ name: name.trim(),
47
+ data: parsedData
48
+ });
49
+ onCreated?.(result);
50
+ onOpenChange(false);
51
+ } catch (error) {
52
+ console.error("Failed to create thing:", error);
53
+ }
54
+ };
55
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { children: [
56
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
57
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Create New Thing" }),
58
+ /* @__PURE__ */ jsxs(DialogDescription, { children: [
59
+ 'Create a new thing in namespace "',
60
+ namespace,
61
+ '"'
62
+ ] })
63
+ ] }),
64
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
65
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
66
+ /* @__PURE__ */ jsx(Label, { htmlFor: "type", children: "Type" }),
67
+ /* @__PURE__ */ jsxs(Select, { value: selectedType, onValueChange: setSelectedType, children: [
68
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a type" }) }),
69
+ /* @__PURE__ */ jsx(SelectContent, { children: types.map((type) => /* @__PURE__ */ jsx(SelectItem, { value: type.name, children: type.label }, type.id)) })
70
+ ] })
71
+ ] }),
72
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
73
+ /* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "Name" }),
74
+ /* @__PURE__ */ jsx(
75
+ Input,
76
+ {
77
+ id: "name",
78
+ value: name,
79
+ onChange: (e) => setName(e.target.value),
80
+ placeholder: "Enter a name",
81
+ required: true
82
+ }
83
+ )
84
+ ] }),
85
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
86
+ /* @__PURE__ */ jsx(Label, { htmlFor: "data", children: "Data (JSON)" }),
87
+ /* @__PURE__ */ jsx(
88
+ Textarea,
89
+ {
90
+ id: "data",
91
+ value: dataJson,
92
+ onChange: (e) => {
93
+ setDataJson(e.target.value);
94
+ setJsonError(null);
95
+ },
96
+ placeholder: '{"key": "value"}',
97
+ className: "font-mono text-sm min-h-[100px]"
98
+ }
99
+ ),
100
+ jsonError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: jsonError })
101
+ ] }),
102
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
103
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
104
+ /* @__PURE__ */ jsx(
105
+ Button,
106
+ {
107
+ type: "submit",
108
+ disabled: !selectedType || !name.trim() || createMutation.isLoading,
109
+ children: createMutation.isLoading ? "Creating..." : "Create"
110
+ }
111
+ )
112
+ ] })
113
+ ] })
114
+ ] }) });
115
+ }
116
+
117
+ // src/features/data-browser/utils/date-formatting.ts
118
+ function isISODateString(value) {
119
+ if (typeof value !== "string") return false;
120
+ const date = new Date(value);
121
+ return !isNaN(date.getTime()) && value.includes("T");
122
+ }
123
+ function formatDate(dateValue) {
124
+ const date = typeof dateValue === "string" ? new Date(dateValue) : dateValue;
125
+ const now = /* @__PURE__ */ new Date();
126
+ const diffMs = now.getTime() - date.getTime();
127
+ const diffMins = Math.floor(diffMs / 6e4);
128
+ const diffHours = Math.floor(diffMins / 60);
129
+ const diffDays = Math.floor(diffHours / 24);
130
+ let relative;
131
+ if (diffMins < 1) relative = "Just now";
132
+ else if (diffMins < 60) relative = `${diffMins} minute${diffMins !== 1 ? "s" : ""} ago`;
133
+ else if (diffHours < 24) relative = `${diffHours} hour${diffHours !== 1 ? "s" : ""} ago`;
134
+ else if (diffDays < 7) relative = `${diffDays} day${diffDays !== 1 ? "s" : ""} ago`;
135
+ else
136
+ relative = date.toLocaleDateString("en-US", {
137
+ month: "short",
138
+ day: "numeric",
139
+ year: "numeric"
140
+ });
141
+ return {
142
+ date: date.toLocaleDateString("en-US", {
143
+ weekday: "short",
144
+ month: "short",
145
+ day: "numeric",
146
+ year: "numeric"
147
+ }),
148
+ time: date.toLocaleTimeString("en-US", {
149
+ hour: "2-digit",
150
+ minute: "2-digit"
151
+ }),
152
+ relative
153
+ };
154
+ }
155
+ function formatFieldName(key) {
156
+ return key.replace(/([A-Z])/g, " $1").replace(/_/g, " ").replace(/^./, (str) => str.toUpperCase()).trim();
157
+ }
158
+
159
+ // src/features/data-browser/utils/export.ts
160
+ function exportToJSON(data, filename) {
161
+ const json = JSON.stringify(data, null, 2);
162
+ const blob = new Blob([json], { type: "application/json" });
163
+ const url = URL.createObjectURL(blob);
164
+ const link = document.createElement("a");
165
+ link.href = url;
166
+ link.download = `${filename}.json`;
167
+ document.body.appendChild(link);
168
+ link.click();
169
+ document.body.removeChild(link);
170
+ URL.revokeObjectURL(url);
171
+ }
172
+ function DetailSheet({ open, onOpenChange, thing, onEdit, onSave }) {
173
+ const [isEditing, setIsEditing] = React3.useState(false);
174
+ const [editedName, setEditedName] = React3.useState("");
175
+ const [editedDataJson, setEditedDataJson] = React3.useState("");
176
+ const [jsonError, setJsonError] = React3.useState(null);
177
+ const [isSaving, setIsSaving] = React3.useState(false);
178
+ React3.useEffect(() => {
179
+ if (thing && open) {
180
+ setEditedName(thing.name);
181
+ setEditedDataJson(JSON.stringify(thing.data ?? {}, null, 2));
182
+ setJsonError(null);
183
+ }
184
+ if (!open) {
185
+ setIsEditing(false);
186
+ }
187
+ }, [thing, open]);
188
+ const handleStartEdit = () => {
189
+ if (thing) {
190
+ setEditedName(thing.name);
191
+ setEditedDataJson(JSON.stringify(thing.data ?? {}, null, 2));
192
+ setJsonError(null);
193
+ setIsEditing(true);
194
+ }
195
+ };
196
+ const handleCancelEdit = () => {
197
+ if (thing) {
198
+ setEditedName(thing.name);
199
+ setEditedDataJson(JSON.stringify(thing.data ?? {}, null, 2));
200
+ setJsonError(null);
201
+ }
202
+ setIsEditing(false);
203
+ };
204
+ const handleSave = async () => {
205
+ if (!thing || !onSave) return;
206
+ setJsonError(null);
207
+ let parsedData;
208
+ try {
209
+ parsedData = JSON.parse(editedDataJson);
210
+ } catch {
211
+ setJsonError("Invalid JSON format");
212
+ return;
213
+ }
214
+ const updates = {};
215
+ if (editedName !== thing.name) {
216
+ updates.name = editedName;
217
+ }
218
+ if (JSON.stringify(parsedData) !== JSON.stringify(thing.data)) {
219
+ updates.data = parsedData;
220
+ }
221
+ if (Object.keys(updates).length === 0) {
222
+ setIsEditing(false);
223
+ return;
224
+ }
225
+ setIsSaving(true);
226
+ try {
227
+ await onSave(thing, updates);
228
+ setIsEditing(false);
229
+ } catch (error) {
230
+ console.error("Failed to save:", error);
231
+ } finally {
232
+ setIsSaving(false);
233
+ }
234
+ };
235
+ if (!thing) return null;
236
+ const renderValue = (_key, value) => {
237
+ if (value === null || value === void 0) {
238
+ return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic text-sm", children: "null" });
239
+ }
240
+ if (typeof value === "boolean") {
241
+ return /* @__PURE__ */ jsx(Badge, { variant: value ? "default" : "secondary", children: value ? "Yes" : "No" });
242
+ }
243
+ if (Array.isArray(value)) {
244
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: value.map((v, i) => /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-xs font-normal", children: String(v) }, String(i))) });
245
+ }
246
+ if (typeof value === "object") {
247
+ return /* @__PURE__ */ jsx("pre", { className: "text-xs bg-muted/50 p-3 rounded-[var(--radius)] overflow-auto max-h-48 font-mono", children: JSON.stringify(value, null, 2) });
248
+ }
249
+ if (typeof value === "string" && (value.startsWith("http://") || value.startsWith("https://"))) {
250
+ return /* @__PURE__ */ jsxs(
251
+ "a",
252
+ {
253
+ href: value,
254
+ target: "_blank",
255
+ rel: "noopener noreferrer",
256
+ className: "text-primary hover:underline inline-flex items-center gap-1.5 break-all",
257
+ children: [
258
+ value,
259
+ /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3 shrink-0" })
260
+ ]
261
+ }
262
+ );
263
+ }
264
+ if (typeof value === "string" && isISODateString(value)) {
265
+ const formatted = formatDate(value);
266
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
267
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
268
+ /* @__PURE__ */ jsx(Calendar, { className: "h-3.5 w-3.5 text-muted-foreground" }),
269
+ /* @__PURE__ */ jsx("span", { children: formatted.date })
270
+ ] }),
271
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
272
+ /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5" }),
273
+ /* @__PURE__ */ jsx("span", { children: formatted.time }),
274
+ /* @__PURE__ */ jsxs("span", { className: "text-xs", children: [
275
+ "(",
276
+ formatted.relative,
277
+ ")"
278
+ ] })
279
+ ] })
280
+ ] });
281
+ }
282
+ if (value instanceof Date) {
283
+ const formatted = formatDate(value);
284
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
285
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
286
+ /* @__PURE__ */ jsx(Calendar, { className: "h-3.5 w-3.5 text-muted-foreground" }),
287
+ /* @__PURE__ */ jsx("span", { children: formatted.date })
288
+ ] }),
289
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
290
+ /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5" }),
291
+ /* @__PURE__ */ jsx("span", { children: formatted.time }),
292
+ /* @__PURE__ */ jsxs("span", { className: "text-xs", children: [
293
+ "(",
294
+ formatted.relative,
295
+ ")"
296
+ ] })
297
+ ] })
298
+ ] });
299
+ }
300
+ if (typeof value === "number") {
301
+ return /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: value.toLocaleString() });
302
+ }
303
+ return /* @__PURE__ */ jsx("span", { className: "break-all", children: String(value) });
304
+ };
305
+ return /* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs(SheetContent, { className: "sm:max-w-lg flex flex-col p-0", children: [
306
+ /* @__PURE__ */ jsx(SheetHeader, { className: "px-6 py-4 border-b bg-muted/30", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4 pr-8", children: [
307
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1 min-w-0", children: [
308
+ isEditing ? /* @__PURE__ */ jsx(
309
+ Input,
310
+ {
311
+ value: editedName,
312
+ onChange: (e) => setEditedName(e.target.value),
313
+ className: "text-lg font-semibold h-auto py-1"
314
+ }
315
+ ) : /* @__PURE__ */ jsx(SheetTitle, { className: "text-lg truncate", children: thing.name }),
316
+ /* @__PURE__ */ jsxs(SheetDescription, { className: "flex items-center gap-2", children: [
317
+ /* @__PURE__ */ jsx(Hash, { className: "h-3.5 w-3.5" }),
318
+ /* @__PURE__ */ jsx("span", { className: "font-mono text-xs", children: thing.id })
319
+ ] })
320
+ ] }),
321
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
322
+ isEditing && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: "Editing" }),
323
+ /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "capitalize shrink-0", children: thing.type })
324
+ ] })
325
+ ] }) }),
326
+ /* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxs("div", { className: "p-4 space-y-4", children: [
327
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
328
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Namespace" }),
329
+ renderValue("ns", thing.ns)
330
+ ] }),
331
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
332
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Type" }),
333
+ renderValue("type", thing.type)
334
+ ] }),
335
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
336
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Created" }),
337
+ renderValue("createdAt", thing.createdAt)
338
+ ] }),
339
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
340
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Updated" }),
341
+ renderValue("updatedAt", thing.updatedAt)
342
+ ] }),
343
+ isEditing ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
344
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Data (JSON)" }),
345
+ /* @__PURE__ */ jsx(
346
+ Textarea,
347
+ {
348
+ value: editedDataJson,
349
+ onChange: (e) => {
350
+ setEditedDataJson(e.target.value);
351
+ setJsonError(null);
352
+ },
353
+ className: "font-mono text-sm min-h-[200px]"
354
+ }
355
+ ),
356
+ jsonError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: jsonError })
357
+ ] }) : thing.data && Object.entries(thing.data).filter(([key]) => !key.startsWith("@")).map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 py-2", children: [
358
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: formatFieldName(key) }),
359
+ renderValue(key, value)
360
+ ] }, key))
361
+ ] }) }),
362
+ /* @__PURE__ */ jsx(SheetFooter, { className: "border-t px-6 py-4 bg-muted/30", children: /* @__PURE__ */ jsx("div", { className: "flex w-full items-center justify-between gap-3", children: isEditing ? /* @__PURE__ */ jsxs(Fragment, { children: [
363
+ /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: handleCancelEdit, disabled: isSaving, children: "Cancel" }),
364
+ /* @__PURE__ */ jsx(
365
+ Button,
366
+ {
367
+ size: "sm",
368
+ onClick: handleSave,
369
+ disabled: isSaving || !editedName.trim(),
370
+ className: "gap-2",
371
+ children: isSaving ? /* @__PURE__ */ jsx(Fragment, { children: "Saving..." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
372
+ /* @__PURE__ */ jsx(Save, { className: "h-4 w-4" }),
373
+ "Save"
374
+ ] })
375
+ }
376
+ )
377
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
378
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
379
+ onSave && /* @__PURE__ */ jsxs(
380
+ Button,
381
+ {
382
+ variant: "outline",
383
+ size: "sm",
384
+ className: "gap-2",
385
+ onClick: handleStartEdit,
386
+ children: [
387
+ /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" }),
388
+ "Edit"
389
+ ]
390
+ }
391
+ ),
392
+ onEdit && !onSave && /* @__PURE__ */ jsxs(
393
+ Button,
394
+ {
395
+ variant: "outline",
396
+ size: "sm",
397
+ className: "gap-2",
398
+ onClick: () => onEdit(thing),
399
+ children: [
400
+ /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" }),
401
+ "Edit"
402
+ ]
403
+ }
404
+ ),
405
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
406
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
407
+ Button,
408
+ {
409
+ variant: "outline",
410
+ size: "sm",
411
+ onClick: () => {
412
+ navigator.clipboard.writeText(JSON.stringify(thing, null, 2));
413
+ },
414
+ children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
415
+ }
416
+ ) }),
417
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Copy as JSON" })
418
+ ] })
419
+ ] }),
420
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", onClick: () => onOpenChange(false), children: "Close" })
421
+ ] }) }) })
422
+ ] }) });
423
+ }
424
+ function getTableColumns() {
425
+ return [
426
+ { accessorKey: "name", header: "Name", type: "text" },
427
+ { accessorKey: "type", header: "Type", type: "text" },
428
+ { accessorKey: "createdAt", header: "Created", type: "date" },
429
+ { accessorKey: "updatedAt", header: "Updated", type: "date" }
430
+ ];
431
+ }
432
+ function DataBrowserView({
433
+ initialNamespace,
434
+ initialType,
435
+ onSelect,
436
+ onOpen,
437
+ className
438
+ }) {
439
+ const { namespace: contextNamespace, client } = useDO();
440
+ const selectedNamespace = initialNamespace ?? contextNamespace;
441
+ const [selectedType, setSelectedType] = React3.useState(
442
+ initialType
443
+ );
444
+ const [viewType, setViewType] = React3.useState("table");
445
+ const [searchQuery, setSearchQuery] = React3.useState("");
446
+ const [selectedIds, setSelectedIds] = React3.useState([]);
447
+ const [sidebarCollapsed, setSidebarCollapsed] = React3.useState(false);
448
+ const [detailThing, setDetailThing] = React3.useState(null);
449
+ const [detailOpen, setDetailOpen] = React3.useState(false);
450
+ const [recentQueries, setRecentQueries] = React3.useState([]);
451
+ const [createDialogOpen, setCreateDialogOpen] = React3.useState(false);
452
+ const [filterPopoverOpen, setFilterPopoverOpen] = React3.useState(false);
453
+ const [filterConditions, setFilterConditions] = React3.useState([]);
454
+ const [hiddenColumns, setHiddenColumns] = React3.useState(
455
+ /* @__PURE__ */ new Set()
456
+ );
457
+ const { error: namespacesError } = useNamespaces();
458
+ const { data: types, error: typesError } = useTypes({ ns: selectedNamespace });
459
+ const filter = React3.useMemo(() => {
460
+ const f = { ns: selectedNamespace };
461
+ if (selectedType) f.type = selectedType;
462
+ if (searchQuery) f.nameSearch = searchQuery;
463
+ return f;
464
+ }, [selectedNamespace, selectedType, searchQuery]);
465
+ const { data: thingsResult, isLoading, error: thingsError, refetch } = useThings(filter);
466
+ const connectionError = namespacesError || typesError || thingsError;
467
+ const queryConditions = React3.useMemo(() => {
468
+ return parseQuery(searchQuery);
469
+ }, [searchQuery]);
470
+ const data = React3.useMemo(() => {
471
+ if (!thingsResult?.data) return [];
472
+ let filtered = thingsResult.data.map((thing) => ({
473
+ id: thing.id,
474
+ ns: thing.ns,
475
+ type: thing.type,
476
+ name: thing.name,
477
+ createdAt: thing.createdAt,
478
+ updatedAt: thing.updatedAt,
479
+ ...thing.data
480
+ }));
481
+ if (queryConditions.length > 0) {
482
+ filtered = applyQueryFilter(filtered, queryConditions);
483
+ }
484
+ if (filterConditions.length > 0) {
485
+ filtered = filtered.filter((item) => {
486
+ return filterConditions.every((condition) => {
487
+ const fieldValue = item[condition.field];
488
+ const strValue = String(fieldValue ?? "").toLowerCase();
489
+ const conditionValue = condition.value.toLowerCase();
490
+ switch (condition.operator) {
491
+ case "equals":
492
+ return strValue === conditionValue;
493
+ case "contains":
494
+ return strValue.includes(conditionValue);
495
+ case "startsWith":
496
+ return strValue.startsWith(conditionValue);
497
+ case "endsWith":
498
+ return strValue.endsWith(conditionValue);
499
+ case "isEmpty":
500
+ return !fieldValue || strValue === "";
501
+ case "isNotEmpty":
502
+ return !!fieldValue && strValue !== "";
503
+ default:
504
+ return true;
505
+ }
506
+ });
507
+ });
508
+ }
509
+ return filtered;
510
+ }, [thingsResult, queryConditions, filterConditions]);
511
+ const allTableColumns = React3.useMemo(() => getTableColumns(), []);
512
+ const tableColumns = React3.useMemo(
513
+ () => allTableColumns.filter((col) => !hiddenColumns.has(col.accessorKey)),
514
+ [allTableColumns, hiddenColumns]
515
+ );
516
+ const queryFields = React3.useMemo(() => {
517
+ return ["name", "type", "ns", "createdAt", "updatedAt"];
518
+ }, []);
519
+ const handleExportSelected = React3.useCallback(() => {
520
+ if (selectedIds.length === 0) return;
521
+ const exportData = data.filter((d) => selectedIds.includes(d.id));
522
+ const filename = `${selectedNamespace}-${selectedType ?? "all"}-selected-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
523
+ exportToJSON(exportData, filename);
524
+ }, [data, selectedIds, selectedNamespace, selectedType]);
525
+ const handleExportAll = React3.useCallback(() => {
526
+ const filename = `${selectedNamespace}-${selectedType ?? "all"}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`;
527
+ exportToJSON(data, filename);
528
+ }, [data, selectedNamespace, selectedType]);
529
+ const handleSaveThing = React3.useCallback(
530
+ async (thing, updates) => {
531
+ await client.Thing.update({
532
+ ns: thing.ns,
533
+ type: thing.type,
534
+ id: thing.id,
535
+ ...updates
536
+ });
537
+ await refetch();
538
+ if (detailThing?.id === thing.id) {
539
+ const updated = thingsResult?.data?.find((t) => t.id === thing.id);
540
+ if (updated) {
541
+ setDetailThing(updated);
542
+ }
543
+ }
544
+ },
545
+ [client, refetch, detailThing, thingsResult]
546
+ );
547
+ const handleItemClick = React3.useCallback(
548
+ (item) => {
549
+ const thing = thingsResult?.data?.find((t) => t.id === item.id);
550
+ if (thing) {
551
+ setDetailThing(thing);
552
+ setDetailOpen(true);
553
+ onSelect?.(thing);
554
+ }
555
+ },
556
+ [thingsResult, onSelect]
557
+ );
558
+ const handleClearSelection = React3.useCallback(() => {
559
+ setSelectedIds([]);
560
+ }, []);
561
+ const handleSelectRecentQuery = React3.useCallback((query) => {
562
+ setRecentQueries((prev) => {
563
+ const filtered = prev.filter((q) => q !== query);
564
+ return [query, ...filtered].slice(0, 10);
565
+ });
566
+ setSearchQuery(query);
567
+ }, []);
568
+ React3.useEffect(() => {
569
+ const mediaQuery = window.matchMedia("(max-width: 768px)");
570
+ const handleMediaChange = (e) => {
571
+ if (e.matches) {
572
+ setSidebarCollapsed(true);
573
+ }
574
+ };
575
+ handleMediaChange(mediaQuery);
576
+ mediaQuery.addEventListener("change", handleMediaChange);
577
+ return () => mediaQuery.removeEventListener("change", handleMediaChange);
578
+ }, []);
579
+ return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: cn("flex h-full bg-background", className), children: [
580
+ /* @__PURE__ */ jsx(
581
+ DataSidebar,
582
+ {
583
+ title: "Types",
584
+ items: types?.map(
585
+ (t) => ({
586
+ id: t.id,
587
+ name: t.name,
588
+ label: t.label
589
+ })
590
+ ),
591
+ selectedItem: selectedType,
592
+ onSelectItem: setSelectedType,
593
+ collapsed: sidebarCollapsed,
594
+ onCollapsedChange: setSidebarCollapsed,
595
+ allItemsLabel: "All Types",
596
+ emptyMessage: "No types found"
597
+ }
598
+ ),
599
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
600
+ /* @__PURE__ */ jsxs("header", { className: "flex h-12 shrink-0 items-center gap-3 border-b px-4", children: [
601
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
602
+ /* @__PURE__ */ jsx(
603
+ DataSidebarTrigger,
604
+ {
605
+ collapsed: sidebarCollapsed,
606
+ onToggle: () => setSidebarCollapsed(!sidebarCollapsed)
607
+ }
608
+ ),
609
+ /* @__PURE__ */ jsx(Shapes, { className: "h-4 w-4 text-muted-foreground hidden sm:block" }),
610
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold hidden sm:inline", children: selectedType ?? "All Things" })
611
+ ] }),
612
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:flex flex-1" }),
613
+ /* @__PURE__ */ jsx(
614
+ QuerySearch,
615
+ {
616
+ query: searchQuery,
617
+ onQueryChange: setSearchQuery,
618
+ conditions: queryConditions,
619
+ fields: queryFields,
620
+ recentQueries,
621
+ onSelectRecentQuery: handleSelectRecentQuery,
622
+ placeholder: "Search... (e.g., type: User)",
623
+ className: "flex-1 min-w-0 sm:w-64 sm:flex-none md:w-80 lg:w-[480px]"
624
+ }
625
+ ),
626
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:flex flex-1" }),
627
+ selectedIds.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 animate-in fade-in-0 slide-in-from-left-2 duration-200 shrink-0", children: [
628
+ /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "gap-1 pl-2 pr-1", children: [
629
+ /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: selectedIds.length }),
630
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "selected" }),
631
+ /* @__PURE__ */ jsx(
632
+ "button",
633
+ {
634
+ type: "button",
635
+ onClick: handleClearSelection,
636
+ className: "ml-0.5 rounded-sm p-0.5 hover:bg-muted-foreground/20 transition-colors",
637
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
638
+ }
639
+ )
640
+ ] }),
641
+ /* @__PURE__ */ jsxs(AlertDialog, { children: [
642
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
643
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", children: /* @__PURE__ */ jsx(Trash2, { className: "h-4 w-4 text-destructive" }) }) }) }),
644
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Delete selected" })
645
+ ] }),
646
+ /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
647
+ /* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
648
+ /* @__PURE__ */ jsxs(AlertDialogTitle, { children: [
649
+ "Delete ",
650
+ selectedIds.length,
651
+ " item",
652
+ selectedIds.length !== 1 ? "s" : "",
653
+ "?"
654
+ ] }),
655
+ /* @__PURE__ */ jsx(AlertDialogDescription, { children: "This action cannot be undone. The selected items will be permanently removed." })
656
+ ] }),
657
+ /* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
658
+ /* @__PURE__ */ jsx(AlertDialogCancel, { children: "Cancel" }),
659
+ /* @__PURE__ */ jsx(
660
+ AlertDialogAction,
661
+ {
662
+ className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
663
+ onClick: async () => {
664
+ try {
665
+ const thingsToDelete = thingsResult?.data?.filter(
666
+ (t) => selectedIds.includes(t.id)
667
+ ) ?? [];
668
+ await Promise.all(
669
+ thingsToDelete.map(
670
+ (thing) => client.Thing.delete({
671
+ ns: thing.ns,
672
+ type: thing.type,
673
+ id: thing.id
674
+ })
675
+ )
676
+ );
677
+ setSelectedIds([]);
678
+ await refetch();
679
+ } catch (err) {
680
+ console.error("Failed to delete:", err);
681
+ }
682
+ },
683
+ children: "Delete"
684
+ }
685
+ )
686
+ ] })
687
+ ] })
688
+ ] })
689
+ ] }),
690
+ /* @__PURE__ */ jsx(
691
+ ViewSwitcher,
692
+ {
693
+ currentView: viewType,
694
+ onViewChange: setViewType,
695
+ availableViews: ["list", "table", "card", "code"],
696
+ className: "hidden sm:inline-flex"
697
+ }
698
+ ),
699
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:block h-4 w-px bg-border" }),
700
+ /* @__PURE__ */ jsx(
701
+ DataFilterPopover,
702
+ {
703
+ open: filterPopoverOpen,
704
+ onOpenChange: setFilterPopoverOpen,
705
+ conditions: filterConditions,
706
+ onConditionsChange: setFilterConditions,
707
+ availableFields: queryFields
708
+ }
709
+ ),
710
+ viewType === "table" && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
711
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
712
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
713
+ Button,
714
+ {
715
+ variant: "ghost",
716
+ size: "icon",
717
+ className: "h-7 w-7 relative",
718
+ children: [
719
+ /* @__PURE__ */ jsx(Columns3, { className: "h-4 w-4" }),
720
+ hiddenColumns.size > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[10px] text-primary-foreground", children: hiddenColumns.size })
721
+ ]
722
+ }
723
+ ) }) }),
724
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Columns" })
725
+ ] }),
726
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", className: "w-48", children: [
727
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Toggle columns" }),
728
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
729
+ allTableColumns.map((column) => /* @__PURE__ */ jsx(
730
+ DropdownMenuCheckboxItem,
731
+ {
732
+ checked: !hiddenColumns.has(column.accessorKey),
733
+ onCheckedChange: (checked) => {
734
+ setHiddenColumns((prev) => {
735
+ const next = new Set(prev);
736
+ if (checked) {
737
+ next.delete(column.accessorKey);
738
+ } else {
739
+ next.add(column.accessorKey);
740
+ }
741
+ return next;
742
+ });
743
+ },
744
+ children: column.header
745
+ },
746
+ column.accessorKey
747
+ ))
748
+ ] })
749
+ ] }),
750
+ /* @__PURE__ */ jsxs(
751
+ Button,
752
+ {
753
+ variant: "default",
754
+ size: "sm",
755
+ className: "gap-1.5 px-3 hidden sm:inline-flex",
756
+ onClick: () => setCreateDialogOpen(true),
757
+ children: [
758
+ /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
759
+ /* @__PURE__ */ jsx("span", { children: "Add" })
760
+ ]
761
+ }
762
+ ),
763
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
764
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
765
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", className: "h-7 w-7", children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-4 w-4" }) }) }) }),
766
+ /* @__PURE__ */ jsx(TooltipContent, { children: "More actions" })
767
+ ] }),
768
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
769
+ /* @__PURE__ */ jsxs(
770
+ DropdownMenuItem,
771
+ {
772
+ disabled: selectedIds.length === 0,
773
+ onClick: handleExportSelected,
774
+ children: [
775
+ /* @__PURE__ */ jsx(Download, { className: "h-4 w-4 mr-2" }),
776
+ "Export selected (",
777
+ selectedIds.length,
778
+ ")"
779
+ ]
780
+ }
781
+ ),
782
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: handleExportAll, children: [
783
+ /* @__PURE__ */ jsx(Download, { className: "h-4 w-4 mr-2" }),
784
+ "Export all (",
785
+ data.length,
786
+ ")"
787
+ ] }),
788
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
789
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: () => refetch(), children: [
790
+ /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4 mr-2" }),
791
+ "Refresh data"
792
+ ] })
793
+ ] })
794
+ ] })
795
+ ] }),
796
+ /* @__PURE__ */ jsx("div", { className: "flex min-h-0 flex-1 flex-col overflow-hidden p-2", children: connectionError ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-md p-6", children: [
797
+ /* @__PURE__ */ jsx("div", { className: "mx-auto mb-4 h-12 w-12 rounded-full bg-destructive/10 flex items-center justify-center", children: /* @__PURE__ */ jsx(X, { className: "h-6 w-6 text-destructive" }) }),
798
+ /* @__PURE__ */ jsx("h3", { className: "font-semibold text-lg mb-2", children: "Connection Error" }),
799
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm mb-4", children: connectionError.message }),
800
+ /* @__PURE__ */ jsxs(
801
+ Button,
802
+ {
803
+ variant: "outline",
804
+ size: "sm",
805
+ onClick: () => refetch(),
806
+ className: "gap-2",
807
+ children: [
808
+ /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }),
809
+ "Retry"
810
+ ]
811
+ }
812
+ )
813
+ ] }) }) : isLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
814
+ /* @__PURE__ */ jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" }),
815
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Loading..." })
816
+ ] }) }) : data.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
817
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No things found" }),
818
+ searchQuery && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your search query" })
819
+ ] }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
820
+ viewType === "list" && /* @__PURE__ */ jsx(
821
+ DatabaseListView,
822
+ {
823
+ data,
824
+ displayFields: ["name", "type", "ns"],
825
+ primaryField: "name",
826
+ secondaryField: "type",
827
+ selectedIds,
828
+ onSelectionChange: setSelectedIds,
829
+ onRecordClick: handleItemClick
830
+ }
831
+ ),
832
+ viewType === "table" && /* @__PURE__ */ jsx(
833
+ DatabaseTableView,
834
+ {
835
+ data,
836
+ columns: tableColumns,
837
+ onSelectionChange: setSelectedIds,
838
+ onRowClick: handleItemClick,
839
+ enableRowSelection: true,
840
+ enablePagination: false,
841
+ enableColumnVisibility: false
842
+ }
843
+ ),
844
+ viewType === "card" && /* @__PURE__ */ jsx("div", { className: "h-full overflow-auto p-2", children: /* @__PURE__ */ jsx(
845
+ DatabaseCardView,
846
+ {
847
+ data,
848
+ titleField: "name",
849
+ descriptionField: "type",
850
+ badgeFields: ["ns"],
851
+ onItemClick: handleItemClick,
852
+ columns: 3
853
+ }
854
+ ) }),
855
+ viewType === "code" && /* @__PURE__ */ jsx(DatabaseCodeView, { data, height: "100%", format: "json" })
856
+ ] }) }),
857
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2 border-t border-border bg-muted/50 text-sm text-muted-foreground", children: [
858
+ /* @__PURE__ */ jsxs("span", { children: [
859
+ thingsResult?.total ?? 0,
860
+ " items",
861
+ selectedType && ` \u2022 Type: ${selectedType}`
862
+ ] }),
863
+ /* @__PURE__ */ jsxs("span", { children: [
864
+ "Page ",
865
+ thingsResult?.page ?? 1,
866
+ " of ",
867
+ thingsResult?.totalPages ?? 1
868
+ ] })
869
+ ] })
870
+ ] }),
871
+ /* @__PURE__ */ jsx(
872
+ DetailSheet,
873
+ {
874
+ open: detailOpen,
875
+ onOpenChange: setDetailOpen,
876
+ thing: detailThing,
877
+ onEdit: onOpen,
878
+ onSave: handleSaveThing
879
+ }
880
+ ),
881
+ /* @__PURE__ */ jsx(
882
+ CreateDialog,
883
+ {
884
+ open: createDialogOpen,
885
+ onOpenChange: setCreateDialogOpen,
886
+ namespace: selectedNamespace,
887
+ defaultType: selectedType,
888
+ types: types ?? [],
889
+ onCreated: (thing) => {
890
+ refetch();
891
+ setDetailThing(thing);
892
+ setDetailOpen(true);
893
+ }
894
+ }
895
+ )
896
+ ] }) });
897
+ }
898
+
899
+ export { CreateDialog, DataBrowserView, DetailSheet };
900
+ //# sourceMappingURL=chunk-UCWMSKCW.js.map
901
+ //# sourceMappingURL=chunk-UCWMSKCW.js.map