@bagelink/blox 1.10.39 → 1.10.40

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.cjs CHANGED
@@ -97,19 +97,19 @@ const PageRenderer = vue.defineComponent({
97
97
  );
98
98
  }
99
99
  });
100
- const _hoisted_1$2 = {
100
+ const _hoisted_1$1 = {
101
101
  key: 0,
102
102
  class: "blox-loading"
103
103
  };
104
- const _hoisted_2$1 = {
104
+ const _hoisted_2 = {
105
105
  key: 1,
106
106
  class: "blox-not-found"
107
107
  };
108
- const _hoisted_3$1 = {
108
+ const _hoisted_3 = {
109
109
  key: 2,
110
110
  class: "blox-error"
111
111
  };
112
- const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
112
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
113
113
  __name: "CmsPageView",
114
114
  setup(__props) {
115
115
  const route = vueRouter.useRoute();
@@ -152,7 +152,7 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
152
152
  return (_ctx, _cache) => {
153
153
  const _component_RouterLink = vue.resolveComponent("RouterLink");
154
154
  return vue.openBlock(), vue.createElementBlock("div", null, [
155
- loading.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, " Loading… ")) : notFound.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$1, [
155
+ loading.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, " Loading… ")) : notFound.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [
156
156
  _cache[0] || (_cache[0] = vue.createElementVNode("h2", null, "404", -1)),
157
157
  vue.createElementVNode("p", null, vue.toDisplayString(vue.unref(locale2) === "he" ? "הדף לא נמצא" : "Page not found"), 1),
158
158
  vue.createVNode(_component_RouterLink, { to: "/" }, {
@@ -161,7 +161,7 @@ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
161
161
  ]),
162
162
  _: 1
163
163
  })
164
- ])) : error.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$1, vue.toDisplayString(error.value), 1)) : (vue.openBlock(), vue.createBlock(vue.unref(PageRenderer), {
164
+ ])) : error.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, vue.toDisplayString(error.value), 1)) : (vue.openBlock(), vue.createBlock(vue.unref(PageRenderer), {
165
165
  key: 3,
166
166
  blocks: blocks.value
167
167
  }, null, 8, ["blocks"]))
@@ -191,7 +191,7 @@ function usePageContext(key) {
191
191
  return value;
192
192
  });
193
193
  }
194
- const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
194
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
195
195
  __name: "LocaleRouterLink",
196
196
  props: {
197
197
  to: {},
@@ -324,7 +324,7 @@ class BloxInstance {
324
324
  component: () => Promise.resolve().then(() => require("./PreviewApp-C1WvJWI4.cjs")),
325
325
  beforeEnter: () => window.parent !== window ? true : "/"
326
326
  });
327
- router.addRoute({ path: "/:pathMatch(.*)*", component: _sfc_main$3 });
327
+ router.addRoute({ path: "/:pathMatch(.*)*", component: _sfc_main$2 });
328
328
  this._routeRegistered = true;
329
329
  return this;
330
330
  }
@@ -352,7 +352,7 @@ class BloxInstance {
352
352
  app.provide(BLOX_REGISTRY_KEY, this._registry);
353
353
  app.provide(BLOX_CONFIG_KEY, this._config);
354
354
  app.provide(BLOX_LOCALE_STRATEGY_KEY, this._strategy);
355
- app.component("RouterLink", _sfc_main$2);
355
+ app.component("RouterLink", _sfc_main$1);
356
356
  }
357
357
  }
358
358
  function createBlox(options) {
@@ -439,8 +439,8 @@ const PreviewRenderer = vue.defineComponent({
439
439
  );
440
440
  }
441
441
  });
442
- const _hoisted_1$1 = { class: "blox-preview-root" };
443
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
442
+ const _hoisted_1 = { class: "blox-preview-root" };
443
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
444
444
  __name: "PreviewApp",
445
445
  setup(__props) {
446
446
  const registry = vue.inject(BLOX_REGISTRY_KEY, {});
@@ -496,7 +496,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
496
496
  heightObserver == null ? void 0 : heightObserver.disconnect();
497
497
  });
498
498
  return (_ctx, _cache) => {
499
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
499
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
500
500
  vue.createVNode(vue.unref(PreviewRenderer), {
501
501
  blocks: blocks.value,
502
502
  "selected-index": selectedIndex.value,
@@ -506,1271 +506,12 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
506
506
  };
507
507
  }
508
508
  });
