tinacms 2.7.3 → 2.7.4

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.mjs CHANGED
@@ -43,6 +43,7 @@ import { twMerge } from "tailwind-merge";
43
43
  import { Command as Command$1 } from "cmdk";
44
44
  import { isHotkey } from "is-hotkey";
45
45
  import { Transforms, Element, Range, Path, Node, Editor as Editor$1 } from "slate";
46
+ import { useWindowWidth } from "@react-hook/window-size";
46
47
  import get from "lodash.get";
47
48
  import moment from "moment";
48
49
  import { formatDistanceToNow } from "date-fns";
@@ -52,7 +53,6 @@ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
52
53
  import { ELEMENT_PARAGRAPH as ELEMENT_PARAGRAPH$1 } from "@udecode/plate-paragraph";
53
54
  import { ELEMENT_BLOCKQUOTE as ELEMENT_BLOCKQUOTE$1 } from "@udecode/plate-block-quote";
54
55
  import { useFloatingToolbarState, offset, flip, useFloatingToolbar } from "@udecode/plate-floating";
55
- import { useWindowWidth } from "@react-hook/window-size";
56
56
  import { getIntrospectionQuery, buildClientSchema, print, parse as parse$3, buildSchema } from "graphql";
57
57
  import gql from "graphql-tag";
58
58
  import { TinaSchema, addNamespaceToSchema, parseURL, resolveForm, normalizePath, validateSchema } from "@tinacms/schema-tools";
@@ -9635,7 +9635,7 @@ let Alerts$1 = class Alerts {
9635
9635
  return this.add("error", message, timeout);
9636
9636
  }
9637
9637
  };
9638
- const NoFormsPlaceholder = () => /* @__PURE__ */ React.createElement(
9638
+ const SidebarLoadingPlaceholder = () => /* @__PURE__ */ React.createElement(
9639
9639
  "div",
9640
9640
  {
9641
9641
  className: "relative flex flex-col items-center justify-center text-center p-5 pb-16 w-full h-full overflow-y-auto",
@@ -9648,25 +9648,8 @@ const NoFormsPlaceholder = () => /* @__PURE__ */ React.createElement(
9648
9648
  animationDuration: "150ms"
9649
9649
  }
9650
9650
  },
9651
- /* @__PURE__ */ React.createElement(Emoji$1, { className: "pb-5" }, "🔎"),
9652
- /* @__PURE__ */ React.createElement("p", { className: "block pb-5" }, "Looks like there's ", /* @__PURE__ */ React.createElement("br", null), "nothing to edit on ", /* @__PURE__ */ React.createElement("br", null), "this page."),
9653
- /* @__PURE__ */ React.createElement("p", { className: "block" }, /* @__PURE__ */ React.createElement(
9654
- Button$1,
9655
- {
9656
- href: "https://tina.io/docs/tinacms-context/",
9657
- target: "_blank",
9658
- as: "a"
9659
- },
9660
- /* @__PURE__ */ React.createElement(Emoji$1, { className: "mr-1.5" }, "📖"),
9661
- " Contextual Editing"
9662
- ))
9663
- );
9664
- const Emoji$1 = ({ className = "", ...props }) => /* @__PURE__ */ React.createElement(
9665
- "span",
9666
- {
9667
- className: `text-[24px] leading-none inline-block ${className}`,
9668
- ...props
9669
- }
9651
+ /* @__PURE__ */ React.createElement("p", { className: "block pb-5" }, "Please wait while TinaCMS", /* @__PURE__ */ React.createElement("br", null), "loads your content"),
9652
+ /* @__PURE__ */ React.createElement(LoadingDots, { color: "var(--tina-color-primary)" })
9670
9653
  );
9671
9654
  class SidebarState {
9672
9655
  constructor(events, options = {}) {
@@ -9681,7 +9664,7 @@ class SidebarState {
9681
9664
  };
9682
9665
  this.position = options.position || "displace";
9683
9666
  this.renderNav = options.renderNav || true;
9684
- this.placeholder = options.placeholder || NoFormsPlaceholder;
9667
+ this.loadingPlaceholder = options.placeholder || SidebarLoadingPlaceholder;
9685
9668
  if ((_a = options.buttons) == null ? void 0 : _a.save) {
9686
9669
  this.buttons.save = options.buttons.save;
9687
9670
  }
@@ -9755,238 +9738,6 @@ const ModalLayout = ({ children, name, close: close2, layout }) => {
9755
9738
  children
9756
9739
  )));
9757
9740
  };
