tinacms 3.7.2 → 3.7.3
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 +429 -178
- package/dist/internalClient/index.d.ts +1 -0
- package/dist/toolkit/core/media.d.ts +7 -0
- package/dist/toolkit/fields/plugins/display-only-field-plugin.d.ts +12 -0
- package/dist/toolkit/fields/plugins/index.d.ts +1 -0
- package/dist/toolkit/form-builder/branch-deleted-modal.d.ts +10 -0
- package/dist/toolkit/form-builder/create-branch-modal.d.ts +2 -1
- package/dist/toolkit/form-builder/use-editorial-workflow.d.ts +26 -0
- package/dist/toolkit/form-builder/workflow-progress-indicator.d.ts +8 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -39571,12 +39571,6 @@ const ResetModal = ({ close: close2, reset: reset2 }) => {
|
|
|
39571
39571
|
"Reset"
|
|
39572
39572
|
))));
|
|
39573
39573
|
};
|
|
39574
|
-
function AiFillWarning(props) {
|
|
39575
|
-
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 1024 1024" }, "child": [{ "tag": "path", "attr": { "d": "M955.7 856l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zM480 416c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v184c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V416zm32 352a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z" }, "child": [] }] })(props);
|
|
39576
|
-
}
|
|
39577
|
-
function AiOutlineLoading(props) {
|
|
39578
|
-
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 1024 1024" }, "child": [{ "tag": "path", "attr": { "d": "M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" }, "child": [] }] })(props);
|
|
39579
|
-
}
|
|
39580
39574
|
const textFieldClasses = "shadow-inner focus:shadow-outline focus:border-blue-500 focus:outline-none block text-base placeholder:text-gray-300 px-3 py-2 text-gray-600 w-full bg-white border border-gray-200 transition-all ease-out duration-150 focus:text-gray-900 rounded";
|
|
39581
39575
|
const disabledClasses$1 = "opacity-50 pointer-events-none cursor-not-allowed";
|
|
39582
39576
|
const BaseTextField = React.forwardRef(({ className, disabled, ...rest }, ref) => {
|
|
@@ -41935,13 +41929,8 @@ const ImageField = wrapFieldsWithMeta(
|
|
|
41935
41929
|
async function onChange(media) {
|
|
41936
41930
|
var _a2, _b;
|
|
41937
41931
|
if (media) {
|
|
41938
|
-
const
|
|
41939
|
-
|
|
41940
|
-
typeof ((_b = (_a2 = cms == null ? void 0 : cms.media) == null ? void 0 : _a2.store) == null ? void 0 : _b.parse) === "function" ? (
|
|
41941
|
-
// @ts-ignore
|
|
41942
|
-
cms.media.store.parse(media)
|
|
41943
|
-
) : media
|
|
41944
|
-
);
|
|
41932
|
+
const item = Array.isArray(media) ? media[0] : media;
|
|
41933
|
+
const parsedValue = typeof ((_b = (_a2 = cms == null ? void 0 : cms.media) == null ? void 0 : _a2.store) == null ? void 0 : _b.parse) === "function" ? cms.media.store.parse(item) : item.src || item;
|
|
41945
41934
|
props.input.onChange(parsedValue);
|
|
41946
41935
|
}
|
|
41947
41936
|
}
|
|
@@ -43774,6 +43763,38 @@ const PasswordFieldPlugin = {
|
|
|
43774
43763
|
},
|
|
43775
43764
|
parse: parse$2
|
|
43776
43765
|
};
|
|
43766
|
+
const DefaultDisplayOnlyField = () => {
|
|
43767
|
+
return /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3 text-sm text-gray-500 italic" }, "Display-only field — provide a component via ", /* @__PURE__ */ React.createElement("code", null, "ui.component"));
|
|
43768
|
+
};
|
|
43769
|
+
const DisplayOnlyFieldPlugin = {
|
|
43770
|
+
name: "displayOnly",
|
|
43771
|
+
Component: wrapFieldWithNoHeader(DefaultDisplayOnlyField)
|
|
43772
|
+
};
|
|
43773
|
+
const InfoBox = ({
|
|
43774
|
+
message,
|
|
43775
|
+
links
|
|
43776
|
+
}) => {
|
|
43777
|
+
const InfoBoxComponent = () => {
|
|
43778
|
+
return /* @__PURE__ */ React.createElement("div", { className: "relative w-full px-2 mb-5 last:mb-0" }, /* @__PURE__ */ React.createElement("div", { className: "rounded-lg border border-blue-200 bg-blue-50 p-3 text-sm w-full" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-700 whitespace-normal break-words" }, message), links && links.length > 0 && /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-1 mt-2" }, links.map((link) => /* @__PURE__ */ React.createElement("li", { key: link.url }, /* @__PURE__ */ React.createElement(
|
|
43779
|
+
"a",
|
|
43780
|
+
{
|
|
43781
|
+
href: link.url,
|
|
43782
|
+
target: "_blank",
|
|
43783
|
+
rel: "noopener noreferrer",
|
|
43784
|
+
className: "text-blue-600 underline hover:text-blue-800"
|
|
43785
|
+
},
|
|
43786
|
+
link.text
|
|
43787
|
+
))))));
|
|
43788
|
+
};
|
|
43789
|
+
InfoBoxComponent.displayName = "InfoBox";
|
|
43790
|
+
return InfoBoxComponent;
|
|
43791
|
+
};
|
|
43792
|
+
function AiFillWarning(props) {
|
|
43793
|
+
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 1024 1024" }, "child": [{ "tag": "path", "attr": { "d": "M955.7 856l-416-720c-6.2-10.7-16.9-16-27.7-16s-21.6 5.3-27.7 16l-416 720C56 877.4 71.4 904 96 904h832c24.6 0 40-26.6 27.7-48zM480 416c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v184c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V416zm32 352a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z" }, "child": [] }] })(props);
|
|
43794
|
+
}
|
|
43795
|
+
function AiOutlineLoading(props) {
|
|
43796
|
+
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 1024 1024" }, "child": [{ "tag": "path", "attr": { "d": "M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" }, "child": [] }] })(props);
|
|
43797
|
+
}
|
|
43777
43798
|
function GrCircleQuestion(props) {
|
|
43778
43799
|
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24" }, "child": [{ "tag": "path", "attr": { "fill": "none", "strokeWidth": "2", "d": "M12,22 C17.5228475,22 22,17.5228475 22,12 C22,6.4771525 17.5228475,2 12,2 C6.4771525,2 2,6.4771525 2,12 C2,17.5228475 6.4771525,22 12,22 Z M12,15 L12,14 C12,13 12,12.5 13,12 C14,11.5 15,11 15,9.5 C15,8.5 14,7 12,7 C10,7 9,8.26413718 9,10 M12,16 L12,18" }, "child": [] }] })(props);
|
|
43779
43800
|
}
|
|
@@ -44179,6 +44200,9 @@ function BranchSelectorTable({
|
|
|
44179
44200
|
null
|
|
44180
44201
|
);
|
|
44181
44202
|
const cms = useCMS$1();
|
|
44203
|
+
const isCurrentBranchDeleted = !branchList.some(
|
|
44204
|
+
(b) => b.name === currentBranch
|
|
44205
|
+
);
|
|
44182
44206
|
const columns = [
|
|
44183
44207
|
{
|
|
44184
44208
|
accessorKey: "name",
|
|
@@ -44355,7 +44379,7 @@ function BranchSelectorTable({
|
|
|
44355
44379
|
{
|
|
44356
44380
|
className: cn(
|
|
44357
44381
|
"bg-transparent hover:!bg-transparent",
|
|
44358
|
-
|
|
44382
|
+
isCurrentBranchDeleted ? "border-l-[3px] border-l-yellow-400 bg-yellow-50" : "border-l-[3px] border-l-tina-orange bg-[#f8fafc]"
|
|
44359
44383
|
)
|
|
44360
44384
|
},
|
|
44361
44385
|
/* @__PURE__ */ React.createElement(TableCell, null, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, currentBranchData.protected ? /* @__PURE__ */ React.createElement(BiLockAlt, { className: "w-4 h-auto opacity-70 text-blue-500 flex-shrink-0" }) : /* @__PURE__ */ React.createElement(BiGitBranch, { className: "w-4 h-auto opacity-70 text-gray-600 flex-shrink-0" }), /* @__PURE__ */ React.createElement("p", { className: "font-bold" }, currentBranchData.name)), /* @__PURE__ */ React.createElement("div", { className: "w-fit mt-1" }, /* @__PURE__ */ React.createElement(
|
|
@@ -44367,6 +44391,15 @@ function BranchSelectorTable({
|
|
|
44367
44391
|
},
|
|
44368
44392
|
/* @__PURE__ */ React.createElement(BiPencil, { className: "w-3 h-auto inline-block mr-1" }),
|
|
44369
44393
|
"Currently editing"
|
|
44394
|
+
)), isCurrentBranchDeleted && /* @__PURE__ */ React.createElement("div", { className: "w-fit" }, /* @__PURE__ */ React.createElement(
|
|
44395
|
+
Badge,
|
|
44396
|
+
{
|
|
44397
|
+
displayIcon: false,
|
|
44398
|
+
calloutStyle: "warning",
|
|
44399
|
+
className: "w-fit flex-shrink-0"
|
|
44400
|
+
},
|
|
44401
|
+
/* @__PURE__ */ React.createElement(AiFillWarning, { className: "w-3 h-auto inline-block mr-1" }),
|
|
44402
|
+
"Branch no longer exists"
|
|
44370
44403
|
)))),
|
|
44371
44404
|
/* @__PURE__ */ React.createElement(TableCell, null, ((_e = currentBranchData.indexStatus) == null ? void 0 : _e.timestamp) && /* @__PURE__ */ React.createElement("div", null, formatDistanceToNow(
|
|
44372
44405
|
new Date(currentBranchData.indexStatus.timestamp)
|
|
@@ -46100,10 +46133,10 @@ function GridMediaItem({ item, active, onClick }) {
|
|
|
46100
46133
|
"button",
|
|
46101
46134
|
{
|
|
46102
46135
|
className: cn(
|
|
46103
|
-
"relative flex flex-col
|
|
46136
|
+
"relative flex flex-col gap-1 items-center w-full outline-none rounded-lg overflow-hidden border-2 transition",
|
|
46104
46137
|
{
|
|
46105
|
-
"
|
|
46106
|
-
"
|
|
46138
|
+
"border-black/10 hover:border-tina-orange/50 shadow-sm hover:shadow-md bg-white": !active,
|
|
46139
|
+
"border-tina-orange bg-tina-orange/10 shadow-md": active,
|
|
46107
46140
|
"cursor-pointer": item.type === "dir"
|
|
46108
46141
|
}
|
|
46109
46142
|
),
|
|
@@ -46115,35 +46148,23 @@ function GridMediaItem({ item, active, onClick }) {
|
|
|
46115
46148
|
}
|
|
46116
46149
|
}
|
|
46117
46150
|
},
|
|
46118
|
-
/* @__PURE__ */ React__default.createElement(
|
|
46119
|
-
"span",
|
|
46120
|
-
{
|
|
46121
|
-
className: cn(
|
|
46122
|
-
"absolute bottom-0 left-0 w-full text-xs text-white px-2 py-1 truncate z-10",
|
|
46123
|
-
active ? "bg-tina-orange/60" : "bg-black/60"
|
|
46124
|
-
),
|
|
46125
|
-
style: { pointerEvents: "none" }
|
|
46126
|
-
},
|
|
46127
|
-
item.filename
|
|
46128
|
-
),
|
|
46129
46151
|
item.new && /* @__PURE__ */ React__default.createElement("span", { className: "absolute top-1 right-1 rounded shadow bg-green-100 border border-green-200 text-[10px] tracking-wide font-bold text-green-600 px-1.5 py-0.5 z-10" }, "NEW"),
|
|
46130
|
-
/* @__PURE__ */ React__default.createElement("div", { className: "
|
|
46152
|
+
/* @__PURE__ */ React__default.createElement("div", { className: "w-full overflow-hidden aspect-[1/1]" }, itemIsImage ? /* @__PURE__ */ React__default.createElement(
|
|
46131
46153
|
"img",
|
|
46132
46154
|
{
|
|
46133
|
-
className:
|
|
46134
|
-
"block overflow-hidden object-center object-contain max-w-full max-h-[16rem] m-auto shadow"
|
|
46135
|
-
),
|
|
46155
|
+
className: "block w-full h-full object-center object-cover",
|
|
46136
46156
|
style: checkerboardStyle,
|
|
46137
46157
|
src: thumbnail,
|
|
46138
46158
|
alt: item.filename
|
|
46139
46159
|
}
|
|
46140
|
-
)
|
|
46160
|
+
) : /* @__PURE__ */ React__default.createElement("div", { className: "w-full h-full flex flex-col items-center justify-center" }, /* @__PURE__ */ React__default.createElement(
|
|
46141
46161
|
FileIcon,
|
|
46142
46162
|
{
|
|
46143
46163
|
className: `w-[40%] h-auto ${item.type === "dir" ? "fill-tina-orange" : "fill-gray-300"}`,
|
|
46144
46164
|
size: 40
|
|
46145
46165
|
}
|
|
46146
|
-
)))
|
|
46166
|
+
))),
|
|
46167
|
+
/* @__PURE__ */ React__default.createElement("div", { className: "mt-auto w-full px-2 py-1 text-sm truncate" }, item.filename)
|
|
46147
46168
|
));
|
|
46148
46169
|
}
|
|
46149
46170
|
const DeleteModal$1 = ({
|
|
@@ -48004,7 +48025,7 @@ const NavProvider = ({
|
|
|
48004
48025
|
const name = "tinacms";
|
|
48005
48026
|
const type = "module";
|
|
48006
48027
|
const typings = "dist/index.d.ts";
|
|
48007
|
-
const version$1 = "3.7.
|
|
48028
|
+
const version$1 = "3.7.3";
|
|
48008
48029
|
const main = "dist/index.js";
|
|
48009
48030
|
const module = "./dist/index.js";
|
|
48010
48031
|
const exports = {
|
|
@@ -48966,7 +48987,7 @@ const TreeNodeComponent = ({
|
|
|
48966
48987
|
node3.children.length > 0 && /* @__PURE__ */ React.createElement(
|
|
48967
48988
|
BiChevronRight,
|
|
48968
48989
|
{
|
|
48969
|
-
className: `w-4 h-4 text-gray-500 transition-transform duration-150 -ml-1 ${isExpanded ? "rotate-90" : ""}`
|
|
48990
|
+
className: `w-4 h-4 flex-none text-gray-500 transition-transform duration-150 -ml-1 ${isExpanded ? "rotate-90" : ""}`
|
|
48970
48991
|
}
|
|
48971
48992
|
),
|
|
48972
48993
|
isExpanded ? /* @__PURE__ */ React.createElement(BiFolderOpen, { className: "w-4 h-4 text-orange-500 flex-none" }) : /* @__PURE__ */ React.createElement(BiFolder, { className: "w-4 h-4 text-orange-500 flex-none" }),
|
|
@@ -49057,16 +49078,21 @@ const FormLists = (props) => {
|
|
|
49057
49078
|
onChange: (e3) => setShowReferences(e3.target.checked),
|
|
49058
49079
|
className: "w-4 h-4 text-orange-500 border-gray-300 rounded focus:ring-orange-500"
|
|
49059
49080
|
}
|
|
49060
|
-
), /* @__PURE__ */ React.createElement("span", null, "Show all references"))), /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-x-auto overflow-y-auto min-h-0
|
|
49081
|
+
), /* @__PURE__ */ React.createElement("span", null, "Show all references"))), /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-x-auto overflow-y-auto min-h-0 pb-16" }, /* @__PURE__ */ React.createElement(
|
|
49061
49082
|
FormList,
|
|
49062
49083
|
{
|
|
49063
49084
|
setActiveFormId: (id2) => {
|
|
49064
49085
|
cms.dispatch({ type: "forms:set-active-form-id", value: id2 });
|
|
49065
49086
|
},
|
|
49066
|
-
formList
|
|
49087
|
+
formList: {
|
|
49088
|
+
id: "merged",
|
|
49089
|
+
label: "All",
|
|
49090
|
+
items: cms.state.formLists.flatMap((fl) => fl.items),
|
|
49091
|
+
formIds: cms.state.formLists.flatMap((fl) => fl.formIds)
|
|
49092
|
+
},
|
|
49067
49093
|
showReferences
|
|
49068
49094
|
}
|
|
49069
|
-
)))
|
|
49095
|
+
)));
|
|
49070
49096
|
};
|
|
49071
49097
|
const FormList = (props) => {
|
|
49072
49098
|
const cms = useCMS();
|
|
@@ -49784,7 +49810,8 @@ const DEFAULT_FIELDS = [
|
|
|
49784
49810
|
ReferenceFieldPlugin,
|
|
49785
49811
|
ButtonToggleFieldPlugin,
|
|
49786
49812
|
HiddenFieldPlugin,
|
|
49787
|
-
PasswordFieldPlugin
|
|
49813
|
+
PasswordFieldPlugin,
|
|
49814
|
+
DisplayOnlyFieldPlugin
|
|
49788
49815
|
];
|
|
49789
49816
|
class TinaCMS extends CMS {
|
|
49790
49817
|
constructor({
|
|
@@ -66034,37 +66061,20 @@ const pathRelativeToCollection = (collectionPath, fullPath) => {
|
|
|
66034
66061
|
`Path ${fullPath} not within collection path ${collectionPath}`
|
|
66035
66062
|
);
|
|
66036
66063
|
};
|
|
66037
|
-
const
|
|
66038
|
-
|
|
66039
|
-
|
|
66040
|
-
|
|
66041
|
-
|
|
66042
|
-
|
|
66043
|
-
const
|
|
66044
|
-
const
|
|
66045
|
-
|
|
66046
|
-
result = result.slice(0, lastDot);
|
|
66047
|
-
}
|
|
66048
|
-
if (crudType === "delete") {
|
|
66049
|
-
result = `❌-${result}`;
|
|
66050
|
-
}
|
|
66051
|
-
return result;
|
|
66064
|
+
const WORKFLOW_STEPS = [
|
|
66065
|
+
{ id: 1, name: "Creating branch", description: "Setting up workspace" },
|
|
66066
|
+
{ id: 2, name: "Updating branch", description: "Syncing content to branch" },
|
|
66067
|
+
{ id: 3, name: "Creating pull request", description: "Preparing for review" }
|
|
66068
|
+
];
|
|
66069
|
+
const formatTime = (seconds) => {
|
|
66070
|
+
const mins = Math.floor(seconds / 60);
|
|
66071
|
+
const secs = seconds % 60;
|
|
66072
|
+
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
66052
66073
|
};
|
|
66053
|
-
|
|
66054
|
-
close: close2,
|
|
66055
|
-
safeSubmit,
|
|
66056
|
-
path: path3,
|
|
66057
|
-
values,
|
|
66058
|
-
crudType,
|
|
66059
|
-
tinaForm
|
|
66060
|
-
}) => {
|
|
66074
|
+
function useEditorialWorkflow() {
|
|
66061
66075
|
const cms = useCMS$1();
|
|
66062
66076
|
const tinaApi = cms.api.tina;
|
|
66063
66077
|
const { setCurrentBranch } = useBranchData();
|
|
66064
|
-
const [disabled, setDisabled] = React.useState(false);
|
|
66065
|
-
const [newBranchName, setNewBranchName] = React.useState(
|
|
66066
|
-
formatDefaultBranchName(path3, crudType)
|
|
66067
|
-
);
|
|
66068
66078
|
const [isExecuting, setIsExecuting] = React.useState(false);
|
|
66069
66079
|
const [errorMessage, setErrorMessage] = React.useState("");
|
|
66070
66080
|
const [currentStep, setCurrentStep] = React.useState(0);
|
|
@@ -66083,33 +66093,21 @@ const CreateBranchModal = ({
|
|
|
66083
66093
|
clearInterval(interval);
|
|
66084
66094
|
};
|
|
66085
66095
|
}, [isExecuting, currentStep]);
|
|
66086
|
-
const
|
|
66087
|
-
|
|
66088
|
-
|
|
66089
|
-
|
|
66096
|
+
const reset2 = () => {
|
|
66097
|
+
setErrorMessage("");
|
|
66098
|
+
setIsExecuting(false);
|
|
66099
|
+
setCurrentStep(0);
|
|
66090
66100
|
};
|
|
66091
|
-
const
|
|
66092
|
-
|
|
66093
|
-
|
|
66094
|
-
|
|
66095
|
-
|
|
66096
|
-
|
|
66097
|
-
|
|
66098
|
-
|
|
66099
|
-
name: "Updating branch",
|
|
66100
|
-
description: "Syncing content to branch"
|
|
66101
|
-
},
|
|
66102
|
-
{
|
|
66103
|
-
id: 3,
|
|
66104
|
-
name: "Creating pull request",
|
|
66105
|
-
description: "Preparing for review"
|
|
66106
|
-
}
|
|
66107
|
-
];
|
|
66108
|
-
const executeEditorialWorkflow = async () => {
|
|
66101
|
+
const executeWorkflow = async ({
|
|
66102
|
+
branchName,
|
|
66103
|
+
baseBranch,
|
|
66104
|
+
path: path3,
|
|
66105
|
+
values,
|
|
66106
|
+
crudType,
|
|
66107
|
+
tinaForm
|
|
66108
|
+
}) => {
|
|
66109
66109
|
var _a2;
|
|
66110
66110
|
try {
|
|
66111
|
-
const branchName = `tina/${newBranchName}`;
|
|
66112
|
-
setDisabled(true);
|
|
66113
66111
|
setIsExecuting(true);
|
|
66114
66112
|
setCurrentStep(1);
|
|
66115
66113
|
let graphql2 = "";
|
|
@@ -66139,7 +66137,7 @@ const CreateBranchModal = ({
|
|
|
66139
66137
|
const relativePath = pathRelativeToCollection(collection.path, path3);
|
|
66140
66138
|
const result = await tinaApi.executeEditorialWorkflow({
|
|
66141
66139
|
branchName,
|
|
66142
|
-
baseBranch
|
|
66140
|
+
baseBranch,
|
|
66143
66141
|
prTitle: `${branchName.replace("tina/", "").replace("-", " ")} (PR from TinaCMS)`,
|
|
66144
66142
|
graphQLContentOp: {
|
|
66145
66143
|
query: graphql2,
|
|
@@ -66186,118 +66184,209 @@ const CreateBranchModal = ({
|
|
|
66186
66184
|
const folderPath = relativePath.includes("/") ? relativePath.substring(0, relativePath.lastIndexOf("/")) : "";
|
|
66187
66185
|
window.location.hash = `#/collections/${collection.name}${folderPath ? `/${folderPath}` : ""}`;
|
|
66188
66186
|
}
|
|
66189
|
-
|
|
66187
|
+
return true;
|
|
66190
66188
|
} catch (e3) {
|
|
66191
66189
|
console.error(e3);
|
|
66192
|
-
let
|
|
66190
|
+
let errMessage = "Branch operation failed. Talking to GitHub was unsuccessful, please try again. If the problem persists please contact support at https://tina.io/support 🦙";
|
|
66193
66191
|
const err = e3;
|
|
66194
66192
|
if (err.errorCode) {
|
|
66195
66193
|
switch (err.errorCode) {
|
|
66196
66194
|
case EDITORIAL_WORKFLOW_ERROR.BRANCH_EXISTS:
|
|
66197
|
-
|
|
66195
|
+
errMessage = "A branch with this name already exists";
|
|
66198
66196
|
break;
|
|
66199
66197
|
case EDITORIAL_WORKFLOW_ERROR.BRANCH_HIERARCHY_CONFLICT:
|
|
66200
|
-
|
|
66198
|
+
errMessage = err.message || "Branch name conflicts with an existing branch";
|
|
66201
66199
|
break;
|
|
66202
66200
|
case EDITORIAL_WORKFLOW_ERROR.VALIDATION_FAILED:
|
|
66203
|
-
|
|
66201
|
+
errMessage = err.message || "Invalid branch name";
|
|
66204
66202
|
break;
|
|
66205
66203
|
default:
|
|
66206
|
-
|
|
66204
|
+
errMessage = err.message || errMessage;
|
|
66207
66205
|
break;
|
|
66208
66206
|
}
|
|
66209
66207
|
} else if (err.message) {
|
|
66210
66208
|
if (err.message.toLowerCase().includes("already exists")) {
|
|
66211
|
-
|
|
66209
|
+
errMessage = "A branch with this name already exists";
|
|
66212
66210
|
} else if (err.message.toLowerCase().includes("conflict")) {
|
|
66213
|
-
|
|
66211
|
+
errMessage = err.message;
|
|
66214
66212
|
}
|
|
66215
66213
|
}
|
|
66216
|
-
setErrorMessage(
|
|
66217
|
-
setDisabled(false);
|
|
66214
|
+
setErrorMessage(errMessage);
|
|
66218
66215
|
setIsExecuting(false);
|
|
66219
66216
|
setCurrentStep(0);
|
|
66217
|
+
return false;
|
|
66220
66218
|
}
|
|
66221
66219
|
};
|
|
66222
|
-
|
|
66223
|
-
|
|
66224
|
-
|
|
66225
|
-
|
|
66226
|
-
|
|
66227
|
-
|
|
66220
|
+
return {
|
|
66221
|
+
isExecuting,
|
|
66222
|
+
errorMessage,
|
|
66223
|
+
currentStep,
|
|
66224
|
+
elapsedTime,
|
|
66225
|
+
executeWorkflow,
|
|
66226
|
+
reset: reset2
|
|
66227
|
+
};
|
|
66228
|
+
}
|
|
66229
|
+
const WorkflowProgressIndicator = ({
|
|
66230
|
+
currentStep,
|
|
66231
|
+
isExecuting,
|
|
66232
|
+
elapsedTime
|
|
66233
|
+
}) => {
|
|
66234
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between my-8 relative px-5 sm:gap-x-8" }, /* @__PURE__ */ React.createElement(
|
|
66235
|
+
"div",
|
|
66236
|
+
{
|
|
66237
|
+
className: "absolute top-5 h-0.5 bg-gray-200 -z-10",
|
|
66238
|
+
style: { left: "50px", right: "50px" }
|
|
66239
|
+
}
|
|
66240
|
+
), currentStep > 1 && currentStep <= WORKFLOW_STEPS.length && /* @__PURE__ */ React.createElement(
|
|
66241
|
+
"div",
|
|
66242
|
+
{
|
|
66243
|
+
className: "absolute top-5 h-0.5 bg-tina-orange -z-10 transition-all duration-500",
|
|
66244
|
+
style: {
|
|
66245
|
+
left: "50px",
|
|
66246
|
+
width: `calc((100% - 100px) * ${(currentStep - 1) / (WORKFLOW_STEPS.length - 1)})`
|
|
66228
66247
|
}
|
|
66229
|
-
|
|
66230
|
-
|
|
66231
|
-
|
|
66232
|
-
|
|
66233
|
-
|
|
66234
|
-
|
|
66235
|
-
|
|
66236
|
-
}
|
|
66248
|
+
}
|
|
66249
|
+
), currentStep > 2 && /* @__PURE__ */ React.createElement(
|
|
66250
|
+
"div",
|
|
66251
|
+
{
|
|
66252
|
+
className: "absolute top-5 h-0.5 bg-green-500 -z-10 transition-all duration-500",
|
|
66253
|
+
style: {
|
|
66254
|
+
left: "50px",
|
|
66255
|
+
width: `calc((100% - 100px) * ${Math.min(1, (currentStep - 2) / (WORKFLOW_STEPS.length - 1))})`
|
|
66237
66256
|
}
|
|
66238
|
-
|
|
66257
|
+
}
|
|
66258
|
+
), WORKFLOW_STEPS.map((step, index) => {
|
|
66259
|
+
const stepNumber = index + 1;
|
|
66260
|
+
const isActive = stepNumber === currentStep;
|
|
66261
|
+
const isCompleted = stepNumber < currentStep;
|
|
66262
|
+
return /* @__PURE__ */ React.createElement("div", { key: step.id, className: "flex flex-col items-center relative" }, /* @__PURE__ */ React.createElement(
|
|
66239
66263
|
"div",
|
|
66240
66264
|
{
|
|
66241
|
-
className:
|
|
66242
|
-
|
|
66243
|
-
|
|
66244
|
-
|
|
66245
|
-
}
|
|
66246
|
-
}
|
|
66247
|
-
), steps.map((step, index) => {
|
|
66248
|
-
const stepNumber = index + 1;
|
|
66249
|
-
const isActive = stepNumber === currentStep;
|
|
66250
|
-
const isCompleted = stepNumber < currentStep;
|
|
66251
|
-
return /* @__PURE__ */ React.createElement(
|
|
66252
|
-
"div",
|
|
66265
|
+
className: `w-10 h-10 rounded-full flex items-center justify-center font-medium mb-3 border-2 transition-all duration-300 select-none ${isCompleted ? "bg-green-500 border-green-500 text-white" : isActive ? "bg-tina-orange border-tina-orange text-white" : "bg-white border-gray-200 text-gray-400"}`
|
|
66266
|
+
},
|
|
66267
|
+
isCompleted ? /* @__PURE__ */ React.createElement(
|
|
66268
|
+
"svg",
|
|
66253
66269
|
{
|
|
66254
|
-
|
|
66255
|
-
|
|
66270
|
+
className: "w-5 h-5",
|
|
66271
|
+
fill: "currentColor",
|
|
66272
|
+
viewBox: "0 0 20 20"
|
|
66256
66273
|
},
|
|
66257
66274
|
/* @__PURE__ */ React.createElement(
|
|
66258
|
-
"
|
|
66275
|
+
"path",
|
|
66259
66276
|
{
|
|
66260
|
-
|
|
66261
|
-
|
|
66262
|
-
|
|
66263
|
-
|
|
66264
|
-
|
|
66265
|
-
|
|
66266
|
-
|
|
66267
|
-
|
|
66268
|
-
|
|
66269
|
-
|
|
66270
|
-
|
|
66271
|
-
|
|
66272
|
-
|
|
66273
|
-
|
|
66274
|
-
|
|
66275
|
-
|
|
66276
|
-
|
|
66277
|
-
|
|
66278
|
-
|
|
66279
|
-
|
|
66277
|
+
fillRule: "evenodd",
|
|
66278
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",
|
|
66279
|
+
clipRule: "evenodd"
|
|
66280
|
+
}
|
|
66281
|
+
)
|
|
66282
|
+
) : isActive ? /* @__PURE__ */ React.createElement(AiOutlineLoading, { className: "animate-spin text-lg" }) : stepNumber
|
|
66283
|
+
), /* @__PURE__ */ React.createElement("div", { className: "text-center max-w-24" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-semibold leading-tight" }, step.name), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-gray-400 mt-1 leading-tight" }, step.description)));
|
|
66284
|
+
})), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs text-gray-500" }, "Estimated time: 1-2 min"), isExecuting && currentStep > 0 && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-1 text-sm text-gray-500 tabular-nums" }, /* @__PURE__ */ React.createElement("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20" }, /* @__PURE__ */ React.createElement(
|
|
66285
|
+
"path",
|
|
66286
|
+
{
|
|
66287
|
+
fillRule: "evenodd",
|
|
66288
|
+
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z",
|
|
66289
|
+
clipRule: "evenodd"
|
|
66290
|
+
}
|
|
66291
|
+
)), formatTime(elapsedTime))), /* @__PURE__ */ React.createElement(
|
|
66292
|
+
"a",
|
|
66293
|
+
{
|
|
66294
|
+
className: "underline text-tina-orange-dark font-medium text-xs",
|
|
66295
|
+
href: "https://tina.io/docs/tinacloud/editorial-workflow",
|
|
66296
|
+
target: "_blank"
|
|
66297
|
+
},
|
|
66298
|
+
"Learn more about Editorial Workflow"
|
|
66299
|
+
));
|
|
66300
|
+
};
|
|
66301
|
+
const formatDefaultBranchName = (filePath, crudType) => {
|
|
66302
|
+
let result = filePath;
|
|
66303
|
+
const contentPrefix = "content/";
|
|
66304
|
+
if (result.startsWith(contentPrefix)) {
|
|
66305
|
+
result = result.substring(contentPrefix.length);
|
|
66306
|
+
}
|
|
66307
|
+
const lastDot = result.lastIndexOf(".");
|
|
66308
|
+
const lastSlash = Math.max(result.lastIndexOf("/"), result.lastIndexOf("\\"));
|
|
66309
|
+
if (lastDot > lastSlash && lastDot > 0) {
|
|
66310
|
+
result = result.slice(0, lastDot);
|
|
66311
|
+
}
|
|
66312
|
+
if (crudType === "delete") {
|
|
66313
|
+
result = `❌-${result}`;
|
|
66314
|
+
}
|
|
66315
|
+
return result;
|
|
66316
|
+
};
|
|
66317
|
+
const CreateBranchModal = ({
|
|
66318
|
+
close: close2,
|
|
66319
|
+
safeSubmit,
|
|
66320
|
+
path: path3,
|
|
66321
|
+
values,
|
|
66322
|
+
crudType,
|
|
66323
|
+
tinaForm,
|
|
66324
|
+
onBaseBranchDeleted
|
|
66325
|
+
}) => {
|
|
66326
|
+
const cms = useCMS$1();
|
|
66327
|
+
const tinaApi = cms.api.tina;
|
|
66328
|
+
const [newBranchName, setNewBranchName] = React.useState(
|
|
66329
|
+
formatDefaultBranchName(path3, crudType)
|
|
66330
|
+
);
|
|
66331
|
+
const [isBranchGuardChecking, setIsBranchGuardChecking] = React.useState(false);
|
|
66332
|
+
const {
|
|
66333
|
+
isExecuting,
|
|
66334
|
+
errorMessage,
|
|
66335
|
+
currentStep,
|
|
66336
|
+
elapsedTime,
|
|
66337
|
+
executeWorkflow,
|
|
66338
|
+
reset: reset2
|
|
66339
|
+
} = useEditorialWorkflow();
|
|
66340
|
+
const executeEditorialWorkflow = async () => {
|
|
66341
|
+
setIsBranchGuardChecking(true);
|
|
66342
|
+
const baseBranch = decodeURIComponent(tinaApi.branch);
|
|
66343
|
+
let baseBranchExists = true;
|
|
66344
|
+
try {
|
|
66345
|
+
console.debug(
|
|
66346
|
+
"[tina:branch-guard] executeEditorialWorkflow: checking base branch:",
|
|
66347
|
+
baseBranch
|
|
66280
66348
|
);
|
|
66281
|
-
|
|
66282
|
-
|
|
66283
|
-
|
|
66284
|
-
|
|
66285
|
-
|
|
66286
|
-
|
|
66287
|
-
|
|
66288
|
-
|
|
66289
|
-
"
|
|
66290
|
-
|
|
66291
|
-
|
|
66292
|
-
|
|
66293
|
-
|
|
66294
|
-
|
|
66295
|
-
|
|
66296
|
-
|
|
66349
|
+
baseBranchExists = await tinaApi.branchExists(baseBranch);
|
|
66350
|
+
} catch (err) {
|
|
66351
|
+
console.error(
|
|
66352
|
+
"[tina:branch-guard] executeEditorialWorkflow: branchExists threw, failing open:",
|
|
66353
|
+
err
|
|
66354
|
+
);
|
|
66355
|
+
}
|
|
66356
|
+
console.debug(
|
|
66357
|
+
"[tina:branch-guard] executeEditorialWorkflow: base branch exists?",
|
|
66358
|
+
baseBranchExists
|
|
66359
|
+
);
|
|
66360
|
+
if (!baseBranchExists) {
|
|
66361
|
+
console.debug(
|
|
66362
|
+
"[tina:branch-guard] executeEditorialWorkflow: base branch deleted — handing off"
|
|
66363
|
+
);
|
|
66364
|
+
onBaseBranchDeleted == null ? void 0 : onBaseBranchDeleted();
|
|
66365
|
+
return;
|
|
66366
|
+
}
|
|
66367
|
+
setIsBranchGuardChecking(false);
|
|
66368
|
+
const success = await executeWorkflow({
|
|
66369
|
+
branchName: `tina/${newBranchName}`,
|
|
66370
|
+
baseBranch,
|
|
66371
|
+
path: path3,
|
|
66372
|
+
values,
|
|
66373
|
+
crudType,
|
|
66374
|
+
tinaForm
|
|
66375
|
+
});
|
|
66376
|
+
if (success) {
|
|
66377
|
+
close2();
|
|
66378
|
+
}
|
|
66297
66379
|
};
|
|
66298
66380
|
const renderStateContent = () => {
|
|
66299
66381
|
if (isExecuting) {
|
|
66300
|
-
return
|
|
66382
|
+
return /* @__PURE__ */ React.createElement(
|
|
66383
|
+
WorkflowProgressIndicator,
|
|
66384
|
+
{
|
|
66385
|
+
currentStep,
|
|
66386
|
+
isExecuting,
|
|
66387
|
+
elapsedTime
|
|
66388
|
+
}
|
|
66389
|
+
);
|
|
66301
66390
|
} else {
|
|
66302
66391
|
return /* @__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(
|
|
66303
66392
|
"a",
|
|
@@ -66315,7 +66404,7 @@ const CreateBranchModal = ({
|
|
|
66315
66404
|
placeholder: "e.g. {{PAGE-NAME}}-updates",
|
|
66316
66405
|
value: newBranchName,
|
|
66317
66406
|
onChange: (e3) => {
|
|
66318
|
-
|
|
66407
|
+
reset2();
|
|
66319
66408
|
setNewBranchName(e3.target.value);
|
|
66320
66409
|
}
|
|
66321
66410
|
}
|
|
@@ -66336,7 +66425,7 @@ const CreateBranchModal = ({
|
|
|
66336
66425
|
variant: "primary",
|
|
66337
66426
|
align: "start",
|
|
66338
66427
|
className: "w-full sm:w-auto",
|
|
66339
|
-
disabled: newBranchName === "" ||
|
|
66428
|
+
disabled: newBranchName === "" || isBranchGuardChecking,
|
|
66340
66429
|
onMainAction: executeEditorialWorkflow,
|
|
66341
66430
|
items: [
|
|
66342
66431
|
{
|
|
@@ -66374,6 +66463,89 @@ const PrefixedTextField = ({
|
|
|
66374
66463
|
}
|
|
66375
66464
|
)));
|
|
66376
66465
|
};
|
|
66466
|
+
const BranchDeletedModal = ({
|
|
66467
|
+
branchName,
|
|
66468
|
+
close: close2,
|
|
66469
|
+
path: path3,
|
|
66470
|
+
values,
|
|
66471
|
+
crudType,
|
|
66472
|
+
tinaForm
|
|
66473
|
+
}) => {
|
|
66474
|
+
const cms = useCMS$1();
|
|
66475
|
+
const tinaApi = cms.api.tina;
|
|
66476
|
+
const [newBranchName, setNewBranchName] = React.useState("");
|
|
66477
|
+
const baseBranch = tinaApi.protectedBranches[0] || cms.api.tina.schema.config.config.repoProvider.defaultBranchName || "main";
|
|
66478
|
+
const {
|
|
66479
|
+
isExecuting,
|
|
66480
|
+
errorMessage,
|
|
66481
|
+
currentStep,
|
|
66482
|
+
elapsedTime,
|
|
66483
|
+
executeWorkflow,
|
|
66484
|
+
reset: reset2
|
|
66485
|
+
} = useEditorialWorkflow();
|
|
66486
|
+
const handleCreate = async () => {
|
|
66487
|
+
const success = await executeWorkflow({
|
|
66488
|
+
branchName: `tina/${newBranchName}`,
|
|
66489
|
+
baseBranch,
|
|
66490
|
+
path: path3,
|
|
66491
|
+
values,
|
|
66492
|
+
crudType,
|
|
66493
|
+
tinaForm
|
|
66494
|
+
});
|
|
66495
|
+
if (success)
|
|
66496
|
+
close2();
|
|
66497
|
+
};
|
|
66498
|
+
return /* @__PURE__ */ React.createElement(Modal, { className: "flex" }, /* @__PURE__ */ React.createElement(PopupModal, { className: "w-auto" }, /* @__PURE__ */ React.createElement(ModalHeader, { close: isExecuting ? void 0 : close2 }, "Branch no longer exists"), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, isExecuting ? /* @__PURE__ */ React.createElement(
|
|
66499
|
+
WorkflowProgressIndicator,
|
|
66500
|
+
{
|
|
66501
|
+
currentStep,
|
|
66502
|
+
isExecuting,
|
|
66503
|
+
elapsedTime
|
|
66504
|
+
}
|
|
66505
|
+
) : /* @__PURE__ */ React.createElement("div", { className: "max-w-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-3 p-3 mb-4 bg-yellow-50 border border-yellow-200 rounded text-yellow-800 text-sm" }, /* @__PURE__ */ React.createElement(
|
|
66506
|
+
GitBranchIcon,
|
|
66507
|
+
{
|
|
66508
|
+
className: "w-4 h-4 mt-0.5 flex-shrink-0 text-yellow-600",
|
|
66509
|
+
style: { fill: "none" }
|
|
66510
|
+
}
|
|
66511
|
+
), /* @__PURE__ */ React.createElement("span", null, "The branch", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, branchName), " ", "no longer exists. It may have been merged or deleted. Your changes cannot be pushed to it.")), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4" }, "Create a new branch from", " ", /* @__PURE__ */ React.createElement("span", { className: "font-mono font-semibold" }, baseBranch), " to continue editing, or cancel and switch to an existing branch from the branch menu."), 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(
|
|
66512
|
+
PrefixedTextField,
|
|
66513
|
+
{
|
|
66514
|
+
name: "new-branch-name",
|
|
66515
|
+
label: "New Branch Name",
|
|
66516
|
+
placeholder: "e.g. my-updates",
|
|
66517
|
+
value: newBranchName,
|
|
66518
|
+
onChange: (e3) => {
|
|
66519
|
+
reset2();
|
|
66520
|
+
setNewBranchName(formatBranchName(e3.target.value));
|
|
66521
|
+
}
|
|
66522
|
+
}
|
|
66523
|
+
))), !isExecuting && /* @__PURE__ */ React.createElement(ModalActions, { align: "end" }, /* @__PURE__ */ React.createElement(
|
|
66524
|
+
Button$2,
|
|
66525
|
+
{
|
|
66526
|
+
variant: "secondary",
|
|
66527
|
+
className: "w-full sm:w-auto",
|
|
66528
|
+
onClick: close2
|
|
66529
|
+
},
|
|
66530
|
+
"Cancel"
|
|
66531
|
+
), /* @__PURE__ */ React.createElement(
|
|
66532
|
+
Button$2,
|
|
66533
|
+
{
|
|
66534
|
+
variant: "primary",
|
|
66535
|
+
className: "w-full sm:w-auto",
|
|
66536
|
+
disabled: !newBranchName,
|
|
66537
|
+
onClick: handleCreate
|
|
66538
|
+
},
|
|
66539
|
+
/* @__PURE__ */ React.createElement(
|
|
66540
|
+
GitBranchIcon,
|
|
66541
|
+
{
|
|
66542
|
+
className: "w-4 h-4 mr-1",
|
|
66543
|
+
style: { fill: "none" }
|
|
66544
|
+
}
|
|
66545
|
+
),
|
|
66546
|
+
"Create new branch"
|
|
66547
|
+
))));
|
|
66548
|
+
};
|
|
66377
66549
|
const NoFieldsPlaceholder = () => /* @__PURE__ */ React.createElement(
|
|
66378
66550
|
"div",
|
|
66379
66551
|
{
|
|
@@ -66430,6 +66602,8 @@ const FormBuilder = ({
|
|
|
66430
66602
|
const cms = useCMS$1();
|
|
66431
66603
|
const hideFooter = !!rest.hideFooter;
|
|
66432
66604
|
const [createBranchModalOpen, setCreateBranchModalOpen] = React.useState(false);
|
|
66605
|
+
const [deletedBranchModalOpen, setDeletedBranchModalOpen] = React.useState(false);
|
|
66606
|
+
const [isGuardChecking, setIsGuardChecking] = React.useState(false);
|
|
66433
66607
|
const tinaForm = form.tinaForm;
|
|
66434
66608
|
const finalForm = form.tinaForm.finalForm;
|
|
66435
66609
|
React.useEffect(() => {
|
|
@@ -66489,26 +66663,79 @@ const FormBuilder = ({
|
|
|
66489
66663
|
const canSubmit = !pristine && !submitting && !hasValidationErrors && !(invalid && !dirtySinceLastSubmit);
|
|
66490
66664
|
const safeSubmit = async () => {
|
|
66491
66665
|
if (canSubmit) {
|
|
66666
|
+
const alertsBefore = new Set(cms.alerts.all.map((a2) => a2.id));
|
|
66667
|
+
console.debug(
|
|
66668
|
+
"[tina:branch-guard] safeSubmit: calling handleSubmit"
|
|
66669
|
+
);
|
|
66492
66670
|
const result = await handleSubmit();
|
|
66493
66671
|
if (result && result[FORM_ERROR]) {
|
|
66494
66672
|
const error2 = result[FORM_ERROR];
|
|
66673
|
+
const errorMsg = error2 instanceof Error ? error2.message : String(error2);
|
|
66674
|
+
console.debug(
|
|
66675
|
+
"[tina:branch-guard] safeSubmit: FORM_ERROR detected:",
|
|
66676
|
+
errorMsg
|
|
66677
|
+
);
|
|
66678
|
+
if (/branch.*not found/i.test(errorMsg)) {
|
|
66679
|
+
console.debug(
|
|
66680
|
+
"[tina:branch-guard] safeSubmit: branch-not-found — dismissing alert and opening modal"
|
|
66681
|
+
);
|
|
66682
|
+
for (const alert of cms.alerts.all) {
|
|
66683
|
+
if (!alertsBefore.has(alert.id) && alert.level === "error") {
|
|
66684
|
+
cms.alerts.dismiss(alert);
|
|
66685
|
+
}
|
|
66686
|
+
}
|
|
66687
|
+
setDeletedBranchModalOpen(true);
|
|
66688
|
+
return;
|
|
66689
|
+
}
|
|
66495
66690
|
captureEvent(SaveContentErrorEvent, {
|
|
66496
66691
|
documentPath: tinaForm.path,
|
|
66497
|
-
error:
|
|
66692
|
+
error: errorMsg
|
|
66498
66693
|
});
|
|
66499
66694
|
} else {
|
|
66500
66695
|
captureEvent(SavedContentEvent, {
|
|
66501
66696
|
documentPath: tinaForm.path
|
|
66502
66697
|
});
|
|
66503
66698
|
}
|
|
66699
|
+
} else {
|
|
66700
|
+
console.debug(
|
|
66701
|
+
"[tina:branch-guard] safeSubmit: skipped — canSubmit is false"
|
|
66702
|
+
);
|
|
66504
66703
|
}
|
|
66505
66704
|
};
|
|
66506
66705
|
const safeHandleSubmit = async () => {
|
|
66706
|
+
setIsGuardChecking(true);
|
|
66707
|
+
const currentBranch = decodeURIComponent(cms.api.tina.getBranch());
|
|
66708
|
+
let exists = true;
|
|
66709
|
+
try {
|
|
66710
|
+
console.debug(
|
|
66711
|
+
"[tina:branch-guard] safeHandleSubmit: checking branch:",
|
|
66712
|
+
currentBranch
|
|
66713
|
+
);
|
|
66714
|
+
exists = await cms.api.tina.branchExists(currentBranch);
|
|
66715
|
+
} catch (err) {
|
|
66716
|
+
console.error(
|
|
66717
|
+
"[tina:branch-guard] safeHandleSubmit: branchExists threw, failing open:",
|
|
66718
|
+
err
|
|
66719
|
+
);
|
|
66720
|
+
}
|
|
66721
|
+
console.debug(
|
|
66722
|
+
"[tina:branch-guard] safeHandleSubmit: branchExists returned:",
|
|
66723
|
+
exists
|
|
66724
|
+
);
|
|
66725
|
+
if (!exists) {
|
|
66726
|
+
console.debug(
|
|
66727
|
+
"[tina:branch-guard] safeHandleSubmit: branch missing — opening modal"
|
|
66728
|
+
);
|
|
66729
|
+
setIsGuardChecking(false);
|
|
66730
|
+
setDeletedBranchModalOpen(true);
|
|
66731
|
+
return;
|
|
66732
|
+
}
|
|
66507
66733
|
if (usingProtectedBranch) {
|
|
66508
66734
|
setCreateBranchModalOpen(true);
|
|
66509
66735
|
} else {
|
|
66510
|
-
safeSubmit();
|
|
66736
|
+
await safeSubmit();
|
|
66511
66737
|
}
|
|
66738
|
+
setIsGuardChecking(false);
|
|
66512
66739
|
};
|
|
66513
66740
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, createBranchModalOpen && /* @__PURE__ */ React.createElement(
|
|
66514
66741
|
CreateBranchModal,
|
|
@@ -66518,7 +66745,21 @@ const FormBuilder = ({
|
|
|
66518
66745
|
path: tinaForm.path,
|
|
66519
66746
|
values: tinaForm.values,
|
|
66520
66747
|
tinaForm,
|
|
66521
|
-
close: () => setCreateBranchModalOpen(false)
|
|
66748
|
+
close: () => setCreateBranchModalOpen(false),
|
|
66749
|
+
onBaseBranchDeleted: () => {
|
|
66750
|
+
setCreateBranchModalOpen(false);
|
|
66751
|
+
setDeletedBranchModalOpen(true);
|
|
66752
|
+
}
|
|
66753
|
+
}
|
|
66754
|
+
), deletedBranchModalOpen && /* @__PURE__ */ React.createElement(
|
|
66755
|
+
BranchDeletedModal,
|
|
66756
|
+
{
|
|
66757
|
+
branchName: decodeURIComponent(cms.api.tina.getBranch()),
|
|
66758
|
+
close: () => setDeletedBranchModalOpen(false),
|
|
66759
|
+
path: tinaForm.path,
|
|
66760
|
+
values: tinaForm.values,
|
|
66761
|
+
crudType: tinaForm.crudType,
|
|
66762
|
+
tinaForm
|
|
66522
66763
|
}
|
|
66523
66764
|
), /* @__PURE__ */ React.createElement(DragDropContext, { onDragEnd: moveArrayItem }, /* @__PURE__ */ React.createElement(FormKeyBindings, { onSubmit: safeHandleSubmit }), /* @__PURE__ */ React.createElement(FormPortalProvider, null, /* @__PURE__ */ React.createElement(FormWrapper, { id: tinaForm.id }, (tinaForm == null ? void 0 : tinaForm.fields.length) ? /* @__PURE__ */ React.createElement(
|
|
66524
66765
|
FieldsBuilder,
|
|
@@ -66542,8 +66783,8 @@ const FormBuilder = ({
|
|
|
66542
66783
|
Button$2,
|
|
66543
66784
|
{
|
|
66544
66785
|
onClick: safeHandleSubmit,
|
|
66545
|
-
disabled: !canSubmit,
|
|
66546
|
-
busy: submitting,
|
|
66786
|
+
disabled: !canSubmit || isGuardChecking,
|
|
66787
|
+
busy: submitting || isGuardChecking,
|
|
66547
66788
|
variant: "primary"
|
|
66548
66789
|
},
|
|
66549
66790
|
submitting && /* @__PURE__ */ React.createElement(LoadingDots, null),
|
|
@@ -68183,7 +68424,9 @@ const useImageToolbarButton = (state) => {
|
|
|
68183
68424
|
allowDelete: true,
|
|
68184
68425
|
directory: "",
|
|
68185
68426
|
onSelect: (media) => {
|
|
68186
|
-
|
|
68427
|
+
var _a2, _b;
|
|
68428
|
+
const src = typeof ((_b = (_a2 = cms == null ? void 0 : cms.media) == null ? void 0 : _a2.store) == null ? void 0 : _b.parse) === "function" ? cms.media.store.parse(media) : media.src;
|
|
68429
|
+
insertImg(editor, { ...media, src: src || media.src });
|
|
68187
68430
|
}
|
|
68188
68431
|
});
|
|
68189
68432
|
};
|
|
@@ -121847,6 +122090,12 @@ mutation addPendingDocumentMutation(
|
|
|
121847
122090
|
var _a2;
|
|
121848
122091
|
return this.usingEditorialWorkflow && ((_a2 = this.protectedBranches) == null ? void 0 : _a2.includes(decodeURIComponent(this.branch)));
|
|
121849
122092
|
}
|
|
122093
|
+
async branchExists(branchName) {
|
|
122094
|
+
if (this.isLocalMode)
|
|
122095
|
+
return true;
|
|
122096
|
+
const branches = await this.listBranches({ includeIndexStatus: false });
|
|
122097
|
+
return branches.some((b) => b.name === branchName);
|
|
122098
|
+
}
|
|
121850
122099
|
async createBranch({ baseBranch, branchName }) {
|
|
121851
122100
|
const url = `${this.contentApiBase}/github/${this.clientId}/create_branch`;
|
|
121852
122101
|
try {
|
|
@@ -124754,7 +125003,7 @@ const RenderForm$1 = ({
|
|
|
124754
125003
|
}
|
|
124755
125004
|
return true;
|
|
124756
125005
|
}
|
|
124757
|
-
const isValid =
|
|
125006
|
+
const isValid = /^[\.\-_\/a-zA-Z0-9]*$/.test(value);
|
|
124758
125007
|
if (value && !isValid) {
|
|
124759
125008
|
return "Must contain only a-z, A-Z, 0-9, -, _, ., or /.";
|
|
124760
125009
|
}
|
|
@@ -125604,6 +125853,7 @@ export {
|
|
|
125604
125853
|
DateFieldPlugin,
|
|
125605
125854
|
DeleteImageButton,
|
|
125606
125855
|
Dismissible,
|
|
125856
|
+
DisplayOnlyFieldPlugin,
|
|
125607
125857
|
DragHandle,
|
|
125608
125858
|
DragIcon,
|
|
125609
125859
|
DropdownButton,
|
|
@@ -125651,6 +125901,7 @@ export {
|
|
|
125651
125901
|
ImageField,
|
|
125652
125902
|
ImageFieldPlugin,
|
|
125653
125903
|
ImageUpload,
|
|
125904
|
+
InfoBox,
|
|
125654
125905
|
InfoIcon,
|
|
125655
125906
|
Input$1 as Input,
|
|
125656
125907
|
ItalicIcon$1 as ItalicIcon,
|
|
@@ -147,6 +147,7 @@ export declare class Client {
|
|
|
147
147
|
githubPullRequestUrl?: string;
|
|
148
148
|
}[]>;
|
|
149
149
|
usingProtectedBranch(): boolean;
|
|
150
|
+
branchExists(branchName: string): Promise<boolean>;
|
|
150
151
|
createBranch({ baseBranch, branchName }: BranchData): Promise<string>;
|
|
151
152
|
getLatestVersion(): Promise<LatestVersionResponse>;
|
|
152
153
|
/**
|
|
@@ -71,6 +71,13 @@ export interface MediaStore {
|
|
|
71
71
|
* @default false
|
|
72
72
|
*/
|
|
73
73
|
isStatic?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Converts a Media object to the value stored in a form field.
|
|
76
|
+
*
|
|
77
|
+
* Typically returns `media.src`. If not implemented, the image field
|
|
78
|
+
* plugin falls back to `media.src`.
|
|
79
|
+
*/
|
|
80
|
+
parse?(media: Media): string;
|
|
74
81
|
}
|
|
75
82
|
export declare type MediaListOffset = string | number;
|
|
76
83
|
/**
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export declare const DisplayOnlyFieldPlugin: {
|
|
3
|
+
name: string;
|
|
4
|
+
Component: (props: any) => React.JSX.Element;
|
|
5
|
+
};
|
|
6
|
+
export declare const InfoBox: ({ message, links, }: {
|
|
7
|
+
message: string;
|
|
8
|
+
links?: {
|
|
9
|
+
text: string;
|
|
10
|
+
url: string;
|
|
11
|
+
}[];
|
|
12
|
+
}) => React.FC<any>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Form } from '../forms';
|
|
3
|
+
export declare const BranchDeletedModal: ({ branchName, close, path, values, crudType, tinaForm, }: {
|
|
4
|
+
branchName: string;
|
|
5
|
+
close: () => void;
|
|
6
|
+
path: string;
|
|
7
|
+
values: Record<string, unknown>;
|
|
8
|
+
crudType: string;
|
|
9
|
+
tinaForm?: Form;
|
|
10
|
+
}) => React.JSX.Element;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Form } from '../forms';
|
|
3
|
-
export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crudType, tinaForm, }: {
|
|
3
|
+
export declare const CreateBranchModal: ({ close, safeSubmit, path, values, crudType, tinaForm, onBaseBranchDeleted, }: {
|
|
4
4
|
safeSubmit: () => Promise<void>;
|
|
5
5
|
close: () => void;
|
|
6
6
|
path: string;
|
|
7
7
|
values: Record<string, unknown>;
|
|
8
8
|
crudType: string;
|
|
9
9
|
tinaForm?: Form;
|
|
10
|
+
onBaseBranchDeleted?: () => void;
|
|
10
11
|
}) => React.JSX.Element;
|
|
11
12
|
export declare const PrefixedTextField: ({ label, prefix, ...props }: {
|
|
12
13
|
[x: string]: any;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Form } from '../forms';
|
|
2
|
+
export declare const WORKFLOW_STEPS: {
|
|
3
|
+
id: number;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
}[];
|
|
7
|
+
export declare const formatTime: (seconds: number) => string;
|
|
8
|
+
export interface ExecuteWorkflowOptions {
|
|
9
|
+
branchName: string;
|
|
10
|
+
baseBranch: string;
|
|
11
|
+
path: string;
|
|
12
|
+
values: Record<string, unknown>;
|
|
13
|
+
crudType: string;
|
|
14
|
+
tinaForm?: Form;
|
|
15
|
+
}
|
|
16
|
+
export interface UseEditorialWorkflowResult {
|
|
17
|
+
isExecuting: boolean;
|
|
18
|
+
errorMessage: string;
|
|
19
|
+
currentStep: number;
|
|
20
|
+
elapsedTime: number;
|
|
21
|
+
/** Returns true on success, false on failure (error captured in errorMessage) */
|
|
22
|
+
executeWorkflow: (opts: ExecuteWorkflowOptions) => Promise<boolean>;
|
|
23
|
+
/** Reset error/executing state so the form can be retried */
|
|
24
|
+
reset: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare function useEditorialWorkflow(): UseEditorialWorkflowResult;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
interface WorkflowProgressIndicatorProps {
|
|
3
|
+
currentStep: number;
|
|
4
|
+
isExecuting: boolean;
|
|
5
|
+
elapsedTime: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const WorkflowProgressIndicator: ({ currentStep, isExecuting, elapsedTime, }: WorkflowProgressIndicatorProps) => React.JSX.Element;
|
|
8
|
+
export {};
|
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.7.
|
|
5
|
+
"version": "3.7.3",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"exports": {
|
|
@@ -114,9 +114,9 @@
|
|
|
114
114
|
"webfontloader": "1.6.28",
|
|
115
115
|
"yup": "^1.6.1",
|
|
116
116
|
"zod": "^3.24.2",
|
|
117
|
-
"@tinacms/
|
|
118
|
-
"@tinacms/
|
|
119
|
-
"@tinacms/
|
|
117
|
+
"@tinacms/schema-tools": "2.7.2",
|
|
118
|
+
"@tinacms/search": "1.2.10",
|
|
119
|
+
"@tinacms/mdx": "2.1.2"
|
|
120
120
|
},
|
|
121
121
|
"devDependencies": {
|
|
122
122
|
"@graphql-tools/utils": "^10.8.1",
|