@dyrected/admin 2.5.56 → 2.5.59
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HeadingLevel, RichTextFeature } from '@dyrected/core';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
interface RichTextEditorProps {
|
|
3
4
|
value: string;
|
|
@@ -5,6 +6,10 @@ interface RichTextEditorProps {
|
|
|
5
6
|
label?: string;
|
|
6
7
|
disabled?: boolean;
|
|
7
8
|
collection?: string;
|
|
9
|
+
/** Enabled editor capabilities. When omitted, every feature is enabled. */
|
|
10
|
+
features?: RichTextFeature[];
|
|
11
|
+
/** Heading levels offered by the `heading` feature. Defaults to `[1, 2, 3]`. */
|
|
12
|
+
headingLevels?: HeadingLevel[];
|
|
8
13
|
}
|
|
9
|
-
export declare function RichTextEditor({ value, onChange, label, disabled, collection }: RichTextEditorProps): React.JSX.Element;
|
|
14
|
+
export declare function RichTextEditor({ value, onChange, label, disabled, collection, features, headingLevels }: RichTextEditorProps): React.JSX.Element;
|
|
10
15
|
export {};
|
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, AlertTriangle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpDown, ArrowUpRight, Bold, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Copy, Database, Download, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, FileUp, Filter, Globe, GripVertical, Heading1, Heading2, Home, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, LayoutGrid, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, Moon, MoreHorizontal, MousePointer2, PanelLeftClose, PanelLeftOpen, Pencil, Play, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield, Smartphone, Sparkles, Strikethrough, Sun, Table, Trash2, Underline, Undo2, Upload, UploadCloud, Users, Video, Volume2, Workflow, X, XCircle, icons } from "lucide-react";
|
|
8
|
+
import { AlertCircle, AlertTriangle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpDown, ArrowUpRight, Bold, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Copy, Database, Download, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, FileUp, Filter, Globe, GripVertical, Heading1, Heading2, Heading3, Heading4, Heading5, Heading6, Home, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, LayoutGrid, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, Moon, MoreHorizontal, MousePointer2, PanelLeftClose, PanelLeftOpen, Pencil, Play, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield, Smartphone, Sparkles, Strikethrough, Sun, Table, Trash2, Underline, Undo2, Upload, UploadCloud, Users, Video, Volume2, Workflow, 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";
|
|
@@ -30,8 +30,6 @@ import { EditorContent, useEditor } from "@tiptap/react";
|
|
|
30
30
|
import StarterKit from "@tiptap/starter-kit";
|
|
31
31
|
import TextAlign from "@tiptap/extension-text-align";
|
|
32
32
|
import Image$2 from "@tiptap/extension-image";
|
|
33
|
-
import LinkExtension from "@tiptap/extension-link";
|
|
34
|
-
import Underline$1 from "@tiptap/extension-underline";
|
|
35
33
|
import { TableKit } from "@tiptap/extension-table";
|
|
36
34
|
import * as TogglePrimitive from "@radix-ui/react-toggle";
|
|
37
35
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
@@ -578,7 +576,7 @@ var SheetOverlay = React$1.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
578
576
|
ref
|
|
579
577
|
}));
|
|
580
578
|
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
|
|
581
|
-
var sheetVariants = cva("dy-fixed dy-z-50 dy-gap-4 dy-bg-background dy-p-
|
|
579
|
+
var sheetVariants = cva("dy-fixed dy-z-50 dy-gap-4 dy-bg-background dy-p-0 dy-shadow-2xl dy-transition dy-ease-in-out data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-duration-300 data-[state=open]:dy-duration-500", {
|
|
582
580
|
variants: { side: {
|
|
583
581
|
top: "dy-inset-x-0 dy-top-0 dy-border-b data-[state=closed]:dy-slide-out-to-top data-[state=open]:dy-slide-in-from-top",
|
|
584
582
|
bottom: "dy-inset-x-0 dy-bottom-0 dy-border-t data-[state=closed]:dy-slide-out-to-bottom data-[state=open]:dy-slide-in-from-bottom",
|
|
@@ -967,7 +965,7 @@ function isNewerVersion(latest, current) {
|
|
|
967
965
|
return false;
|
|
968
966
|
}
|
|
969
967
|
function useUpdateCheck() {
|
|
970
|
-
const currentVersion = "2.5.
|
|
968
|
+
const currentVersion = "2.5.58";
|
|
971
969
|
const [updateInfo, setUpdateInfo] = useState(() => {
|
|
972
970
|
if (typeof window === "undefined") return null;
|
|
973
971
|
const cacheKey = "dyrected_latest_release";
|
|
@@ -1114,20 +1112,24 @@ function AdminShell({ children, isEmbedded = false }) {
|
|
|
1114
1112
|
})
|
|
1115
1113
|
}), /* @__PURE__ */ jsxs("div", {
|
|
1116
1114
|
className: "dy-ml-auto dy-flex dy-items-center dy-gap-1.5",
|
|
1117
|
-
children: [
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1115
|
+
children: [
|
|
1116
|
+
/* @__PURE__ */ jsx(ThemeSelector, { mobile: true }),
|
|
1117
|
+
user && /* @__PURE__ */ jsx("div", {
|
|
1118
|
+
className: "dy-flex dy-h-8 dy-w-8 dy-items-center dy-justify-center dy-rounded-full dy-bg-primary/10 dy-text-primary dy-font-semibold dy-text-xs dy-shrink-0",
|
|
1119
|
+
children: (user.name || user.email || "?").charAt(0).toUpperCase()
|
|
1120
|
+
}),
|
|
1121
|
+
/* @__PURE__ */ jsx("button", {
|
|
1122
|
+
type: "button",
|
|
1123
|
+
onClick: () => setMobileOpen(true),
|
|
1124
|
+
className: "dy-flex dy-h-9 dy-w-9 dy-items-center dy-justify-center dy-rounded-md dy-text-muted-foreground hover:dy-bg-accent hover:dy-text-foreground dy-transition-colors",
|
|
1125
|
+
"aria-label": "Open menu",
|
|
1126
|
+
children: /* @__PURE__ */ jsx(Menu, { className: "dy-h-5 dy-w-5" })
|
|
1127
|
+
})
|
|
1128
|
+
]
|
|
1121
1129
|
})]
|
|
1122
|
-
}), /* @__PURE__ */
|
|
1130
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1123
1131
|
className: "dy-flex-1 dy-py-6 dy-px-4 lg:dy-py-10 lg:dy-px-6",
|
|
1124
|
-
children
|
|
1125
|
-
type: "button",
|
|
1126
|
-
onClick: () => setMobileOpen(true),
|
|
1127
|
-
className: "dy-flex dy-h-9 dy-w-9 dy-items-center dy-justify-center dy-rounded-md dy-text-muted-foreground hover:dy-bg-accent hover:dy-text-foreground dy-transition-colors",
|
|
1128
|
-
"aria-label": "Open menu",
|
|
1129
|
-
children: /* @__PURE__ */ jsx(Menu, { className: "dy-h-5 dy-w-5" })
|
|
1130
|
-
})]
|
|
1132
|
+
children
|
|
1131
1133
|
})]
|
|
1132
1134
|
})
|
|
1133
1135
|
]
|
|
@@ -1217,7 +1219,7 @@ function getStatusLabel(doc) {
|
|
|
1217
1219
|
}
|
|
1218
1220
|
function Dashboard() {
|
|
1219
1221
|
const { client, components, user } = useDyrected();
|
|
1220
|
-
const currentVersion = "2.5.
|
|
1222
|
+
const currentVersion = "2.5.58";
|
|
1221
1223
|
const [latestVersion, setLatestVersion] = useState(() => {
|
|
1222
1224
|
if (typeof window === "undefined") return null;
|
|
1223
1225
|
return localStorage.getItem("dyrected_latest_release");
|
|
@@ -3294,6 +3296,28 @@ function MediaGrid({ items, baseUrl, onDelete, slug }) {
|
|
|
3294
3296
|
});
|
|
3295
3297
|
}
|
|
3296
3298
|
//#endregion
|
|
3299
|
+
//#region src/lib/preview-url.ts
|
|
3300
|
+
/**
|
|
3301
|
+
* Resolves the previewUrl from a collection schema against a document entry.
|
|
3302
|
+
* Handles both function-based configurations and Jexl string evaluations.
|
|
3303
|
+
*/
|
|
3304
|
+
function resolvePreviewUrl(previewUrlConfig, entry, siteUrl) {
|
|
3305
|
+
if (!previewUrlConfig) return null;
|
|
3306
|
+
let previewUrl = typeof previewUrlConfig === "function" ? previewUrlConfig(entry, { locale: "en" }) : previewUrlConfig;
|
|
3307
|
+
if (typeof previewUrl === "string" && previewUrl.includes("{{")) previewUrl = previewUrl.replace(/{{(.*?)}}/g, (_, key) => String(entry?.[key.trim()] || ""));
|
|
3308
|
+
else if (typeof previewUrl === "string" && entry) try {
|
|
3309
|
+
const context = {
|
|
3310
|
+
...entry,
|
|
3311
|
+
siteUrl
|
|
3312
|
+
};
|
|
3313
|
+
if (previewUrl.includes("+") || previewUrl.includes("?") || previewUrl.includes("==") || previewUrl.includes("siteUrl")) previewUrl = jexl.evalSync(previewUrl, context);
|
|
3314
|
+
} catch (e) {
|
|
3315
|
+
console.error("[PreviewDebug] Jexl Evaluation Failed:", e);
|
|
3316
|
+
}
|
|
3317
|
+
if (typeof previewUrl === "string" && previewUrl.startsWith("/")) previewUrl = `${siteUrl}${previewUrl}`;
|
|
3318
|
+
return typeof previewUrl === "string" ? previewUrl : null;
|
|
3319
|
+
}
|
|
3320
|
+
//#endregion
|
|
3297
3321
|
//#region src/components/ui/toggle.tsx
|
|
3298
3322
|
var toggleVariants = cva("dy-inline-flex dy-items-center dy-justify-center dy-rounded-md dy-text-sm dy-font-medium dy-ring-offset-background dy-transition-colors hover:dy-bg-muted hover:dy-text-muted-foreground focus-visible:dy-outline-none focus-visible:dy-ring-2 focus-visible:dy-ring-ring focus-visible:dy-ring-offset-2 disabled:dy-pointer-events-none disabled:dy-opacity-50 data-[state=on]:dy-bg-accent data-[state=on]:dy-text-accent-foreground [&_svg]:dy-pointer-events-none [&_svg]:dy-size-4 [&_svg]:dy-shrink-0 dy-gap-2", {
|
|
3299
3323
|
variants: {
|
|
@@ -4705,11 +4729,35 @@ var Label = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
4705
4729
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
4706
4730
|
//#endregion
|
|
4707
4731
|
//#region src/components/forms/fields/rich-text-editor.tsx
|
|
4708
|
-
var
|
|
4732
|
+
var DEFAULT_HEADING_LEVELS = [
|
|
4733
|
+
1,
|
|
4734
|
+
2,
|
|
4735
|
+
3
|
|
4736
|
+
];
|
|
4737
|
+
var HEADING_ICONS = {
|
|
4738
|
+
1: Heading1,
|
|
4739
|
+
2: Heading2,
|
|
4740
|
+
3: Heading3,
|
|
4741
|
+
4: Heading4,
|
|
4742
|
+
5: Heading5,
|
|
4743
|
+
6: Heading6
|
|
4744
|
+
};
|
|
4745
|
+
/** True when `feature` is enabled. An undefined feature list means every feature is on. */
|
|
4746
|
+
function hasFeature(features, feature) {
|
|
4747
|
+
return !features || features.includes(feature);
|
|
4748
|
+
}
|
|
4749
|
+
var Separator$1 = () => /* @__PURE__ */ jsx("div", { className: "dy-w-[1px] dy-h-6 dy-bg-border dy-mx-1" });
|
|
4750
|
+
var MenuBar = ({ editor, collection = "media", features, headingLevels }) => {
|
|
4709
4751
|
const [linkOpen, setLinkOpen] = React$1.useState(false);
|
|
4710
4752
|
const [linkUrl, setLinkUrl] = React$1.useState("");
|
|
4711
4753
|
const [linkNewTab, setLinkNewTab] = React$1.useState(false);
|
|
4712
4754
|
if (!editor) return null;
|
|
4755
|
+
const has = (feature) => hasFeature(features, feature);
|
|
4756
|
+
const inlineGroup = has("bold") || has("italic") || has("underline") || has("strike");
|
|
4757
|
+
const blockGroup = has("heading") || has("bulletList") || has("orderedList") || has("blockquote");
|
|
4758
|
+
const alignGroup = has("align");
|
|
4759
|
+
const linkGroup = has("link");
|
|
4760
|
+
const tableGroup = has("table");
|
|
4713
4761
|
const openLinkDialog = () => {
|
|
4714
4762
|
const attrs = editor.getAttributes("link");
|
|
4715
4763
|
setLinkUrl(attrs.href || "");
|
|
@@ -4731,82 +4779,85 @@ var MenuBar = ({ editor, collection = "media" }) => {
|
|
|
4731
4779
|
return /* @__PURE__ */ jsxs("div", {
|
|
4732
4780
|
className: "dy-border dy-border-input dy-rounded-t-md dy-p-1 dy-flex dy-flex-wrap dy-gap-1 dy-items-center dy-bg-muted/50",
|
|
4733
4781
|
children: [
|
|
4734
|
-
/* @__PURE__ */
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
/* @__PURE__ */ jsx(
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4782
|
+
inlineGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4783
|
+
has("bold") && /* @__PURE__ */ jsx(Toggle, {
|
|
4784
|
+
size: "sm",
|
|
4785
|
+
pressed: editor.isActive("bold"),
|
|
4786
|
+
onPressedChange: () => editor.chain().focus().toggleBold().run(),
|
|
4787
|
+
children: /* @__PURE__ */ jsx(Bold, { className: "dy-h-4 dy-w-4" })
|
|
4788
|
+
}),
|
|
4789
|
+
has("italic") && /* @__PURE__ */ jsx(Toggle, {
|
|
4790
|
+
size: "sm",
|
|
4791
|
+
pressed: editor.isActive("italic"),
|
|
4792
|
+
onPressedChange: () => editor.chain().focus().toggleItalic().run(),
|
|
4793
|
+
children: /* @__PURE__ */ jsx(Italic, { className: "dy-h-4 dy-w-4" })
|
|
4794
|
+
}),
|
|
4795
|
+
has("underline") && /* @__PURE__ */ jsx(Toggle, {
|
|
4796
|
+
size: "sm",
|
|
4797
|
+
pressed: editor.isActive("underline"),
|
|
4798
|
+
onPressedChange: () => editor.chain().focus().toggleUnderline().run(),
|
|
4799
|
+
children: /* @__PURE__ */ jsx(Underline, { className: "dy-h-4 dy-w-4" })
|
|
4800
|
+
}),
|
|
4801
|
+
has("strike") && /* @__PURE__ */ jsx(Toggle, {
|
|
4802
|
+
size: "sm",
|
|
4803
|
+
pressed: editor.isActive("strike"),
|
|
4804
|
+
onPressedChange: () => editor.chain().focus().toggleStrike().run(),
|
|
4805
|
+
children: /* @__PURE__ */ jsx(Strikethrough, { className: "dy-h-4 dy-w-4" })
|
|
4806
|
+
})
|
|
4807
|
+
] }),
|
|
4808
|
+
inlineGroup && blockGroup && /* @__PURE__ */ jsx(Separator$1, {}),
|
|
4809
|
+
blockGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4810
|
+
has("heading") && headingLevels.map((level) => {
|
|
4811
|
+
const Icon = HEADING_ICONS[level];
|
|
4812
|
+
return /* @__PURE__ */ jsx(Toggle, {
|
|
4813
|
+
size: "sm",
|
|
4814
|
+
pressed: editor.isActive("heading", { level }),
|
|
4815
|
+
onPressedChange: () => editor.chain().focus().toggleHeading({ level }).run(),
|
|
4816
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "dy-h-4 dy-w-4" })
|
|
4817
|
+
}, level);
|
|
4818
|
+
}),
|
|
4819
|
+
has("bulletList") && /* @__PURE__ */ jsx(Toggle, {
|
|
4820
|
+
size: "sm",
|
|
4821
|
+
pressed: editor.isActive("bulletList"),
|
|
4822
|
+
onPressedChange: () => editor.chain().focus().toggleBulletList().run(),
|
|
4823
|
+
children: /* @__PURE__ */ jsx(List, { className: "dy-h-4 dy-w-4" })
|
|
4824
|
+
}),
|
|
4825
|
+
has("orderedList") && /* @__PURE__ */ jsx(Toggle, {
|
|
4826
|
+
size: "sm",
|
|
4827
|
+
pressed: editor.isActive("orderedList"),
|
|
4828
|
+
onPressedChange: () => editor.chain().focus().toggleOrderedList().run(),
|
|
4829
|
+
children: /* @__PURE__ */ jsx(ListOrdered, { className: "dy-h-4 dy-w-4" })
|
|
4830
|
+
}),
|
|
4831
|
+
has("blockquote") && /* @__PURE__ */ jsx(Toggle, {
|
|
4832
|
+
size: "sm",
|
|
4833
|
+
pressed: editor.isActive("blockquote"),
|
|
4834
|
+
onPressedChange: () => editor.chain().focus().toggleBlockquote().run(),
|
|
4835
|
+
children: /* @__PURE__ */ jsx(Quote, { className: "dy-h-4 dy-w-4" })
|
|
4836
|
+
})
|
|
4837
|
+
] }),
|
|
4838
|
+
(inlineGroup || blockGroup) && alignGroup && /* @__PURE__ */ jsx(Separator$1, {}),
|
|
4839
|
+
alignGroup && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4840
|
+
/* @__PURE__ */ jsx(Toggle, {
|
|
4841
|
+
size: "sm",
|
|
4842
|
+
pressed: editor.isActive({ textAlign: "left" }),
|
|
4843
|
+
onPressedChange: () => editor.chain().focus().setTextAlign("left").run(),
|
|
4844
|
+
children: /* @__PURE__ */ jsx(AlignLeft, { className: "dy-h-4 dy-w-4" })
|
|
4845
|
+
}),
|
|
4846
|
+
/* @__PURE__ */ jsx(Toggle, {
|
|
4847
|
+
size: "sm",
|
|
4848
|
+
pressed: editor.isActive({ textAlign: "center" }),
|
|
4849
|
+
onPressedChange: () => editor.chain().focus().setTextAlign("center").run(),
|
|
4850
|
+
children: /* @__PURE__ */ jsx(AlignCenter, { className: "dy-h-4 dy-w-4" })
|
|
4851
|
+
}),
|
|
4852
|
+
/* @__PURE__ */ jsx(Toggle, {
|
|
4853
|
+
size: "sm",
|
|
4854
|
+
pressed: editor.isActive({ textAlign: "right" }),
|
|
4855
|
+
onPressedChange: () => editor.chain().focus().setTextAlign("right").run(),
|
|
4856
|
+
children: /* @__PURE__ */ jsx(AlignRight, { className: "dy-h-4 dy-w-4" })
|
|
4857
|
+
})
|
|
4858
|
+
] }),
|
|
4859
|
+
(inlineGroup || blockGroup || alignGroup) && linkGroup && /* @__PURE__ */ jsx(Separator$1, {}),
|
|
4860
|
+
linkGroup && /* @__PURE__ */ jsxs(Popover, {
|
|
4810
4861
|
open: linkOpen,
|
|
4811
4862
|
onOpenChange: setLinkOpen,
|
|
4812
4863
|
children: [/* @__PURE__ */ jsx(PopoverTrigger, {
|
|
@@ -4873,8 +4924,8 @@ var MenuBar = ({ editor, collection = "media" }) => {
|
|
|
4873
4924
|
})
|
|
4874
4925
|
})]
|
|
4875
4926
|
}),
|
|
4876
|
-
/* @__PURE__ */ jsx(
|
|
4877
|
-
/* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
4927
|
+
(inlineGroup || blockGroup || alignGroup || linkGroup) && tableGroup && /* @__PURE__ */ jsx(Separator$1, {}),
|
|
4928
|
+
tableGroup && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
4878
4929
|
asChild: true,
|
|
4879
4930
|
children: /* @__PURE__ */ jsx(Toggle, {
|
|
4880
4931
|
size: "sm",
|
|
@@ -4935,7 +4986,7 @@ var MenuBar = ({ editor, collection = "media" }) => {
|
|
|
4935
4986
|
})
|
|
4936
4987
|
]
|
|
4937
4988
|
})] }),
|
|
4938
|
-
/* @__PURE__ */ jsx("div", {
|
|
4989
|
+
has("image") && /* @__PURE__ */ jsx("div", {
|
|
4939
4990
|
className: "dy-ml-auto",
|
|
4940
4991
|
children: /* @__PURE__ */ jsx(MediaPicker, {
|
|
4941
4992
|
collection,
|
|
@@ -4956,24 +5007,34 @@ var MenuBar = ({ editor, collection = "media" }) => {
|
|
|
4956
5007
|
]
|
|
4957
5008
|
});
|
|
4958
5009
|
};
|
|
4959
|
-
function RichTextEditor({ value, onChange, label, disabled, collection = "media" }) {
|
|
5010
|
+
function RichTextEditor({ value, onChange, label, disabled, collection = "media", features, headingLevels }) {
|
|
4960
5011
|
const [editingImage, setEditingImage] = React$1.useState(null);
|
|
4961
5012
|
const [tempAlt, setTempAlt] = React$1.useState("");
|
|
5013
|
+
const levels = headingLevels ?? DEFAULT_HEADING_LEVELS;
|
|
5014
|
+
const has = (feature) => hasFeature(features, feature);
|
|
4962
5015
|
const editor = useEditor({
|
|
4963
5016
|
extensions: [
|
|
4964
|
-
StarterKit
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
5017
|
+
StarterKit.configure({
|
|
5018
|
+
bold: has("bold") ? void 0 : false,
|
|
5019
|
+
italic: has("italic") ? void 0 : false,
|
|
5020
|
+
strike: has("strike") ? void 0 : false,
|
|
5021
|
+
underline: has("underline") ? void 0 : false,
|
|
5022
|
+
blockquote: has("blockquote") ? void 0 : false,
|
|
5023
|
+
bulletList: has("bulletList") ? void 0 : false,
|
|
5024
|
+
orderedList: has("orderedList") ? void 0 : false,
|
|
5025
|
+
heading: has("heading") ? { levels } : false,
|
|
5026
|
+
link: has("link") ? {
|
|
5027
|
+
openOnClick: false,
|
|
5028
|
+
HTMLAttributes: { rel: "noopener noreferrer" }
|
|
5029
|
+
} : false
|
|
4971
5030
|
}),
|
|
4972
|
-
|
|
5031
|
+
...has("align") ? [TextAlign.configure({ types: ["heading", "paragraph"] })] : [],
|
|
5032
|
+
...has("image") ? [Image$2.configure({ HTMLAttributes: { class: "rounded-md max-w-full h-auto my-4 cursor-pointer hover:ring-2 hover:ring-primary/50 transition-all" } })] : [],
|
|
5033
|
+
...has("table") ? [TableKit.configure({
|
|
4973
5034
|
table: { HTMLAttributes: { class: "dy-border-collapse dy-w-full dy-my-4" } },
|
|
4974
5035
|
tableCell: { HTMLAttributes: { class: "dy-border dy-border-border dy-p-2 dy-align-top dy-min-w-[100px]" } },
|
|
4975
5036
|
tableHeader: { HTMLAttributes: { class: "dy-border dy-border-border dy-p-2 dy-bg-muted dy-font-semibold dy-text-left" } }
|
|
4976
|
-
})
|
|
5037
|
+
})] : []
|
|
4977
5038
|
],
|
|
4978
5039
|
content: value,
|
|
4979
5040
|
editable: !disabled,
|
|
@@ -5030,7 +5091,9 @@ function RichTextEditor({ value, onChange, label, disabled, collection = "media"
|
|
|
5030
5091
|
className: "dy-flex dy-flex-col dy-w-full",
|
|
5031
5092
|
children: [!disabled && /* @__PURE__ */ jsx(MenuBar, {
|
|
5032
5093
|
editor,
|
|
5033
|
-
collection
|
|
5094
|
+
collection,
|
|
5095
|
+
features,
|
|
5096
|
+
headingLevels: levels
|
|
5034
5097
|
}), /* @__PURE__ */ jsx(EditorContent, {
|
|
5035
5098
|
editor,
|
|
5036
5099
|
className: cn(disabled && "dy-opacity-80 dy-prose prose lg:prose-xl lg:dy-prose-xl")
|
|
@@ -5855,6 +5918,7 @@ function initSandbox() {
|
|
|
5855
5918
|
`;
|
|
5856
5919
|
document.body.appendChild(sandboxIframe);
|
|
5857
5920
|
window.addEventListener("message", (event) => {
|
|
5921
|
+
if (!sandboxIframe?.contentWindow || event.source !== sandboxIframe.contentWindow) return;
|
|
5858
5922
|
if (event.data && typeof event.data === "object" && "hookId" in event.data) {
|
|
5859
5923
|
const { hookId, result, error } = event.data;
|
|
5860
5924
|
const handler = messageHandlers.get(hookId);
|
|
@@ -7447,12 +7511,17 @@ function FieldRenderer({ schema, field, collection, context }) {
|
|
|
7447
7511
|
disabled,
|
|
7448
7512
|
multiple: relSchema.hasMany
|
|
7449
7513
|
});
|
|
7450
|
-
case "richText":
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7514
|
+
case "richText": {
|
|
7515
|
+
const rtSchema = schema;
|
|
7516
|
+
return /* @__PURE__ */ jsx(RichTextEditor, {
|
|
7517
|
+
collection: rtSchema.uploadCollection || context?.schemas?.collections?.find((c) => c.upload)?.slug || "media",
|
|
7518
|
+
value: field.value,
|
|
7519
|
+
onChange: field.onChange,
|
|
7520
|
+
disabled,
|
|
7521
|
+
features: rtSchema.features,
|
|
7522
|
+
headingLevels: rtSchema.headingLevels
|
|
7523
|
+
});
|
|
7524
|
+
}
|
|
7456
7525
|
case "json": return /* @__PURE__ */ jsx(JsonEditor, {
|
|
7457
7526
|
value: field.value,
|
|
7458
7527
|
onChange: field.onChange,
|
|
@@ -10761,21 +10830,8 @@ function CollectionListPage({ slug }) {
|
|
|
10761
10830
|
return true;
|
|
10762
10831
|
};
|
|
10763
10832
|
const getPreviewUrl = (item) => {
|
|
10764
|
-
if (!schema?.admin?.previewUrl) return null;
|
|
10765
|
-
let previewUrl = typeof schema.admin.previewUrl === "function" ? schema.admin.previewUrl(item, { locale: "en" }) : schema.admin.previewUrl;
|
|
10766
10833
|
const siteUrl = getSiteUrl(schemas?.admin?.siteUrl);
|
|
10767
|
-
|
|
10768
|
-
else if (typeof previewUrl === "string") try {
|
|
10769
|
-
const context = {
|
|
10770
|
-
...item,
|
|
10771
|
-
siteUrl
|
|
10772
|
-
};
|
|
10773
|
-
if (previewUrl.includes("+") || previewUrl.includes("?") || previewUrl.includes("==") || previewUrl.includes("siteUrl")) previewUrl = jexl.evalSync(previewUrl, context);
|
|
10774
|
-
} catch (e) {
|
|
10775
|
-
console.warn("Preview URL eval failed:", e);
|
|
10776
|
-
}
|
|
10777
|
-
if (typeof previewUrl === "string" && previewUrl.startsWith("/")) previewUrl = `${siteUrl}${previewUrl}`;
|
|
10778
|
-
return typeof previewUrl === "string" ? previewUrl : null;
|
|
10834
|
+
return resolvePreviewUrl(schema?.admin?.previewUrl, item, siteUrl);
|
|
10779
10835
|
};
|
|
10780
10836
|
const renderLinkedCell = (item, cell) => {
|
|
10781
10837
|
const canDelete = canDeleteRow(item);
|
|
@@ -12150,19 +12206,8 @@ function EditEntryPage() {
|
|
|
12150
12206
|
const workflowMeta = isEdit && entry ? entry._workflow ?? null : null;
|
|
12151
12207
|
const hasStatus = schema?.fields.some((f) => f.name === "status");
|
|
12152
12208
|
const currentStatus = entry?.status || "draft";
|
|
12153
|
-
let previewUrl = typeof schema.admin?.previewUrl === "function" ? schema.admin.previewUrl(previewData || entry, { locale: "en" }) : schema.admin?.previewUrl;
|
|
12154
12209
|
const siteUrl = getSiteUrl(schemas?.admin?.siteUrl);
|
|
12155
|
-
|
|
12156
|
-
else if (typeof previewUrl === "string" && (previewData || entry)) try {
|
|
12157
|
-
const context = {
|
|
12158
|
-
...previewData || entry,
|
|
12159
|
-
siteUrl
|
|
12160
|
-
};
|
|
12161
|
-
if (previewUrl.includes("+") || previewUrl.includes("?") || previewUrl.includes("==") || previewUrl.includes("siteUrl")) previewUrl = jexl.evalSync(previewUrl, context);
|
|
12162
|
-
} catch (e) {
|
|
12163
|
-
console.error("[PreviewDebug] Jexl Evaluation Failed:", e);
|
|
12164
|
-
}
|
|
12165
|
-
if (typeof previewUrl === "string" && previewUrl.startsWith("/")) previewUrl = `${siteUrl}${previewUrl}`;
|
|
12210
|
+
const previewUrl = resolvePreviewUrl(schema.admin?.previewUrl, previewData || entry, siteUrl);
|
|
12166
12211
|
const readAccess = schema.access?.read;
|
|
12167
12212
|
let canRead = true;
|
|
12168
12213
|
if (readAccess === false) canRead = false;
|
|
@@ -13923,7 +13968,7 @@ function SetupPromptUI({ config }) {
|
|
|
13923
13968
|
setCopied(true);
|
|
13924
13969
|
window.setTimeout(() => setCopied(false), 1800);
|
|
13925
13970
|
}
|
|
13926
|
-
const currentVersion = "2.5.
|
|
13971
|
+
const currentVersion = "2.5.58";
|
|
13927
13972
|
const [latestVersion, setLatestVersion] = useState(() => {
|
|
13928
13973
|
if (typeof window === "undefined") return null;
|
|
13929
13974
|
return localStorage.getItem("dyrected_latest_release");
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the previewUrl from a collection schema against a document entry.
|
|
3
|
+
* Handles both function-based configurations and Jexl string evaluations.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolvePreviewUrl(previewUrlConfig: string | ((doc: any, opts: any) => string | null) | undefined, entry: any, siteUrl: string): string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dyrected/admin",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.59",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -64,9 +64,9 @@
|
|
|
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.
|
|
69
|
-
"@dyrected/knowledge": "^0.2.
|
|
67
|
+
"@dyrected/core": "^2.5.59",
|
|
68
|
+
"@dyrected/sdk": "^2.5.59",
|
|
69
|
+
"@dyrected/knowledge": "^0.2.11"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
72
|
"@tanstack/react-query": "^5.0.0",
|