9758
- const Item = ({
9759
- item,
9760
- depth,
9761
- setActiveFormId
9762
- }) => {
9763
- const cms = useCMS();
9764
- const depths = ["pl-6", "pl-10", "pl-14"];
9765
- const form = React.useMemo(
9766
- () => cms.state.forms.find(({ tinaForm }) => item.formId === tinaForm.id),
9767
- [item.formId]
9768
- );
9769
- return /* @__PURE__ */ React.createElement(
9770
- "button",
9771
- {
9772
- type: "button",
9773
- key: item.path,
9774
- onClick: () => setActiveFormId(item.formId),
9775
- className: `${depths[depth] || "pl-12"} pr-6 py-3 w-full h-full bg-transparent border-none text-lg text-gray-700 group hover:bg-gray-50 transition-all ease-out duration-150 flex items-center justify-between gap-2`
9776
- },
9777
- /* @__PURE__ */ React.createElement(BiEdit, { className: "opacity-70 w-5 h-auto text-blue-500 flex-none" }),
9778
- /* @__PURE__ */ React.createElement("div", { className: "flex-1 flex flex-col gap-0.5 items-start" }, /* @__PURE__ */ React.createElement("div", { className: "group-hover:text-blue-500 font-sans text-xs font-semibold text-gray-700 whitespace-normal" }, form.tinaForm.label), /* @__PURE__ */ React.createElement("div", { className: "group-hover:text-blue-500 text-base truncate leading-tight text-gray-600" }, form.tinaForm.id))
9779
- );
9780
- };
9781
- const FormListItem = ({
9782
- item,
9783
- depth,
9784
- setActiveFormId
9785
- }) => {
9786
- var _a;
9787
- return /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-gray-200" }, /* @__PURE__ */ React.createElement(Item, { setActiveFormId, item, depth }), item.subItems && /* @__PURE__ */ React.createElement("ul", { className: "divide-y divide-gray-200" }, (_a = item.subItems) == null ? void 0 : _a.map((subItem) => {
9788
- if (subItem.type === "document") {
9789
- return /* @__PURE__ */ React.createElement("li", { key: subItem.formId }, /* @__PURE__ */ React.createElement(
9790
- Item,
9791
- {
9792
- setActiveFormId,
9793
- depth: depth + 1,
9794
- item: subItem
9795
- }
9796
- ));
9797
- }
9798
- })));
9799
- };
9800
- const FormLists = (props) => {
9801
- const cms = useCMS();
9802
- return /* @__PURE__ */ React.createElement(
9803
- Transition,
9804
- {
9805
- appear: true,
9806
- show: true,
9807
- as: "div",
9808
- enter: "transition-all ease-out duration-150",
9809
- enterFrom: "opacity-0 -translate-x-1/2",
9810
- enterTo: "opacity-100",
9811
- leave: "transition-all ease-out duration-150",
9812
- leaveFrom: "opacity-100",
9813
- leaveTo: "opacity-0 -translate-x-1/2"
9814
- },
9815
- cms.state.formLists.map((formList, index) => /* @__PURE__ */ React.createElement("div", { key: `${formList.id}-${index}`, className: "pt-16" }, /* @__PURE__ */ React.createElement(
9816
- FormList,
9817
- {
9818
- isEditing: props.isEditing,
9819
- setActiveFormId: (id) => {
9820
- cms.dispatch({ type: "forms:set-active-form-id", value: id });
9821
- },
9822
- formList
9823
- }
9824
- )))
9825
- );
9826
- };
9827
- const FormList = (props) => {
9828
- const cms = useCMS();
9829
- const listItems = React.useMemo(() => {
9830
- var _a;
9831
- const orderedListItems = [];
9832
- const globalItems = [];
9833
- const topItems = [];
9834
- props.formList.items.forEach((item) => {
9835
- if (item.type === "document") {
9836
- const form = cms.state.forms.find(
9837
- ({ tinaForm }) => tinaForm.id === item.formId
9838
- );
9839
- if (form.tinaForm.global) {
9840
- globalItems.push(item);
9841
- } else {
9842
- orderedListItems.push(item);
9843
- }
9844
- } else {
9845
- orderedListItems.push(item);
9846
- }
9847
- });
9848
- if (((_a = orderedListItems[0]) == null ? void 0 : _a.type) === "document") {
9849
- topItems.push({ type: "list", label: "Documents" });
9850
- }
9851
- let extra = [];
9852
- if (globalItems.length) {
9853
- extra = [{ type: "list", label: "Global Documents" }, ...globalItems];
9854
- }
9855
- return [...topItems, ...orderedListItems, ...extra];
9856
- }, [JSON.stringify(props.formList.items)]);
9857
- return /* @__PURE__ */ React.createElement("ul", null, /* @__PURE__ */ React.createElement("li", { className: "divide-y divide-gray-200" }, listItems.map((item, index) => {
9858
- if (item.type === "list") {
9859
- return /* @__PURE__ */ React.createElement(
9860
- "div",
9861
- {
9862
- key: item.label,
9863
- className: `relative group text-left w-full bg-white shadow-sm
9864
- border-gray-100 px-6 -mt-px pb-3 ${index > 0 ? "pt-6 bg-gradient-to-b from-gray-50 via-white to-white" : "pt-3"}`
9865
- },
9866
- /* @__PURE__ */ React.createElement(
9867
- "span",
9868
- {
9869
- className: "text-sm tracking-wide font-bold text-gray-700 uppercase"
9870
- },
9871
- item.label
9872
- )
9873
- );
9874
- }
9875
- return /* @__PURE__ */ React.createElement(
9876
- FormListItem,
9877
- {
9878
- setActiveFormId: (id) => props.setActiveFormId(id),
9879
- key: item.formId,
9880
- item,
9881
- depth: 0
9882
- }
9883
- );
9884
- })));
9885
- };
9886
- const FormsView = ({
9887
- children
9888
- }) => {
9889
- const cms = useCMS$1();
9890
- const { setFormIsPristine } = React.useContext(SidebarContext);
9891
- const isMultiform = cms.state.forms.length > 1;
9892
- const activeForm = cms.state.forms.find(
9893
- ({ tinaForm }) => tinaForm.id === cms.state.activeFormId
9894
- );
9895
- const isEditing = !!activeForm;
9896
- if (!cms.state.formLists.length) {
9897
- return /* @__PURE__ */ React.createElement(React.Fragment, null, " ", children, " ");
9898
- }
9899
- if (isMultiform && !activeForm) {
9900
- return /* @__PURE__ */ React.createElement(FormLists, { isEditing });
9901
- }
9902
- const formMetas = cms.plugins.all("form:meta");
9903
- return /* @__PURE__ */ React.createElement(React.Fragment, null, activeForm && /* @__PURE__ */ React.createElement(FormWrapper$1, { isEditing, isMultiform }, isMultiform && /* @__PURE__ */ React.createElement(MultiformFormHeader, { activeForm }), !isMultiform && /* @__PURE__ */ React.createElement(FormHeader, { activeForm }), formMetas == null ? void 0 : formMetas.map((meta) => /* @__PURE__ */ React.createElement(React.Fragment, { key: meta.name }, /* @__PURE__ */ React.createElement(meta.Component, null))), /* @__PURE__ */ React.createElement(FormBuilder, { form: activeForm, onPristineChange: setFormIsPristine })));
9904
- };
9905
- const FormWrapper$1 = ({ isEditing, children }) => {
9906
- return /* @__PURE__ */ React.createElement(
9907
- "div",
9908
- {
9909
- className: "flex-1 flex flex-col flex-nowrap overflow-hidden h-full w-full relative bg-white",
9910
- style: isEditing ? {
9911
- transform: "none",
9912
- animationName: "fly-in-left",
9913
- animationDuration: "150ms",
9914
- animationDelay: "0",
9915
- animationIterationCount: 1,
9916
- animationTimingFunction: "ease-out"
9917
- } : {
9918
- transform: "translate3d(100%, 0, 0)"
9919
- }
9920
- },
9921
- children
9922
- );
9923
- };
9924
- const MultiformFormHeader = ({
9925
- activeForm
9926
- }) => {
9927
- const cms = useCMS$1();
9928
- const { formIsPristine } = React.useContext(SidebarContext);
9929
- return /* @__PURE__ */ React.createElement(
9930
- "div",
9931
- {
9932
- className: "pt-18 pb-4 px-6 border-b border-gray-200 bg-gradient-to-t from-white to-gray-50"
9933
- },
9934
- /* @__PURE__ */ React.createElement("div", { className: "max-w-form mx-auto flex gap-2 justify-between items-center" }, /* @__PURE__ */ React.createElement(
9935
- "button",
9936
- {
9937
- type: "button",
9938
- className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
9939
- onClick: () => {
9940
- const state = activeForm.tinaForm.finalForm.getState();
9941
- if (state.invalid === true) {
9942
- cms.alerts.error("Cannot navigate away from an invalid form.");
9943
- } else {
9944
- cms.dispatch({ type: "forms:set-active-form-id", value: null });
9945
- }
9946
- }
9947
- },
9948
- /* @__PURE__ */ React.createElement(BiDotsVertical, { className: "h-auto w-5 inline-block opacity-70" })
9949
- ), /* @__PURE__ */ React.createElement(
9950
- "button",
9951
- {
9952
- type: "button",
9953
- className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
9954
- onClick: () => {
9955
- const collectionName = cms.api.tina.schema.getCollectionByFullPath(
9956
- cms.state.activeFormId
9957
- ).name;
9958
- window.location.href = `${new URL(window.location.href).pathname}#/collections/${collectionName}/~`;
9959
- }
9960
- },
9961
- /* @__PURE__ */ React.createElement(BiHomeAlt, { className: "h-auto w-5 inline-block opacity-70" })
9962
- ), /* @__PURE__ */ React.createElement("span", { className: "opacity-30 text-sm leading-tight whitespace-nowrap flex-0" }, "/"), /* @__PURE__ */ React.createElement("span", { className: "block w-full text-sm leading-tight whitespace-nowrap truncate" }, activeForm.tinaForm.label || activeForm.tinaForm.id), /* @__PURE__ */ React.createElement(FormStatus, { pristine: formIsPristine }))
9963
- );
9964
- };
9965
- const FormHeader = ({ activeForm }) => {
9966
- const { formIsPristine } = React.useContext(SidebarContext);
9967
- const cms = useCMS$1();
9968
- const shortFormLabel = activeForm.tinaForm.label ? activeForm.tinaForm.label.replace(/^.*[\\\/]/, "") : false;
9969
- return /* @__PURE__ */ React.createElement(
9970
- "div",
9971
- {
9972
- className: "pt-18 pb-4 px-6 border-b border-gray-200 bg-gradient-to-t from-white to-gray-50"
9973
- },
9974
- /* @__PURE__ */ React.createElement("div", { className: "max-w-form mx-auto flex gap-2 justify-between items-center" }, /* @__PURE__ */ React.createElement(
9975
- "button",
9976
- {
9977
- type: "button",
9978
- className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
9979
- onClick: () => {
9980
- const collectionName = cms.api.tina.schema.getCollectionByFullPath(
9981
- cms.state.activeFormId
9982
- ).name;
9983
- window.location.href = `${new URL(window.location.href).pathname}#/collections/${collectionName}/~`;
9984
- }
9985
- },
9986
- /* @__PURE__ */ React.createElement(BiHomeAlt, { className: "h-auto w-5 inline-block opacity-70" })
9987
- ), shortFormLabel && /* @__PURE__ */ React.createElement("span", { className: "block w-full text-sm leading-tight whitespace-nowrap truncate" }, shortFormLabel), /* @__PURE__ */ React.createElement(FormStatus, { pristine: formIsPristine }))
9988
- );
9989
- };
9990
9741
  function ImFilesEmpty(props) {
9991
9742
  return GenIcon({ "tag": "svg", "attr": { "version": "1.1", "viewBox": "0 0 16 16" }, "child": [{ "tag": "path", "attr": { "d": "M14.341 5.579c-0.347-0.473-0.831-1.027-1.362-1.558s-1.085-1.015-1.558-1.362c-0.806-0.591-1.197-0.659-1.421-0.659h-5.75c-0.689 0-1.25 0.561-1.25 1.25v11.5c0 0.689 0.561 1.25 1.25 1.25h9.5c0.689 0 1.25-0.561 1.25-1.25v-7.75c0-0.224-0.068-0.615-0.659-1.421zM12.271 4.729c0.48 0.48 0.856 0.912 1.134 1.271h-2.406v-2.405c0.359 0.278 0.792 0.654 1.271 1.134v0zM14 14.75c0 0.136-0.114 0.25-0.25 0.25h-9.5c-0.136 0-0.25-0.114-0.25-0.25v-11.5c0-0.135 0.114-0.25 0.25-0.25 0 0 5.749-0 5.75 0v3.5c0 0.276 0.224 0.5 0.5 0.5h3.5v7.75z" }, "child": [] }, { "tag": "path", "attr": { "d": "M9.421 0.659c-0.806-0.591-1.197-0.659-1.421-0.659h-5.75c-0.689 0-1.25 0.561-1.25 1.25v11.5c0 0.604 0.43 1.109 1 1.225v-12.725c0-0.135 0.115-0.25 0.25-0.25h7.607c-0.151-0.124-0.297-0.238-0.437-0.341z" }, "child": [] }] })(props);
9992
9743
  }
