tinacms 3.9.4 → 3.10.0
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/index.js +215 -104
- package/dist/internalClient/index.d.ts +1 -0
- package/dist/lib/posthog/posthog.d.ts +6 -0
- package/dist/react.js +17 -10
- package/dist/toolkit/form-builder/create-branch-modal.d.ts +6 -3
- package/dist/toolkit/form-builder/save-options.d.ts +7 -0
- package/dist/toolkit/form-builder/use-editorial-workflow.d.ts +6 -2
- package/dist/toolkit/styles/dropdown-button.d.ts +2 -0
- package/package.json +12 -13
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import React__default, { useState, useCallback, useRef, useEffect, createContext
|
|
|
10
10
|
import { createPortal } from "react-dom";
|
|
11
11
|
import { clsx } from "clsx";
|
|
12
12
|
import { twMerge } from "tailwind-merge";
|
|
13
|
-
import { withRef, cn as cn$1, withCn, createPrimitiveElement, withVariants, withProps, useComposedRef as useComposedRef$1
|
|
13
|
+
import { withRef, cn as cn$1, withCn, createPrimitiveElement, withVariants, withProps, PortalBody, useComposedRef as useComposedRef$1 } from "@udecode/cn";
|
|
14
14
|
import { CodePlugin, UnderlinePlugin, StrikethroughPlugin, ItalicPlugin, BoldPlugin, BasicMarksPlugin } from "@udecode/plate-basic-marks/react";
|
|
15
15
|
import { BlockquotePlugin } from "@udecode/plate-block-quote/react";
|
|
16
16
|
import { CodeBlockPlugin, CodeLinePlugin, CodeSyntaxPlugin } from "@udecode/plate-code-block/react";
|
|
@@ -23,7 +23,7 @@ import { SlashInputPlugin, SlashPlugin } from "@udecode/plate-slash-command/reac
|
|
|
23
23
|
import { TablePlugin, TableRowPlugin, useTableCellElement, TableProvider, useTableElement, useTableMergeState, useTableBordersDropdownMenuContentState, TableCellHeaderPlugin, TableCellPlugin } from "@udecode/plate-table/react";
|
|
24
24
|
import { PlateElement, useReadOnly, useElement, PlateLeaf, useSelected, useFocused, useEditorRef, withRef as withRef$1, useComposedRef, useEditorPlugin, useElementSelector, withHOC, usePluginOption, useRemoveNodeButton, useEditorSelector, ParagraphPlugin, createPlatePlugin, PlateContent, PlateContainer, useEditorState, useMarkToolbarButtonState, useMarkToolbarButton, usePlateEditor, useFormInputProps, useEditorSelection, useEditorReadOnly, useOnClickOutside, useEventEditorValue, Plate } from "@udecode/plate/react";
|
|
25
25
|
import { isLangSupported, formatCodeBlock, insertEmptyCodeBlock, unwrapCodeBlock, isCodeBlockEmpty, isSelectionAtCodeBlockStart } from "@udecode/plate-code-block";
|
|
26
|
-
import { X, Search, ChevronDown, Check, AlertTriangle, BracesIcon, Plus, AlignCenter as AlignCenter$1, AlignJustify, AlignLeft as AlignLeft$1, AlignRight as AlignRight$1, PaintBucket, Quote, ChevronRight, ChevronsUpDown, FileCode, Baseline, RectangleVertical, Combine, Ungroup, MessageSquare, MessageSquarePlus, Trash, GripVertical, Edit2, Smile, ExternalLink, Heading1 as Heading1$1, Heading2 as Heading2$1, Heading3 as Heading3$1, Heading4 as Heading4$1, Heading5 as Heading5$1, Heading6 as Heading6$1, Indent, Keyboard, WrapText, Minus, MoreHorizontal, Outdent, Pilcrow, RotateCcw, RectangleHorizontal, Settings, Highlighter, Strikethrough, Subscript, Superscript, Table as Table$1, Text, Underline, Link2Off, Eye, SeparatorHorizontal, Moon, SunMedium, Twitter, PaintBucketIcon, CombineIcon, SquareSplitHorizontalIcon, Grid2X2Icon, Trash2Icon, ArrowUp, ArrowDown, XIcon, ArrowLeft, ArrowRight, EraserIcon, ChevronDownIcon as ChevronDownIcon$1, ChevronUp, Clock, CalendarCheck, Calendar as Calendar$1, CalendarDays, RotateCw, ChevronLeft, ArrowUpDown, AlertCircle, Image, RefreshCw, Database, CheckCircle2, ImageOff, LoaderCircle, TriangleAlert, FileStack, History, GitBranchIcon, List as List$1, ListOrdered, Grid3x3Icon, CircleX, Link, Unlink } from "lucide-react";
|
|
26
|
+
import { X, Search, ChevronDown, Check, AlertTriangle, BracesIcon, Plus, AlignCenter as AlignCenter$1, AlignJustify, AlignLeft as AlignLeft$1, AlignRight as AlignRight$1, PaintBucket, Quote, ChevronRight, ChevronsUpDown, FileCode, Baseline, RectangleVertical, Combine, Ungroup, MessageSquare, MessageSquarePlus, Trash, GripVertical, Edit2, Smile, ExternalLink, Heading1 as Heading1$1, Heading2 as Heading2$1, Heading3 as Heading3$1, Heading4 as Heading4$1, Heading5 as Heading5$1, Heading6 as Heading6$1, Indent, Keyboard, WrapText, Minus, MoreHorizontal, Outdent, Pilcrow, RotateCcw, RectangleHorizontal, Settings, Highlighter, Strikethrough, Subscript, Superscript, Table as Table$1, Text, Underline, Link2Off, Eye, SeparatorHorizontal, Moon, SunMedium, Twitter, PaintBucketIcon, CombineIcon, SquareSplitHorizontalIcon, Grid2X2Icon, Trash2Icon, ArrowUp, ArrowDown, XIcon, ArrowLeft, ArrowRight, EraserIcon, ChevronDownIcon as ChevronDownIcon$1, ChevronUp, Clock, CalendarCheck, Calendar as Calendar$1, CalendarDays, RotateCw, ChevronLeft, ArrowUpDown, AlertCircle, Image, RefreshCw, Database, CheckCircle2, ImageOff, LoaderCircle, TriangleAlert, FileStack, History, GitBranchIcon, FileText, Globe, List as List$1, ListOrdered, Grid3x3Icon, CircleX, Link, Unlink } from "lucide-react";
|
|
27
27
|
import mermaid from "mermaid";
|
|
28
28
|
import { Slot } from "@radix-ui/react-slot";
|
|
29
29
|
import { cva } from "class-variance-authority";
|
|
@@ -36,7 +36,7 @@ import { useHTMLInputCursorState, useComboboxInput } from "@udecode/plate-combob
|
|
|
36
36
|
import { useComboboxContext, Combobox as Combobox$1, useComboboxStore, ComboboxProvider, Portal, ComboboxPopover, ComboboxItem } from "@ariakit/react";
|
|
37
37
|
import { filterWords } from "@udecode/plate-combobox";
|
|
38
38
|
import { toggleList, unwrapList, getListItemEntry } from "@udecode/plate-list";
|
|
39
|
-
import { normalizeHeadingLevels, ALL_HEADING_LEVELS, canonicalPath, isHeadingLevel, TinaSchema, addNamespaceToSchema, parseURL, resolveForm, normalizePath, validateSchema } from "@tinacms/schema-tools";
|
|
39
|
+
import { normalizeHeadingLevels, ALL_HEADING_LEVELS, ASYNC_POLLER_ERROR, canonicalPath, ERR_BRANCH_EXISTS, ERR_BRANCH_CONFLICT, isHeadingLevel, TinaSchema, addNamespaceToSchema, parseURL, ERR_HAS_REFERENCES, ERR_ALREADY_EXISTS, isValidRelativePath, RELATIVE_PATH_ALLOWED_CHARS_MESSAGE, resolveForm, RELATIVE_PATH_REGEX, normalizePath, ERR_NOT_INDEXED, validateSchema } from "@tinacms/schema-tools";
|
|
40
40
|
import { NAMER, resolveField } from "@tinacms/schema-tools";
|
|
41
41
|
import { useBlockSelected, BlockSelectionPlugin } from "@udecode/plate-selection/react";
|
|
42
42
|
import "@udecode/plate-dnd";
|
|
@@ -67,7 +67,7 @@ import { MdKeyboardArrowDown, MdOutlineClear, MdArrowForward, MdAccessTime, MdOu
|
|
|
67
67
|
import * as dropzone from "react-dropzone";
|
|
68
68
|
import { IoMdArrowDropup, IoMdArrowDropdown, IoMdClose, IoMdRefresh } from "react-icons/io";
|
|
69
69
|
import { Command as Command$3 } from "@udecode/cmdk";
|
|
70
|
-
import { Popover as Popover$4, PopoverButton, Transition, PopoverPanel, TransitionChild, Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItems, MenuItem } from "@headlessui/react";
|
|
70
|
+
import { Popover as Popover$4, PopoverButton, Transition, PopoverPanel, TransitionChild, Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItems, MenuItem as MenuItem$1 } from "@headlessui/react";
|
|
71
71
|
import { isHotkey } from "is-hotkey";
|
|
72
72
|
import { AutoformatPlugin } from "@udecode/plate-autoformat/react";
|
|
73
73
|
import { ExitBreakPlugin, SoftBreakPlugin } from "@udecode/plate-break/react";
|
|
@@ -77,7 +77,7 @@ import { BaseBlockquotePlugin } from "@udecode/plate-block-quote";
|
|
|
77
77
|
import { HeadingPlugin } from "@udecode/plate-heading/react";
|
|
78
78
|
import { IndentListPlugin } from "@udecode/plate-indent-list/react";
|
|
79
79
|
import { NodeIdPlugin } from "@udecode/plate-node-id";
|
|
80
|
-
import { offset, flip, useVirtualFloating, getSelectionBoundingClientRect } from "@udecode/plate-floating";
|
|
80
|
+
import { offset, flip, shift, limitShift, useVirtualFloating, getSelectionBoundingClientRect } from "@udecode/plate-floating";
|
|
81
81
|
import { getLinkAttributes } from "@udecode/plate-link";
|
|
82
82
|
import "@heroicons/react/solid";
|
|
83
83
|
import { autoformatSmartQuotes, autoformatPunctuation, autoformatLegal, autoformatArrow, autoformatMath } from "@udecode/plate-autoformat";
|
|
@@ -2280,6 +2280,7 @@ const BranchSwitcherDropDownEvent = "branch-switcher-dropdown";
|
|
|
2280
2280
|
const BranchSwitcherPRClickedEvent = "branch-switcher-pr-clicked";
|
|
2281
2281
|
const SavedContentEvent = "saved-content";
|
|
2282
2282
|
const SaveContentErrorEvent = "save-content-error";
|
|
2283
|
+
const EditorialWorkflowSaveEvent = "editorial-workflow-save";
|
|
2283
2284
|
const FormResetEvent = "form-reset";
|
|
2284
2285
|
const MediaManagerContentUploadedEvent = "media-manager-content-uploaded";
|
|
2285
2286
|
const MediaManagerContentDeletedEvent = "media-manager-content-deleted";
|
|
@@ -4493,6 +4494,21 @@ function DropdownMenuSeparator({
|
|
|
4493
4494
|
}
|
|
4494
4495
|
);
|
|
4495
4496
|
}
|
|
4497
|
+
const MenuItem = ({ item }) => {
|
|
4498
|
+
const menuItem = /* @__PURE__ */ React.createElement(
|
|
4499
|
+
DropdownMenuItem,
|
|
4500
|
+
{
|
|
4501
|
+
onClick: item.onClick,
|
|
4502
|
+
disabled: item.disabled,
|
|
4503
|
+
variant: item.variant
|
|
4504
|
+
},
|
|
4505
|
+
item.icon && item.icon,
|
|
4506
|
+
item.label
|
|
4507
|
+
);
|
|
4508
|
+
if (!item.tooltip)
|
|
4509
|
+
return menuItem;
|
|
4510
|
+
return /* @__PURE__ */ React.createElement(Tooltip$1, null, /* @__PURE__ */ React.createElement(TooltipTrigger$1, { asChild: true }, /* @__PURE__ */ React.createElement("div", null, menuItem)), /* @__PURE__ */ React.createElement(TooltipPortal, null, /* @__PURE__ */ React.createElement(TooltipContent$1, { side: "left" }, item.tooltip)));
|
|
4511
|
+
};
|
|
4496
4512
|
const DropdownButton = React.forwardRef(
|
|
4497
4513
|
({
|
|
4498
4514
|
variant = "primary",
|
|
@@ -4530,17 +4546,7 @@ const DropdownButton = React.forwardRef(
|
|
|
4530
4546
|
)
|
|
4531
4547
|
}
|
|
4532
4548
|
)
|
|
4533
|
-
)), /* @__PURE__ */ React.createElement(DropdownMenuContent, { align: "end", side: "bottom", className: "z-[100000]" }, items.map((item, index) => /* @__PURE__ */ React.createElement(
|
|
4534
|
-
DropdownMenuItem,
|
|
4535
|
-
{
|
|
4536
|
-
key: index,
|
|
4537
|
-
onClick: item.onClick,
|
|
4538
|
-
disabled: item.disabled,
|
|
4539
|
-
variant: item.variant
|
|
4540
|
-
},
|
|
4541
|
-
item.icon && item.icon,
|
|
4542
|
-
item.label
|
|
4543
|
-
))));
|
|
4549
|
+
)), /* @__PURE__ */ React.createElement(DropdownMenuContent, { align: "end", side: "bottom", className: "z-[100000]" }, /* @__PURE__ */ React.createElement(TooltipProvider$1, null, items.map((item, index) => /* @__PURE__ */ React.createElement(MenuItem, { key: index, item })))));
|
|
4544
4550
|
}
|
|
4545
4551
|
return /* @__PURE__ */ React.createElement("div", { className: cn("inline-flex", className) }, /* @__PURE__ */ React.createElement(
|
|
4546
4552
|
Button$2,
|
|
@@ -4577,19 +4583,10 @@ const DropdownButton = React.forwardRef(
|
|
|
4577
4583
|
style: { fill: "none" }
|
|
4578
4584
|
}
|
|
4579
4585
|
)
|
|
4580
|
-
)), /* @__PURE__ */ React.createElement(DropdownMenuContent, { align: "end", side: "bottom" }, items.map((item, index) => {
|
|
4586
|
+
)), /* @__PURE__ */ React.createElement(DropdownMenuContent, { align: "end", side: "bottom" }, /* @__PURE__ */ React.createElement(TooltipProvider$1, null, items.map((item, index) => {
|
|
4581
4587
|
var _a;
|
|
4582
|
-
return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, /* @__PURE__ */ React.createElement(
|
|
4583
|
-
|
|
4584
|
-
{
|
|
4585
|
-
onClick: item.onClick,
|
|
4586
|
-
disabled: item.disabled,
|
|
4587
|
-
variant: item.variant
|
|
4588
|
-
},
|
|
4589
|
-
item.icon && item.icon,
|
|
4590
|
-
item.label
|
|
4591
|
-
), item.variant === "destructive" && index < items.length - 1 && ((_a = items[index + 1]) == null ? void 0 : _a.variant) !== "destructive" && /* @__PURE__ */ React.createElement(DropdownMenuSeparator, null));
|
|
4592
|
-
}))));
|
|
4588
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, /* @__PURE__ */ React.createElement(MenuItem, { item }), item.variant === "destructive" && index < items.length - 1 && ((_a = items[index + 1]) == null ? void 0 : _a.variant) !== "destructive" && /* @__PURE__ */ React.createElement(DropdownMenuSeparator, null));
|
|
4589
|
+
})))));
|
|
4593
4590
|
}
|
|
4594
4591
|
);
|
|
4595
4592
|
DropdownButton.displayName = "DropdownButton";
|
|
@@ -8780,7 +8777,7 @@ const BranchSwitcherLegacy = ({
|
|
|
8780
8777
|
return newBranchList;
|
|
8781
8778
|
});
|
|
8782
8779
|
}).catch((e) => {
|
|
8783
|
-
if (e.message ===
|
|
8780
|
+
if (e.message === ASYNC_POLLER_ERROR.CANCELLED)
|
|
8784
8781
|
return;
|
|
8785
8782
|
console.error(e);
|
|
8786
8783
|
});
|
|
@@ -9508,7 +9505,7 @@ const EditoralBranchSwitcher = ({
|
|
|
9508
9505
|
return newBranchList;
|
|
9509
9506
|
});
|
|
9510
9507
|
}).catch((e) => {
|
|
9511
|
-
if (e.message ===
|
|
9508
|
+
if (e.message === ASYNC_POLLER_ERROR.CANCELLED)
|
|
9512
9509
|
return;
|
|
9513
9510
|
console.error(e);
|
|
9514
9511
|
});
|
|
@@ -13264,7 +13261,7 @@ const FormModal = ({ plugin, close: close2 }) => {
|
|
|
13264
13261
|
const name = "tinacms";
|
|
13265
13262
|
const type = "module";
|
|
13266
13263
|
const typings = "dist/index.d.ts";
|
|
13267
|
-
const version$1 = "3.
|
|
13264
|
+
const version$1 = "3.10.0";
|
|
13268
13265
|
const main = "dist/index.js";
|
|
13269
13266
|
const module = "./dist/index.js";
|
|
13270
13267
|
const exports = {
|
|
@@ -13313,13 +13310,12 @@ const dependencies = {
|
|
|
13313
13310
|
"@headlessui/react": "2.1.8",
|
|
13314
13311
|
"@heroicons/react": "^1.0.6",
|
|
13315
13312
|
"@monaco-editor/react": "catalog:",
|
|
13316
|
-
"@radix-ui/react-checkbox": "catalog:",
|
|
13317
13313
|
"@radix-ui/react-dialog": "catalog:",
|
|
13318
13314
|
"@radix-ui/react-dropdown-menu": "catalog:",
|
|
13319
13315
|
"@radix-ui/react-popover": "catalog:",
|
|
13320
13316
|
"@radix-ui/react-select": "catalog:",
|
|
13321
13317
|
"@radix-ui/react-separator": "catalog:",
|
|
13322
|
-
"@radix-ui/react-slot": "
|
|
13318
|
+
"@radix-ui/react-slot": "catalog:",
|
|
13323
13319
|
"@radix-ui/react-toolbar": "catalog:",
|
|
13324
13320
|
"@radix-ui/react-tooltip": "catalog:",
|
|
13325
13321
|
"@react-hook/window-size": "catalog:",
|
|
@@ -16370,9 +16366,9 @@ const getEditorialWorkflowErrorMessage = (e) => {
|
|
|
16370
16366
|
break;
|
|
16371
16367
|
}
|
|
16372
16368
|
} else if (err.message) {
|
|
16373
|
-
if (err.message.toLowerCase().includes(
|
|
16369
|
+
if (err.message.toLowerCase().includes(ERR_BRANCH_EXISTS)) {
|
|
16374
16370
|
errMessage = "A branch with this name already exists";
|
|
16375
|
-
} else if (err.message.toLowerCase().includes(
|
|
16371
|
+
} else if (err.message.toLowerCase().includes(ERR_BRANCH_CONFLICT)) {
|
|
16376
16372
|
errMessage = err.message;
|
|
16377
16373
|
}
|
|
16378
16374
|
}
|
|
@@ -16412,12 +16408,13 @@ function useEditorialWorkflow() {
|
|
|
16412
16408
|
values,
|
|
16413
16409
|
crudType,
|
|
16414
16410
|
tinaForm,
|
|
16415
|
-
signal
|
|
16411
|
+
signal,
|
|
16412
|
+
isDraft
|
|
16416
16413
|
}) => {
|
|
16417
16414
|
var _a;
|
|
16418
16415
|
try {
|
|
16419
16416
|
if (signal == null ? void 0 : signal.aborted)
|
|
16420
|
-
return false;
|
|
16417
|
+
return { success: false };
|
|
16421
16418
|
const targetBranchExists = await checkTargetBranchExists(
|
|
16422
16419
|
tinaApi,
|
|
16423
16420
|
branchName,
|
|
@@ -16425,12 +16422,12 @@ function useEditorialWorkflow() {
|
|
|
16425
16422
|
signal
|
|
16426
16423
|
);
|
|
16427
16424
|
if (signal == null ? void 0 : signal.aborted)
|
|
16428
|
-
return false;
|
|
16425
|
+
return { success: false };
|
|
16429
16426
|
if (targetBranchExists) {
|
|
16430
16427
|
setErrorMessage(TARGET_BRANCH_EXISTS_ERROR);
|
|
16431
16428
|
setIsExecuting(false);
|
|
16432
16429
|
setCurrentStep(0);
|
|
16433
|
-
return false;
|
|
16430
|
+
return { success: false, error: TARGET_BRANCH_EXISTS_ERROR };
|
|
16434
16431
|
}
|
|
16435
16432
|
setIsExecuting(true);
|
|
16436
16433
|
setCurrentStep(1);
|
|
@@ -16456,6 +16453,7 @@ function useEditorialWorkflow() {
|
|
|
16456
16453
|
branchName,
|
|
16457
16454
|
baseBranch,
|
|
16458
16455
|
prTitle: getEditorialWorkflowPrTitle(branchName),
|
|
16456
|
+
isDraft,
|
|
16459
16457
|
graphQLContentOp: {
|
|
16460
16458
|
query: graphql2,
|
|
16461
16459
|
variables: {
|
|
@@ -16501,14 +16499,14 @@ function useEditorialWorkflow() {
|
|
|
16501
16499
|
const folderPath = relativePath.includes("/") ? relativePath.substring(0, relativePath.lastIndexOf("/")) : "";
|
|
16502
16500
|
window.location.hash = `#/collections/${collection.name}${folderPath ? `/${folderPath}` : ""}`;
|
|
16503
16501
|
}
|
|
16504
|
-
return true;
|
|
16502
|
+
return { success: true };
|
|
16505
16503
|
} catch (e) {
|
|
16506
16504
|
console.error(e);
|
|
16507
16505
|
const errMessage = getEditorialWorkflowErrorMessage(e);
|
|
16508
16506
|
setErrorMessage(errMessage);
|
|
16509
16507
|
setIsExecuting(false);
|
|
16510
16508
|
setCurrentStep(0);
|
|
16511
|
-
return false;
|
|
16509
|
+
return { success: false, error: errMessage };
|
|
16512
16510
|
}
|
|
16513
16511
|
};
|
|
16514
16512
|
return {
|
|
@@ -16604,6 +16602,41 @@ const EditorialWorkflowProgressModal = ({
|
|
|
16604
16602
|
elapsedTime
|
|
16605
16603
|
}
|
|
16606
16604
|
))));
|
|
16605
|
+
function useLocalStorage(key, initialValue) {
|
|
16606
|
+
const [storedValue, setStoredValue] = React.useState(() => {
|
|
16607
|
+
try {
|
|
16608
|
+
const valueFromStorage = typeof window !== "undefined" && window.localStorage && window.localStorage.getItem(key);
|
|
16609
|
+
if (valueFromStorage != null) {
|
|
16610
|
+
return JSON.parse(valueFromStorage);
|
|
16611
|
+
}
|
|
16612
|
+
} catch (error2) {
|
|
16613
|
+
}
|
|
16614
|
+
return initialValue;
|
|
16615
|
+
});
|
|
16616
|
+
React.useEffect(() => {
|
|
16617
|
+
const valueFromStorage = window.localStorage && window.localStorage.getItem(key);
|
|
16618
|
+
if (valueFromStorage != null && valueFromStorage != void 0) {
|
|
16619
|
+
setStoredValue(JSON.parse(valueFromStorage));
|
|
16620
|
+
}
|
|
16621
|
+
}, [key]);
|
|
16622
|
+
const setValue = (value) => {
|
|
16623
|
+
try {
|
|
16624
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
16625
|
+
setStoredValue(valueToStore);
|
|
16626
|
+
localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
16627
|
+
} catch (error2) {
|
|
16628
|
+
console.log(error2);
|
|
16629
|
+
}
|
|
16630
|
+
};
|
|
16631
|
+
return [storedValue, setValue];
|
|
16632
|
+
}
|
|
16633
|
+
const SAVE_CHOICE_KEY = "tina.editorialWorkflow.saveChoice";
|
|
16634
|
+
const SAVE_CHOICE_ORDER = ["draft", "review", "publish"];
|
|
16635
|
+
const resolveSaveOptions = (lastChoice, disablePublish) => {
|
|
16636
|
+
const main2 = lastChoice === "publish" && disablePublish ? "draft" : lastChoice;
|
|
16637
|
+
const menu = SAVE_CHOICE_ORDER.filter((choice) => choice !== main2);
|
|
16638
|
+
return { main: main2, menu };
|
|
16639
|
+
};
|
|
16607
16640
|
const formatDefaultBranchName = (filePath, crudType) => {
|
|
16608
16641
|
let result = filePath;
|
|
16609
16642
|
const contentPrefix = "content/";
|
|
@@ -16656,7 +16689,7 @@ const CreateBranchModal = ({
|
|
|
16656
16689
|
(_a = branchGuardAbortRef.current) == null ? void 0 : _a.abort();
|
|
16657
16690
|
};
|
|
16658
16691
|
}, []);
|
|
16659
|
-
const executeEditorialWorkflow = async () => {
|
|
16692
|
+
const executeEditorialWorkflow = async (isDraft) => {
|
|
16660
16693
|
abortBranchGuard();
|
|
16661
16694
|
const abortController = new AbortController();
|
|
16662
16695
|
branchGuardAbortRef.current = abortController;
|
|
@@ -16680,18 +16713,26 @@ const CreateBranchModal = ({
|
|
|
16680
16713
|
return;
|
|
16681
16714
|
}
|
|
16682
16715
|
setIsBranchGuardChecking(false);
|
|
16683
|
-
const success = await executeWorkflow({
|
|
16716
|
+
const { success, error: error2 } = await executeWorkflow({
|
|
16684
16717
|
branchName: targetBranch,
|
|
16685
16718
|
baseBranch,
|
|
16686
16719
|
path,
|
|
16687
16720
|
values,
|
|
16688
16721
|
crudType,
|
|
16689
16722
|
tinaForm,
|
|
16690
|
-
signal: abortController.signal
|
|
16723
|
+
signal: abortController.signal,
|
|
16724
|
+
isDraft
|
|
16691
16725
|
});
|
|
16692
16726
|
if (branchGuardAbortRef.current === abortController) {
|
|
16693
16727
|
branchGuardAbortRef.current = null;
|
|
16694
16728
|
}
|
|
16729
|
+
if (abortController.signal.aborted)
|
|
16730
|
+
return;
|
|
16731
|
+
captureEvent(EditorialWorkflowSaveEvent, {
|
|
16732
|
+
choice: isDraft ? "draft" : "review",
|
|
16733
|
+
success,
|
|
16734
|
+
error: error2
|
|
16735
|
+
});
|
|
16695
16736
|
if (success) {
|
|
16696
16737
|
close2();
|
|
16697
16738
|
}
|
|
@@ -16725,8 +16766,10 @@ const CreateBranchModal = ({
|
|
|
16725
16766
|
onSaveToProtectedBranch: () => {
|
|
16726
16767
|
abortBranchGuard();
|
|
16727
16768
|
close2();
|
|
16728
|
-
safeSubmit();
|
|
16729
|
-
}
|
|
16769
|
+
safeSubmit("publish");
|
|
16770
|
+
},
|
|
16771
|
+
showSaveOptions: true,
|
|
16772
|
+
disablePublish: !!tinaApi.usingProtectedBranch()
|
|
16730
16773
|
}
|
|
16731
16774
|
);
|
|
16732
16775
|
};
|
|
@@ -16737,8 +16780,36 @@ const CreateBranchPromptModal = ({
|
|
|
16737
16780
|
errorMessage,
|
|
16738
16781
|
onBranchNameChange,
|
|
16739
16782
|
onCreateBranch,
|
|
16740
|
-
onSaveToProtectedBranch
|
|
16783
|
+
onSaveToProtectedBranch,
|
|
16784
|
+
showSaveOptions = false,
|
|
16785
|
+
disablePublish = false
|
|
16741
16786
|
}) => {
|
|
16787
|
+
const [lastChoice, setLastChoice] = useLocalStorage(
|
|
16788
|
+
SAVE_CHOICE_KEY,
|
|
16789
|
+
"draft"
|
|
16790
|
+
);
|
|
16791
|
+
const { main: main2, menu } = resolveSaveOptions(lastChoice, disablePublish);
|
|
16792
|
+
const choices = {
|
|
16793
|
+
draft: {
|
|
16794
|
+
label: "Save draft",
|
|
16795
|
+
Icon: FileText,
|
|
16796
|
+
run: () => onCreateBranch(true)
|
|
16797
|
+
},
|
|
16798
|
+
review: {
|
|
16799
|
+
label: "Save (ready for review)",
|
|
16800
|
+
Icon: Eye,
|
|
16801
|
+
run: () => onCreateBranch(false)
|
|
16802
|
+
},
|
|
16803
|
+
publish: {
|
|
16804
|
+
label: "Save and publish",
|
|
16805
|
+
Icon: Globe,
|
|
16806
|
+
run: onSaveToProtectedBranch,
|
|
16807
|
+
disabled: disablePublish,
|
|
16808
|
+
tooltip: disablePublish ? "This branch is protected. Save a draft or send it for review instead." : void 0
|
|
16809
|
+
}
|
|
16810
|
+
};
|
|
16811
|
+
const mainChoice = choices[main2] ?? choices.draft;
|
|
16812
|
+
const MainIcon = mainChoice.Icon;
|
|
16742
16813
|
return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: close2 }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between w-full" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center" }, "Save changes to new branch"))), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("div", { className: "max-w-sm" }, errorMessage && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 text-red-700 py-2 px-3 mb-4 bg-red-50 border border-red-200 rounded" }, /* @__PURE__ */ React.createElement(BiError, { className: "w-5 h-auto text-red-400 flex-shrink-0" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, /* @__PURE__ */ React.createElement("b", null, "Error:"), " ", errorMessage)), /* @__PURE__ */ React.createElement("p", { className: "text-lg text-gray-700 font-bold mb-2" }, "First, let's create a copy"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4 max-w-sm" }, "To make changes, you need to create a copy then get it approved and merged for it to go live.", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("span", { className: "text-gray-500" }, "Learn more about "), /* @__PURE__ */ React.createElement(
|
|
16743
16814
|
"a",
|
|
16744
16815
|
{
|
|
@@ -16766,14 +16837,39 @@ const CreateBranchPromptModal = ({
|
|
|
16766
16837
|
onClick: close2
|
|
16767
16838
|
},
|
|
16768
16839
|
"Cancel"
|
|
16769
|
-
), /* @__PURE__ */ React.createElement(
|
|
16840
|
+
), showSaveOptions ? /* @__PURE__ */ React.createElement(
|
|
16841
|
+
DropdownButton,
|
|
16842
|
+
{
|
|
16843
|
+
variant: "primary",
|
|
16844
|
+
align: "start",
|
|
16845
|
+
className: "w-full sm:w-auto",
|
|
16846
|
+
disabled,
|
|
16847
|
+
onMainAction: mainChoice.run,
|
|
16848
|
+
items: menu.map((choice) => {
|
|
16849
|
+
const option = choices[choice];
|
|
16850
|
+
const OptionIcon = option.Icon;
|
|
16851
|
+
return {
|
|
16852
|
+
label: option.label,
|
|
16853
|
+
icon: /* @__PURE__ */ React.createElement(OptionIcon, { className: "w-4 h-4" }),
|
|
16854
|
+
disabled: option.disabled,
|
|
16855
|
+
tooltip: option.tooltip,
|
|
16856
|
+
onClick: () => {
|
|
16857
|
+
setLastChoice(choice);
|
|
16858
|
+
option.run();
|
|
16859
|
+
}
|
|
16860
|
+
};
|
|
16861
|
+
})
|
|
16862
|
+
},
|
|
16863
|
+
/* @__PURE__ */ React.createElement(MainIcon, { className: "w-4 h-4 mr-1", style: { fill: "none" } }),
|
|
16864
|
+
mainChoice.label
|
|
16865
|
+
) : /* @__PURE__ */ React.createElement(
|
|
16770
16866
|
DropdownButton,
|
|
16771
16867
|
{
|
|
16772
16868
|
variant: "primary",
|
|
16773
16869
|
align: "start",
|
|
16774
16870
|
className: "w-full sm:w-auto",
|
|
16775
16871
|
disabled,
|
|
16776
|
-
onMainAction: onCreateBranch,
|
|
16872
|
+
onMainAction: () => onCreateBranch(false),
|
|
16777
16873
|
items: [
|
|
16778
16874
|
{
|
|
16779
16875
|
label: "Save to Protected Branch",
|
|
@@ -16782,7 +16878,13 @@ const CreateBranchPromptModal = ({
|
|
|
16782
16878
|
}
|
|
16783
16879
|
]
|
|
16784
16880
|
},
|
|
16785
|
-
/* @__PURE__ */ React.createElement(
|
|
16881
|
+
/* @__PURE__ */ React.createElement(
|
|
16882
|
+
GitBranchIcon,
|
|
16883
|
+
{
|
|
16884
|
+
className: "w-4 h-4 mr-1",
|
|
16885
|
+
style: { fill: "none" }
|
|
16886
|
+
}
|
|
16887
|
+
),
|
|
16786
16888
|
"Save to a new branch"
|
|
16787
16889
|
))));
|
|
16788
16890
|
};
|
|
@@ -16822,7 +16924,7 @@ const BranchDeletedModal = ({
|
|
|
16822
16924
|
reset
|
|
16823
16925
|
} = useEditorialWorkflow();
|
|
16824
16926
|
const handleCreate = async () => {
|
|
16825
|
-
const success = await executeWorkflow({
|
|
16927
|
+
const { success } = await executeWorkflow({
|
|
16826
16928
|
branchName: `tina/${newBranchName}`,
|
|
16827
16929
|
baseBranch,
|
|
16828
16930
|
path,
|
|
@@ -16999,7 +17101,16 @@ const FormBuilder = ({
|
|
|
16999
17101
|
}) => {
|
|
17000
17102
|
const usingProtectedBranch = cms.api.tina.usingProtectedBranch();
|
|
17001
17103
|
const canSubmit = !pristine && !submitting && !hasValidationErrors && !(invalid && !dirtySinceLastSubmit);
|
|
17002
|
-
const safeSubmit = async () => {
|
|
17104
|
+
const safeSubmit = async (editorialWorkflowChoice) => {
|
|
17105
|
+
const captureWorkflowChoice = (success, error2) => {
|
|
17106
|
+
if (editorialWorkflowChoice) {
|
|
17107
|
+
captureEvent(EditorialWorkflowSaveEvent, {
|
|
17108
|
+
choice: editorialWorkflowChoice,
|
|
17109
|
+
success,
|
|
17110
|
+
error: error2
|
|
17111
|
+
});
|
|
17112
|
+
}
|
|
17113
|
+
};
|
|
17003
17114
|
if (canSubmit) {
|
|
17004
17115
|
const alertsBefore = new Set(cms.alerts.all.map((a) => a.id));
|
|
17005
17116
|
console.debug(
|
|
@@ -17022,6 +17133,7 @@ const FormBuilder = ({
|
|
|
17022
17133
|
cms.alerts.dismiss(alert);
|
|
17023
17134
|
}
|
|
17024
17135
|
}
|
|
17136
|
+
captureWorkflowChoice(false, errorMsg);
|
|
17025
17137
|
setDeletedBranchModalOpen(true);
|
|
17026
17138
|
return;
|
|
17027
17139
|
}
|
|
@@ -17029,10 +17141,12 @@ const FormBuilder = ({
|
|
|
17029
17141
|
documentPath: tinaForm.path,
|
|
17030
17142
|
error: errorMsg
|
|
17031
17143
|
});
|
|
17144
|
+
captureWorkflowChoice(false, errorMsg);
|
|
17032
17145
|
} else {
|
|
17033
17146
|
captureEvent(SavedContentEvent, {
|
|
17034
17147
|
documentPath: tinaForm.path
|
|
17035
17148
|
});
|
|
17149
|
+
captureWorkflowChoice(true);
|
|
17036
17150
|
}
|
|
17037
17151
|
} else {
|
|
17038
17152
|
console.debug(
|
|
@@ -18909,7 +19023,7 @@ const useCreateEditor = ({
|
|
|
18909
19023
|
});
|
|
18910
19024
|
};
|
|
18911
19025
|
const popoverVariants = cva(
|
|
18912
|
-
"z-
|
|
19026
|
+
"z-[999999] w-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-hidden"
|
|
18913
19027
|
);
|
|
18914
19028
|
const inputVariants = cva(
|
|
18915
19029
|
"flex h-[28px] w-full rounded-md border-none bg-transparent px-1.5 py-1 text-base placeholder:text-muted-foreground focus-visible:ring-transparent focus-visible:outline-none md:text-sm"
|
|
@@ -18943,7 +19057,8 @@ function LinkFloatingToolbar({
|
|
|
18943
19057
|
flip({
|
|
18944
19058
|
fallbackPlacements: ["bottom-end", "top-start", "top-end"],
|
|
18945
19059
|
padding: 12
|
|
18946
|
-
})
|
|
19060
|
+
}),
|
|
19061
|
+
shift({ padding: 8, limiter: limitShift() })
|
|
18947
19062
|
],
|
|
18948
19063
|
placement: activeSuggestionId || activeCommentId ? "top-start" : "bottom-start"
|
|
18949
19064
|
};
|
|
@@ -19063,13 +19178,13 @@ function LinkFloatingToolbar({
|
|
|
19063
19178
|
},
|
|
19064
19179
|
/* @__PURE__ */ React.createElement(Unlink, { width: 18 })
|
|
19065
19180
|
));
|
|
19066
|
-
return /* @__PURE__ */ React.createElement(
|
|
19181
|
+
return /* @__PURE__ */ React.createElement(PortalBody, null, /* @__PURE__ */ React.createElement(
|
|
19067
19182
|
"div",
|
|
19068
19183
|
{
|
|
19069
19184
|
ref: insertRef,
|
|
19070
19185
|
className: popoverVariants(),
|
|
19071
19186
|
...insertProps,
|
|
19072
|
-
style: insertProps.style
|
|
19187
|
+
style: { ...insertProps.style }
|
|
19073
19188
|
},
|
|
19074
19189
|
input
|
|
19075
19190
|
), /* @__PURE__ */ React.createElement(
|
|
@@ -19078,7 +19193,7 @@ function LinkFloatingToolbar({
|
|
|
19078
19193
|
ref: editRef,
|
|
19079
19194
|
className: popoverVariants(),
|
|
19080
19195
|
...editProps,
|
|
19081
|
-
style: editProps.style
|
|
19196
|
+
style: { ...editProps.style }
|
|
19082
19197
|
},
|
|
19083
19198
|
editContent
|
|
19084
19199
|
));
|
|
@@ -70525,25 +70640,6 @@ class FormMetaPlugin {
|
|
|
70525
70640
|
this.Component = options.Component;
|
|
70526
70641
|
}
|
|
70527
70642
|
}
|
|
70528
|
-
function useLocalStorage(key, initialValue) {
|
|
70529
|
-
const [storedValue, setStoredValue] = React.useState(initialValue);
|
|
70530
|
-
React.useEffect(() => {
|
|
70531
|
-
const valueFromStorage = window.localStorage && window.localStorage.getItem(key);
|
|
70532
|
-
if (valueFromStorage != null && valueFromStorage != void 0) {
|
|
70533
|
-
setStoredValue(JSON.parse(valueFromStorage));
|
|
70534
|
-
}
|
|
70535
|
-
}, [key]);
|
|
70536
|
-
const setValue = (value) => {
|
|
70537
|
-
try {
|
|
70538
|
-
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
70539
|
-
setStoredValue(valueToStore);
|
|
70540
|
-
localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
70541
|
-
} catch (error2) {
|
|
70542
|
-
console.log(error2);
|
|
70543
|
-
}
|
|
70544
|
-
};
|
|
70545
|
-
return [storedValue, setValue];
|
|
70546
|
-
}
|
|
70547
70643
|
const MediaWorkflowOverlay = () => {
|
|
70548
70644
|
const cms = useCMS$1();
|
|
70549
70645
|
const { setCurrentBranch } = useBranchData();
|
|
@@ -70739,13 +70835,13 @@ function asyncPoll(fn, pollInterval = 5 * 1e3, pollTimeout = 30 * 1e3) {
|
|
|
70739
70835
|
Promise.resolve(fn()).then((result) => {
|
|
70740
70836
|
const now = (/* @__PURE__ */ new Date()).getTime();
|
|
70741
70837
|
if (stop) {
|
|
70742
|
-
reject(new Error(
|
|
70838
|
+
reject(new Error(ASYNC_POLLER_ERROR.CANCELLED));
|
|
70743
70839
|
} else if (result.done) {
|
|
70744
70840
|
resolve(result.data);
|
|
70745
70841
|
} else if (now < endTime) {
|
|
70746
70842
|
setTimeout(checkCondition, pollInterval, resolve, reject);
|
|
70747
70843
|
} else {
|
|
70748
|
-
reject(new Error(
|
|
70844
|
+
reject(new Error(ASYNC_POLLER_ERROR.TIMEOUT));
|
|
70749
70845
|
}
|
|
70750
70846
|
}).catch((err) => {
|
|
70751
70847
|
reject(err);
|
|
@@ -71359,9 +71455,7 @@ mutation addPendingDocumentMutation(
|
|
|
71359
71455
|
if (result.status === "unknown") {
|
|
71360
71456
|
unknownCount++;
|
|
71361
71457
|
if (unknownCount > 5) {
|
|
71362
|
-
throw new Error(
|
|
71363
|
-
"AsyncPoller: status unknown for too long, please check indexing progress the TinaCloud dashboard"
|
|
71364
|
-
);
|
|
71458
|
+
throw new Error(ASYNC_POLLER_ERROR.STATUS_UNKNOWN);
|
|
71365
71459
|
}
|
|
71366
71460
|
}
|
|
71367
71461
|
return Promise.resolve({
|
|
@@ -71381,7 +71475,7 @@ mutation addPendingDocumentMutation(
|
|
|
71381
71475
|
);
|
|
71382
71476
|
return [prom, cancel];
|
|
71383
71477
|
} catch (error2) {
|
|
71384
|
-
if (error2.message ===
|
|
71478
|
+
if (error2.message === ASYNC_POLLER_ERROR.TIMEOUT) {
|
|
71385
71479
|
console.warn(error2);
|
|
71386
71480
|
return [Promise.resolve({ status: "timeout" }), () => {
|
|
71387
71481
|
}];
|
|
@@ -71575,6 +71669,7 @@ mutation addPendingDocumentMutation(
|
|
|
71575
71669
|
branchName: options.branchName,
|
|
71576
71670
|
baseBranch: options.baseBranch,
|
|
71577
71671
|
prTitle: options.prTitle,
|
|
71672
|
+
isDraft: options.isDraft,
|
|
71578
71673
|
graphQLContentOp: options.graphQLContentOp
|
|
71579
71674
|
},
|
|
71580
71675
|
"Failed to start editorial workflow"
|
|
@@ -73014,7 +73109,7 @@ const TemplateMenu = ({
|
|
|
73014
73109
|
leaveFrom: "transform opacity-100 scale-100",
|
|
73015
73110
|
leaveTo: "transform opacity-0 scale-95"
|
|
73016
73111
|
},
|
|
73017
|
-
/* @__PURE__ */ React__default.createElement(MenuItems, { className: "origin-top-right absolute right-0 mt-2 z-menu w-56 rounded shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none" }, /* @__PURE__ */ React__default.createElement("div", { className: "py-1" }, templates.map((template) => /* @__PURE__ */ React__default.createElement(MenuItem, { key: `${template.label}-${template.name}` }, ({ focus }) => /* @__PURE__ */ React__default.createElement(
|
|
73112
|
+
/* @__PURE__ */ React__default.createElement(MenuItems, { className: "origin-top-right absolute right-0 mt-2 z-menu w-56 rounded shadow-lg bg-white ring-1 ring-black ring-opacity-5 focus:outline-none" }, /* @__PURE__ */ React__default.createElement("div", { className: "py-1" }, templates.map((template) => /* @__PURE__ */ React__default.createElement(MenuItem$1, { key: `${template.label}-${template.name}` }, ({ focus }) => /* @__PURE__ */ React__default.createElement(
|
|
73018
73113
|
Link$1,
|
|
73019
73114
|
{
|
|
73020
73115
|
to: `/${folder.fullyQualifiedName ? [
|
|
@@ -73238,7 +73333,7 @@ const CollectionListPage = () => {
|
|
|
73238
73333
|
);
|
|
73239
73334
|
reFetchCollection();
|
|
73240
73335
|
} catch (error2) {
|
|
73241
|
-
if (error2.message.
|
|
73336
|
+
if (error2.message.includes(ERR_HAS_REFERENCES)) {
|
|
73242
73337
|
cms.alerts.error(
|
|
73243
73338
|
error2.message.split("\n ").filter(Boolean)[1]
|
|
73244
73339
|
);
|
|
@@ -73248,7 +73343,6 @@ const CollectionListPage = () => {
|
|
|
73248
73343
|
"Document was not deleted, ask a developer for help or check the console for an error message"
|
|
73249
73344
|
);
|
|
73250
73345
|
console.error(error2);
|
|
73251
|
-
throw error2;
|
|
73252
73346
|
}
|
|
73253
73347
|
},
|
|
73254
73348
|
close: () => setDeleteModalOpen(false)
|
|
@@ -73300,11 +73394,11 @@ const CollectionListPage = () => {
|
|
|
73300
73394
|
);
|
|
73301
73395
|
reFetchCollection();
|
|
73302
73396
|
} catch (error2) {
|
|
73303
|
-
if (error2.message && error2.message.includes(
|
|
73397
|
+
if (error2.message && error2.message.includes(ERR_ALREADY_EXISTS)) {
|
|
73304
73398
|
cms.alerts.error(
|
|
73305
73399
|
`Document was not renamed. The filename "${vars.newRelativePath}" is already used by another document, please choose a different name.`
|
|
73306
73400
|
);
|
|
73307
|
-
} else if (error2.message && error2.message.includes(
|
|
73401
|
+
} else if (error2.message && error2.message.includes(ERR_HAS_REFERENCES)) {
|
|
73308
73402
|
cms.alerts.error(
|
|
73309
73403
|
error2.message.split("\n ").filter(Boolean)[1]
|
|
73310
73404
|
);
|
|
@@ -73346,7 +73440,7 @@ const CollectionListPage = () => {
|
|
|
73346
73440
|
);
|
|
73347
73441
|
cms.alerts.info("Folder was successfully created");
|
|
73348
73442
|
} catch (error2) {
|
|
73349
|
-
if (error2.message && error2.message.includes(
|
|
73443
|
+
if (error2.message && error2.message.includes(ERR_ALREADY_EXISTS)) {
|
|
73350
73444
|
cms.alerts.error(
|
|
73351
73445
|
`Folder was not created, folder with name "${vars.folderName}" already exists ${folder.name ? `in ${folder.name}` : ""}`
|
|
73352
73446
|
);
|
|
@@ -73932,38 +74026,56 @@ const FolderModal = ({
|
|
|
73932
74026
|
validationRegex
|
|
73933
74027
|
}) => {
|
|
73934
74028
|
const [isFolderNameValid, setIsFolderNameValid] = useState(false);
|
|
74029
|
+
const [validationMessage, setValidationMessage] = useState(
|
|
74030
|
+
null
|
|
74031
|
+
);
|
|
73935
74032
|
const [isInteracted, setIsInteracted] = useState(false);
|
|
73936
74033
|
useEffect(() => {
|
|
73937
74034
|
validateFolderName(folderName);
|
|
73938
74035
|
}, [folderName]);
|
|
73939
74036
|
const validateFolderName = (name2) => {
|
|
73940
|
-
if (!
|
|
73941
|
-
setIsFolderNameValid(
|
|
73942
|
-
|
|
74037
|
+
if (!name2.trim()) {
|
|
74038
|
+
setIsFolderNameValid(false);
|
|
74039
|
+
setValidationMessage(null);
|
|
74040
|
+
return false;
|
|
73943
74041
|
}
|
|
73944
|
-
|
|
73945
|
-
const regex = new RegExp(validationRegex);
|
|
73946
|
-
const valid = regex.test(name2);
|
|
73947
|
-
setIsFolderNameValid(valid);
|
|
73948
|
-
return valid;
|
|
73949
|
-
} catch (error2) {
|
|
74042
|
+
if (!isValidRelativePath(name2)) {
|
|
73950
74043
|
setIsFolderNameValid(false);
|
|
74044
|
+
setValidationMessage(RELATIVE_PATH_ALLOWED_CHARS_MESSAGE);
|
|
73951
74045
|
return false;
|
|
73952
74046
|
}
|
|
74047
|
+
if (validationRegex) {
|
|
74048
|
+
let passesCustomRegex = false;
|
|
74049
|
+
try {
|
|
74050
|
+
passesCustomRegex = new RegExp(validationRegex).test(name2);
|
|
74051
|
+
} catch (error2) {
|
|
74052
|
+
passesCustomRegex = false;
|
|
74053
|
+
}
|
|
74054
|
+
if (!passesCustomRegex) {
|
|
74055
|
+
setIsFolderNameValid(false);
|
|
74056
|
+
setValidationMessage(
|
|
74057
|
+
"Folder name is not valid, please enter a valid folder name."
|
|
74058
|
+
);
|
|
74059
|
+
return false;
|
|
74060
|
+
}
|
|
74061
|
+
}
|
|
74062
|
+
setIsFolderNameValid(true);
|
|
74063
|
+
setValidationMessage(null);
|
|
74064
|
+
return true;
|
|
73953
74065
|
};
|
|
73954
74066
|
return /* @__PURE__ */ React__default.createElement(Modal, null, /* @__PURE__ */ React__default.createElement(PopupModal, null, /* @__PURE__ */ React__default.createElement(ModalHeader, { close: close2 }, "Create Folder"), /* @__PURE__ */ React__default.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
|
|
73955
74067
|
BaseTextField,
|
|
73956
74068
|
{
|
|
73957
74069
|
placeholder: "Enter the name of the new folder",
|
|
73958
74070
|
value: folderName,
|
|
73959
|
-
className: `mb-4 ${
|
|
74071
|
+
className: `mb-4 ${isInteracted && validationMessage ? "border-red-500" : ""}`,
|
|
73960
74072
|
onChange: (event) => {
|
|
73961
74073
|
setFolderName(event.target.value);
|
|
73962
74074
|
setIsInteracted(true);
|
|
73963
74075
|
validateFolderName(event.target.value);
|
|
73964
74076
|
}
|
|
73965
74077
|
}
|
|
73966
|
-
),
|
|
74078
|
+
), isInteracted && validationMessage && /* @__PURE__ */ React__default.createElement("p", { className: "text-red-500 text-sm pl-1" }, validationMessage))), /* @__PURE__ */ React__default.createElement(ModalActions, null, /* @__PURE__ */ React__default.createElement(Button$2, { style: { flexGrow: 2 }, onClick: close2 }, "Cancel"), /* @__PURE__ */ React__default.createElement(
|
|
73967
74079
|
Button$2,
|
|
73968
74080
|
{
|
|
73969
74081
|
style: { flexGrow: 3 },
|
|
@@ -74403,9 +74515,8 @@ const RenderForm$1 = ({
|
|
|
74403
74515
|
}
|
|
74404
74516
|
return true;
|
|
74405
74517
|
}
|
|
74406
|
-
|
|
74407
|
-
|
|
74408
|
-
return "Must contain only a-z, A-Z, 0-9, -, _, ., or /.";
|
|
74518
|
+
if (!RELATIVE_PATH_REGEX.test(value)) {
|
|
74519
|
+
return RELATIVE_PATH_ALLOWED_CHARS_MESSAGE;
|
|
74409
74520
|
}
|
|
74410
74521
|
if (((_a2 = schemaCollection.match) == null ? void 0 : _a2.exclude) || ((_b2 = schemaCollection.match) == null ? void 0 : _b2.include)) {
|
|
74411
74522
|
const filePath = `${normalizePath(schemaCollection.path)}/${value}.${schemaCollection.format || "md"}`;
|
|
@@ -74467,7 +74578,7 @@ const RenderForm$1 = ({
|
|
|
74467
74578
|
}, 10);
|
|
74468
74579
|
} catch (error2) {
|
|
74469
74580
|
const defaultErrorText = "There was a problem saving your document.";
|
|
74470
|
-
if (error2.message && error2.message.includes(
|
|
74581
|
+
if (error2.message && error2.message.includes(ERR_ALREADY_EXISTS)) {
|
|
74471
74582
|
cms.alerts.error(
|
|
74472
74583
|
`${defaultErrorText} The filename "${form.values.filename}.${collection.format || "md"}" is already used for another document, please modify it.`
|
|
74473
74584
|
);
|
|
@@ -74928,7 +75039,7 @@ const CheckSchema = ({
|
|
|
74928
75039
|
);
|
|
74929
75040
|
}
|
|
74930
75041
|
}).catch((error2) => {
|
|
74931
|
-
if (error2.message.includes(
|
|
75042
|
+
if (error2.message.includes(ERR_NOT_INDEXED)) {
|
|
74932
75043
|
setSchemaMissingError(true);
|
|
74933
75044
|
} else {
|
|
74934
75045
|
console.error("Unexpected error checking schema:", error2);
|
|
@@ -23,6 +23,12 @@ export type SaveContentErrorPayload = {
|
|
|
23
23
|
documentPath?: string;
|
|
24
24
|
error?: string;
|
|
25
25
|
};
|
|
26
|
+
export declare const EditorialWorkflowSaveEvent: string;
|
|
27
|
+
export type EditorialWorkflowSavePayload = {
|
|
28
|
+
choice: 'draft' | 'review' | 'publish';
|
|
29
|
+
success: boolean;
|
|
30
|
+
error?: string;
|
|
31
|
+
};
|
|
26
32
|
export declare const FormResetEvent: string;
|
|
27
33
|
export declare const MediaManagerContentUploadedEvent: string;
|
|
28
34
|
export type MediaManagerContentUploadedPayload = {
|
package/dist/react.js
CHANGED
|
@@ -147,17 +147,24 @@ function useTina(props) {
|
|
|
147
147
|
}
|
|
148
148
|
function useEditState() {
|
|
149
149
|
const [edit, setEdit] = React.useState(false);
|
|
150
|
+
const trustedAdminOrigins = useTrustedAdminOrigins();
|
|
150
151
|
React.useEffect(() => {
|
|
151
|
-
if (typeof window
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
152
|
+
if (typeof window === "undefined")
|
|
153
|
+
return;
|
|
154
|
+
parent.postMessage({ type: "isEditMode" }, window.location.origin);
|
|
155
|
+
const handleMessage = (event) => {
|
|
156
|
+
var _a;
|
|
157
|
+
if (!isFromAdmin(event, trustedAdminOrigins))
|
|
158
|
+
return;
|
|
159
|
+
if (((_a = event.data) == null ? void 0 : _a.type) === "tina:editMode") {
|
|
160
|
+
setEdit(true);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
window.addEventListener("message", handleMessage);
|
|
164
|
+
return () => {
|
|
165
|
+
window.removeEventListener("message", handleMessage);
|
|
166
|
+
};
|
|
167
|
+
}, [trustedAdminOrigins]);
|
|
161
168
|
return { edit };
|
|
162
169
|
}
|
|
163
170
|
export {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Form } from '../forms';
|
|
3
|
+
import { type SaveChoice } from './save-options';
|
|
3
4
|
export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crudType, tinaForm, onBaseBranchDeleted, }: {
|
|
4
|
-
safeSubmit: () => Promise<void>;
|
|
5
|
+
safeSubmit: (editorialWorkflowChoice?: SaveChoice) => Promise<void>;
|
|
5
6
|
close: () => void;
|
|
6
7
|
path: string;
|
|
7
8
|
values: Record<string, unknown>;
|
|
@@ -9,14 +10,16 @@ export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crud
|
|
|
9
10
|
tinaForm?: Form;
|
|
10
11
|
onBaseBranchDeleted?: () => void;
|
|
11
12
|
}) => React.JSX.Element;
|
|
12
|
-
export declare const CreateBranchPromptModal: ({ branchName, close, disabled, errorMessage, onBranchNameChange, onCreateBranch, onSaveToProtectedBranch, }: {
|
|
13
|
+
export declare const CreateBranchPromptModal: ({ branchName, close, disabled, errorMessage, onBranchNameChange, onCreateBranch, onSaveToProtectedBranch, showSaveOptions, disablePublish, }: {
|
|
13
14
|
branchName: string;
|
|
14
15
|
close: () => void;
|
|
15
16
|
disabled?: boolean;
|
|
16
17
|
errorMessage?: string;
|
|
17
18
|
onBranchNameChange: (value: string) => void;
|
|
18
|
-
onCreateBranch: () => void;
|
|
19
|
+
onCreateBranch: (isDraft: boolean) => void;
|
|
19
20
|
onSaveToProtectedBranch: () => void;
|
|
21
|
+
showSaveOptions?: boolean;
|
|
22
|
+
disablePublish?: boolean;
|
|
20
23
|
}) => React.JSX.Element;
|
|
21
24
|
export declare const PrefixedTextField: ({ label, prefix, ...props }: {
|
|
22
25
|
[x: string]: any;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SaveChoice = 'draft' | 'review' | 'publish';
|
|
2
|
+
export declare const SAVE_CHOICE_KEY = "tina.editorialWorkflow.saveChoice";
|
|
3
|
+
export declare const SAVE_CHOICE_ORDER: SaveChoice[];
|
|
4
|
+
export declare const resolveSaveOptions: (lastChoice: SaveChoice, disablePublish: boolean) => {
|
|
5
|
+
main: SaveChoice;
|
|
6
|
+
menu: SaveChoice[];
|
|
7
|
+
};
|
|
@@ -13,14 +13,18 @@ export interface ExecuteWorkflowOptions {
|
|
|
13
13
|
crudType: string;
|
|
14
14
|
tinaForm?: Form;
|
|
15
15
|
signal?: AbortSignal;
|
|
16
|
+
isDraft?: boolean;
|
|
16
17
|
}
|
|
17
18
|
export interface UseEditorialWorkflowResult {
|
|
18
19
|
isExecuting: boolean;
|
|
19
20
|
errorMessage: string;
|
|
20
21
|
currentStep: number;
|
|
21
22
|
elapsedTime: number;
|
|
22
|
-
/**
|
|
23
|
-
executeWorkflow: (opts: ExecuteWorkflowOptions) => Promise<
|
|
23
|
+
/** Resolves with the outcome; on failure `error` holds the message. */
|
|
24
|
+
executeWorkflow: (opts: ExecuteWorkflowOptions) => Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
error?: string;
|
|
27
|
+
}>;
|
|
24
28
|
/** Reset error/executing state so the form can be retried */
|
|
25
29
|
reset: () => void;
|
|
26
30
|
}
|
|
@@ -6,6 +6,8 @@ export interface DropdownButtonItem {
|
|
|
6
6
|
variant?: 'default' | 'destructive';
|
|
7
7
|
icon?: React.ReactNode;
|
|
8
8
|
disabled?: boolean;
|
|
9
|
+
/** Optional hover tooltip. Shown even when the item is disabled. */
|
|
10
|
+
tooltip?: string;
|
|
9
11
|
}
|
|
10
12
|
export interface DropdownButtonProps extends Omit<ButtonProps, 'onClick'> {
|
|
11
13
|
/**
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "tinacms",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"typings": "dist/index.d.ts",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.10.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"exports": {
|
|
@@ -45,15 +45,14 @@
|
|
|
45
45
|
"@headlessui/react": "2.1.8",
|
|
46
46
|
"@heroicons/react": "^1.0.6",
|
|
47
47
|
"@monaco-editor/react": "4.7.0-rc.0",
|
|
48
|
-
"@radix-ui/react-
|
|
49
|
-
"@radix-ui/react-
|
|
50
|
-
"@radix-ui/react-
|
|
51
|
-
"@radix-ui/react-
|
|
52
|
-
"@radix-ui/react-
|
|
53
|
-
"@radix-ui/react-
|
|
54
|
-
"@radix-ui/react-
|
|
55
|
-
"@radix-ui/react-
|
|
56
|
-
"@radix-ui/react-tooltip": "^1.2.8",
|
|
48
|
+
"@radix-ui/react-dialog": "^1.1.18",
|
|
49
|
+
"@radix-ui/react-dropdown-menu": "^2.1.19",
|
|
50
|
+
"@radix-ui/react-popover": "^1.1.18",
|
|
51
|
+
"@radix-ui/react-select": "^2.3.2",
|
|
52
|
+
"@radix-ui/react-separator": "^1.1.11",
|
|
53
|
+
"@radix-ui/react-slot": "^1.3.0",
|
|
54
|
+
"@radix-ui/react-toolbar": "^1.1.14",
|
|
55
|
+
"@radix-ui/react-tooltip": "^1.2.11",
|
|
57
56
|
"@react-hook/window-size": "^3.1.1",
|
|
58
57
|
"@tanstack/react-table": "^8.21.3",
|
|
59
58
|
"@udecode/cmdk": "^0.2.1",
|
|
@@ -114,9 +113,9 @@
|
|
|
114
113
|
"yup": "^1.6.1",
|
|
115
114
|
"zod": "^3.24.2",
|
|
116
115
|
"@tinacms/bridge": "0.3.0",
|
|
117
|
-
"@tinacms/
|
|
118
|
-
"@tinacms/
|
|
119
|
-
"@tinacms/
|
|
116
|
+
"@tinacms/schema-tools": "2.8.3",
|
|
117
|
+
"@tinacms/search": "1.2.21",
|
|
118
|
+
"@tinacms/mdx": "2.1.9"
|
|
120
119
|
},
|
|
121
120
|
"devDependencies": {
|
|
122
121
|
"@graphql-tools/utils": "^10.8.1",
|