509
- const _hoisted_1 = { class: "py-05 h-100vh m_p-0" };
510
- const _hoisted_2 = { class: "grid grid-wrap-5 gap-1 mt-1" };
511
- const _hoisted_3 = ["onClick"];
512
- const _hoisted_4 = {
513
- key: 0,
514
- class: "absolute inset-0 bg-opacity-80 flex-center rounded z-10"
515
- };
516
- const _hoisted_5 = { class: "flex flex-column align-items-center gap-025" };
517
- const _hoisted_6 = { class: "txt10 m-0" };
518
- const _hoisted_7 = { class: "txt-12 m-0 pt-025" };
519
- const _hoisted_8 = { class: "overflow-hidden m_none h-100p gap-0" };
520
- const _hoisted_9 = { class: "flex gap-1" };
521
- const _hoisted_10 = { class: "overflow-hidden rounded" };
522
- const _hoisted_11 = { class: "hm-400px overflow-auto" };
523
- const _hoisted_12 = { class: "p-05" };
524
- const _hoisted_13 = { key: 1 };
525
- const _hoisted_14 = {
526
- class: "radius-1 overflow-hidden grid grid-list-wrapper",
527
- style: { "max-height": "300px" }
528
- };
529
- const _hoisted_15 = { class: "px-075 pt-075" };
530
- const _hoisted_16 = { class: "overflow" };
531
- const _hoisted_17 = { class: "relative" };
532
- const _hoisted_18 = { class: "min-w-150px overflow-hidden radius-1" };
533
- const _hoisted_19 = {
534
- key: 0,
535
- class: "txt-10 opacity-5 px-025 shrink-0 flex gap-025 relative"
536
- };
537
- const _hoisted_20 = {
538
- key: 0,
539
- class: "locale-add border-top flex gap-025 p-05"
540
- };
541
- const _hoisted_21 = { class: "flex gap-025" };
542
- const _hoisted_22 = { class: "py-025" };
543
- const _hoisted_23 = { class: "m-0 txt12 px-05 opacity-7" };
544
- const _hoisted_24 = { class: "gap-025 flex align-items-center" };
545
- const _hoisted_25 = { class: "relative overflow-hidden h-100p gap-0" };
546
- const _hoisted_26 = { class: "flex space-between border-bottom px-1 py-075" };
547
- const _hoisted_27 = {
548
- key: 0,
549
- class: "absolute flex column start-auto end-1 top-4 w-150px txt-center gap-1 opacity-5"
550
- };
551
- const _hoisted_28 = {
552
- xmlns: "http://www.w3.org/2000/svg",
553
- viewBox: "6 0 8 20",
554
- class: "h-80px",
555
- style: { "transform": "rotateY(180deg) rotateZ(30deg)" }
556
- };
557
- const _hoisted_29 = ["data-draggable-id"];
558
- const _hoisted_30 = ["onMouseenter", "onFocusin"];
559
- const _hoisted_31 = ["onClick"];
560
- const _hoisted_32 = { class: "me-05 txt-12 semi ellipsis-1" };
561
- const _hoisted_33 = ["innerHTML"];
562
- const _hoisted_34 = { class: "add-sec-btn transition txt-9 relative txt-start" };
563
- const _hoisted_35 = { class: "grid relative h-100p" };
564
- const _hoisted_36 = {
565
- key: 0,
566
- class: "relative z-2 bg-white"
567
- };
568
- const _hoisted_37 = { class: "flex px-1 py-075 border-bottom" };
569
- const _hoisted_38 = { class: "txt-gray me-05 txt-14" };
570
- const _hoisted_39 = { class: "ms-auto flex gap-025" };
571
- const _hoisted_40 = { class: "px-025 block-form-container" };
572
- const _hoisted_41 = {
573
- key: 1,
574
- class: "px-1 py-2 txt-center opacity-5"
575
- };
576
- const _hoisted_42 = { class: "border-top txt-center mt-1" };
577
- const _hoisted_43 = { class: "txt-center pt-5 opacity-3 position-center z-0 user-select-none" };
578
- const _hoisted_44 = { class: "none m_block txt-center p-1 w-300px h-100p smallScreen" };
579
- const _sfc_main = /* @__PURE__ */ vue.defineComponent({
580
- __name: "PageDesigner",
581
- props: {
582
- websiteId: {},
583
- pageId: {},
584
- api: {},
585
- schema: {},
586
- previewBaseUrl: {},
587
- supportedLocales: {},
588
- defaultLocale: {},
589
- updateLocales: { type: Function }
590
- },
591
- emits: ["navigate"],
592
- setup(__props, { emit: __emit }) {
593
- const props = __props;
594
- const emit = __emit;
595
- const dialog = vue$1.useDialog();
596
- const route = vueRouter.useRoute();
597
- vueRouter.useRouter();
598
- const currentPageId = vue.computed(() => props.pageId || route.params.pageId);
599
- const previewUrl = vue.computed(() => {
600
- const base = (props.previewBaseUrl ?? "").replace(/\/+$/, "");
601
- return `${base}/_blox_preview`;
602
- });
603
- const menuState = vue.inject("menuState", {
604
- isOpen: { value: false },
605
- isMobile: { value: false },
606
- toggleMenu: () => {
607
- }
608
- });
609
- const webpages = vue$1.filterRef([]);
610
- const page = vue.ref(null);
611
- const resolvedPage = vue.ref(null);
612
- const isSaving = vue.ref(false);
613
- const blocks = vue.ref([]);
614
- const savedBlocks = vue.ref([]);
615
- const isDirty = vue.computed(() => JSON.stringify(blocks.value) !== JSON.stringify(savedBlocks.value));
616
- const blockKeys = vue.ref([]);
617
- function syncBlockKeys() {
618
- while (blockKeys.value.length < blocks.value.length) {
619
- blockKeys.value.push(crypto.randomUUID());
620
- }
621
- blockKeys.value.length = blocks.value.length;
622
- }
623
- const registry = vue.ref({});
624
- function registryLabel(type) {
625
- var _a;
626
- return ((_a = registry.value[type]) == null ? void 0 : _a.label) ?? type;
627
- }
628
- function registryIcon(type) {
629
- var _a;
630
- return ((_a = registry.value[type]) == null ? void 0 : _a.icon) ?? "check_box_outline_blank";
631
- }
632
- function blockSchema(type) {
633
- const r = registry.value[type];
634
- if (!r) return null;
635
- if (Object.keys(r.fields).length === 0) return null;
636
- return r.fields;
637
- }
638
- const selectedIndex = vue.ref(null);
639
- const hoveredIndex = vue.ref(null);
640
- const selectedBlock = vue.computed(
641
- () => selectedIndex.value !== null ? blocks.value[selectedIndex.value] ?? null : null
642
- );
643
- function selectBlock(index) {
644
- selectedIndex.value = index;
645
- sendToPreview2({ type: "BLOX_SELECT_BLOCK", index });
646
- }
647
- function clearSelection() {
648
- selectedIndex.value = null;
649
- sendToPreview2({ type: "BLOX_SELECT_BLOCK", index: null });
650
- }
651
- function hoverBlock(index) {
652
- hoveredIndex.value = index;
653
- sendToPreview2({ type: "BLOX_HOVER_BLOCK", index });
654
- }
655
- const currentLocale = vue.ref(props.defaultLocale ?? "");
656
- const isSwitchingLocale = vue.ref(false);
657
- const isUpdatingLocales = vue.ref(false);
658
- const newLocaleInput = vue.ref("");
659
- const localeList = vue.computed(
660
- () => props.supportedLocales ?? (currentLocale.value ? [currentLocale.value] : [])
661
- );
662
- const activeBinding = vue.ref(null);
663
- const bindingItems = vue$1.filterRef([]);
664
- const selectedBindParams = vue.ref({});
665
- const isLoadingBindItems = vue.ref(false);
666
- function extractFirstDatastoreBinding(p) {
667
- if (!(p == null ? void 0 : p.data_bindings)) return null;
668
- for (const [key, b] of Object.entries(p.data_bindings)) {
669
- if ((b == null ? void 0 : b.adapter) === "datastore" && (b == null ? void 0 : b.collection) && (b == null ? void 0 : b.store) && (b == null ? void 0 : b.bind_by)) {
670
- return { contextKey: key, store: b.store, collection: b.collection, bindBy: b.bind_by };
671
- }
672
- }
673
- return null;
674
- }
675
- async function loadBindingItems(binding, keepSelection = false) {
676
- if (!props.api.listCollectionItems) return;
677
- isLoadingBindItems.value = true;
678
- try {
679
- const items = await props.api.listCollectionItems(binding.store, binding.collection);
680
- bindingItems.value = items;
681
- if (!keepSelection || !selectedBindParams.value[binding.bindBy]) {
682
- const first = items[0];
683
- selectedBindParams.value = first ? { [binding.bindBy]: String(first[binding.bindBy] ?? "") } : {};
684
- }
685
- } finally {
686
- isLoadingBindItems.value = false;
687
- }
688
- }
689
- function bindItemLabel(item) {
690
- var _a;
691
- return String(
692
- item.title ?? item.name ?? item.slug ?? item.label ?? item[((_a = activeBinding.value) == null ? void 0 : _a.bindBy) ?? ""] ?? item.id ?? ""
693
- );
694
- }
695
- async function selectBindItem(item) {
696
- if (!activeBinding.value) return;
697
- selectedBindParams.value = {
698
- [activeBinding.value.bindBy]: String(item[activeBinding.value.bindBy] ?? "")
699
- };
700
- await reloadWithBindParams();
701
- }
702
- async function reloadWithBindParams() {
703
- var _a;
704
- if (!currentPageId.value) return;
705
- try {
706
- const resolved = await props.api.resolvePage(
707
- props.websiteId,
708
- currentPageId.value,
709
- currentLocale.value || void 0,
710
- Object.keys(selectedBindParams.value).length ? selectedBindParams.value : void 0
711
- );
712
- resolvedPage.value = resolved;
713
- blocks.value = ((_a = resolved.page.content) == null ? void 0 : _a.blocks) ?? [];
714
- if (Object.keys(registry.value).length > 0) {
715
- sendToPreview2({ type: "BLOX_INIT", page: resolved, locale: currentLocale.value });
716
- }
717
- } catch (e) {
718
- console.error(e);
719
- }
720
- }
721
- async function switchLocale(locale2) {
722
- var _a;
723
- if (!currentPageId.value || locale2 === currentLocale.value) return;
724
- isSwitchingLocale.value = true;
725
- try {
726
- currentLocale.value = locale2;
727
- const resolved = await props.api.resolvePage(
728
- props.websiteId,
729
- currentPageId.value,
730
- locale2,
731
- Object.keys(selectedBindParams.value).length ? selectedBindParams.value : void 0
732
- );
733
- resolvedPage.value = resolved;
734
- blocks.value = ((_a = resolved.page.content) == null ? void 0 : _a.blocks) ?? [];
735
- savedBlocks.value = JSON.parse(JSON.stringify(blocks.value));
736
- syncBlockKeys();
737
- selectedIndex.value = null;
738
- sendToPreview2({ type: "BLOX_INIT", page: resolved, locale: locale2 });
739
- } finally {
740
- isSwitchingLocale.value = false;
741
- }
742
- }
743
- async function addLocale() {
744
- const code = newLocaleInput.value.trim().toLowerCase();
745
- if (!code || localeList.value.includes(code) || !props.updateLocales) return;
746
- isUpdatingLocales.value = true;
747
- try {
748
- await props.updateLocales(
749
- [...localeList.value, code],
750
- props.defaultLocale ?? localeList.value[0] ?? code
751
- );
752
- newLocaleInput.value = "";
753
- } finally {
754
- isUpdatingLocales.value = false;
755
- }
756
- }
757
- async function removeLocale(locale2) {
758
- if (!props.updateLocales || localeList.value.length <= 1) return;
759
- if (!await dialog.confirm(`הסר את שפה "${locale2.toUpperCase()}"?`)) return;
760
- isUpdatingLocales.value = true;
761
- try {
762
- const next = localeList.value.filter((l) => l !== locale2);
763
- const newDefault = locale2 === props.defaultLocale ? next[0] : props.defaultLocale ?? next[0];
764
- await props.updateLocales(next, newDefault);
765
- } finally {
766
- isUpdatingLocales.value = false;
767
- }
768
- }
769
- async function setDefaultLocale(locale2) {
770
- if (!props.updateLocales || locale2 === props.defaultLocale) return;
771
- isUpdatingLocales.value = true;
772
- try {
773
- await props.updateLocales(localeList.value, locale2);
774
- } finally {
775
- isUpdatingLocales.value = false;
776
- }
777
- }
778
- const draggableContainer = vue.ref();
779
- const draggable = vue$1.useDraggable({
780
- animation: 150,
781
- mode: "line",
782
- handle: ".drag-handle",
783
- items: blocks,
784
- onEnd: ({ oldIndex, newIndex }) => {
785
- if (oldIndex !== newIndex) {
786
- const movedBlock = blocks.value.splice(oldIndex, 1)[0];
787
- blocks.value.splice(newIndex, 0, movedBlock);
788
- const movedKey = blockKeys.value.splice(oldIndex, 1)[0];
789
- blockKeys.value.splice(newIndex, 0, movedKey);
790
- if (selectedIndex.value === oldIndex) {
791
- selectedIndex.value = newIndex;
792
- } else if (selectedIndex.value !== null && selectedIndex.value > oldIndex && selectedIndex.value <= newIndex) {
793
- selectedIndex.value--;
794
- } else if (selectedIndex.value !== null && selectedIndex.value < oldIndex && selectedIndex.value >= newIndex) {
795
- selectedIndex.value++;
796
- }
797
- sendBlocksToPreview();
798
- }
799
- }
800
- });
801
- const iframePreview = vue.ref();
802
- const iframeLoaded = vue.ref(false);
803
- const iframeHeight = vue.ref("800px");
804
- const iframeZoom = vue.ref("1");
805
- const isMobile = vue.ref(false);
806
- const previewMode = vue.ref(false);
807
- const zoomPercent = vue.ref(100);
808
- const zoomPercentOptions = [25, 50, 75, 100];
809
- const middlePanelEl = vue.ref(null);
810
- const currentMiddlePanelWidth = vue.ref(typeof window !== "undefined" ? window.innerWidth * 0.6 : 800);
811
- let middlePanelRo = null;
812
- const maxPossibleZoomPercent = vue.computed(() => {
813
- const availableWidth = currentMiddlePanelWidth.value - 60;
814
- if (isMobile.value) {
815
- return Math.min(100, Math.max(25, Math.floor(availableWidth / 375 * 100)));
816
- }
817
- return Math.min(100, Math.max(25, Math.floor(availableWidth / 1280 * 100)));
818
- });
819
- const visibleScreenPx = vue.computed(() => {
820
- const zoom = Number.parseFloat(iframeZoom.value);
821
- if (isMobile.value) return Math.round(375 * zoom);
822
- return Math.round(currentMiddlePanelWidth.value / zoom);
823
- });
824
- const zoomDisplayLabel = vue.computed(() => `${zoomPercent.value}%`);
825
- const zoomOptions = vue.computed(() => {
826
- const options = zoomPercentOptions.filter((p) => p <= maxPossibleZoomPercent.value).map((p) => ({ value: p, label: `${p}%` }));
827
- if (!options.some((o) => o.value === zoomPercent.value) && zoomPercent.value <= maxPossibleZoomPercent.value) {
828
- options.push({ value: zoomPercent.value, label: `${zoomPercent.value}%` });
829
- options.sort((a, b) => a.value - b.value);
830
- }
831
- if (!options.some((o) => o.value === maxPossibleZoomPercent.value) && maxPossibleZoomPercent.value > 0) {
832
- options.push({
833
- value: maxPossibleZoomPercent.value,
834
- label: `${maxPossibleZoomPercent.value}% מקסימום`
835
- });
836
- }
837
- return options;
838
- });
839
- function sendToPreview2(msg) {
840
- var _a, _b;
841
- (_b = (_a = iframePreview.value) == null ? void 0 : _a.contentWindow()) == null ? void 0 : _b.postMessage(JSON.parse(JSON.stringify(msg)), "*");
842
- }
843
- function sendBlocksToPreview() {
844
- sendToPreview2({ type: "BLOX_SET_BLOCKS", blocks: JSON.parse(JSON.stringify(blocks.value)) });
845
- }
846
- function applyEditorZoom() {
847
- if (previewMode.value) {
848
- iframeZoom.value = "1";
849
- return;
850
- }
851
- if (isMobile.value) {
852
- iframeZoom.value = (zoomPercent.value / 100).toString();
853
- } else {
854
- const availableWidth = currentMiddlePanelWidth.value - 60;
855
- const autoZoom = Math.min(zoomPercent.value / 100, availableWidth / 1280);
856
- iframeZoom.value = Math.max(0.1, autoZoom).toString();
857
- }
858
- }
859
- function calculateOptimalMobileZoom() {
860
- return Math.min(100, Math.max(25, Math.floor((currentMiddlePanelWidth.value - 40) / 375 * 95)));
861
- }
862
- function calculateOptimalDesktopZoom() {
863
- const available = currentMiddlePanelWidth.value - 60;
864
- return Math.min(100, Math.max(25, Math.floor(available / 1280 * 95)));
865
- }
866
- function setZoomPercent(percent) {
867
- zoomPercent.value = percent;
868
- applyEditorZoom();
869
- }
870
- function setIframeSize(view) {
871
- if (view === "desktop") {
872
- zoomPercent.value = calculateOptimalDesktopZoom();
873
- isMobile.value = false;
874
- document.body.classList.remove("editor-mobile-mode");
875
- document.body.classList.add("editor-desktop-mode");
876
- } else {
877
- zoomPercent.value = calculateOptimalMobileZoom();
878
- isMobile.value = true;
879
- document.body.classList.remove("editor-desktop-mode");
880
- document.body.classList.add("editor-mobile-mode");
881
- }
882
- applyEditorZoom();
883
- }
884
- function togglePreviewMode() {
885
- previewMode.value = !previewMode.value;
886
- if (previewMode.value) {
887
- document.body.classList.add("preview-mode");
888
- document.body.classList.remove("edit-mode");
889
- iframeZoom.value = "1";
890
- clearSelection();
891
- } else {
892
- document.body.classList.remove("preview-mode");
893
- document.body.classList.add("edit-mode");
894
- applyEditorZoom();
895
- }
896
- }
897
- const newBlock = vue.ref(false);
898
- const newBlockIndex = vue.ref(-1);
899
- const searchBlock = vue.ref("");
900
- const isAddingBlock = vue.ref(false);
901
- const addingBlockType = vue.ref(null);
902
- const filteredBlocks = vue.computed(() => {
903
- const q = searchBlock.value.toLowerCase();
904
- return Object.entries(registry.value).filter(([, info]) => info.label.toLowerCase().includes(q)).map(([type, info]) => ({ type, ...info })).sort((a, b) => a.label.localeCompare(b.label));
905
- });
906
- function defaultProps(type) {
907
- var _a, _b;
908
- const fields = ((_a = registry.value[type]) == null ? void 0 : _a.fields) ?? {};
909
- const defaults = {};
910
- for (const [key, field] of Object.entries(fields)) {
911
- const f = field;
912
- const val = ((_b = f == null ? void 0 : f._config) == null ? void 0 : _b.default) ?? (f == null ? void 0 : f.default);
913
- if (val !== void 0) defaults[key] = val;
914
- }
915
- return defaults;
916
- }
917
- async function addBlock(type) {
918
- addingBlockType.value = type;
919
- isAddingBlock.value = true;
920
- newBlock.value = false;
921
- try {
922
- const newBlockEl = {
923
- type,
924
- props: defaultProps(type)
925
- };
926
- const newKey = crypto.randomUUID();
927
- if (newBlockIndex.value > -1) {
928
- blocks.value.splice(newBlockIndex.value, 0, newBlockEl);
929
- blockKeys.value.splice(newBlockIndex.value, 0, newKey);
930
- selectedIndex.value = newBlockIndex.value;
931
- } else {
932
- blocks.value.push(newBlockEl);
933
- blockKeys.value.push(newKey);
934
- selectedIndex.value = blocks.value.length - 1;
935
- }
936
- newBlockIndex.value = -1;
937
- sendBlocksToPreview();
938
- sendToPreview2({ type: "BLOX_SELECT_BLOCK", index: selectedIndex.value });
939
- await vue.nextTick();
940
- if (draggableContainer.value) draggable.initDraggableContainer(draggableContainer.value);
941
- } finally {
942
- setTimeout(() => {
943
- addingBlockType.value = null;
944
- isAddingBlock.value = false;
945
- }, 600);
946
- }
947
- }
948
- function addNewBlock(index) {
949
- newBlockIndex.value = index + 1;
950
- newBlock.value = true;
951
- }
952
- async function removeBlock(index) {
953
- if (!await dialog.confirm("האם אתם בטוחים שברצונכם למחוק את הסקשן הזה?")) return;
954
- blocks.value.splice(index, 1);
955
- blockKeys.value.splice(index, 1);
956
- if (selectedIndex.value === index) {
957
- selectedIndex.value = null;
958
- sendToPreview2({ type: "BLOX_SELECT_BLOCK", index: null });
959
- } else if (selectedIndex.value !== null && selectedIndex.value > index) {
960
- selectedIndex.value--;
961
- }
962
- sendBlocksToPreview();
963
- await vue.nextTick();
964
- if (draggableContainer.value) draggable.initDraggableContainer(draggableContainer.value);
965
- }
966
- function onIframeMessage(event) {
967
- var _a;
968
- const msg = event.data;
969
- if (!((_a = msg == null ? void 0 : msg.type) == null ? void 0 : _a.startsWith("BLOX_"))) return;
970
- switch (msg.type) {
971
- case "BLOX_READY":
972
- registry.value = msg.registry;
973
- iframeLoaded.value = true;
974
- if (resolvedPage.value) {
975
- sendToPreview2({ type: "BLOX_INIT", page: resolvedPage.value, locale: currentLocale.value });
976
- }
977
- break;
978
- case "BLOX_BLOCK_CLICK":
979
- selectedIndex.value = msg.index;
980
- break;
981
- case "BLOX_BLOCK_HOVER":
982
- hoveredIndex.value = msg.index;
983
- break;
984
- case "BLOX_HEIGHT":
985
- iframeHeight.value = `${msg.height}px`;
986
- break;
987
- case "BLOX_ERROR":
988
- console.error("[Blox preview error]", msg.message);
989
- break;
990
- }
991
- }
992
- async function loadData() {
993
- webpages.value = await props.api.listPages(props.websiteId);
994
- }
995
- async function loadPage(pageId) {
996
- var _a;
997
- iframeLoaded.value = false;
998
- if (!pageId || pageId === "new") {
999
- const pages = await props.api.listPages(props.websiteId);
1000
- if (pages.length > 0) {
1001
- emit("navigate", pages[0].id);
1002
- return;
1003
- }
1004
- page.value = null;
1005
- resolvedPage.value = null;
1006
- blocks.value = [];
1007
- savedBlocks.value = [];
1008
- syncBlockKeys();
1009
- return;
1010
- }
1011
- try {
1012
- activeBinding.value = null;
1013
- bindingItems.value = [];
1014
- selectedBindParams.value = {};
1015
- const initial = await props.api.resolvePage(
1016
- props.websiteId,
1017
- pageId,
1018
- currentLocale.value || void 0
1019
- );
1020
- page.value = initial.page;
1021
- const binding = extractFirstDatastoreBinding(initial.page);
1022
- let resolved = initial;
1023
- if (binding) {
1024
- activeBinding.value = binding;
1025
- await loadBindingItems(binding);
1026
- if (Object.keys(selectedBindParams.value).length) {
1027
- resolved = await props.api.resolvePage(
1028
- props.websiteId,
1029
- pageId,
1030
- currentLocale.value || void 0,
1031
- selectedBindParams.value
1032
- );
1033
- }
1034
- }
1035
- resolvedPage.value = resolved;
1036
- blocks.value = ((_a = resolved.page.content) == null ? void 0 : _a.blocks) ?? [];
1037
- savedBlocks.value = JSON.parse(JSON.stringify(blocks.value));
1038
- syncBlockKeys();
1039
- selectedIndex.value = null;
1040
- if (Object.keys(registry.value).length > 0) {
1041
- sendToPreview2({ type: "BLOX_INIT", page: resolved, locale: currentLocale.value });
1042
- }
1043
- } catch (e) {
1044
- console.error(e);
1045
- }
1046
- }
1047
- const saveStatus = vue.ref("saved");
1048
- async function save() {
1049
- var _a;
1050
- if (!((_a = page.value) == null ? void 0 : _a.id) || isSaving.value) return;
1051
- isSaving.value = true;
1052
- saveStatus.value = "saving";
1053
- try {
1054
- const updated = await props.api.updatePage(
1055
- props.websiteId,
1056
- page.value.id,
1057
- { content: { blocks: blocks.value } },
1058
- currentLocale.value !== props.defaultLocale ? currentLocale.value : void 0
1059
- );
1060
- page.value = updated;
1061
- savedBlocks.value = JSON.parse(JSON.stringify(blocks.value));
1062
- saveStatus.value = "saved";
1063
- } catch {
1064
- saveStatus.value = "error";
1065
- } finally {
1066
- isSaving.value = false;
1067
- }
1068
- }
1069
- function discard() {
1070
- blocks.value = JSON.parse(JSON.stringify(savedBlocks.value));
1071
- syncBlockKeys();
1072
- selectedIndex.value = null;
1073
- sendBlocksToPreview();
1074
- }
1075
- async function publish() {
1076
- var _a;
1077
- if (!((_a = page.value) == null ? void 0 : _a.id)) return;
1078
- isSaving.value = true;
1079
- saveStatus.value = "saving";
1080
- try {
1081
- const updated = await props.api.updatePage(props.websiteId, page.value.id, {
1082
- content: { blocks: blocks.value },
1083
- status: "published"
1084
- });
1085
- page.value = updated;
1086
- savedBlocks.value = JSON.parse(JSON.stringify(blocks.value));
1087
- saveStatus.value = "saved";
1088
- } catch {
1089
- saveStatus.value = "error";
1090
- } finally {
1091
- isSaving.value = false;
1092
- }
1093
- }
1094
- async function unpublish() {
1095
- var _a;
1096
- if (!((_a = page.value) == null ? void 0 : _a.id)) return;
1097
- const updated = await props.api.updatePage(props.websiteId, page.value.id, {
1098
- status: "draft"
1099
- });
1100
- page.value = updated;
1101
- }
1102
- const isPublished = vue.computed(() => {
1103
- var _a;
1104
- return ((_a = page.value) == null ? void 0 : _a.status) === "published";
1105
- });
1106
- const saveLabel = vue.computed(() => {
1107
- if (saveStatus.value === "saving") return "שומר...";
1108
- if (saveStatus.value === "error") return "שגיאה";
1109
- if (isDirty.value) return "שמירה";
1110
- return "נשמר";
1111
- });
1112
- const defaultPageSchema = vue$1.schema({
1113
- title: vue$1.$.text({ label: "כותרת", default: "" }),
1114
- slug: vue$1.$.text({ label: "נתיב (slug)", placeholder: "my-page" }),
1115
- meta_title: vue$1.$.text({ label: "SEO כותרת" }),
1116
- meta_description: vue$1.$.text({ label: "SEO תיאור", multiline: true }),
1117
- og_image: vue$1.$.text({ label: "OG Image URL", placeholder: "https://" })
1118
- });
1119
- const pageCreateSchema = vue$1.schema({
1120
- title: vue$1.$.text({ label: "כותרת", default: "" }),
1121
- slug: vue$1.$.text({ label: "נתיב (slug)", placeholder: "my-page" })
1122
- });
1123
- async function pageSettings() {
1124
- if (!page.value) return;
1125
- const activeSchema = props.schema ?? defaultPageSchema;
1126
- await dialog.form({
1127
- title: page.value.title || "הגדרות עמוד",
1128
- schema: activeSchema,
1129
- modelValue: { ...page.value },
1130
- width: "l",
1131
- onSubmit: async (data) => {
1132
- var _a;
1133
- if (!((_a = page.value) == null ? void 0 : _a.id)) return;
1134
- const updated = await props.api.updatePage(props.websiteId, page.value.id, data);
1135
- page.value = updated;
1136
- await loadData();
1137
- },
1138
- onDelete: deletePage,
1139
- deleteText: "מחיקת עמוד"
1140
- });
1141
- }
1142
- async function deletePage() {
1143
- var _a;
1144
- if (!((_a = page.value) == null ? void 0 : _a.id)) return;
1145
- const ok = await dialog.confirm({ message: "מחיקת עמוד זה אינה ניתנת לביטול." });
1146
- if (!ok) return;
1147
- await props.api.deletePage(props.websiteId, page.value.id);
1148
- emit("navigate", void 0);
1149
- }
1150
- async function newWebpage() {
1151
- const result = await dialog.form({
1152
- title: "עמוד חדש",
1153
- schema: pageCreateSchema,
1154
- modelValue: { title: "", slug: "" },
1155
- submitText: "צור עמוד"
1156
- });
1157
- if (result.action !== "submit") return;
1158
- const saved = await props.api.createPage(props.websiteId, {
1159
- title: result.data.title,
1160
- slug: result.data.slug,
1161
- status: "draft"
1162
- });
1163
- await loadData();
1164
- emit("navigate", saved.id);
1165
- }
1166
- function keyboardShortcuts(event) {
1167
- const isEditing = document.activeElement instanceof HTMLInputElement || document.activeElement instanceof HTMLTextAreaElement;
1168
- if (event.key === "Escape" && selectedIndex.value !== null && !isEditing) {
1169
- clearSelection();
1170
- }
1171
- if ((event.ctrlKey || event.metaKey) && event.key === "s" && !isEditing) {
1172
- event.preventDefault();
1173
- save();
1174
- }
1175
- }
1176
- vue.onMounted(async () => {
1177
- if (menuState.isOpen.value && !menuState.isMobile.value) menuState.toggleMenu();
1178
- document.body.classList.add("edit-mode");
1179
- document.body.style.height = "100vh";
1180
- document.body.style.overflow = "hidden";
1181
- window.addEventListener("message", onIframeMessage);
1182
- document.addEventListener("keydown", keyboardShortcuts);
1183
- await vue.nextTick();
1184
- if (middlePanelEl.value) {
1185
- middlePanelRo = new ResizeObserver(() => {
1186
- var _a;
1187
- currentMiddlePanelWidth.value = ((_a = middlePanelEl.value) == null ? void 0 : _a.offsetWidth) ?? currentMiddlePanelWidth.value;
1188
- applyEditorZoom();
1189
- });
1190
- middlePanelRo.observe(middlePanelEl.value);
1191
- }
1192
- await loadData();
1193
- await loadPage(currentPageId.value);
1194
- setIframeSize("desktop");
1195
- await vue.nextTick();
1196
- if (draggableContainer.value) draggable.initDraggableContainer(draggableContainer.value);
1197
- });
1198
- vue.onUnmounted(() => {
1199
- window.removeEventListener("message", onIframeMessage);
1200
- document.removeEventListener("keydown", keyboardShortcuts);
1201
- middlePanelRo == null ? void 0 : middlePanelRo.disconnect();
1202
- middlePanelRo = null;
1203
- document.body.classList.remove(
1204
- "editor-mobile-mode",
1205
- "editor-desktop-mode",
1206
- "preview-mode",
1207
- "edit-mode"
1208
- );
1209
- document.body.style.height = "";
1210
- document.body.style.overflow = "";
1211
- });
1212
- vue.watch(
1213
- () => props.pageId,
1214
- (newId, oldId) => {
1215
- if (newId && newId !== oldId) loadPage(newId);
1216
- }
1217
- );
1218
- vue.watch(zoomPercent, () => {
1219
- applyEditorZoom();
1220
- });
1221
- vue.watch(currentMiddlePanelWidth, (newW, oldW) => {
1222
- if (Math.abs(newW - (oldW || 0)) < 10) return;
1223
- setTimeout(() => {
1224
- const optimal = isMobile.value ? calculateOptimalMobileZoom() : calculateOptimalDesktopZoom();
1225
- if (!previewMode.value && Math.abs(optimal - zoomPercent.value) > 5) {
1226
- zoomPercent.value = optimal;
1227
- applyEditorZoom();
1228
- }
1229
- }, 100);
1230
- });
1231
- vue.watch(
1232
- () => blocks.value.length,
1233
- async (newLen, oldLen) => {
1234
- if (newLen !== oldLen && draggableContainer.value) {
1235
- await vue.nextTick();
1236
- draggable.initDraggableContainer(draggableContainer.value);
1237
- }
1238
- }
1239
- );
1240
- const debouncedSendBlocks = vue$1.useDebounceFn(sendBlocksToPreview, 150);
1241
- return (_ctx, _cache) => {
1242
- const _directive_tooltip = vue.resolveDirective("tooltip");
1243
- return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
1244
- vue.createVNode(vue.unref(vue$1.Card), {
1245
- frame: "",
1246
- class: "h-100p p-0 radius-1 page-builder overflow-hidden"
1247
- }, {
1248
- default: vue.withCtx(() => [
1249
- vue.createVNode(vue.unref(vue$1.Modal), {
1250
- visible: newBlock.value,
1251
- "onUpdate:visible": _cache[1] || (_cache[1] = ($event) => newBlock.value = $event),
1252
- width: "800px",
1253
- title: "הוספת בלוק חדש"
1254
- }, {
1255
- default: vue.withCtx(() => [
1256
- vue.createVNode(vue.unref(vue$1.TextInput), {
1257
- modelValue: searchBlock.value,
1258
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchBlock.value = $event),
1259
- placeholder: "חיפוש בלוק",
1260
- icon: "search"
1261
- }, null, 8, ["modelValue"]),
1262
- vue.createElementVNode("div", _hoisted_2, [
1263
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(filteredBlocks.value, (block) => {
1264
- return vue.openBlock(), vue.createElementBlock("div", {
1265
- key: block.type,
1266
- class: vue.normalizeClass(["block-preview bg-gray-light rounded p-05 txt-center hover user-select-none relative", {
1267
- "opacity-5 pointer-events-none": addingBlockType.value === block.type,
1268
- "hover-disabled": isAddingBlock.value && addingBlockType.value !== block.type
1269
- }]),
1270
- onClick: ($event) => addBlock(block.type)
1271
- }, [
1272
- addingBlockType.value === block.type ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_4, [
1273
- vue.createElementVNode("div", _hoisted_5, [
1274
- vue.createVNode(vue.unref(vue$1.Icon), {
1275
- icon: "hourglass_empty",
1276
- class: "spin txt16"
1277
- }),
1278
- vue.createElementVNode("p", _hoisted_6, " מוסיף " + vue.toDisplayString(block.label) + "... ", 1)
1279
- ])
1280
- ])) : vue.createCommentVNode("", true),
1281
- vue.createVNode(vue.unref(vue$1.Icon), {
1282
- icon: block.icon ?? "check_box_outline_blank",
1283
- size: "2",
1284
- weight: "200",
1285
- class: "block mx-auto"
1286
- }, null, 8, ["icon"]),
1287
- vue.createElementVNode("p", _hoisted_7, vue.toDisplayString(block.label), 1)
1288
- ], 10, _hoisted_3);
1289
- }), 128))
1290
- ])
1291
- ]),
1292
- _: 1
1293
- }, 8, ["visible"]),
1294
- vue.createElementVNode("div", _hoisted_8, [
1295
- vue.createVNode(vue.unref(vue$1.TopBar), { class: "flex border-bottom space-between px-05" }, {
1296
- default: vue.withCtx(() => {
1297
- var _a;
1298
- return [
1299
- vue.createElementVNode("div", _hoisted_9, [
1300
- vue.unref(webpages) ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Dropdown), {
1301
- key: 0,
1302
- value: ((_a = page.value) == null ? void 0 : _a.title) ?? "עמוד",
1303
- "icon-end": "keyboard_arrow_down"
1304
- }, {
1305
- default: vue.withCtx(() => [
1306
- vue.createVNode(vue.unref(vue$1.TextInput), {
1307
- modelValue: vue.unref(webpages).searchTerm,
1308
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vue.unref(webpages).searchTerm = $event),
1309
- placeholder: "עמוד",
1310
- icon: "search",
1311
- class: "p-1"
1312
- }, null, 8, ["modelValue"]),
1313
- vue.createElementVNode("div", _hoisted_10, [
1314
- vue.createElementVNode("div", _hoisted_11, [
1315
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(webpages), (wp) => {
1316
- return vue.openBlock(), vue.createBlock(vue.unref(vue$1.ListItem), {
1317
- key: wp.id,
1318
- title: wp.title,
1319
- subtitle: `${wp.slug}`,
1320
- thin: "",
1321
- class: "txt12 smallerUrl",
1322
- onClick: ($event) => emit("navigate", wp.id)
1323
- }, null, 8, ["title", "subtitle", "onClick"]);
1324
- }), 128)),
1325
- vue.createElementVNode("div", _hoisted_12, [
1326
- vue.createVNode(vue.unref(vue$1.Btn), {
1327
- thin: "",
1328
- value: "עמוד חדש",
1329
- icon: "add",
1330
- onClick: newWebpage
1331
- })
1332
- ])
1333
- ])
1334
- ])
1335
- ]),
1336
- _: 1
1337
- }, 8, ["value"])) : vue.createCommentVNode("", true),
1338
- vue.withDirectives(vue.createVNode(vue.unref(vue$1.Btn), {
1339
- flat: "",
1340
- thin: "",
1341
- size: "small",
1342
- icon: "tune",
1343
- onClick: pageSettings
1344
- }, null, 512), [
1345
- [_directive_tooltip, "הגדרות עמוד"]
1346
- ]),
1347
- activeBinding.value ? vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_13, [
1348
- vue.createVNode(vue.unref(vue$1.Dropdown), {
1349
- value: selectedBindParams.value[activeBinding.value.bindBy] || "…",
1350
- "icon-start": "data_object",
1351
- "icon-end": "keyboard_arrow_down",
1352
- thin: "",
1353
- loading: isLoadingBindItems.value
1354
- }, {
1355
- default: vue.withCtx(() => [
1356
- vue.createElementVNode("div", _hoisted_14, [
1357
- vue.createElementVNode("div", _hoisted_15, [
1358
- vue.createVNode(vue.unref(vue$1.TextInput), {
1359
- modelValue: vue.unref(bindingItems).searchTerm,
1360
- "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vue.unref(bindingItems).searchTerm = $event),
1361
- autofocus: "",
1362
- placeholder: "חיפוש...",
1363
- icon: "search"
1364
- }, null, 8, ["modelValue"])
1365
- ]),
1366
- vue.createElementVNode("div", _hoisted_16, [
1367
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(bindingItems), (item) => {
1368
- return vue.openBlock(), vue.createBlock(vue.unref(vue$1.ListItem), {
1369
- key: String(item.id),
1370
- title: bindItemLabel(item),
1371
- thin: "",
1372
- class: "txt12",
1373
- active: selectedBindParams.value[activeBinding.value.bindBy] === String(item[activeBinding.value.bindBy] ?? ""),
1374
- onClick: ($event) => selectBindItem(item)
1375
- }, null, 8, ["title", "active", "onClick"]);
1376
- }), 128))
1377
- ])
1378
- ])
1379
- ]),
1380
- _: 1
1381
- }, 8, ["value", "loading"])
1382
- ])), [
1383
- [_directive_tooltip, `בחר פריט לתצוגה מקדימה`]
1384
- ]) : vue.createCommentVNode("", true),
1385
- vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", _hoisted_17, [
1386
- localeList.value.length > 0 ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Dropdown), {
1387
- key: 0,
1388
- value: currentLocale.value.toUpperCase() || "??",
1389
- "icon-end": "keyboard_arrow_down",
1390
- thin: "",
1391
- disabled: isSwitchingLocale.value || isUpdatingLocales.value
1392
- }, {
1393
- default: vue.withCtx(() => [
1394
- vue.createElementVNode("div", _hoisted_18, [
1395
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(localeList.value, (locale2) => {
1396
- return vue.openBlock(), vue.createElementBlock("div", {
1397
- key: locale2,
1398
- class: vue.normalizeClass(["flex px-025", { "color-primary bg-gray-30": locale2 === currentLocale.value }])
1399
- }, [
1400
- vue.createVNode(vue.unref(vue$1.Btn), {
1401
- class: "flex-grow-1 txt-start txt12 px-05",
1402
- flat: "",
1403
- value: locale2.toUpperCase(),
1404
- "align-txt": "start",
1405
- ripple: false,
1406
- onClick: ($event) => switchLocale(locale2)
1407
- }, null, 8, ["value", "onClick"]),
1408
- locale2 === props.defaultLocale ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_19, [
1409
- _cache[13] || (_cache[13] = vue.createElementVNode("span", { class: "absolute -start-3-5 white-space bold" }, "ברירת מחדל", -1)),
1410
- vue.createVNode(vue.unref(vue$1.Icon), {
1411
- icon: "star",
1412
- size: "1",
1413
- class: "txt-10",
1414
- fill: ""
1415
- })
1416
- ])) : props.updateLocales ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Btn), {
1417
- key: 1,
1418
- icon: "star_border",
1419
- title: "קביעת ברירת מחדל",
1420
- thin: "",
1421
- size: "small",
1422
- class: "opacity-4 shrink-0 ms-auto bg-white color-black",
1423
- onClick: vue.withModifiers(($event) => setDefaultLocale(locale2), ["stop"])
1424
- }, null, 8, ["onClick"])) : vue.createCommentVNode("", true),
1425
- props.updateLocales && localeList.value.length > 1 ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Btn), {
1426
- key: 2,
1427
- title: "הסרת שפה",
1428
- icon: "delete",
1429
- thin: "",
1430
- class: "opacity-4 shrink-0 bg-white color-black",
1431
- onClick: vue.withModifiers(($event) => removeLocale(locale2), ["stop"])
1432
- }, null, 8, ["onClick"])) : vue.createCommentVNode("", true)
1433
- ], 2);
1434
- }), 128)),
1435
- props.updateLocales ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_20, [
1436
- vue.createVNode(vue.unref(vue$1.TextInput), {
1437
- modelValue: newLocaleInput.value,
1438
- "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => newLocaleInput.value = $event),
1439
- placeholder: "he / en / fr",
1440
- class: "m-0",
1441
- onKeydown: vue.withKeys(addLocale, ["enter"])
1442
- }, null, 8, ["modelValue"]),
1443
- vue.createVNode(vue.unref(vue$1.Btn), {
1444
- icon: "add",
1445
- thin: "",
1446
- disabled: !newLocaleInput.value.trim() || isUpdatingLocales.value,
1447
- onClick: addLocale
1448
- }, null, 8, ["disabled"])
1449
- ])) : vue.createCommentVNode("", true)
1450
- ])
1451
- ]),
1452
- _: 1
1453
- }, 8, ["value", "disabled"])) : vue.createCommentVNode("", true)
1454
- ])), [
1455
- [_directive_tooltip, "שפה"]
1456
- ])
1457
- ]),
1458
- vue.createElementVNode("div", _hoisted_21, [
1459
- vue.createVNode(vue.unref(vue$1.Btn), {
1460
- icon: "desktop_windows",
1461
- class: vue.normalizeClass({ "bg-gray-light color-primary": isMobile.value }),
1462
- onClick: _cache[5] || (_cache[5] = ($event) => setIframeSize("desktop"))
1463
- }, null, 8, ["class"]),
1464
- vue.createVNode(vue.unref(vue$1.Btn), {
1465
- icon: "smartphone",
1466
- class: vue.normalizeClass({ "bg-gray-light color-primary": !isMobile.value }),
1467
- onClick: _cache[6] || (_cache[6] = ($event) => setIframeSize("mobile"))
1468
- }, null, 8, ["class"]),
1469
- vue.createVNode(vue.unref(vue$1.Dropdown), {
1470
- value: zoomDisplayLabel.value,
1471
- "icon-end": "keyboard_arrow_down",
1472
- thin: ""
1473
- }, {
1474
- default: vue.withCtx(() => [
1475
- vue.createElementVNode("div", _hoisted_22, [
1476
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(zoomOptions.value, (opt) => {
1477
- return vue.openBlock(), vue.createBlock(vue.unref(vue$1.Btn), {
1478
- key: opt.value,
1479
- class: "w-100 txt12",
1480
- thin: "",
1481
- flat: "",
1482
- value: opt.label,
1483
- onClick: ($event) => setZoomPercent(opt.value)
1484
- }, null, 8, ["value", "onClick"]);
1485
- }), 128))
1486
- ])
1487
- ]),
1488
- _: 1
1489
- }, 8, ["value"]),
1490
- vue.createElementVNode("p", _hoisted_23, vue.toDisplayString(visibleScreenPx.value) + "px ", 1),
1491
- vue.createVNode(vue.unref(vue$1.Btn), {
1492
- icon: "play_arrow",
1493
- class: vue.normalizeClass({ "bg-gray-light color-primary": !previewMode.value }),
1494
- onClick: togglePreviewMode
1495
- }, null, 8, ["class"])
1496
- ]),
1497
- vue.createElementVNode("div", _hoisted_24, [
1498
- isDirty.value ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Btn), {
1499
- key: 0,
1500
- flat: "",
1501
- thin: "",
1502
- value: "ביטול",
1503
- class: "txt12 opacity-7",
1504
- onClick: discard
1505
- })) : vue.createCommentVNode("", true),
1506
- vue.createVNode(vue.unref(vue$1.Btn), {
1507
- disabled: isSaving.value || !isDirty.value && saveStatus.value === "saved",
1508
- class: vue.normalizeClass([{
1509
- "bg-blue": isDirty.value,
1510
- "bg-gray": !isDirty.value && saveStatus.value === "saved",
1511
- "bg-red": saveStatus.value === "error"
1512
- }, "ps-1-5 pe-1-5 txt12 radius-1 px-1 min-w-70px"]),
1513
- value: saveLabel.value,
1514
- onClick: save
1515
- }, null, 8, ["disabled", "class", "value"]),
1516
- vue.createVNode(vue.unref(vue$1.Dropdown), {
1517
- icon: "keyboard_arrow_down",
1518
- thin: "",
1519
- class: "ms-075 -me-2-5 pt-025 relative z-2"
1520
- }, {
1521
- default: vue.withCtx(() => [
1522
- vue.createVNode(vue.unref(vue$1.Btn), {
1523
- class: "px-1 txt12",
1524
- thin: "",
1525
- flat: "",
1526
- value: "ביטול פרסום",
1527
- onClick: unpublish
1528
- })
1529
- ]),
1530
- _: 1
1531
- }),
1532
- vue.createVNode(vue.unref(vue$1.Btn), {
1533
- class: vue.normalizeClass([{ "bg-green": isPublished.value, "bg-gray": !isPublished.value }, "ps-2-5 pe-1-5 txt12 radius-1"]),
1534
- value: "פרסום",
1535
- onClick: publish
1536
- }, null, 8, ["class"])
1537
- ])
1538
- ];
1539
- }),
1540
- _: 1
1541
- }),
1542
- vue.createVNode(vue.unref(vue$1.Resizable), {
1543
- horizontal: "",
1544
- class: "h-100"
1545
- }, {
1546
- default: vue.withCtx(() => [
1547
- vue.createVNode(vue.unref(vue$1.Panel), {
1548
- "default-size": 260,
1549
- min: 100,
1550
- max: 260,
1551
- collapsed: previewMode.value
1552
- }, {
1553
- default: vue.withCtx(() => [
1554
- vue.createElementVNode("div", _hoisted_25, [
1555
- vue.createElementVNode("div", _hoisted_26, [
1556
- _cache[14] || (_cache[14] = vue.createElementVNode("p", { class: "m-0 pe-05 txt14" }, " מבנה העמוד ", -1)),
1557
- vue.createVNode(vue.unref(vue$1.Btn), {
1558
- thin: "",
1559
- icon: "add",
1560
- class: "txt12",
1561
- onClick: _cache[7] || (_cache[7] = ($event) => newBlock.value = !newBlock.value)
1562
- })
1563
- ]),
1564
- !blocks.value.length && !isAddingBlock.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_27, [
1565
- (vue.openBlock(), vue.createElementBlock("svg", _hoisted_28, _cache[15] || (_cache[15] = [
1566
- vue.createElementVNode("path", {
1567
- d: "M7 4l3-3 1 5M10 1S5 8 13 19",
1568
- stroke: "#000",
1569
- "stroke-width": "1",
1570
- fill: "none",
1571
- "stroke-linecap": "round",
1572
- "stroke-linejoin": "round"
1573
- }, null, -1)
1574
- ]))),
1575
- _cache[16] || (_cache[16] = vue.createElementVNode("p", null, [
1576
- vue.createTextVNode("לחצו כאן להוספת"),
1577
- vue.createElementVNode("br"),
1578
- vue.createElementVNode("b", null, "בלוק חדש")
1579
- ], -1))
1580
- ])) : vue.createCommentVNode("", true),
1581
- vue.createElementVNode("div", {
1582
- ref_key: "draggableContainer",
1583
- ref: draggableContainer,
1584
- outline: "",
1585
- class: "h-100 overflow"
1586
- }, [
1587
- (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(blocks.value, (block, i) => {
1588
- return vue.openBlock(), vue.createElementBlock("div", {
1589
- key: blockKeys.value[i],
1590
- "data-draggable-id": blockKeys.value[i],
1591
- class: "draggable-item"
1592
- }, [
1593
- vue.createElementVNode("div", {
1594
- class: "my-025 flex gap-025 overflow-hidden px-025",
1595
- onMouseenter: ($event) => hoverBlock(i),
1596
- onMouseleave: _cache[8] || (_cache[8] = ($event) => hoverBlock(null)),
1597
- onFocusin: ($event) => hoverBlock(i),
1598
- onFocusout: _cache[9] || (_cache[9] = ($event) => hoverBlock(null))
1599
- }, [
1600
- vue.createElementVNode("div", {
1601
- class: vue.normalizeClass(["sectionAccordionBlock rounded border-none hover flex-grow p-025 my-025 transition flex", {
1602
- "highlightID bg-gray-light": hoveredIndex.value === i && selectedIndex.value !== i,
1603
- "bg-primary color-white": selectedIndex.value === i
1604
- }]),
1605
- onClick: ($event) => selectBlock(i)
1606
- }, [
1607
- vue.createVNode(vue.unref(vue$1.Icon), {
1608
- icon: registryIcon(block.type),
1609
- class: "mx-05"
1610
- }, null, 8, ["icon"]),
1611
- vue.createElementVNode("p", _hoisted_32, vue.toDisplayString(registryLabel(block.type)), 1),
1612
- vue.createElementVNode("p", {
1613
- class: "ellipsis-1 m-0 txt-12 txt-start opacity-5",
1614
- innerHTML: block.props.title || block.props.heading || block.props.name || ""
1615
- }, null, 8, _hoisted_33),
1616
- vue.createVNode(vue.unref(vue$1.Icon), {
1617
- name: "drag_indicator",
1618
- class: "reorderHover color-gray opacity-0 ms-auto transition drag-handle"
1619
- })
1620
- ], 10, _hoisted_31)
1621
- ], 40, _hoisted_30),
1622
- vue.createElementVNode("div", _hoisted_34, [
1623
- vue.createVNode(vue.unref(vue$1.Icon), {
1624
- round: "",
1625
- icon: "add",
1626
- size: "0.5",
1627
- class: "z-1 relative transition opacity-0 hover bg-blue color-white",
1628
- onClick: ($event) => addNewBlock(i)
1629
- }, null, 8, ["onClick"])
1630
- ])
1631
- ], 8, _hoisted_29);
1632
- }), 128))
1633
- ], 512)
1634
- ])
1635
- ]),
1636
- _: 1
1637
- }, 8, ["collapsed"]),
1638
- vue.createVNode(vue.unref(vue$1.Panel), {
1639
- flex: "",
1640
- min: 400
1641
- }, {
1642
- default: vue.withCtx(() => [
1643
- vue.createElementVNode("div", {
1644
- ref_key: "middlePanelEl",
1645
- ref: middlePanelEl,
1646
- class: vue.normalizeClass(["h-100 overflow-hidden txt-center bg-gray-80 flex-center relative", { "overflow-auto": isMobile.value }]),
1647
- style: { "user-select": "none" }
1648
- }, [
1649
- vue.createVNode(vue.unref(vue$1.IframeVue), {
1650
- ref_key: "iframePreview",
1651
- ref: iframePreview,
1652
- class: vue.normalizeClass(["site-iframe h-100", { "mobile-view": isMobile.value }]),
1653
- src: previewUrl.value,
1654
- style: vue.normalizeStyle({
1655
- width: isMobile.value ? "375px" : "100%",
1656
- height: iframeHeight.value,
1657
- zoom: iframeZoom.value,
1658
- transformOrigin: "top left"
1659
- })
1660
- }, null, 8, ["src", "class", "style"])
1661
- ], 2)
1662
- ]),
1663
- _: 1
1664
- }),
1665
- vue.createVNode(vue.unref(vue$1.Panel), {
1666
- "default-size": 280,
1667
- min: 180,
1668
- max: 320,
1669
- collapsed: previewMode.value,
1670
- handle: false
1671
- }, {
1672
- default: vue.withCtx(() => [
1673
- vue.createElementVNode("div", _hoisted_35, [
1674
- selectedBlock.value !== null ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_36, [
1675
- vue.createElementVNode("div", _hoisted_37, [
1676
- vue.createVNode(vue.unref(vue$1.Icon), {
1677
- icon: registryIcon(selectedBlock.value.type),
1678
- class: "txt-gray mx-05"
1679
- }, null, 8, ["icon"]),
1680
- vue.createElementVNode("p", _hoisted_38, vue.toDisplayString(registryLabel(selectedBlock.value.type)), 1),
1681
- vue.createElementVNode("div", _hoisted_39, [
1682
- vue.withDirectives(vue.createVNode(vue.unref(vue$1.Btn), {
1683
- title: "סגור עורך (ESC)",
1684
- icon: "close",
1685
- flat: "",
1686
- thin: "",
1687
- class: "txt10 opacity-7",
1688
- onClick: clearSelection
1689
- }, null, 512), [
1690
- [_directive_tooltip, "סגור עורך (ESC)"]
1691
- ])
1692
- ])
1693
- ]),
1694
- vue.createElementVNode("div", {
1695
- class: "h-100p overflow pt-1 scrollbar-gutter-both",
1696
- onClick: _cache[12] || (_cache[12] = vue.withModifiers(() => {
1697
- }, ["stop"]))
1698
- }, [
1699
- vue.createElementVNode("div", _hoisted_40, [
1700
- blockSchema(selectedBlock.value.type) ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.FormFlow), {
1701
- key: 0,
1702
- modelValue: selectedBlock.value.props,
1703
- "onUpdate:modelValue": [
1704
- _cache[10] || (_cache[10] = ($event) => selectedBlock.value.props = $event),
1705
- vue.unref(debouncedSendBlocks)
1706
- ],
1707
- schema: blockSchema(selectedBlock.value.type)
1708
- }, null, 8, ["modelValue", "schema", "onUpdate:modelValue"])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_41, [
1709
- vue.createVNode(vue.unref(vue$1.Icon), {
1710
- icon: "data_object",
1711
- size: "3",
1712
- weight: "200",
1713
- class: "block"
1714
- }),
1715
- _cache[17] || (_cache[17] = vue.createElementVNode("p", { class: "txt-12 mt-05" }, [
1716
- vue.createTextVNode(" תוכן הבלוק הזה מגיע ממקור נתונים"),
1717
- vue.createElementVNode("br"),
1718
- vue.createTextVNode("ואינו ניתן לעריכה כאן. ")
1719
- ], -1))
1720
- ]))
1721
- ]),
1722
- vue.createElementVNode("div", _hoisted_42, [
1723
- selectedIndex.value !== null ? (vue.openBlock(), vue.createBlock(vue.unref(vue$1.Btn), {
1724
- key: 0,
1725
- icon: "delete",
1726
- class: "txt10 opacity-7 color-red m-1 w-a",
1727
- flat: "",
1728
- thin: "",
1729
- value: "הסרת מקטע",
1730
- onClick: _cache[11] || (_cache[11] = ($event) => removeBlock(selectedIndex.value))
1731
- })) : vue.createCommentVNode("", true)
1732
- ])
1733
- ])
1734
- ])) : vue.createCommentVNode("", true),
1735
- vue.createElementVNode("div", _hoisted_43, [
1736
- vue.createVNode(vue.unref(vue$1.Icon), {
1737
- class: "txt-center block",
1738
- icon: "bolt",
1739
- weight: "200",
1740
- size: "10"
1741
- }),
1742
- _cache[18] || (_cache[18] = vue.createElementVNode("p", { class: "txt-center" }, " לחצו על מקטע כדי לערוך ", -1))
1743
- ])
1744
- ])
1745
- ]),
1746
- _: 1
1747
- }, 8, ["collapsed"])
1748
- ]),
1749
- _: 1
1750
- })
1751
- ]),
1752
- vue.createElementVNode("div", _hoisted_44, [
1753
- vue.createVNode(vue.unref(vue$1.Icon), {
1754
- size: 10,
1755
- weight: 200,
1756
- icon: "desktop_windows"
1757
- }),
1758
- _cache[19] || (_cache[19] = vue.createElementVNode("p", null, "המסך קטן מדי לעורך הזה. נסו להקטין זום או להשתמש במסך גדול יותר.", -1))
1759
- ])
1760
- ]),
1761
- _: 1
1762
- })
1763
- ]);
1764
- };
1765
- }
1766
- });
1767
509
  exports.BLOX_CONFIG_KEY = BLOX_CONFIG_KEY;
1768
510
  exports.BLOX_LOCALE_STRATEGY_KEY = BLOX_LOCALE_STRATEGY_KEY;
1769
511
  exports.BloxInstance = BloxInstance;
1770
- exports.CmsPageView = _sfc_main$3;
1771
- exports.PageDesigner = _sfc_main;
512
+ exports.CmsPageView = _sfc_main$2;
1772
513
  exports.PageRenderer = PageRenderer;
1773
- exports.PreviewApp = _sfc_main$1;
514
+ exports.PreviewApp = _sfc_main;
1774
515
  exports.PreviewRenderer = PreviewRenderer;
1775
516
  exports.configureApi = configureApi;
1776
517
  exports.createBlox = createBlox;