@@ -10229,7 +9980,7 @@ const SyncStatus = ({ cms, setEventsOpen }) => {
10229
9980
  "Event Log"
10230
9981
  ));
10231
9982
  };
10232
- const version = "2.7.3";
9983
+ const version = "2.7.4";
10233
9984
  const Nav = ({
10234
9985
  isLocalMode,
10235
9986
  className = "",
@@ -10274,201 +10025,488 @@ const Nav = ({
10274
10025
  acc[category].push(screen);
10275
10026
  return acc;
10276
10027
  },
10277
- { Site: [] }
10028
+ { Site: [] }
10029
+ );
10030
+ return /* @__PURE__ */ React.createElement(
10031
+ "div",
10032
+ {
10033
+ className: `relative z-30 flex flex-col bg-white border-r border-gray-200 w-96 h-full ${className}`,
10034
+ style: { maxWidth: `${sidebarWidth}px` },
10035
+ ...props
10036
+ },
10037
+ /* @__PURE__ */ React.createElement("div", { className: "border-b border-gray-200" }, /* @__PURE__ */ React.createElement(Menu, { as: "div", className: "relative block" }, ({ open: open2 }) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
10038
+ MenuButton,
10039
+ {
10040
+ className: `group w-full px-6 py-3 gap-2 flex justify-between items-center transition-colors duration-150 ease-out ${open2 ? "bg-gray-50" : "bg-transparent"}`
10041
+ },
10042
+ /* @__PURE__ */ React.createElement("span", { className: "text-left inline-flex items-center text-xl tracking-wide text-gray-800 flex-1 gap-1 opacity-80 group-hover:opacity-100 transition-opacity duration-150 ease-out" }, /* @__PURE__ */ React.createElement(
10043
+ "svg",
10044
+ {
10045
+ viewBox: "0 0 32 32",
10046
+ fill: "#EC4815",
10047
+ xmlns: "http://www.w3.org/2000/svg",
10048
+ className: "w-10 h-auto -ml-1"
10049
+ },
10050
+ /* @__PURE__ */ React.createElement("path", { d: "M18.6466 14.5553C19.9018 13.5141 20.458 7.36086 21.0014 5.14903C21.5447 2.9372 23.7919 3.04938 23.7919 3.04938C23.7919 3.04938 23.2085 4.06764 23.4464 4.82751C23.6844 5.58738 25.3145 6.26662 25.3145 6.26662L24.9629 7.19622C24.9629 7.19622 24.2288 7.10204 23.7919 7.9785C23.355 8.85496 24.3392 17.4442 24.3392 17.4442C24.3392 17.4442 21.4469 22.7275 21.4469 24.9206C21.4469 27.1136 22.4819 28.9515 22.4819 28.9515H21.0296C21.0296 28.9515 18.899 26.4086 18.462 25.1378C18.0251 23.8669 18.1998 22.596 18.1998 22.596C18.1998 22.596 15.8839 22.4646 13.8303 22.596C11.7767 22.7275 10.4072 24.498 10.16 25.4884C9.91287 26.4787 9.81048 28.9515 9.81048 28.9515H8.66211C7.96315 26.7882 7.40803 26.0129 7.70918 24.9206C8.54334 21.8949 8.37949 20.1788 8.18635 19.4145C7.99321 18.6501 6.68552 17.983 6.68552 17.983C7.32609 16.6741 7.97996 16.0452 10.7926 15.9796C13.6052 15.914 17.3915 15.5965 18.6466 14.5553Z" }),
10051
+ /* @__PURE__ */ React.createElement("path", { d: "M11.1268 24.7939C11.1268 24.7939 11.4236 27.5481 13.0001 28.9516H14.3511C13.0001 27.4166 12.8527 23.4155 12.8527 23.4155C12.1656 23.6399 11.3045 24.3846 11.1268 24.7939Z" })
10052
+ ), /* @__PURE__ */ React.createElement("span", null, "Tina")),
10053
+ /* @__PURE__ */ React.createElement(SyncErrorWidget, { cms }),
10054
+ /* @__PURE__ */ React.createElement(
10055
+ FiMoreVertical,
10056
+ {
10057
+ className: `flex-0 w-6 h-full inline-block group-hover:opacity-80 transition-all duration-300 ease-in-out transform ${open2 ? "opacity-100 text-blue-400" : "text-gray-400 opacity-50 hover:opacity-70"}`
10058
+ }
10059
+ )
10060
+ ), /* @__PURE__ */ React.createElement("div", { className: "transform translate-y-full absolute bottom-3 right-5 z-50" }, /* @__PURE__ */ React.createElement(
10061
+ Transition,
10062
+ {
10063
+ enter: "transition duration-150 ease-out",
10064
+ enterFrom: "transform opacity-0 -translate-y-2",
10065
+ enterTo: "transform opacity-100 translate-y-0",
10066
+ leave: "transition duration-75 ease-in",
10067
+ leaveFrom: "transform opacity-100 translate-y-0",
10068
+ leaveTo: "transform opacity-0 -translate-y-2"
10069
+ },
10070
+ /* @__PURE__ */ React.createElement(MenuItems, { className: "bg-white border border-gray-150 rounded-lg shadow-lg flex flex-col items-stretch overflow-hidden" }, /* @__PURE__ */ React.createElement(MenuItem, null, /* @__PURE__ */ React.createElement(
10071
+ "button",
10072
+ {
10073
+ className: `text-lg px-4 py-2 first:pt-3 last:pb-3 tracking-wide whitespace-nowrap flex items-center opacity-80 text-gray-600 hover:text-blue-400 hover:bg-gray-50 hover:opacity-100`,
10074
+ onClick: async () => {
10075
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10076
+ updateBodyDisplacement({
10077
+ displayState: "closed",
10078
+ sidebarWidth: null,
10079
+ resizingSidebar: false
10080
+ });
10081
+ try {
10082
+ if ((_c = (_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.authProvider) == null ? void 0 : _c.logout) {
10083
+ await ((_d = cms.api.tina) == null ? void 0 : _d.authProvider.logout());
10084
+ if ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout) {
10085
+ await ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout());
10086
+ await new Promise(
10087
+ (resolve) => setTimeout(resolve, 500)
10088
+ );
10089
+ }
10090
+ window.location.href = new URL(
10091
+ window.location.href
10092
+ ).pathname;
10093
+ }
10094
+ } catch (e) {
10095
+ cms.alerts.error(`Error logging out: ${e}`);
10096
+ console.error("Unexpected error calling logout");
10097
+ console.error(e);
10098
+ }
10099
+ }
10100
+ },
10101
+ /* @__PURE__ */ React.createElement(BiExit, { className: "w-6 h-auto mr-2 text-blue-400" }),
10102
+ " Log Out"
10103
+ )), /* @__PURE__ */ React.createElement(MenuItem, null, /* @__PURE__ */ React.createElement(
10104
+ WrappedSyncStatus,
10105
+ {
10106
+ cms,
10107
+ setEventsOpen
10108
+ }
10109
+ )))
10110
+ ))))),
10111
+ eventsOpen && /* @__PURE__ */ React.createElement(SyncStatusModal, { cms, closeEventsModal }),
10112
+ children,
10113
+ /* @__PURE__ */ React.createElement("div", { className: "flex flex-col px-6 flex-1 overflow-auto" }, showCollections && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "flex space-x-1 justify-items-start uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, /* @__PURE__ */ React.createElement("span", null, "Collections"), isLocalMode && /* @__PURE__ */ React.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React.createElement(
10114
+ "a",
10115
+ {
10116
+ href: "https://tina.io/docs/schema/#defining-collections",
10117
+ target: "_blank"
10118
+ },
10119
+ /* @__PURE__ */ React.createElement(FiInfo, null)
10120
+ ))), /* @__PURE__ */ React.createElement(
10121
+ CollectionsList,
10122
+ {
10123
+ RenderNavCollection,
10124
+ collections: contentCollections
10125
+ }
10126
+ )), (screenCategories.Site.length > 0 || contentCreators.length) > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Site"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screenCategories.Site.map((view) => {
10127
+ return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
10128
+ }), contentCreators.map((plugin, idx) => {
10129
+ return /* @__PURE__ */ React.createElement(CreateContentNavItem, { key: `plugin-${idx}`, plugin });
10130
+ }), authCollection && /* @__PURE__ */ React.createElement(
10131
+ CollectionsList,
10132
+ {
10133
+ RenderNavCollection: AuthRenderNavCollection,
10134
+ collections: [authCollection]
10135
+ }
10136
+ ))), Object.entries(screenCategories).map(([category, screens2]) => {
10137
+ if (category !== "Site") {
10138
+ return /* @__PURE__ */ React.createElement("div", { key: category }, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, category), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screens2.map((view) => {
10139
+ return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
10140
+ })));
10141
+ }
10142
+ }), !!(cloudConfigs == null ? void 0 : cloudConfigs.length) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Cloud"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, cloudConfigs.map((config) => {
10143
+ return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${config.name}` }, /* @__PURE__ */ React.createElement(RenderNavCloud, { config }));
10144
+ }))), /* @__PURE__ */ React.createElement("div", { className: "grow" }), /* @__PURE__ */ React.createElement("span", { className: "font-sans font-light text-xs mb-3 mt-8 text-gray-500" }, "v", version))
10145
+ );
10146
+ };
10147
+ const CollectionsList = ({
10148
+ collections,
10149
+ RenderNavCollection
10150
+ }) => {
10151
+ if (collections.length === 0) {
10152
+ return /* @__PURE__ */ React.createElement("div", null, "No collections found");
10153
+ }
10154
+ return /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, collections.map((collection) => {
10155
+ return /* @__PURE__ */ React.createElement("li", { key: `nav-collection-${collection.name}` }, /* @__PURE__ */ React.createElement(RenderNavCollection, { collection }));
10156
+ }));
10157
+ };
10158
+ const CreateContentNavItem = ({ plugin }) => {
10159
+ const [open2, setOpen] = React.useState(false);
10160
+ return /* @__PURE__ */ React.createElement("li", { key: plugin.name }, /* @__PURE__ */ React.createElement(
10161
+ "button",
10162
+ {
10163
+ className: "text-base tracking-wide text-gray-500 hover:text-blue-600 flex items-center opacity-90 hover:opacity-100",
10164
+ onClick: () => {
10165
+ setOpen(true);
10166
+ }
10167
+ },
10168
+ /* @__PURE__ */ React.createElement(VscNewFile, { className: "mr-3 h-6 opacity-80 w-auto" }),
10169
+ " ",
10170
+ plugin.name
10171
+ ), open2 && /* @__PURE__ */ React.createElement(FormModal, { plugin, close: () => setOpen(false) }));
10172
+ };
10173
+ const ResizeHandle = () => {
10174
+ const {
10175
+ resizingSidebar,
10176
+ setResizingSidebar,
10177
+ fullscreen,
10178
+ setSidebarWidth,
10179
+ displayState
10180
+ } = React.useContext(SidebarContext);
10181
+ React.useEffect(() => {
10182
+ const handleMouseUp = () => setResizingSidebar(false);
10183
+ window.addEventListener("mouseup", handleMouseUp);
10184
+ return () => {
10185
+ window.removeEventListener("mouseup", handleMouseUp);
10186
+ };
10187
+ }, []);
10188
+ React.useEffect(() => {
10189
+ const handleMouseMove = (e) => {
10190
+ setSidebarWidth((sidebarWidth) => {
10191
+ const newWidth = sidebarWidth + e.movementX;
10192
+ const maxWidth = window.innerWidth - 8;
10193
+ if (newWidth < minSidebarWidth) {
10194
+ return minSidebarWidth;
10195
+ } else if (newWidth > maxWidth) {
10196
+ return maxWidth;
10197
+ } else {
10198
+ return newWidth;
10199
+ }
10200
+ });
10201
+ };
10202
+ if (resizingSidebar) {
10203
+ window.addEventListener("mousemove", handleMouseMove);
10204
+ document.body.classList.add("select-none");
10205
+ }
10206
+ return () => {
10207
+ window.removeEventListener("mousemove", handleMouseMove);
10208
+ document.body.classList.remove("select-none");
10209
+ };
10210
+ }, [resizingSidebar]);
10211
+ const handleresizingSidebar = () => setResizingSidebar(true);
10212
+ if (fullscreen) {
10213
+ return null;
10214
+ }
10215
+ return /* @__PURE__ */ React.createElement(
10216
+ "div",
10217
+ {
10218
+ onMouseDown: handleresizingSidebar,
10219
+ className: `z-100 absolute top-1/2 right-px w-2 h-32 bg-white rounded-r-md border border-gray-150 shadow-sm hover:shadow-md origin-left transition-all duration-150 ease-out transform translate-x-full -translate-y-1/2 group hover:bg-gray-50 ${displayState !== "closed" ? `opacity-100` : `opacity-0`} ${resizingSidebar ? `scale-110` : `scale-90 hover:scale-100`}`,
10220
+ style: { cursor: "grab" }
10221
+ },
10222
+ /* @__PURE__ */ React.createElement("span", { className: "absolute top-1/2 left-1/2 h-4/6 w-px bg-gray-200 transform -translate-y-1/2 -translate-x-1/2 opacity-30 transition-opacity duration-150 ease-out group-hover:opacity-100" })
10223
+ );
10224
+ };
10225
+ const Item = ({
10226
+ item,
10227
+ depth,
10228
+ setActiveFormId
10229
+ }) => {
10230
+ const cms = useCMS();
10231
+ const depths = ["pl-6", "pl-10", "pl-14"];
10232
+ const form = React.useMemo(
10233
+ () => cms.state.forms.find(({ tinaForm }) => item.formId === tinaForm.id),
10234
+ [item.formId]
10235
+ );
10236
+ return /* @__PURE__ */ React.createElement(
10237
+ "button",
10238
+ {
10239
+ type: "button",
10240
+ key: item.path,
10241
+ onClick: () => setActiveFormId(item.formId),
10242
+ className: `${depths[depth] || "pl-12"} pr-6 py-3 w-full h-full bg-transparent border-none text-lg text-gray-700 group hover:bg-gray-50 transition-all ease-out duration-150 flex items-center justify-between gap-2`
10243
+ },
10244
+ /* @__PURE__ */ React.createElement(BiEdit, { className: "opacity-70 w-5 h-auto text-blue-500 flex-none" }),
10245
+ /* @__PURE__ */ React.createElement("div", { className: "flex-1 flex flex-col gap-0.5 items-start" }, /* @__PURE__ */ React.createElement("div", { className: "group-hover:text-blue-500 font-sans text-xs font-semibold text-gray-700 whitespace-normal" }, form.tinaForm.label), /* @__PURE__ */ React.createElement("div", { className: "group-hover:text-blue-500 text-base truncate leading-tight text-gray-600" }, form.tinaForm.id))
10246
+ );
10247
+ };
10248
+ const FormListItem = ({
10249
+ item,
10250
+ depth,
10251
+ setActiveFormId
10252
+ }) => {
10253
+ var _a;
10254
+ return /* @__PURE__ */ React.createElement("div", { className: "divide-y divide-gray-200" }, /* @__PURE__ */ React.createElement(Item, { setActiveFormId, item, depth }), item.subItems && /* @__PURE__ */ React.createElement("ul", { className: "divide-y divide-gray-200" }, (_a = item.subItems) == null ? void 0 : _a.map((subItem) => {
10255
+ if (subItem.type === "document") {
10256
+ return /* @__PURE__ */ React.createElement("li", { key: subItem.formId }, /* @__PURE__ */ React.createElement(
10257
+ Item,
10258
+ {
10259
+ setActiveFormId,
10260
+ depth: depth + 1,
10261
+ item: subItem
10262
+ }
10263
+ ));
10264
+ }
10265
+ })));
10266
+ };
10267
+ const FormLists = (props) => {
10268
+ const cms = useCMS();
10269
+ return /* @__PURE__ */ React.createElement(
10270
+ Transition,
10271
+ {
10272
+ appear: true,
10273
+ show: true,
10274
+ as: "div",
10275
+ enter: "transition-all ease-out duration-150",
10276
+ enterFrom: "opacity-0 -translate-x-1/2",
10277
+ enterTo: "opacity-100",
10278
+ leave: "transition-all ease-out duration-150",
10279
+ leaveFrom: "opacity-100",
10280
+ leaveTo: "opacity-0 -translate-x-1/2"
10281
+ },
10282
+ cms.state.formLists.map((formList, index) => /* @__PURE__ */ React.createElement("div", { key: `${formList.id}-${index}`, className: "pt-16" }, /* @__PURE__ */ React.createElement(
10283
+ FormList,
10284
+ {
10285
+ isEditing: props.isEditing,
10286
+ setActiveFormId: (id) => {
10287
+ cms.dispatch({ type: "forms:set-active-form-id", value: id });
10288
+ },
10289
+ formList
10290
+ }
10291
+ )))
10292
+ );
10293
+ };
10294
+ const FormList = (props) => {
10295
+ const cms = useCMS();
10296
+ const listItems = React.useMemo(() => {
10297
+ var _a;
10298
+ const orderedListItems = [];
10299
+ const globalItems = [];
10300
+ const topItems = [];
10301
+ props.formList.items.forEach((item) => {
10302
+ if (item.type === "document") {
10303
+ const form = cms.state.forms.find(
10304
+ ({ tinaForm }) => tinaForm.id === item.formId
10305
+ );
10306
+ if (form.tinaForm.global) {
10307
+ globalItems.push(item);
10308
+ } else {
10309
+ orderedListItems.push(item);
10310
+ }
10311
+ } else {
10312
+ orderedListItems.push(item);
10313
+ }
10314
+ });
10315
+ if (((_a = orderedListItems[0]) == null ? void 0 : _a.type) === "document") {
10316
+ topItems.push({ type: "list", label: "Documents" });
10317
+ }
10318
+ let extra = [];
10319
+ if (globalItems.length) {
10320
+ extra = [{ type: "list", label: "Global Documents" }, ...globalItems];
10321
+ }
10322
+ return [...topItems, ...orderedListItems, ...extra];
10323
+ }, [JSON.stringify(props.formList.items)]);
10324
+ return /* @__PURE__ */ React.createElement("ul", null, /* @__PURE__ */ React.createElement("li", { className: "divide-y divide-gray-200" }, listItems.map((item, index) => {
10325
+ if (item.type === "list") {
10326
+ return /* @__PURE__ */ React.createElement(
10327
+ "div",
10328
+ {
10329
+ key: item.label,
10330
+ className: `relative group text-left w-full bg-white shadow-sm
10331
+ border-gray-100 px-6 -mt-px pb-3 ${index > 0 ? "pt-6 bg-gradient-to-b from-gray-50 via-white to-white" : "pt-3"}`
10332
+ },
10333
+ /* @__PURE__ */ React.createElement(
10334
+ "span",
10335
+ {
10336
+ className: "text-sm tracking-wide font-bold text-gray-700 uppercase"
10337
+ },
10338
+ item.label
10339
+ )
10340
+ );
10341
+ }
10342
+ return /* @__PURE__ */ React.createElement(
10343
+ FormListItem,
10344
+ {
10345
+ setActiveFormId: (id) => props.setActiveFormId(id),
10346
+ key: item.formId,
10347
+ item,
10348
+ depth: 0
10349
+ }
10350
+ );
10351
+ })));
10352
+ };
10353
+ const SidebarNoFormsPlaceholder = () => /* @__PURE__ */ React.createElement(
10354
+ "div",
10355
+ {
10356
+ className: "relative flex flex-col items-center justify-center text-center p-5 pb-16 w-full h-full overflow-y-auto",
10357
+ style: {
10358
+ animationName: "fade-in",
10359
+ animationDelay: "300ms",
10360
+ animationTimingFunction: "ease-out",
10361
+ animationIterationCount: 1,
10362
+ animationFillMode: "both",
10363
+ animationDuration: "150ms"
10364
+ }
10365
+ },
10366
+ /* @__PURE__ */ React.createElement("p", { className: "block pb-5" }, "Looks like there's ", /* @__PURE__ */ React.createElement("br", null), "nothing to edit on ", /* @__PURE__ */ React.createElement("br", null), "this page."),
10367
+ /* @__PURE__ */ React.createElement("p", { className: "block pt-5" }, /* @__PURE__ */ React.createElement(
10368
+ Button$1,
10369
+ {
10370
+ href: "https://tina.io/docs/contextual-editing/overview",
10371
+ target: "_blank",
10372
+ as: "a"
10373
+ },
10374
+ /* @__PURE__ */ React.createElement(Emoji$1, { className: "mr-1.5" }, "📖"),
10375
+ " Contextual Editing Docs"
10376
+ ))
10377
+ );
10378
+ const Emoji$1 = ({ className = "", ...props }) => /* @__PURE__ */ React.createElement(
10379
+ "span",
10380
+ {
10381
+ className: `text-[24px] leading-none inline-block ${className}`,
10382
+ ...props
10383
+ }
10384
+ );
10385
+ const minimumTimeToShowLoadingIndicator = 1e3;
10386
+ const FormsView = ({ loadingPlaceholder } = {}) => {
10387
+ const cms = useCMS$1();
10388
+ const { setFormIsPristine } = React.useContext(SidebarContext);
10389
+ const [isShowingLoading, setIsShowingLoading] = React.useState(true);
10390
+ const [initialLoadComplete, setInitialLoadComplete] = React.useState(false);
10391
+ React.useEffect(() => {
10392
+ if (cms.state.isLoadingContent) {
10393
+ setIsShowingLoading(true);
10394
+ const timer = setTimeout(() => {
10395
+ if (!cms.state.isLoadingContent) {
10396
+ setIsShowingLoading(false);
10397
+ setInitialLoadComplete(true);
10398
+ }
10399
+ }, minimumTimeToShowLoadingIndicator);
10400
+ return () => clearTimeout(timer);
10401
+ } else {
10402
+ const timer = setTimeout(() => {
10403
+ setIsShowingLoading(false);
10404
+ setInitialLoadComplete(true);
10405
+ }, minimumTimeToShowLoadingIndicator);
10406
+ return () => clearTimeout(timer);
10407
+ }
10408
+ }, [cms.state.isLoadingContent]);
10409
+ if (isShowingLoading || !initialLoadComplete) {
10410
+ const LoadingPlaceholder = loadingPlaceholder || SidebarLoadingPlaceholder;
10411
+ return /* @__PURE__ */ React.createElement(LoadingPlaceholder, null);
10412
+ }
10413
+ if (!cms.state.formLists.length) {
10414
+ return /* @__PURE__ */ React.createElement(SidebarNoFormsPlaceholder, null);
10415
+ }
10416
+ const isMultiform = cms.state.forms.length > 1;
10417
+ const activeForm = cms.state.forms.find(
10418
+ ({ tinaForm }) => tinaForm.id === cms.state.activeFormId
10419
+ );
10420
+ const isEditing = !!activeForm;
10421
+ if (isMultiform && !activeForm) {
10422
+ return /* @__PURE__ */ React.createElement(FormLists, { isEditing });
10423
+ }
10424
+ const formMetas = cms.plugins.all("form:meta");
10425
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, activeForm && /* @__PURE__ */ React.createElement(FormWrapper$1, { isEditing, isMultiform }, isMultiform && /* @__PURE__ */ React.createElement(MultiformFormHeader, { activeForm }), !isMultiform && /* @__PURE__ */ React.createElement(FormHeader, { activeForm }), formMetas == null ? void 0 : formMetas.map((meta) => /* @__PURE__ */ React.createElement(React.Fragment, { key: meta.name }, /* @__PURE__ */ React.createElement(meta.Component, null))), /* @__PURE__ */ React.createElement(FormBuilder, { form: activeForm, onPristineChange: setFormIsPristine })));
10426
+ };
10427
+ const FormWrapper$1 = ({ isEditing, children }) => {
10428
+ return /* @__PURE__ */ React.createElement(
10429
+ "div",
10430
+ {
10431
+ className: "flex-1 flex flex-col flex-nowrap overflow-hidden h-full w-full relative bg-white",
10432
+ style: isEditing ? {
10433
+ transform: "none",
10434
+ animationName: "fly-in-left",
10435
+ animationDuration: "150ms",
10436
+ animationDelay: "0",
10437
+ animationIterationCount: 1,
10438
+ animationTimingFunction: "ease-out"
10439
+ } : {
10440
+ transform: "translate3d(100%, 0, 0)"
10441
+ }
10442
+ },
10443
+ children
10278
10444
  );
10445
+ };
10446
+ const MultiformFormHeader = ({
10447
+ activeForm
10448
+ }) => {
10449
+ const cms = useCMS$1();
10450
+ const { formIsPristine } = React.useContext(SidebarContext);
10279
10451
  return /* @__PURE__ */ React.createElement(
10280
10452
  "div",
10281
10453
  {
10282
- className: `relative z-30 flex flex-col bg-white border-r border-gray-200 w-96 h-full ${className}`,
10283
- style: { maxWidth: `${sidebarWidth}px` },
10284
- ...props
10454
+ className: "pt-18 pb-4 px-6 border-b border-gray-200 bg-gradient-to-t from-white to-gray-50"
10285
10455
  },
10286
- /* @__PURE__ */ React.createElement("div", { className: "border-b border-gray-200" }, /* @__PURE__ */ React.createElement(Menu, { as: "div", className: "relative block" }, ({ open: open2 }) => /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
10287
- MenuButton,
10288
- {
10289
- className: `group w-full px-6 py-3 gap-2 flex justify-between items-center transition-colors duration-150 ease-out ${open2 ? "bg-gray-50" : "bg-transparent"}`
10290
- },
10291
- /* @__PURE__ */ React.createElement("span", { className: "text-left inline-flex items-center text-xl tracking-wide text-gray-800 flex-1 gap-1 opacity-80 group-hover:opacity-100 transition-opacity duration-150 ease-out" }, /* @__PURE__ */ React.createElement(
10292
- "svg",
10293
- {
10294
- viewBox: "0 0 32 32",
10295
- fill: "#EC4815",
10296
- xmlns: "http://www.w3.org/2000/svg",
10297
- className: "w-10 h-auto -ml-1"
10298
- },
10299
- /* @__PURE__ */ React.createElement("path", { d: "M18.6466 14.5553C19.9018 13.5141 20.458 7.36086 21.0014 5.14903C21.5447 2.9372 23.7919 3.04938 23.7919 3.04938C23.7919 3.04938 23.2085 4.06764 23.4464 4.82751C23.6844 5.58738 25.3145 6.26662 25.3145 6.26662L24.9629 7.19622C24.9629 7.19622 24.2288 7.10204 23.7919 7.9785C23.355 8.85496 24.3392 17.4442 24.3392 17.4442C24.3392 17.4442 21.4469 22.7275 21.4469 24.9206C21.4469 27.1136 22.4819 28.9515 22.4819 28.9515H21.0296C21.0296 28.9515 18.899 26.4086 18.462 25.1378C18.0251 23.8669 18.1998 22.596 18.1998 22.596C18.1998 22.596 15.8839 22.4646 13.8303 22.596C11.7767 22.7275 10.4072 24.498 10.16 25.4884C9.91287 26.4787 9.81048 28.9515 9.81048 28.9515H8.66211C7.96315 26.7882 7.40803 26.0129 7.70918 24.9206C8.54334 21.8949 8.37949 20.1788 8.18635 19.4145C7.99321 18.6501 6.68552 17.983 6.68552 17.983C7.32609 16.6741 7.97996 16.0452 10.7926 15.9796C13.6052 15.914 17.3915 15.5965 18.6466 14.5553Z" }),
10300
- /* @__PURE__ */ React.createElement("path", { d: "M11.1268 24.7939C11.1268 24.7939 11.4236 27.5481 13.0001 28.9516H14.3511C13.0001 27.4166 12.8527 23.4155 12.8527 23.4155C12.1656 23.6399 11.3045 24.3846 11.1268 24.7939Z" })
10301
- ), /* @__PURE__ */ React.createElement("span", null, "Tina")),
10302
- /* @__PURE__ */ React.createElement(SyncErrorWidget, { cms }),
10303
- /* @__PURE__ */ React.createElement(
10304
- FiMoreVertical,
10305
- {
10306
- className: `flex-0 w-6 h-full inline-block group-hover:opacity-80 transition-all duration-300 ease-in-out transform ${open2 ? "opacity-100 text-blue-400" : "text-gray-400 opacity-50 hover:opacity-70"}`
10307
- }
10308
- )
10309
- ), /* @__PURE__ */ React.createElement("div", { className: "transform translate-y-full absolute bottom-3 right-5 z-50" }, /* @__PURE__ */ React.createElement(
10310
- Transition,
10456
+ /* @__PURE__ */ React.createElement("div", { className: "max-w-form mx-auto flex gap-2 justify-between items-center" }, /* @__PURE__ */ React.createElement(
10457
+ "button",
10311
10458
  {
10312
- enter: "transition duration-150 ease-out",
10313
- enterFrom: "transform opacity-0 -translate-y-2",
10314
- enterTo: "transform opacity-100 translate-y-0",
10315
- leave: "transition duration-75 ease-in",
10316
- leaveFrom: "transform opacity-100 translate-y-0",
10317
- leaveTo: "transform opacity-0 -translate-y-2"
10318
- },
10319
- /* @__PURE__ */ React.createElement(MenuItems, { className: "bg-white border border-gray-150 rounded-lg shadow-lg flex flex-col items-stretch overflow-hidden" }, /* @__PURE__ */ React.createElement(MenuItem, null, /* @__PURE__ */ React.createElement(
10320
- "button",
10321
- {
10322
- className: `text-lg px-4 py-2 first:pt-3 last:pb-3 tracking-wide whitespace-nowrap flex items-center opacity-80 text-gray-600 hover:text-blue-400 hover:bg-gray-50 hover:opacity-100`,
10323
- onClick: async () => {
10324
- var _a, _b, _c, _d, _e, _f, _g, _h;
10325
- updateBodyDisplacement({
10326
- displayState: "closed",
10327
- sidebarWidth: null,
10328
- resizingSidebar: false
10329
- });
10330
- try {
10331
- if ((_c = (_b = (_a = cms == null ? void 0 : cms.api) == null ? void 0 : _a.tina) == null ? void 0 : _b.authProvider) == null ? void 0 : _c.logout) {
10332
- await ((_d = cms.api.tina) == null ? void 0 : _d.authProvider.logout());
10333
- if ((_f = (_e = cms == null ? void 0 : cms.api) == null ? void 0 : _e.tina) == null ? void 0 : _f.onLogout) {
10334
- await ((_h = (_g = cms == null ? void 0 : cms.api) == null ? void 0 : _g.tina) == null ? void 0 : _h.onLogout());
10335
- await new Promise(
10336
- (resolve) => setTimeout(resolve, 500)
10337
- );
10338
- }
10339
- window.location.href = new URL(
10340
- window.location.href
10341
- ).pathname;
10342
- }
10343
- } catch (e) {
10344
- cms.alerts.error(`Error logging out: ${e}`);
10345
- console.error("Unexpected error calling logout");
10346
- console.error(e);
10347
- }
10459
+ type: "button",
10460
+ className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
10461
+ onClick: () => {
10462
+ const state = activeForm.tinaForm.finalForm.getState();
10463
+ if (state.invalid === true) {
10464
+ cms.alerts.error("Cannot navigate away from an invalid form.");
10465
+ } else {
10466
+ cms.dispatch({ type: "forms:set-active-form-id", value: null });
10348
10467
  }
10349
- },
10350
- /* @__PURE__ */ React.createElement(BiExit, { className: "w-6 h-auto mr-2 text-blue-400" }),
10351
- " Log Out"
10352
- )), /* @__PURE__ */ React.createElement(MenuItem, null, /* @__PURE__ */ React.createElement(
10353
- WrappedSyncStatus,
10354
- {
10355
- cms,
10356
- setEventsOpen
10357
10468
  }
10358
- )))
10359
- ))))),
10360
- eventsOpen && /* @__PURE__ */ React.createElement(SyncStatusModal, { cms, closeEventsModal }),
10361
- children,
10362
- /* @__PURE__ */ React.createElement("div", { className: "flex flex-col px-6 flex-1 overflow-auto" }, showCollections && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "flex space-x-1 justify-items-start uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, /* @__PURE__ */ React.createElement("span", null, "Collections"), isLocalMode && /* @__PURE__ */ React.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React.createElement(
10363
- "a",
10364
- {
10365
- href: "https://tina.io/docs/schema/#defining-collections",
10366
- target: "_blank"
10367
10469
  },
10368
- /* @__PURE__ */ React.createElement(FiInfo, null)
10369
- ))), /* @__PURE__ */ React.createElement(
10370
- CollectionsList,
10371
- {
10372
- RenderNavCollection,
10373
- collections: contentCollections
10374
- }
10375
- )), (screenCategories.Site.length > 0 || contentCreators.length) > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Site"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screenCategories.Site.map((view) => {
10376
- return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
10377
- }), contentCreators.map((plugin, idx) => {
10378
- return /* @__PURE__ */ React.createElement(CreateContentNavItem, { key: `plugin-${idx}`, plugin });
10379
- }), authCollection && /* @__PURE__ */ React.createElement(
10380
- CollectionsList,
10470
+ /* @__PURE__ */ React.createElement(BiDotsVertical, { className: "h-auto w-5 inline-block opacity-70" })
10471
+ ), /* @__PURE__ */ React.createElement(
10472
+ "button",
10381
10473
  {
10382
- RenderNavCollection: AuthRenderNavCollection,
10383
- collections: [authCollection]
10384
- }
10385
- ))), Object.entries(screenCategories).map(([category, screens2]) => {
10386
- if (category !== "Site") {
10387
- return /* @__PURE__ */ React.createElement("div", { key: category }, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, category), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, screens2.map((view) => {
10388
- return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${view.name}` }, /* @__PURE__ */ React.createElement(RenderNavSite, { view }));
10389
- })));
10390
- }
10391
- }), !!(cloudConfigs == null ? void 0 : cloudConfigs.length) && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("h4", { className: "uppercase font-sans font-bold text-sm mb-3 mt-8 text-gray-700" }, "Cloud"), /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, cloudConfigs.map((config) => {
10392
- return /* @__PURE__ */ React.createElement("li", { key: `nav-site-${config.name}` }, /* @__PURE__ */ React.createElement(RenderNavCloud, { config }));
10393
- }))), /* @__PURE__ */ React.createElement("div", { className: "grow" }), /* @__PURE__ */ React.createElement("span", { className: "font-sans font-light text-xs mb-3 mt-8 text-gray-500" }, "v", version))
10474
+ type: "button",
10475
+ className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
10476
+ onClick: () => {
10477
+ const collectionName = cms.api.tina.schema.getCollectionByFullPath(
10478
+ cms.state.activeFormId
10479
+ ).name;
10480
+ window.location.href = `${new URL(window.location.href).pathname}#/collections/${collectionName}/~`;
10481
+ }
10482
+ },
10483
+ /* @__PURE__ */ React.createElement(BiHomeAlt, { className: "h-auto w-5 inline-block opacity-70" })
10484
+ ), /* @__PURE__ */ React.createElement("span", { className: "opacity-30 text-sm leading-tight whitespace-nowrap flex-0" }, "/"), /* @__PURE__ */ React.createElement("span", { className: "block w-full text-sm leading-tight whitespace-nowrap truncate" }, activeForm.tinaForm.label || activeForm.tinaForm.id), /* @__PURE__ */ React.createElement(FormStatus, { pristine: formIsPristine }))
10394
10485
  );
