@dyrected/admin 2.5.38 → 2.5.39
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/admin.css +29 -5
- package/dist/index.mjs +340 -163
- package/package.json +3 -3
package/dist/admin.css
CHANGED
|
@@ -1828,6 +1828,10 @@
|
|
|
1828
1828
|
width: 2.25rem;
|
|
1829
1829
|
}
|
|
1830
1830
|
|
|
1831
|
+
.dy-w-96{
|
|
1832
|
+
width: 24rem;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1831
1835
|
.dy-w-\[--cell-size\]{
|
|
1832
1836
|
width: var(--cell-size);
|
|
1833
1837
|
}
|
|
@@ -1965,6 +1969,11 @@
|
|
|
1965
1969
|
min-width: var(--radix-select-trigger-width);
|
|
1966
1970
|
}
|
|
1967
1971
|
|
|
1972
|
+
.dy-min-w-max{
|
|
1973
|
+
min-width: -moz-max-content;
|
|
1974
|
+
min-width: max-content;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1968
1977
|
.dy-max-w-2xl{
|
|
1969
1978
|
max-width: 42rem;
|
|
1970
1979
|
}
|
|
@@ -4202,6 +4211,12 @@
|
|
|
4202
4211
|
--cell-size: 2.25rem;
|
|
4203
4212
|
}
|
|
4204
4213
|
|
|
4214
|
+
.\[appearance\:textfield\]{
|
|
4215
|
+
-webkit-appearance: textfield;
|
|
4216
|
+
-moz-appearance: textfield;
|
|
4217
|
+
appearance: textfield;
|
|
4218
|
+
}
|
|
4219
|
+
|
|
4205
4220
|
.dy-admin-ui .media-preview-dialod-details-form div[style="min-width: 100%;display: table;"] {
|
|
4206
4221
|
display: flex !important;
|
|
4207
4222
|
}
|
|
@@ -5595,6 +5610,10 @@
|
|
|
5595
5610
|
width: 95vw;
|
|
5596
5611
|
}
|
|
5597
5612
|
|
|
5613
|
+
.sm\:dy-w-\[var\(--field-w\)\]{
|
|
5614
|
+
width: var(--field-w);
|
|
5615
|
+
}
|
|
5616
|
+
|
|
5598
5617
|
.sm\:dy-w-auto{
|
|
5599
5618
|
width: auto;
|
|
5600
5619
|
}
|
|
@@ -5826,11 +5845,6 @@
|
|
|
5826
5845
|
line-height: 1.75rem;
|
|
5827
5846
|
}
|
|
5828
5847
|
|
|
5829
|
-
.sm\:dy-text-sm{
|
|
5830
|
-
font-size: 0.875rem;
|
|
5831
|
-
line-height: 1.25rem;
|
|
5832
|
-
}
|
|
5833
|
-
|
|
5834
5848
|
.sm\:dy-text-xl{
|
|
5835
5849
|
font-size: 1.25rem;
|
|
5836
5850
|
line-height: 1.75rem;
|
|
@@ -6179,6 +6193,16 @@
|
|
|
6179
6193
|
}
|
|
6180
6194
|
}
|
|
6181
6195
|
|
|
6196
|
+
.\[\&\:\:-webkit-inner-spin-button\]\:dy-appearance-none::-webkit-inner-spin-button{
|
|
6197
|
+
-webkit-appearance: none;
|
|
6198
|
+
appearance: none;
|
|
6199
|
+
}
|
|
6200
|
+
|
|
6201
|
+
.\[\&\:\:-webkit-outer-spin-button\]\:dy-appearance-none::-webkit-outer-spin-button{
|
|
6202
|
+
-webkit-appearance: none;
|
|
6203
|
+
appearance: none;
|
|
6204
|
+
}
|
|
6205
|
+
|
|
6182
6206
|
.\[\&\:has\(\[role\=checkbox\]\)\]\:dy-pr-0:has([role=checkbox]){
|
|
6183
6207
|
padding-right: 0px;
|
|
6184
6208
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import { cva } from "class-variance-authority";
|
|
|
14
14
|
import { Toaster, toast } from "sonner";
|
|
15
15
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
16
16
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
17
|
-
import { flexRender, getCoreRowModel, getFilteredRowModel,
|
|
17
|
+
import { flexRender, getCoreRowModel, getFilteredRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
|
18
18
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
19
19
|
import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
|
|
20
20
|
import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
@@ -1810,7 +1810,6 @@ function DataTable({ columns, data, searchKey, rowSelection: externalRowSelectio
|
|
|
1810
1810
|
onSortingChange: setSorting,
|
|
1811
1811
|
onColumnFiltersChange: setColumnFilters,
|
|
1812
1812
|
getCoreRowModel: getCoreRowModel(),
|
|
1813
|
-
getPaginationRowModel: getPaginationRowModel(),
|
|
1814
1813
|
getSortedRowModel: getSortedRowModel(),
|
|
1815
1814
|
getFilteredRowModel: getFilteredRowModel(),
|
|
1816
1815
|
onColumnVisibilityChange: setColumnVisibility,
|
|
@@ -1824,111 +1823,65 @@ function DataTable({ columns, data, searchKey, rowSelection: externalRowSelectio
|
|
|
1824
1823
|
});
|
|
1825
1824
|
return /* @__PURE__ */ jsxs("div", {
|
|
1826
1825
|
className: "dy-w-full dy-space-y-4",
|
|
1827
|
-
children: [
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
children: /* @__PURE__ */ jsxs(Button, {
|
|
1836
|
-
variant: "outline",
|
|
1837
|
-
size: "sm",
|
|
1838
|
-
className: "dy-flex dy-h-9 dy-w-full dy-gap-2 sm:dy-h-8 sm:dy-w-auto",
|
|
1839
|
-
children: [/* @__PURE__ */ jsx(Settings2, { className: "dy-h-4 dy-w-4" }), "View"]
|
|
1840
|
-
})
|
|
1841
|
-
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
1842
|
-
align: "end",
|
|
1843
|
-
children: table.getAllColumns().filter((column) => column.getCanHide()).map((column) => {
|
|
1844
|
-
return /* @__PURE__ */ jsx(DropdownMenuCheckboxItem, {
|
|
1845
|
-
className: "dy-capitalize",
|
|
1846
|
-
checked: column.getIsVisible(),
|
|
1847
|
-
onCheckedChange: (value) => column.toggleVisibility(!!value),
|
|
1848
|
-
children: column.id
|
|
1849
|
-
}, column.id);
|
|
1850
|
-
})
|
|
1851
|
-
})] })]
|
|
1852
|
-
}),
|
|
1853
|
-
searchKey && /* @__PURE__ */ jsx(Input, {
|
|
1854
|
-
placeholder: `Search ${searchKey}...`,
|
|
1855
|
-
value: table.getColumn(searchKey)?.getFilterValue() ?? "",
|
|
1856
|
-
onChange: (event) => table.getColumn(searchKey)?.setFilterValue(event.target.value),
|
|
1857
|
-
className: "dy-order-2 dy-h-9 dy-w-full sm:dy-order-1 sm:dy-max-w-sm"
|
|
1858
|
-
}),
|
|
1859
|
-
bulkActions && table.getFilteredSelectedRowModel().rows.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
1860
|
-
className: "dy-order-3 dy-flex dy-w-full dy-items-center dy-gap-2 dy-animate-in dy-slide-in-from-left-2 sm:dy-order-2 sm:dy-w-auto",
|
|
1861
|
-
children: bulkActions(table.getFilteredSelectedRowModel().rows.map((r) => r.original.id))
|
|
1862
|
-
})
|
|
1863
|
-
]
|
|
1864
|
-
}),
|
|
1865
|
-
/* @__PURE__ */ jsx("div", {
|
|
1866
|
-
className: "dy-overflow-x-auto dy-rounded-md dy-border dy-border-border/40",
|
|
1867
|
-
children: /* @__PURE__ */ jsxs(Table$1, {
|
|
1868
|
-
className: "dy-min-w-[720px]",
|
|
1869
|
-
children: [/* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
|
|
1870
|
-
return /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id);
|
|
1871
|
-
}) }, headerGroup.id)) }), /* @__PURE__ */ jsx(TableBody, {
|
|
1872
|
-
className: "dy-border-t dy-border-border/40",
|
|
1873
|
-
children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
|
|
1874
|
-
"data-state": row.getIsSelected() && "selected",
|
|
1875
|
-
className: "dy-border-none even:dy-bg-primary/[0.03] hover:dy-bg-primary/[0.06] dy-transition-colors dy-duration-200",
|
|
1876
|
-
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, {
|
|
1877
|
-
className: "dy-py-4 dy-px-4 dy-border-none first:dy-pl-4 last:dy-pr-4",
|
|
1878
|
-
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
1879
|
-
}, cell.id))
|
|
1880
|
-
}, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
|
|
1881
|
-
colSpan: columns.length,
|
|
1882
|
-
className: "dy-h-24 dy-text-center",
|
|
1883
|
-
children: "No results."
|
|
1884
|
-
}) })
|
|
1885
|
-
})]
|
|
1886
|
-
})
|
|
1887
|
-
}),
|
|
1888
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1889
|
-
className: "dy-flex dy-flex-col dy-gap-3 dy-px-2 sm:dy-flex-row sm:dy-items-center sm:dy-justify-between",
|
|
1890
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
1891
|
-
className: "dy-flex-1 dy-text-xs dy-text-muted-foreground sm:dy-text-sm",
|
|
1892
|
-
children: [
|
|
1893
|
-
table.getFilteredSelectedRowModel().rows.length,
|
|
1894
|
-
" of",
|
|
1895
|
-
" ",
|
|
1896
|
-
table.getFilteredRowModel().rows.length,
|
|
1897
|
-
" row(s) selected."
|
|
1898
|
-
]
|
|
1899
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1900
|
-
className: "dy-flex dy-items-center dy-justify-between dy-gap-2 sm:dy-justify-end",
|
|
1901
|
-
children: [
|
|
1902
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1903
|
-
variant: "outline",
|
|
1904
|
-
size: "sm",
|
|
1905
|
-
className: "dy-h-9 dy-w-9 dy-p-0",
|
|
1906
|
-
onClick: () => table.previousPage(),
|
|
1907
|
-
disabled: !table.getCanPreviousPage(),
|
|
1908
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "dy-h-4 dy-w-4" })
|
|
1909
|
-
}),
|
|
1910
|
-
/* @__PURE__ */ jsxs("span", {
|
|
1911
|
-
className: "dy-min-w-0 dy-text-center dy-text-xs dy-font-medium sm:dy-text-sm",
|
|
1912
|
-
children: [
|
|
1913
|
-
"Page ",
|
|
1914
|
-
table.getState().pagination.pageIndex + 1,
|
|
1915
|
-
" of",
|
|
1916
|
-
" ",
|
|
1917
|
-
table.getPageCount()
|
|
1918
|
-
]
|
|
1919
|
-
}),
|
|
1920
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1826
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1827
|
+
className: "dy-flex dy-flex-col dy-gap-3 sm:dy-flex-row sm:dy-items-center sm:dy-gap-4",
|
|
1828
|
+
children: [
|
|
1829
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1830
|
+
className: `dy-order-1 dy-grid dy-w-full dy-gap-2 sm:dy-order-3 sm:dy-ml-auto sm:dy-flex sm:dy-w-auto sm:dy-items-center ${toolbarActions ? hideViewButton ? "dy-grid-cols-2" : "dy-grid-cols-3" : hideViewButton ? "dy-grid-cols-1" : "dy-grid-cols-2"}`,
|
|
1831
|
+
children: [toolbarActions, !hideViewButton && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
1832
|
+
asChild: true,
|
|
1833
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
1921
1834
|
variant: "outline",
|
|
1922
1835
|
size: "sm",
|
|
1923
|
-
className: "dy-h-9 dy-w-
|
|
1924
|
-
|
|
1925
|
-
disabled: !table.getCanNextPage(),
|
|
1926
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "dy-h-4 dy-w-4" })
|
|
1836
|
+
className: "dy-flex dy-h-9 dy-w-full dy-gap-2 sm:dy-h-8 sm:dy-w-auto",
|
|
1837
|
+
children: [/* @__PURE__ */ jsx(Settings2, { className: "dy-h-4 dy-w-4" }), "View"]
|
|
1927
1838
|
})
|
|
1928
|
-
|
|
1839
|
+
}), /* @__PURE__ */ jsx(DropdownMenuContent, {
|
|
1840
|
+
align: "end",
|
|
1841
|
+
children: table.getAllColumns().filter((column) => column.getCanHide()).map((column) => {
|
|
1842
|
+
return /* @__PURE__ */ jsx(DropdownMenuCheckboxItem, {
|
|
1843
|
+
className: "dy-capitalize",
|
|
1844
|
+
checked: column.getIsVisible(),
|
|
1845
|
+
onCheckedChange: (value) => column.toggleVisibility(!!value),
|
|
1846
|
+
children: column.id
|
|
1847
|
+
}, column.id);
|
|
1848
|
+
})
|
|
1849
|
+
})] })]
|
|
1850
|
+
}),
|
|
1851
|
+
searchKey && /* @__PURE__ */ jsx(Input, {
|
|
1852
|
+
placeholder: `Search ${searchKey}...`,
|
|
1853
|
+
value: table.getColumn(searchKey)?.getFilterValue() ?? "",
|
|
1854
|
+
onChange: (event) => table.getColumn(searchKey)?.setFilterValue(event.target.value),
|
|
1855
|
+
className: "dy-order-2 dy-h-9 dy-w-full sm:dy-order-1 sm:dy-max-w-sm"
|
|
1856
|
+
}),
|
|
1857
|
+
bulkActions && table.getFilteredSelectedRowModel().rows.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
1858
|
+
className: "dy-order-3 dy-flex dy-w-full dy-items-center dy-gap-2 dy-animate-in dy-slide-in-from-left-2 sm:dy-order-2 sm:dy-w-auto",
|
|
1859
|
+
children: bulkActions(table.getFilteredSelectedRowModel().rows.map((r) => r.original.id))
|
|
1860
|
+
})
|
|
1861
|
+
]
|
|
1862
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1863
|
+
className: "dy-overflow-x-auto dy-rounded-md dy-border dy-border-border/40",
|
|
1864
|
+
children: /* @__PURE__ */ jsxs(Table$1, {
|
|
1865
|
+
className: "dy-min-w-[720px]",
|
|
1866
|
+
children: [/* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => {
|
|
1867
|
+
return /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id);
|
|
1868
|
+
}) }, headerGroup.id)) }), /* @__PURE__ */ jsx(TableBody, {
|
|
1869
|
+
className: "dy-border-t dy-border-border/40",
|
|
1870
|
+
children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
|
|
1871
|
+
"data-state": row.getIsSelected() && "selected",
|
|
1872
|
+
className: "dy-border-none even:dy-bg-primary/[0.03] hover:dy-bg-primary/[0.06] dy-transition-colors dy-duration-200",
|
|
1873
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, {
|
|
1874
|
+
className: "dy-py-4 dy-px-4 dy-border-none first:dy-pl-4 last:dy-pr-4",
|
|
1875
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
1876
|
+
}, cell.id))
|
|
1877
|
+
}, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
|
|
1878
|
+
colSpan: columns.length,
|
|
1879
|
+
className: "dy-h-24 dy-text-center",
|
|
1880
|
+
children: "No results."
|
|
1881
|
+
}) })
|
|
1929
1882
|
})]
|
|
1930
1883
|
})
|
|
1931
|
-
]
|
|
1884
|
+
})]
|
|
1932
1885
|
});
|
|
1933
1886
|
}
|
|
1934
1887
|
//#endregion
|
|
@@ -2092,7 +2045,7 @@ function CsvImporter({ slug, schema, onClose }) {
|
|
|
2092
2045
|
const strVal = String(val).trim();
|
|
2093
2046
|
switch (field.type) {
|
|
2094
2047
|
case "number": {
|
|
2095
|
-
const num = Number(strVal);
|
|
2048
|
+
const num = Number(strVal.replace(/[$€£¥₹₦₩₪₺₽฿,]/g, ""));
|
|
2096
2049
|
if (isNaN(num)) return {
|
|
2097
2050
|
value: null,
|
|
2098
2051
|
error: "Must be a valid number"
|
|
@@ -2117,6 +2070,28 @@ function CsvImporter({ slug, schema, onClose }) {
|
|
|
2117
2070
|
};
|
|
2118
2071
|
return { value: date.toISOString() };
|
|
2119
2072
|
}
|
|
2073
|
+
case "image": try {
|
|
2074
|
+
new URL(strVal);
|
|
2075
|
+
return { value: strVal };
|
|
2076
|
+
} catch {
|
|
2077
|
+
return {
|
|
2078
|
+
value: null,
|
|
2079
|
+
error: "Must be a valid image URL"
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
case "url": try {
|
|
2083
|
+
new URL(strVal);
|
|
2084
|
+
return { value: {
|
|
2085
|
+
type: "custom",
|
|
2086
|
+
url: strVal,
|
|
2087
|
+
label: ""
|
|
2088
|
+
} };
|
|
2089
|
+
} catch {
|
|
2090
|
+
return {
|
|
2091
|
+
value: null,
|
|
2092
|
+
error: "Must be a valid URL (e.g. https://example.com)"
|
|
2093
|
+
};
|
|
2094
|
+
}
|
|
2120
2095
|
case "select":
|
|
2121
2096
|
case "radio":
|
|
2122
2097
|
if (field.options && Array.isArray(field.options) && field.options.length > 0) {
|
|
@@ -2186,7 +2161,21 @@ function CsvImporter({ slug, schema, onClose }) {
|
|
|
2186
2161
|
continue;
|
|
2187
2162
|
}
|
|
2188
2163
|
try {
|
|
2189
|
-
|
|
2164
|
+
const data = { ...rowResult.data };
|
|
2165
|
+
for (const field of importableFields) {
|
|
2166
|
+
if (field.type !== "image") continue;
|
|
2167
|
+
const url = data[field.name];
|
|
2168
|
+
if (!url || typeof url !== "string") continue;
|
|
2169
|
+
const mediaCollection = field.relationTo || "media";
|
|
2170
|
+
const response = await fetch(url);
|
|
2171
|
+
if (!response.ok) throw new Error(`Failed to fetch image: ${url}`);
|
|
2172
|
+
const blob = await response.blob();
|
|
2173
|
+
const filename = url.split("/").pop()?.split("?")[0] || "image";
|
|
2174
|
+
const file = new File([blob], filename, { type: blob.type });
|
|
2175
|
+
const media = await client.collection(mediaCollection).upload(file);
|
|
2176
|
+
data[field.name] = media.id;
|
|
2177
|
+
}
|
|
2178
|
+
await client.collection(slug).create(data);
|
|
2190
2179
|
success++;
|
|
2191
2180
|
setSuccessCount(success);
|
|
2192
2181
|
} catch (error) {
|
|
@@ -2267,8 +2256,8 @@ function CsvImporter({ slug, schema, onClose }) {
|
|
|
2267
2256
|
className: "dy-p-4 dy-bg-muted/40 dy-border dy-border-border dy-rounded-xl dy-text-sm dy-text-muted-foreground",
|
|
2268
2257
|
children: "Map the columns in your CSV file to the corresponding fields of the collection. All required fields must be mapped to proceed."
|
|
2269
2258
|
}),
|
|
2270
|
-
/* @__PURE__ */ jsx(
|
|
2271
|
-
className: "dy-h-[300px] dy-
|
|
2259
|
+
/* @__PURE__ */ jsx("div", {
|
|
2260
|
+
className: "dy-h-[300px] dy-overflow-y-auto dy-border dy-border-border dy-rounded-xl",
|
|
2272
2261
|
children: /* @__PURE__ */ jsx("div", {
|
|
2273
2262
|
className: "dy-divide-y dy-divide-border",
|
|
2274
2263
|
children: csvHeaders.map((header) => {
|
|
@@ -2361,10 +2350,10 @@ function CsvImporter({ slug, schema, onClose }) {
|
|
|
2361
2350
|
]
|
|
2362
2351
|
})]
|
|
2363
2352
|
}),
|
|
2364
|
-
/* @__PURE__ */ jsx(
|
|
2365
|
-
className: "dy-h-[300px] dy-border dy-border-border dy-rounded-xl",
|
|
2353
|
+
/* @__PURE__ */ jsx("div", {
|
|
2354
|
+
className: "dy-h-[300px] dy-overflow-auto dy-border dy-border-border dy-rounded-xl",
|
|
2366
2355
|
children: /* @__PURE__ */ jsxs("table", {
|
|
2367
|
-
className: "dy-w-full dy-text-left dy-border-collapse",
|
|
2356
|
+
className: "dy-w-full dy-min-w-max dy-text-left dy-border-collapse",
|
|
2368
2357
|
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", {
|
|
2369
2358
|
className: "dy-border-b dy-border-border dy-bg-muted/40 dy-text-xs dy-font-semibold dy-text-muted-foreground",
|
|
2370
2359
|
children: [/* @__PURE__ */ jsx("th", {
|
|
@@ -8358,8 +8347,8 @@ function FormEngine({ collection, fields, defaultValues = {}, onSubmit, onChange
|
|
|
8358
8347
|
const tabbedFields = visibleFields.filter((f) => !!f.admin?.tab);
|
|
8359
8348
|
let fieldsContent;
|
|
8360
8349
|
const renderFieldColumn = (field) => /* @__PURE__ */ jsx("div", {
|
|
8361
|
-
className: "dy-min-w-0 dy-px-3",
|
|
8362
|
-
style: {
|
|
8350
|
+
className: "dy-min-w-0 dy-px-3 dy-w-full sm:dy-w-[var(--field-w)]",
|
|
8351
|
+
style: { "--field-w": field.admin?.width || "100%" },
|
|
8363
8352
|
children: /* @__PURE__ */ jsx(FormFieldRenderer, {
|
|
8364
8353
|
schema: field,
|
|
8365
8354
|
basePath: "",
|
|
@@ -8765,7 +8754,7 @@ function RelationshipPicker({ value, onChange, label, relationTo, multiple, disa
|
|
|
8765
8754
|
}
|
|
8766
8755
|
//#endregion
|
|
8767
8756
|
//#region src/components/ui/spreadsheet-editor.tsx
|
|
8768
|
-
function
|
|
8757
|
+
function useFieldOptions(field, collection, siblingValues) {
|
|
8769
8758
|
const { client } = useDyrected();
|
|
8770
8759
|
const isDynamic = !!(field.options && typeof field.options === "object" && "_dynamic" in field.options);
|
|
8771
8760
|
const { data: dynamicOptions } = useQuery({
|
|
@@ -8777,7 +8766,7 @@ function SelectCellDisplay({ field, value, collection, siblingValues }) {
|
|
|
8777
8766
|
],
|
|
8778
8767
|
queryFn: async () => {
|
|
8779
8768
|
const q = new URLSearchParams();
|
|
8780
|
-
|
|
8769
|
+
Object.entries(siblingValues).forEach(([k, v]) => {
|
|
8781
8770
|
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") q.append(k, String(v));
|
|
8782
8771
|
});
|
|
8783
8772
|
const url = `${client?.getBaseUrl() || ""}/api/dyrected/options/${collection}/${field.name}?${q.toString()}`;
|
|
@@ -8793,7 +8782,7 @@ function SelectCellDisplay({ field, value, collection, siblingValues }) {
|
|
|
8793
8782
|
},
|
|
8794
8783
|
enabled: !!client && isDynamic && !!collection && !!field.name
|
|
8795
8784
|
});
|
|
8796
|
-
|
|
8785
|
+
return React$1.useMemo(() => {
|
|
8797
8786
|
const rawOptions = isDynamic ? dynamicOptions || [] : field.options;
|
|
8798
8787
|
return (Array.isArray(rawOptions) ? rawOptions : []).map((opt) => {
|
|
8799
8788
|
if (typeof opt === "object" && opt !== null) return {
|
|
@@ -8809,54 +8798,14 @@ function SelectCellDisplay({ field, value, collection, siblingValues }) {
|
|
|
8809
8798
|
isDynamic,
|
|
8810
8799
|
dynamicOptions,
|
|
8811
8800
|
field.options
|
|
8812
|
-
])
|
|
8801
|
+
]);
|
|
8802
|
+
}
|
|
8803
|
+
function SelectCellDisplay({ field, value, collection, siblingValues }) {
|
|
8804
|
+
const matched = useFieldOptions(field, collection, siblingValues).find((opt) => opt.value === String(value ?? ""));
|
|
8813
8805
|
return /* @__PURE__ */ jsx("span", { children: matched ? matched.label : value !== null && value !== void 0 ? String(value) : "" });
|
|
8814
8806
|
}
|
|
8815
8807
|
function SelectPopoverEditor({ field, value, collection, siblingValues, onCommit }) {
|
|
8816
|
-
const
|
|
8817
|
-
const isDynamic = !!(field.options && typeof field.options === "object" && "_dynamic" in field.options);
|
|
8818
|
-
const { data: dynamicOptions } = useQuery({
|
|
8819
|
-
queryKey: [
|
|
8820
|
-
"options",
|
|
8821
|
-
collection,
|
|
8822
|
-
field.name,
|
|
8823
|
-
siblingValues
|
|
8824
|
-
],
|
|
8825
|
-
queryFn: async () => {
|
|
8826
|
-
const q = new URLSearchParams();
|
|
8827
|
-
if (siblingValues) Object.entries(siblingValues).forEach(([k, v]) => {
|
|
8828
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") q.append(k, String(v));
|
|
8829
|
-
});
|
|
8830
|
-
const url = `${client?.getBaseUrl() || ""}/api/dyrected/options/${collection}/${field.name}?${q.toString()}`;
|
|
8831
|
-
const authHeaders = {};
|
|
8832
|
-
const token = typeof window !== "undefined" ? localStorage.getItem("dyrected_token") : null;
|
|
8833
|
-
if (token) authHeaders["Authorization"] = `Bearer ${token}`;
|
|
8834
|
-
const res = await fetch(url, { headers: {
|
|
8835
|
-
"Content-Type": "application/json",
|
|
8836
|
-
...authHeaders
|
|
8837
|
-
} });
|
|
8838
|
-
if (!res.ok) throw new Error("Failed to fetch options");
|
|
8839
|
-
return res.json();
|
|
8840
|
-
},
|
|
8841
|
-
enabled: !!client && isDynamic && !!collection && !!field.name
|
|
8842
|
-
});
|
|
8843
|
-
const options = React$1.useMemo(() => {
|
|
8844
|
-
const rawOptions = isDynamic ? dynamicOptions || [] : field.options;
|
|
8845
|
-
return (Array.isArray(rawOptions) ? rawOptions : []).map((opt) => {
|
|
8846
|
-
if (typeof opt === "object" && opt !== null) return {
|
|
8847
|
-
label: opt.label,
|
|
8848
|
-
value: String(opt.value ?? "")
|
|
8849
|
-
};
|
|
8850
|
-
return {
|
|
8851
|
-
label: String(opt),
|
|
8852
|
-
value: String(opt)
|
|
8853
|
-
};
|
|
8854
|
-
});
|
|
8855
|
-
}, [
|
|
8856
|
-
isDynamic,
|
|
8857
|
-
dynamicOptions,
|
|
8858
|
-
field.options
|
|
8859
|
-
]);
|
|
8808
|
+
const options = useFieldOptions(field, collection, siblingValues);
|
|
8860
8809
|
return /* @__PURE__ */ jsxs("div", {
|
|
8861
8810
|
className: "dy-max-h-60 dy-overflow-y-auto dy-flex dy-flex-col dy-divide-y dy-divide-border dy-bg-popover dy-rounded-md",
|
|
8862
8811
|
children: [options.map((opt) => /* @__PURE__ */ jsx("button", {
|
|
@@ -8870,6 +8819,163 @@ function SelectPopoverEditor({ field, value, collection, siblingValues, onCommit
|
|
|
8870
8819
|
})]
|
|
8871
8820
|
});
|
|
8872
8821
|
}
|
|
8822
|
+
function MultiSelectCellDisplay({ field, value, collection, siblingValues }) {
|
|
8823
|
+
const options = useFieldOptions(field, collection, siblingValues);
|
|
8824
|
+
const labels = (Array.isArray(value) ? value.map(String) : []).map((v) => options.find((o) => o.value === v)?.label ?? v);
|
|
8825
|
+
return /* @__PURE__ */ jsx("span", { children: labels.length > 0 ? labels.join(", ") : "" });
|
|
8826
|
+
}
|
|
8827
|
+
function MultiSelectPopoverEditor({ field, value, collection, siblingValues, onToggle }) {
|
|
8828
|
+
const options = useFieldOptions(field, collection, siblingValues);
|
|
8829
|
+
const selected = Array.isArray(value) ? value.map(String) : [];
|
|
8830
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8831
|
+
className: "dy-max-h-60 dy-overflow-y-auto dy-flex dy-flex-col dy-divide-y dy-divide-border dy-bg-popover dy-rounded-md",
|
|
8832
|
+
children: [options.map((opt) => {
|
|
8833
|
+
const checked = selected.includes(opt.value);
|
|
8834
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
8835
|
+
type: "button",
|
|
8836
|
+
className: cn("dy-w-full dy-text-left dy-px-3 dy-py-2 dy-text-xs hover:dy-bg-accent hover:dy-text-accent-foreground dy-transition-colors dy-flex dy-items-center dy-gap-2", checked && "dy-bg-accent/50"),
|
|
8837
|
+
onClick: () => onToggle(checked ? selected.filter((v) => v !== opt.value) : [...selected, opt.value]),
|
|
8838
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
8839
|
+
className: cn("dy-w-3.5 dy-h-3.5 dy-rounded-sm dy-border dy-border-border dy-flex-shrink-0 dy-flex dy-items-center dy-justify-center", checked && "dy-bg-primary dy-border-primary"),
|
|
8840
|
+
children: checked && /* @__PURE__ */ jsx("span", {
|
|
8841
|
+
className: "dy-text-primary-foreground dy-text-[10px] dy-leading-none",
|
|
8842
|
+
children: "✓"
|
|
8843
|
+
})
|
|
8844
|
+
}), opt.label]
|
|
8845
|
+
}, opt.value);
|
|
8846
|
+
}), options.length === 0 && /* @__PURE__ */ jsx("div", {
|
|
8847
|
+
className: "dy-text-xs dy-text-muted-foreground dy-p-3 dy-text-center",
|
|
8848
|
+
children: "No options available"
|
|
8849
|
+
})]
|
|
8850
|
+
});
|
|
8851
|
+
}
|
|
8852
|
+
function SubFieldRow({ subField, value, onChange, collection }) {
|
|
8853
|
+
const { user, schemas } = useDyrected();
|
|
8854
|
+
const handleChange = React$1.useCallback((eventOrValue) => {
|
|
8855
|
+
if (eventOrValue != null && typeof eventOrValue === "object" && "target" in eventOrValue) {
|
|
8856
|
+
const e = eventOrValue;
|
|
8857
|
+
if (e.target.type === "checkbox") onChange(e.target.checked);
|
|
8858
|
+
else if (e.target.value === "") onChange(null);
|
|
8859
|
+
else if (subField.type === "number") onChange(Number(e.target.value));
|
|
8860
|
+
else onChange(e.target.value);
|
|
8861
|
+
} else onChange(eventOrValue);
|
|
8862
|
+
}, [onChange, subField.type]);
|
|
8863
|
+
const syntheticField = React$1.useMemo(() => ({
|
|
8864
|
+
value: value ?? (subField.type === "boolean" ? false : ""),
|
|
8865
|
+
onChange: handleChange,
|
|
8866
|
+
name: subField.name ?? "",
|
|
8867
|
+
ref: { current: null }
|
|
8868
|
+
}), [
|
|
8869
|
+
value,
|
|
8870
|
+
handleChange,
|
|
8871
|
+
subField.name,
|
|
8872
|
+
subField.type
|
|
8873
|
+
]);
|
|
8874
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8875
|
+
className: "dy-flex dy-flex-col dy-gap-0.5",
|
|
8876
|
+
children: [/* @__PURE__ */ jsx("label", {
|
|
8877
|
+
className: "dy-text-[10px] dy-text-muted-foreground",
|
|
8878
|
+
children: subField.label || subField.name
|
|
8879
|
+
}), /* @__PURE__ */ jsx(FieldRenderer, {
|
|
8880
|
+
schema: subField,
|
|
8881
|
+
field: syntheticField,
|
|
8882
|
+
collection,
|
|
8883
|
+
context: {
|
|
8884
|
+
user: user ?? null,
|
|
8885
|
+
schemas,
|
|
8886
|
+
siblingData: {}
|
|
8887
|
+
}
|
|
8888
|
+
})]
|
|
8889
|
+
});
|
|
8890
|
+
}
|
|
8891
|
+
function ObjectPopoverEditor({ field, value, onChange, collection }) {
|
|
8892
|
+
const subFields = field.fields || [];
|
|
8893
|
+
const obj = typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
8894
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8895
|
+
className: "dy-flex dy-flex-col dy-gap-3 dy-max-h-[400px] dy-overflow-y-auto",
|
|
8896
|
+
children: [
|
|
8897
|
+
/* @__PURE__ */ jsx("div", {
|
|
8898
|
+
className: "dy-text-xs dy-font-semibold dy-text-muted-foreground",
|
|
8899
|
+
children: field.label || field.name
|
|
8900
|
+
}),
|
|
8901
|
+
subFields.filter((sf) => ![
|
|
8902
|
+
"object",
|
|
8903
|
+
"array",
|
|
8904
|
+
"blocks",
|
|
8905
|
+
"join",
|
|
8906
|
+
"row",
|
|
8907
|
+
"richText"
|
|
8908
|
+
].includes(sf.type)).map((sf) => /* @__PURE__ */ jsx(SubFieldRow, {
|
|
8909
|
+
subField: sf,
|
|
8910
|
+
value: obj[sf.name],
|
|
8911
|
+
onChange: (val) => onChange({
|
|
8912
|
+
...obj,
|
|
8913
|
+
[sf.name]: val
|
|
8914
|
+
}),
|
|
8915
|
+
collection
|
|
8916
|
+
}, sf.name)),
|
|
8917
|
+
subFields.length === 0 && /* @__PURE__ */ jsx("div", {
|
|
8918
|
+
className: "dy-text-xs dy-text-muted-foreground",
|
|
8919
|
+
children: "No fields defined"
|
|
8920
|
+
})
|
|
8921
|
+
]
|
|
8922
|
+
});
|
|
8923
|
+
}
|
|
8924
|
+
function ArrayPopoverEditor({ field, value, onChange, collection }) {
|
|
8925
|
+
const subFields = field.fields || [];
|
|
8926
|
+
const items = Array.isArray(value) ? value : [];
|
|
8927
|
+
const updateItem = (idx, key, val) => onChange(items.map((item, i) => i === idx ? {
|
|
8928
|
+
...item,
|
|
8929
|
+
[key]: val
|
|
8930
|
+
} : item));
|
|
8931
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8932
|
+
className: "dy-flex dy-flex-col dy-gap-3 dy-max-h-[400px] dy-overflow-y-auto",
|
|
8933
|
+
children: [
|
|
8934
|
+
/* @__PURE__ */ jsxs("div", {
|
|
8935
|
+
className: "dy-text-xs dy-font-semibold dy-text-muted-foreground",
|
|
8936
|
+
children: [
|
|
8937
|
+
field.label || field.name,
|
|
8938
|
+
" (",
|
|
8939
|
+
items.length,
|
|
8940
|
+
" items)"
|
|
8941
|
+
]
|
|
8942
|
+
}),
|
|
8943
|
+
items.map((item, idx) => /* @__PURE__ */ jsxs("div", {
|
|
8944
|
+
className: "dy-border dy-rounded-md dy-p-2 dy-flex dy-flex-col dy-gap-2",
|
|
8945
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
8946
|
+
className: "dy-flex dy-items-center dy-justify-between",
|
|
8947
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
8948
|
+
className: "dy-text-[10px] dy-font-medium dy-text-muted-foreground",
|
|
8949
|
+
children: ["Item ", idx + 1]
|
|
8950
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
8951
|
+
type: "button",
|
|
8952
|
+
className: "dy-text-[10px] dy-text-destructive hover:dy-underline",
|
|
8953
|
+
onClick: () => onChange(items.filter((_, i) => i !== idx)),
|
|
8954
|
+
children: "Remove"
|
|
8955
|
+
})]
|
|
8956
|
+
}), subFields.filter((sf) => ![
|
|
8957
|
+
"object",
|
|
8958
|
+
"array",
|
|
8959
|
+
"blocks",
|
|
8960
|
+
"join",
|
|
8961
|
+
"row",
|
|
8962
|
+
"richText"
|
|
8963
|
+
].includes(sf.type)).map((sf) => /* @__PURE__ */ jsx(SubFieldRow, {
|
|
8964
|
+
subField: sf,
|
|
8965
|
+
value: item[sf.name],
|
|
8966
|
+
onChange: (val) => updateItem(idx, sf.name, val),
|
|
8967
|
+
collection
|
|
8968
|
+
}, sf.name))]
|
|
8969
|
+
}, idx)),
|
|
8970
|
+
/* @__PURE__ */ jsx("button", {
|
|
8971
|
+
type: "button",
|
|
8972
|
+
className: "dy-w-full dy-border dy-border-dashed dy-rounded dy-py-1.5 dy-text-xs dy-text-muted-foreground hover:dy-bg-muted/30 dy-transition-colors",
|
|
8973
|
+
onClick: () => onChange([...items, {}]),
|
|
8974
|
+
children: "+ Add item"
|
|
8975
|
+
})
|
|
8976
|
+
]
|
|
8977
|
+
});
|
|
8978
|
+
}
|
|
8873
8979
|
function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
8874
8980
|
const { client } = useDyrected();
|
|
8875
8981
|
const [drafts, setDrafts] = React$1.useState({});
|
|
@@ -8960,7 +9066,7 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
8960
9066
|
};
|
|
8961
9067
|
const columns = React$1.useMemo(() => {
|
|
8962
9068
|
const cols = [];
|
|
8963
|
-
schema.fields.filter((f) => f.name !== "password" && !f.admin?.hidden && f.type !== "row" && f.type !== "join").forEach((field) => {
|
|
9069
|
+
schema.fields.filter((f) => f.name !== "password" && !f.admin?.hidden && f.type !== "row" && f.type !== "join" && f.type !== "blocks").forEach((field) => {
|
|
8964
9070
|
const isReadOnly = !!field.admin?.readOnly;
|
|
8965
9071
|
if (field.type === "text" || field.type === "email" || field.type === "url") {
|
|
8966
9072
|
cols.push({
|
|
@@ -8978,6 +9084,34 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
8978
9084
|
});
|
|
8979
9085
|
return;
|
|
8980
9086
|
}
|
|
9087
|
+
if (field.type === "number") {
|
|
9088
|
+
cols.push({
|
|
9089
|
+
...keyColumn(field.name, {
|
|
9090
|
+
component: ({ rowData: value, setRowData: onChange, focus }) => {
|
|
9091
|
+
return /* @__PURE__ */ jsx("input", {
|
|
9092
|
+
type: "number",
|
|
9093
|
+
className: "dy-w-full dy-h-full dy-bg-transparent dy-outline-none dy-px-2 dy-text-xs dy-text-foreground [appearance:textfield] [&::-webkit-outer-spin-button]:dy-appearance-none [&::-webkit-inner-spin-button]:dy-appearance-none",
|
|
9094
|
+
value: value != null ? String(value) : "",
|
|
9095
|
+
onChange: (e) => {
|
|
9096
|
+
const raw = e.target.value;
|
|
9097
|
+
onChange(raw === "" ? null : Number(raw));
|
|
9098
|
+
},
|
|
9099
|
+
disabled: isReadOnly,
|
|
9100
|
+
autoFocus: focus
|
|
9101
|
+
});
|
|
9102
|
+
},
|
|
9103
|
+
deleteValue: () => null,
|
|
9104
|
+
copyValue: ({ rowData: value }) => String(value ?? ""),
|
|
9105
|
+
pasteValue: ({ value }) => {
|
|
9106
|
+
const n = Number(value);
|
|
9107
|
+
return isNaN(n) ? null : n;
|
|
9108
|
+
}
|
|
9109
|
+
}),
|
|
9110
|
+
title: field.label || field.name,
|
|
9111
|
+
disabled: isReadOnly
|
|
9112
|
+
});
|
|
9113
|
+
return;
|
|
9114
|
+
}
|
|
8981
9115
|
if (field.type === "date" || field.type === "datetime" || field.type === "time") {
|
|
8982
9116
|
const inputType = field.type === "date" ? "date" : field.type === "datetime" ? "datetime-local" : "time";
|
|
8983
9117
|
cols.push({
|
|
@@ -9021,10 +9155,18 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
9021
9155
|
if (!rowData) return null;
|
|
9022
9156
|
const value = rowData[field.name];
|
|
9023
9157
|
const isSelectOrRadio = field.type === "select" || field.type === "radio";
|
|
9158
|
+
const isMultiSelect = field.type === "multiSelect";
|
|
9159
|
+
const isArray = field.type === "array";
|
|
9160
|
+
const isObject = field.type === "object";
|
|
9024
9161
|
let display = "";
|
|
9025
|
-
if (!isSelectOrRadio && value !== null && value !== void 0) if (typeof value === "object") display = value.title || value.name || value.filename || JSON.stringify(value);
|
|
9162
|
+
if (!isSelectOrRadio && !isMultiSelect && !isArray && !isObject && value !== null && value !== void 0) if (typeof value === "object") display = value.title || value.name || value.filename || JSON.stringify(value);
|
|
9026
9163
|
else display = String(value);
|
|
9027
9164
|
if (field.type === "richText" && display) display = display.replace(/<[^>]*>/g, "");
|
|
9165
|
+
if (isArray) display = Array.isArray(value) ? `${value.length} item${value.length !== 1 ? "s" : ""}` : "0 items";
|
|
9166
|
+
if (isObject && typeof value === "object" && value !== null) {
|
|
9167
|
+
const keys = Object.keys(value).filter((k) => value[k] != null);
|
|
9168
|
+
display = keys.length > 0 ? keys.slice(0, 2).map((k) => `${k}: ${String(value[k]).slice(0, 15)}`).join(", ") : "{ empty }";
|
|
9169
|
+
}
|
|
9028
9170
|
return /* @__PURE__ */ jsxs("div", {
|
|
9029
9171
|
tabIndex: -1,
|
|
9030
9172
|
className: "dy-w-full dy-h-full dy-px-2 dy-py-1 dy-truncate dy-cursor-pointer hover:dy-bg-muted/30 dy-flex dy-items-center dy-gap-2 dy-outline-none",
|
|
@@ -9051,6 +9193,14 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
9051
9193
|
collection: slug,
|
|
9052
9194
|
siblingValues: rowData
|
|
9053
9195
|
})
|
|
9196
|
+
}) : isMultiSelect ? /* @__PURE__ */ jsx("span", {
|
|
9197
|
+
className: "dy-text-xs dy-text-foreground",
|
|
9198
|
+
children: /* @__PURE__ */ jsx(MultiSelectCellDisplay, {
|
|
9199
|
+
field,
|
|
9200
|
+
value,
|
|
9201
|
+
collection: slug,
|
|
9202
|
+
siblingValues: rowData
|
|
9203
|
+
})
|
|
9054
9204
|
}) : /* @__PURE__ */ jsx("span", {
|
|
9055
9205
|
className: "dy-text-xs dy-text-muted-foreground",
|
|
9056
9206
|
children: display || `Click to edit`
|
|
@@ -9170,10 +9320,15 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
9170
9320
|
if (!open) handlePopoverClose();
|
|
9171
9321
|
},
|
|
9172
9322
|
children: activePopover && activePopover.field.type !== "richText" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(PopoverAnchor, { virtualRef: { current: activePopover.element } }), /* @__PURE__ */ jsxs(PopoverContent, {
|
|
9173
|
-
className: "dy-z-[100] dy-p-3 dy-
|
|
9323
|
+
className: cn("dy-z-[100] dy-p-3 dy-bg-popover dy-border dy-rounded-md dy-shadow-md", activePopover.field.type === "object" || activePopover.field.type === "array" ? "dy-w-96" : "dy-w-80"),
|
|
9174
9324
|
onInteractOutside: () => {
|
|
9175
9325
|
const { rowIdx, field } = activePopover;
|
|
9176
|
-
if (
|
|
9326
|
+
if (![
|
|
9327
|
+
"textarea",
|
|
9328
|
+
"json",
|
|
9329
|
+
"object",
|
|
9330
|
+
"array"
|
|
9331
|
+
].includes(field.type)) return;
|
|
9177
9332
|
const row = gridData[rowIdx];
|
|
9178
9333
|
if (row) setDrafts((prev) => ({
|
|
9179
9334
|
...prev,
|
|
@@ -9258,6 +9413,28 @@ function SpreadsheetEditor({ slug, schema, data, onSave, isSaving }) {
|
|
|
9258
9413
|
setLocalDraft(val);
|
|
9259
9414
|
commitValue(val);
|
|
9260
9415
|
}
|
|
9416
|
+
}),
|
|
9417
|
+
activePopover.field.type === "multiSelect" && /* @__PURE__ */ jsx(MultiSelectPopoverEditor, {
|
|
9418
|
+
field: activePopover.field,
|
|
9419
|
+
value: Array.isArray(localDraft) ? localDraft : [],
|
|
9420
|
+
collection: slug,
|
|
9421
|
+
siblingValues: gridData[activePopover.rowIdx] || {},
|
|
9422
|
+
onToggle: (val) => {
|
|
9423
|
+
setLocalDraft(val);
|
|
9424
|
+
commitValue(val);
|
|
9425
|
+
}
|
|
9426
|
+
}),
|
|
9427
|
+
activePopover.field.type === "object" && /* @__PURE__ */ jsx(ObjectPopoverEditor, {
|
|
9428
|
+
field: activePopover.field,
|
|
9429
|
+
value: localDraft,
|
|
9430
|
+
onChange: (val) => setLocalDraft(val),
|
|
9431
|
+
collection: slug
|
|
9432
|
+
}),
|
|
9433
|
+
activePopover.field.type === "array" && /* @__PURE__ */ jsx(ArrayPopoverEditor, {
|
|
9434
|
+
field: activePopover.field,
|
|
9435
|
+
value: localDraft,
|
|
9436
|
+
onChange: (val) => setLocalDraft(val),
|
|
9437
|
+
collection: slug
|
|
9261
9438
|
})
|
|
9262
9439
|
]
|
|
9263
9440
|
})] })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dyrected/admin",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"tailwind-merge": "^3.5.0",
|
|
65
65
|
"tailwindcss-animate": "^1.0.7",
|
|
66
66
|
"zod": "^3.25.76",
|
|
67
|
-
"@dyrected/core": "^2.5.
|
|
68
|
-
"@dyrected/sdk": "^2.5.
|
|
67
|
+
"@dyrected/core": "^2.5.39",
|
|
68
|
+
"@dyrected/sdk": "^2.5.39"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@tanstack/react-query": "^5.0.0",
|