@dyrected/admin 2.5.30 → 2.5.33
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 +0 -4
- package/dist/index.mjs +129 -51
- package/dist/pages/collections/list-page.test.d.ts +1 -0
- package/dist/pages/dashboard/dashboard.test.d.ts +1 -0
- package/dist/pages/media/media-page.d.ts +3 -7
- package/dist/pages/media/media-page.test.d.ts +1 -0
- package/dist/pages/setup/setup-prompt.d.ts +9 -2
- package/dist/test/setup.d.ts +1 -0
- package/package.json +3 -3
package/dist/admin.css
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { HashRouter, Link, MemoryRouter, Route, Routes, useLocation, useNavigate
|
|
|
5
5
|
import { QueryClient, QueryClientProvider, useInfiniteQuery, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
6
6
|
import { createClient } from "@dyrected/sdk";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { AlertCircle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpRight, Bold, BookOpen, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Code2, Compass, Copy, Database, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, Filter, Globe, GripVertical, Heading1, Heading2, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, MoreHorizontal, PanelLeftClose, PanelLeftOpen, Pencil, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield,
|
|
8
|
+
import { AlertCircle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpRight, Bold, BookOpen, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Code2, Compass, Copy, Database, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, Filter, Globe, GripVertical, Heading1, Heading2, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, MoreHorizontal, PanelLeftClose, PanelLeftOpen, Pencil, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield, Smartphone, Sparkles, Strikethrough, Table, Trash2, Underline, Upload, UploadCloud, Users, Video, Volume2, X, XCircle, icons } from "lucide-react";
|
|
9
9
|
import { clsx } from "clsx";
|
|
10
10
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
11
11
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
@@ -9048,11 +9048,12 @@ function EditEntryPage() {
|
|
|
9048
9048
|
enabled: !!client
|
|
9049
9049
|
});
|
|
9050
9050
|
const schema = schemas?.collections.find((c) => c.slug === slug);
|
|
9051
|
-
const
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
if (
|
|
9055
|
-
|
|
9051
|
+
const schemaSlug = schema?.slug;
|
|
9052
|
+
const schemaPreviewUrl = schema?.admin?.previewUrl;
|
|
9053
|
+
useEffect(() => {
|
|
9054
|
+
if (!schemaSlug || !schemaPreviewUrl) return;
|
|
9055
|
+
setShowPreview((previous) => previous ? false : previous);
|
|
9056
|
+
}, [schemaSlug, schemaPreviewUrl]);
|
|
9056
9057
|
const { data: entry, isLoading: isEntryLoading } = useQuery({
|
|
9057
9058
|
queryKey: [
|
|
9058
9059
|
"entry",
|
|
@@ -9062,11 +9063,14 @@ function EditEntryPage() {
|
|
|
9062
9063
|
queryFn: () => client.collection(slug).findOne(id),
|
|
9063
9064
|
enabled: !!client && isEdit
|
|
9064
9065
|
});
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9066
|
+
useEffect(() => {
|
|
9067
|
+
if (!entry) return;
|
|
9068
|
+
setPreviewData((previous) => previous === entry ? previous : entry);
|
|
9069
|
+
}, [
|
|
9070
|
+
entry,
|
|
9071
|
+
id,
|
|
9072
|
+
slug
|
|
9073
|
+
]);
|
|
9070
9074
|
const isAdminUser = Array.isArray(user?.roles) && user.roles.includes("admin");
|
|
9071
9075
|
const isSelf = !!user && !!id && (user.id === id || user.sub === id);
|
|
9072
9076
|
const passwordChangeMode = schema?.auth ? isSelf ? "self" : isAdminUser ? "admin" : null : null;
|
|
@@ -9519,7 +9523,7 @@ Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
|
9519
9523
|
//#endregion
|
|
9520
9524
|
//#region src/pages/media/media-page.tsx
|
|
9521
9525
|
function MediaPage({ collectionSlug, schema }) {
|
|
9522
|
-
const { client } = useDyrected();
|
|
9526
|
+
const { client, components, user } = useDyrected();
|
|
9523
9527
|
const queryClient = useQueryClient();
|
|
9524
9528
|
const [search, setSearch] = React$1.useState("");
|
|
9525
9529
|
const [isUploadOpen, setIsUploadOpen] = React$1.useState(false);
|
|
@@ -9545,6 +9549,49 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9545
9549
|
const mediaResponse = React$1.useMemo(() => {
|
|
9546
9550
|
return data?.pages.flatMap((page) => page.docs) || [];
|
|
9547
9551
|
}, [data]);
|
|
9552
|
+
const readAccess = schema.access?.read;
|
|
9553
|
+
const createAccess = schema.access?.create;
|
|
9554
|
+
const evaluateAccess = (access) => {
|
|
9555
|
+
if (access === false) return false;
|
|
9556
|
+
if (typeof access !== "string") return true;
|
|
9557
|
+
try {
|
|
9558
|
+
return Boolean(jexl.evalSync(access, { user }));
|
|
9559
|
+
} catch (error) {
|
|
9560
|
+
console.warn("Media collection access evaluation failed:", error);
|
|
9561
|
+
return false;
|
|
9562
|
+
}
|
|
9563
|
+
};
|
|
9564
|
+
const canRead = evaluateAccess(readAccess);
|
|
9565
|
+
const canCreate = evaluateAccess(createAccess);
|
|
9566
|
+
const lastPage = data?.pages[data.pages.length - 1];
|
|
9567
|
+
const collectionComponentProps = {
|
|
9568
|
+
client,
|
|
9569
|
+
user,
|
|
9570
|
+
collection: schema,
|
|
9571
|
+
collectionSlug,
|
|
9572
|
+
response: lastPage ? {
|
|
9573
|
+
...lastPage,
|
|
9574
|
+
docs: mediaResponse
|
|
9575
|
+
} : void 0,
|
|
9576
|
+
documents: mediaResponse,
|
|
9577
|
+
isLoading,
|
|
9578
|
+
pagination: {
|
|
9579
|
+
page: lastPage?.page ?? 1,
|
|
9580
|
+
totalPages: lastPage?.totalPages ?? 1,
|
|
9581
|
+
total: lastPage?.total ?? 0,
|
|
9582
|
+
hasNextPage: Boolean(hasNextPage),
|
|
9583
|
+
hasPrevPage: Boolean(lastPage?.hasPrevPage)
|
|
9584
|
+
},
|
|
9585
|
+
permissions: {
|
|
9586
|
+
canRead,
|
|
9587
|
+
canCreate
|
|
9588
|
+
},
|
|
9589
|
+
urls: {
|
|
9590
|
+
collection: `/collections/${collectionSlug}`,
|
|
9591
|
+
create: `/collections/${collectionSlug}/new`
|
|
9592
|
+
}
|
|
9593
|
+
};
|
|
9594
|
+
const collectionSlots = schema.admin?.components;
|
|
9548
9595
|
const observerRef = React$1.useRef(null);
|
|
9549
9596
|
const sentinelRef = React$1.useCallback((node) => {
|
|
9550
9597
|
if (observerRef.current) {
|
|
@@ -9584,12 +9631,13 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9584
9631
|
}
|
|
9585
9632
|
});
|
|
9586
9633
|
const onDrop = React$1.useCallback((acceptedFiles) => {
|
|
9587
|
-
if (acceptedFiles.length > 0) {
|
|
9634
|
+
if (canCreate && acceptedFiles.length > 0) {
|
|
9588
9635
|
setUploadFiles(acceptedFiles);
|
|
9589
9636
|
setIsUploadOpen(true);
|
|
9590
9637
|
}
|
|
9591
|
-
}, []);
|
|
9638
|
+
}, [canCreate]);
|
|
9592
9639
|
const handlePaste = React$1.useCallback((e) => {
|
|
9640
|
+
if (!canCreate) return;
|
|
9593
9641
|
const items = e.clipboardData?.items;
|
|
9594
9642
|
if (!items) return;
|
|
9595
9643
|
const filesToUpload = [];
|
|
@@ -9602,7 +9650,7 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9602
9650
|
setUploadFiles((prev) => [...prev, ...filesToUpload]);
|
|
9603
9651
|
setIsUploadOpen(true);
|
|
9604
9652
|
}
|
|
9605
|
-
}, []);
|
|
9653
|
+
}, [canCreate]);
|
|
9606
9654
|
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
|
9607
9655
|
onDrop,
|
|
9608
9656
|
noClick: true
|
|
@@ -9611,6 +9659,19 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9611
9659
|
setIsUploadOpen(open);
|
|
9612
9660
|
if (!open) setUploadFiles([]);
|
|
9613
9661
|
};
|
|
9662
|
+
if (!canRead) return /* @__PURE__ */ jsx("div", {
|
|
9663
|
+
className: "dy-flex dy-h-[calc(100vh-200px)] dy-items-center dy-justify-center",
|
|
9664
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
9665
|
+
className: "dy-space-y-2 dy-text-center",
|
|
9666
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
9667
|
+
className: "dy-text-lg dy-font-bold",
|
|
9668
|
+
children: "Access Denied"
|
|
9669
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
9670
|
+
className: "dy-text-sm dy-text-muted-foreground",
|
|
9671
|
+
children: "You do not have permission to view this collection."
|
|
9672
|
+
})]
|
|
9673
|
+
})
|
|
9674
|
+
});
|
|
9614
9675
|
return /* @__PURE__ */ jsxs("div", {
|
|
9615
9676
|
...getRootProps(),
|
|
9616
9677
|
onPaste: handlePaste,
|
|
@@ -9630,6 +9691,12 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9630
9691
|
})]
|
|
9631
9692
|
})
|
|
9632
9693
|
}),
|
|
9694
|
+
/* @__PURE__ */ jsx(AdminComponentSlot, {
|
|
9695
|
+
slot: "beforeList",
|
|
9696
|
+
componentKeys: collectionSlots?.beforeList,
|
|
9697
|
+
registry: components?.collectionList,
|
|
9698
|
+
componentProps: collectionComponentProps
|
|
9699
|
+
}),
|
|
9633
9700
|
/* @__PURE__ */ jsxs("div", {
|
|
9634
9701
|
className: "dy-flex dy-flex-col dy-gap-4 dy-border-b dy-border-border/50 dy-pb-5 sm:dy-flex-row sm:dy-items-end sm:dy-justify-between sm:dy-pb-6",
|
|
9635
9702
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -9638,13 +9705,13 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9638
9705
|
className: "dy-flex dy-items-center dy-gap-2 dy-mb-1",
|
|
9639
9706
|
children: [/* @__PURE__ */ jsx(Image$1, { className: "dy-h-5 dy-w-5 dy-flex-shrink-0 dy-text-primary" }), /* @__PURE__ */ jsx("h1", {
|
|
9640
9707
|
className: "dy-min-w-0 dy-break-words dy-text-2xl dy-font-bold dy-tracking-tight dy-text-foreground sm:dy-text-3xl",
|
|
9641
|
-
children: schema
|
|
9708
|
+
children: schema.labels?.plural ?? (collectionSlug !== "media" ? collectionSlug.charAt(0).toUpperCase() + collectionSlug.slice(1) : "Media Library")
|
|
9642
9709
|
})]
|
|
9643
9710
|
}), /* @__PURE__ */ jsx("p", {
|
|
9644
9711
|
className: "dy-text-sm dy-leading-5 dy-text-muted-foreground",
|
|
9645
9712
|
children: "Manage your images, documents, and other assets for this site."
|
|
9646
9713
|
})]
|
|
9647
|
-
}), /* @__PURE__ */ jsxs(Dialog, {
|
|
9714
|
+
}), canCreate && /* @__PURE__ */ jsxs(Dialog, {
|
|
9648
9715
|
open: isUploadOpen,
|
|
9649
9716
|
onOpenChange: handleUploadOpenChange,
|
|
9650
9717
|
children: [/* @__PURE__ */ jsx(DialogTrigger, {
|
|
@@ -9685,6 +9752,12 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9685
9752
|
})]
|
|
9686
9753
|
})
|
|
9687
9754
|
}),
|
|
9755
|
+
/* @__PURE__ */ jsx(AdminComponentSlot, {
|
|
9756
|
+
slot: "beforeListTable",
|
|
9757
|
+
componentKeys: collectionSlots?.beforeListTable,
|
|
9758
|
+
registry: components?.collectionList,
|
|
9759
|
+
componentProps: collectionComponentProps
|
|
9760
|
+
}),
|
|
9688
9761
|
/* @__PURE__ */ jsx(ScrollArea, {
|
|
9689
9762
|
className: "dy-h-auto dy-pr-0 md:dy-h-[calc(100vh-320px)] md:dy-pr-4",
|
|
9690
9763
|
children: isLoading ? /* @__PURE__ */ jsx("div", {
|
|
@@ -9721,6 +9794,18 @@ function MediaPage({ collectionSlug, schema }) {
|
|
|
9721
9794
|
})]
|
|
9722
9795
|
})
|
|
9723
9796
|
}),
|
|
9797
|
+
/* @__PURE__ */ jsx(AdminComponentSlot, {
|
|
9798
|
+
slot: "afterListTable",
|
|
9799
|
+
componentKeys: collectionSlots?.afterListTable,
|
|
9800
|
+
registry: components?.collectionList,
|
|
9801
|
+
componentProps: collectionComponentProps
|
|
9802
|
+
}),
|
|
9803
|
+
/* @__PURE__ */ jsx(AdminComponentSlot, {
|
|
9804
|
+
slot: "afterList",
|
|
9805
|
+
componentKeys: collectionSlots?.afterList,
|
|
9806
|
+
registry: components?.collectionList,
|
|
9807
|
+
componentProps: collectionComponentProps
|
|
9808
|
+
}),
|
|
9724
9809
|
/* @__PURE__ */ jsx(MediaDetailsDialog, {
|
|
9725
9810
|
item: selectedItem,
|
|
9726
9811
|
collectionSlug,
|
|
@@ -10417,41 +10502,34 @@ function SetupPromptUI({ config }) {
|
|
|
10417
10502
|
className: "dy-relative dy-flex dy-items-end lg:dy-justify-end",
|
|
10418
10503
|
children: /* @__PURE__ */ jsxs("div", {
|
|
10419
10504
|
className: "dy-w-full dy-max-w-sm dy-rounded-2xl dy-border dy-border-border dy-bg-background/90 dy-p-5 dy-text-foreground dy-shadow-lg dy-backdrop-blur-sm",
|
|
10420
|
-
children: [
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
/* @__PURE__ */ jsxs("
|
|
10429
|
-
className: "dy-
|
|
10430
|
-
children: [/* @__PURE__ */
|
|
10431
|
-
className: "dy-
|
|
10432
|
-
children:
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
className: "dy-font-mono dy-font-semibold dy-text-foreground",
|
|
10437
|
-
children: stack ?? "Choose in guide"
|
|
10438
|
-
})]
|
|
10439
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
10440
|
-
className: "dy-flex dy-items-center dy-justify-between dy-gap-4",
|
|
10441
|
-
children: [/* @__PURE__ */ jsx("dt", {
|
|
10442
|
-
className: "dy-text-muted-foreground",
|
|
10443
|
-
children: "Site"
|
|
10444
|
-
}), /* @__PURE__ */ jsx("dd", {
|
|
10445
|
-
className: "dy-max-w-[180px] dy-truncate dy-font-mono dy-font-semibold dy-text-foreground",
|
|
10446
|
-
children: config.siteId || "Not provided"
|
|
10447
|
-
})]
|
|
10505
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
10506
|
+
className: "dy-mb-5 dy-flex dy-items-center dy-justify-between",
|
|
10507
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
10508
|
+
className: "dy-text-xs dy-font-bold dy-uppercase dy-tracking-[0.12em] dy-text-muted-foreground",
|
|
10509
|
+
children: "Context included"
|
|
10510
|
+
}), /* @__PURE__ */ jsx(Code2, { className: "dy-h-4 dy-w-4 dy-text-primary" })]
|
|
10511
|
+
}), /* @__PURE__ */ jsxs("dl", {
|
|
10512
|
+
className: "dy-space-y-4 dy-text-sm",
|
|
10513
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
10514
|
+
className: "dy-flex dy-items-center dy-justify-between dy-gap-4",
|
|
10515
|
+
children: [/* @__PURE__ */ jsx("dt", {
|
|
10516
|
+
className: "dy-text-muted-foreground",
|
|
10517
|
+
children: "Tech stack"
|
|
10518
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
10519
|
+
className: "dy-font-mono dy-font-semibold dy-text-foreground",
|
|
10520
|
+
children: stack ?? "Choose in guide"
|
|
10448
10521
|
})]
|
|
10449
|
-
}),
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
|
|
10453
|
-
|
|
10454
|
-
|
|
10522
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
10523
|
+
className: "dy-flex dy-items-center dy-justify-between dy-gap-4",
|
|
10524
|
+
children: [/* @__PURE__ */ jsx("dt", {
|
|
10525
|
+
className: "dy-text-muted-foreground",
|
|
10526
|
+
children: "Site"
|
|
10527
|
+
}), /* @__PURE__ */ jsx("dd", {
|
|
10528
|
+
className: "dy-max-w-[180px] dy-truncate dy-font-mono dy-font-semibold dy-text-foreground",
|
|
10529
|
+
children: config.siteId || "Not provided"
|
|
10530
|
+
})]
|
|
10531
|
+
})]
|
|
10532
|
+
})]
|
|
10455
10533
|
})
|
|
10456
10534
|
})]
|
|
10457
10535
|
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
+
import { CollectionConfig } from '@dyrected/core';
|
|
1
2
|
export declare function MediaPage({ collectionSlug, schema }: {
|
|
2
|
-
collectionSlug
|
|
3
|
-
schema
|
|
4
|
-
labels?: {
|
|
5
|
-
plural?: string;
|
|
6
|
-
};
|
|
7
|
-
label?: string;
|
|
8
|
-
};
|
|
3
|
+
collectionSlug: string;
|
|
4
|
+
schema: CollectionConfig;
|
|
9
5
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export interface SetupPromptConfig {
|
|
2
|
+
siteName?: string;
|
|
3
|
+
siteId?: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
isSelfHosted?: boolean;
|
|
7
|
+
existingSite?: boolean;
|
|
8
|
+
defaultTechStack?: string;
|
|
9
|
+
}
|
|
3
10
|
export interface SetupPromptProps {
|
|
4
11
|
config: SetupPromptConfig;
|
|
5
12
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dyrected/admin",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"tailwind-merge": "^3.5.0",
|
|
63
63
|
"tailwindcss-animate": "^1.0.7",
|
|
64
64
|
"zod": "^3.25.76",
|
|
65
|
-
"@dyrected/core": "^2.5.
|
|
66
|
-
"@dyrected/sdk": "^2.5.
|
|
65
|
+
"@dyrected/core": "^2.5.33",
|
|
66
|
+
"@dyrected/sdk": "^2.5.33"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@tanstack/react-query": "^5.0.0",
|