10395
10486
  };
10396
- const CollectionsList = ({
10397
- collections,
10398
- RenderNavCollection
10399
- }) => {
10400
- if (collections.length === 0) {
10401
- return /* @__PURE__ */ React.createElement("div", null, "No collections found");
10402
- }
10403
- return /* @__PURE__ */ React.createElement("ul", { className: "flex flex-col gap-4" }, collections.map((collection) => {
10404
- return /* @__PURE__ */ React.createElement("li", { key: `nav-collection-${collection.name}` }, /* @__PURE__ */ React.createElement(RenderNavCollection, { collection }));
10405
- }));
10406
- };
10407
- const CreateContentNavItem = ({ plugin }) => {
10408
- const [open2, setOpen] = React.useState(false);
10409
- return /* @__PURE__ */ React.createElement("li", { key: plugin.name }, /* @__PURE__ */ React.createElement(
10410
- "button",
10411
- {
10412
- className: "text-base tracking-wide text-gray-500 hover:text-blue-600 flex items-center opacity-90 hover:opacity-100",
10413
- onClick: () => {
10414
- setOpen(true);
10415
- }
10416
- },
10417
- /* @__PURE__ */ React.createElement(VscNewFile, { className: "mr-3 h-6 opacity-80 w-auto" }),
10418
- " ",
10419
- plugin.name
10420
- ), open2 && /* @__PURE__ */ React.createElement(FormModal, { plugin, close: () => setOpen(false) }));
10421
- };
10422
- const ResizeHandle = () => {
10423
- const {
10424
- resizingSidebar,
10425
- setResizingSidebar,
10426
- fullscreen,
10427
- setSidebarWidth,
10428
- displayState
10429
- } = React.useContext(SidebarContext);
10430
- React.useEffect(() => {
10431
- const handleMouseUp = () => setResizingSidebar(false);
10432
- window.addEventListener("mouseup", handleMouseUp);
10433
- return () => {
10434
- window.removeEventListener("mouseup", handleMouseUp);
10435
- };
10436
- }, []);
10437
- React.useEffect(() => {
10438
- const handleMouseMove = (e) => {
10439
- setSidebarWidth((sidebarWidth) => {
10440
- const newWidth = sidebarWidth + e.movementX;
10441
- const maxWidth = window.innerWidth - 8;
10442
- if (newWidth < minSidebarWidth) {
10443
- return minSidebarWidth;
10444
- } else if (newWidth > maxWidth) {
10445
- return maxWidth;
10446
- } else {
10447
- return newWidth;
10448
- }
10449
- });
10450
- };
10451
- if (resizingSidebar) {
10452
- window.addEventListener("mousemove", handleMouseMove);
10453
- document.body.classList.add("select-none");
10454
- }
10455
- return () => {
10456
- window.removeEventListener("mousemove", handleMouseMove);
10457
- document.body.classList.remove("select-none");
10458
- };
10459
- }, [resizingSidebar]);
10460
- const handleresizingSidebar = () => setResizingSidebar(true);
10461
- if (fullscreen) {
10462
- return null;
10463
- }
10487
+ const FormHeader = ({ activeForm }) => {
10488
+ const { formIsPristine } = React.useContext(SidebarContext);
10489
+ const cms = useCMS$1();
10490
+ const shortFormLabel = activeForm.tinaForm.label ? activeForm.tinaForm.label.replace(/^.*[\\\/]/, "") : false;
10464
10491
  return /* @__PURE__ */ React.createElement(
10465
10492
  "div",
10466
10493
  {
10467
- onMouseDown: handleresizingSidebar,
10468
- className: `z-100 absolute top-1/2 right-px w-2 h-32 bg-white rounded-r-md border border-gray-150 shadow-sm hover:shadow-md origin-left transition-all duration-150 ease-out transform translate-x-full -translate-y-1/2 group hover:bg-gray-50 ${displayState !== "closed" ? `opacity-100` : `opacity-0`} ${resizingSidebar ? `scale-110` : `scale-90 hover:scale-100`}`,
10469
- style: { cursor: "grab" }
10494
+ className: "pt-18 pb-4 px-6 border-b border-gray-200 bg-gradient-to-t from-white to-gray-50"
10470
10495
  },
10471
- /* @__PURE__ */ React.createElement("span", { className: "absolute top-1/2 left-1/2 h-4/6 w-px bg-gray-200 transform -translate-y-1/2 -translate-x-1/2 opacity-30 transition-opacity duration-150 ease-out group-hover:opacity-100" })
10496
+ /* @__PURE__ */ React.createElement("div", { className: "max-w-form mx-auto flex gap-2 justify-between items-center" }, /* @__PURE__ */ React.createElement(
10497
+ "button",
10498
+ {
10499
+ type: "button",
10500
+ className: "pointer-events-auto text-xs text-blue-400 hover:text-blue-500 hover:underline transition-all ease-out duration-150",
10501
+ onClick: () => {
10502
+ const collectionName = cms.api.tina.schema.getCollectionByFullPath(
10503
+ cms.state.activeFormId
10504
+ ).name;
10505
+ window.location.href = `${new URL(window.location.href).pathname}#/collections/${collectionName}/~`;
10506
+ }
10507
+ },
10508
+ /* @__PURE__ */ React.createElement(BiHomeAlt, { className: "h-auto w-5 inline-block opacity-70" })
10509
+ ), shortFormLabel && /* @__PURE__ */ React.createElement("span", { className: "block w-full text-sm leading-tight whitespace-nowrap truncate" }, shortFormLabel), /* @__PURE__ */ React.createElement(FormStatus, { pristine: formIsPristine }))
10472
10510
  );
10473
10511
  };
10474
10512
  const SidebarContext = React.createContext(null);
@@ -10689,7 +10727,7 @@ const Sidebar$1 = ({
10689
10727
  isLocalMode: (_d = (_c = cms.api) == null ? void 0 : _c.tina) == null ? void 0 : _d.isLocalMode,
10690
10728
  branchingEnabled
10691
10729
  }
10692
- ), /* @__PURE__ */ React.createElement(FormsView, null, /* @__PURE__ */ React.createElement(sidebar.placeholder, null)), activeScreen && /* @__PURE__ */ React.createElement(
10730
+ ), /* @__PURE__ */ React.createElement(FormsView, { loadingPlaceholder: sidebar.loadingPlaceholder }), activeScreen && /* @__PURE__ */ React.createElement(
10693
10731
  ScreenPluginModal,
10694
10732
  {
10695
10733
  screen: activeScreen,
@@ -12053,6 +12091,7 @@ const initialState = (cms) => {
12053
12091
  forms: [],
12054
12092
  formLists: [],
12055
12093
  editingMode: "basic",
12094
+ isLoadingContent: false,
12056
12095
  quickEditSupported: false,
12057
12096
  sidebarDisplayState: ((_a = cms == null ? void 0 : cms.sidebar) == null ? void 0 : _a.defaultState) || "open"
12058
12097
  };
@@ -12112,7 +12151,12 @@ function tinaReducer(state, action) {
12112
12151
  }
12113
12152
  });
12114
12153
  }
12115
- return { ...state, activeFormId, formLists: nextFormLists };
12154
+ return {
12155
+ ...state,
12156
+ activeFormId,
12157
+ formLists: nextFormLists,
12158
+ isLoadingContent: false
12159
+ };
12116
12160
  }
12117
12161
  case "form-lists:remove": {
12118
12162
  const nextFormLists = state.formLists.filter(
@@ -12181,6 +12225,9 @@ function tinaReducer(state, action) {
12181
12225
  }
12182
12226
  return { ...state, sidebarDisplayState: action.value };
12183
12227
  }
12228
+ case "sidebar:set-loading-state": {
12229
+ return { ...state, isLoadingContent: action.value };
12230
+ }
12184
12231
  default:
12185
12232
  throw new Error(`Unhandled action ${action.type}`);
12186
12233
  }
@@ -12866,7 +12913,6 @@ const CreateBranchModel = ({
12866
12913
  }) => {
12867
12914
  const cms = useCMS$1();
12868
12915
  const tinaApi = cms.api.tina;
12869
- tinaApi.branch;
12870
12916
  const [disabled, setDisabled] = React.useState(false);
12871
12917
  const [newBranchName, setNewBranchName] = React.useState("");
12872
12918
  const [error, setError] = React.useState("");
@@ -12892,10 +12938,10 @@ const CreateBranchModel = ({
12892
12938
  const newUrl = window.location.href.replace(hash, newHash);
12893
12939
  window.location.href = newUrl;
12894
12940
  };
12895
- return /* @__PURE__ */ React.createElement(Modal, null, /* @__PURE__ */ React.createElement(PopupModal, null, /* @__PURE__ */ React.createElement(ModalHeader, { close: close2 }, /* @__PURE__ */ React.createElement(BiGitBranch, { className: "w-6 h-auto mr-1 text-blue-500 opacity-70" }), " ", "Create Branch"), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("p", { className: "text-base text-gray-700 mb-2" }, "This branch is ", /* @__PURE__ */ React.createElement("strong", null, "protected"), ". Create a new branch to save your changes."), /* @__PURE__ */ React.createElement(
12941
+ return /* @__PURE__ */ React.createElement(Modal, null, /* @__PURE__ */ React.createElement(PopupModal, null, /* @__PURE__ */ React.createElement(ModalHeader, { close: close2 }, /* @__PURE__ */ React.createElement(BiGitBranch, { className: "w-6 h-auto mr-1 text-blue-500 opacity-70" }), " ", "Create Branch"), /* @__PURE__ */ React.createElement(ModalBody, { padded: true }, /* @__PURE__ */ React.createElement("p", { className: "text-lg text-gray-700 font-bold mb-2" }, "This content is protected 🚧"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-700 mb-4" }, "To make changes, you need to create a copy then get it approved and merged for it to go live."), /* @__PURE__ */ React.createElement(
12896
12942
  PrefixedTextField,
12897
12943
  {
12898
- placeholder: "Branch Name",
12944
+ placeholder: "e.g. {{PAGE-NAME}}-updates",
12899
12945
  value: newBranchName,
12900
12946
  onChange: (e) => {
12901
12947
  setError("");
@@ -32645,6 +32691,35 @@ const FullscreenError = ({
32645
32691
  }) => {
32646
32692
  return /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col justify-center items-center h-screen bg-gray-100" }, /* @__PURE__ */ React__default.createElement("div", { className: "text-red-500 text-4xl mb-6 flex items-center" }, /* @__PURE__ */ React__default.createElement(BiError, { className: "w-12 h-auto fill-current text-red-400 opacity-70 mr-1" }), " ", title), /* @__PURE__ */ React__default.createElement("p", { className: "text-gray-700 text-xl mb-8" }, errorMessage), /* @__PURE__ */ React__default.createElement(Button$1, { variant: "danger", onClick: () => window.location.reload() }, /* @__PURE__ */ React__default.createElement(BiSync, { className: "w-7 h-auto fill-current opacity-70 mr-1" }), " Reload"));
32647
32693
  };
32694
+ const isValidSortKey = (sortKey, collection) => {
32695
+ if (collection.fields) {
32696
+ const sortKeys = collection.fields.map((x) => x.name);
32697
+ return sortKeys.includes(sortKey);
32698
+ } else if (collection.templates) {
32699
+ const collectionMap = {};
32700
+ const conflictedFields = /* @__PURE__ */ new Set();
32701
+ for (const template of collection.templates) {
32702
+ for (const field of template.fields) {
32703
+ if (collectionMap[field.name]) {
32704
+ if (collectionMap[field.name].type !== field.type) {
32705
+ conflictedFields.add(field.name);
32706
+ }
32707
+ } else {
32708
+ collectionMap[field.name] = field;
32709
+ }
32710
+ }
32711
+ }
32712
+ for (const key in conflictedFields) {
32713
+ delete collectionMap[key];
32714
+ }
32715
+ for (const key in collectionMap) {
32716
+ if (key === sortKey) {
32717
+ return true;
32718
+ }
32719
+ }
32720
+ return false;
32721
+ }
32722
+ };
32648
32723
  const useGetCollection = (cms, collectionName, includeDocuments = true, folder, after = "", sortKey, filterArgs) => {
32649
32724
  const api = new TinaAdminApi(cms);
32650
32725
  const schema = cms.api.tina.schema;
@@ -32656,10 +32731,9 @@ const useGetCollection = (cms, collectionName, includeDocuments = true, folder,
32656
32731
  useEffect(() => {
32657
32732
  let cancelled = false;
32658
32733
  const fetchCollection = async () => {
32659
- var _a;
32660
32734
  if (await api.isAuthenticated() && !folder.loading && !cancelled) {
32661
32735
  const { name, order } = JSON.parse(sortKey || "{}");
32662
- const validSortKey = ((_a = collectionExtra.fields) == null ? void 0 : _a.map((x) => x.name).includes(name)) ? name : void 0;
32736
+ const validSortKey = isValidSortKey(name, collectionExtra) ? name : void 0;
32663
32737
  try {
32664
32738
  const collection2 = await api.fetchCollection(
32665
32739
  collectionName,