From 9bd558d07cd73812d598b529202c70c5b0f53785 Mon Sep 17 00:00:00 2001 From: Maxwell Morais Date: Sun, 29 Dec 2024 23:05:14 -0300 Subject: [PATCH 01/48] Use block dataKey instead of block key for define for variable name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To construct a UI like below ![image](https://github.com/user-attachments/assets/2ddc5046-6c1f-42c3-8e2b-9eae0b1b3b86) We often need to use `repeater` block, internally the repeater block define a key based on the blockKey, what create codes like ```jinja {%- if not key_u7ps3awh6.price.unitary -%} {%- if key_u7ps3awh6.price.monthly -%}

R$ {{ key_u7ps3awh6.price.monthly.real }}{{ key_u7ps3awh6.price.monthly.dec }}/mês

{%- endif -%} {%- if key_u7ps3awh6.price.yearly -%}

{%- if key_u7ps3awh6.price.monthly %} - {%- endif -%}R$ {{ key_u7ps3awh6.price.yearly.real }}{{ key_u7ps3awh6.price.yearly.dec }}/ano

{%- endif -%} {%- else -%}

R$ {{ key_u7ps3awh6.price.unitary.real }}{{ key_u7ps3awh6.price.unitary.dec }}/und

{%- endif -%} ``` This code works because internally, the builder defined a variable `key_{block.get('blockId')}`, but it makes impractical to deal with that in the long term! Reasons are: 1 - We dont have any reference on the UI that tell me that my block have the id `u7ps3awh6` 2 - The block ID is internally controlled by the framework, what means, if we duplicate the block, the logic breaks and again we dont have hints about the new variable name! My proposal is to make use of the `dataKey` of the `repeater` block, to generate a more organic key like below ![image](https://github.com/user-attachments/assets/c8b03707-0127-48b8-bcc2-d32adff79811) ```jinja {%- if not key_products.price.unitary -%} {%- if key_products.price.monthly -%}

R$ {{ key_products.price.monthly.real }}{{ key_products.price.monthly.dec }}/mês

{%- endif -%} {%- if key_products.price.yearly -%}

{%- if key_products.price.monthly %} - {%- endif -%}R$ {{ key_products.price.yearly.real }}{{ key_products.price.yearly.dec }}/ano

{%- endif -%} {%- else -%}

R$ {{ key_products.price.unitary.real }}{{ key_products.price.unitary.dec }}/und

{%- endif -%} ``` --- builder/builder/doctype/builder_page/builder_page.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/builder/doctype/builder_page/builder_page.py b/builder/builder/doctype/builder_page/builder_page.py index 5df167241..248b7b062 100644 --- a/builder/builder/doctype/builder_page/builder_page.py +++ b/builder/builder/doctype/builder_page/builder_page.py @@ -418,7 +418,7 @@ def get_tag(block, soup, data_key=None): if data_key: _key = f"{data_key}.{_key}" - item_key = f"key_{block.get('blockId')}" + item_key = f"key_{_key.replace('.', '__')}" tag.append(f"{{% for {item_key} in {_key} %}}") tag.append(get_tag(block.get("children")[0], soup, item_key)) tag.append("{% endfor %}") From ee1612c075a00ea962e620608a783475d3064f79 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 2 Jan 2025 16:06:04 +0530 Subject: [PATCH 02/48] fix: Style in DM closes: https://github.com/frappe/builder/issues/280 --- frontend/src/components/AppsMenu.vue | 2 +- frontend/src/components/Settings/GlobalGeneral.vue | 3 ++- frontend/src/components/Settings/PageGeneral.vue | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/AppsMenu.vue b/frontend/src/components/AppsMenu.vue index 3cd429d28..ca75a4e89 100644 --- a/frontend/src/components/AppsMenu.vue +++ b/frontend/src/components/AppsMenu.vue @@ -7,7 +7,7 @@ @click.prevent="togglePopover()">
- Apps + Apps
diff --git a/frontend/src/components/Settings/GlobalGeneral.vue b/frontend/src/components/Settings/GlobalGeneral.vue index d4398e295..c88910619 100644 --- a/frontend/src/components/Settings/GlobalGeneral.vue +++ b/frontend/src/components/Settings/GlobalGeneral.vue @@ -16,7 +16,8 @@
Favicon
-
+
Site Favicon Favicon
-
+
{ + // wait for the page to load + targetWindow?.location.reload(); + }, 50); } }, savePage() { From d3783fd8fe7bbd6a151f7cf71f657c502ca93f05 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sat, 4 Jan 2025 20:59:52 +0530 Subject: [PATCH 04/48] fix: Style cleanup --- frontend/src/components/BackgroundHandler.vue | 10 +++------- .../src/components/BlockPositionHandler.vue | 13 ++++++------ frontend/src/components/BlockProperties.vue | 6 +++--- .../src/components/BorderRadiusHandler.vue | 2 +- frontend/src/components/BuilderAssets.vue | 10 +++++----- frontend/src/components/BuilderCanvas.vue | 4 ++-- frontend/src/components/BuilderLeftPanel.vue | 15 +------------- frontend/src/components/BuilderToolbar.vue | 2 +- .../src/components/CollapsibleSection.vue | 5 ++--- frontend/src/components/ContextMenu.vue | 8 ++++---- .../src/components/Controls/ColorPicker.vue | 5 +---- .../src/components/Controls/InputLabel.vue | 3 +-- .../src/components/Controls/OptionToggle.vue | 2 +- frontend/src/components/ImageUploadInput.vue | 11 +++------- frontend/src/components/ObjectEditor.vue | 20 ++++++------------- frontend/src/components/PanelResizer.vue | 2 +- frontend/src/components/PlacementControl.vue | 14 ++++++------- frontend/src/pages/PageBuilder.vue | 6 ++---- frontend/src/pages/PageBuilderDashboard.vue | 2 +- frontend/src/pages/PagePreview.vue | 14 ++++++------- 20 files changed, 58 insertions(+), 96 deletions(-) diff --git a/frontend/src/components/BackgroundHandler.vue b/frontend/src/components/BackgroundHandler.vue index 8729b1eb6..07652d822 100644 --- a/frontend/src/components/BackgroundHandler.vue +++ b/frontend/src/components/BackgroundHandler.vue @@ -16,7 +16,7 @@ class="absolute left-2 top-[6px] z-10 h-4 w-4 rounded shadow-sm" @click="togglePopover" :class="{ - 'bg-gray-400 dark:bg-zinc-600': !backgroundURL, + 'bg-surface-gray-4': !backgroundURL, }" :style="{ backgroundImage: backgroundURL ? `url(${backgroundURL})` : '', @@ -31,7 +31,7 @@ diff --git a/frontend/src/components/BlockPositionHandler.vue b/frontend/src/components/BlockPositionHandler.vue index 97c900d32..3124c63e9 100644 --- a/frontend/src/components/BlockPositionHandler.vue +++ b/frontend/src/components/BlockPositionHandler.vue @@ -28,17 +28,16 @@ @update:modelValue="(value: string) => blockController.setStyle('left', value)" />
+ class="grid-col-3 grid h-16 w-16 grid-rows-3 gap-1 self-center justify-self-center rounded bg-surface-gray-2 p-2">
+ class="col-span-3 row-start-1 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-4">
+ class="col-span-3 row-start-3 h-2 w-[2px] self-center justify-self-center rounded bg-surface-gray-4">
+
+ class="col-span-1 col-start-1 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-4">
-
+ class="col-span-1 col-start-3 row-start-2 h-[2px] w-2 self-center justify-self-center rounded bg-surface-gray-4">
-

Select a block to edit properties

+

Select a block to edit properties

From 259bf720e00ce74973ed8f1f90aec82d40530c87 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 14 Jan 2025 00:42:07 +0530 Subject: [PATCH 12/48] fix: Add help option in main menu --- frontend/src/components/MainMenu.vue | 11 +++++++---- frontend/src/main.ts | 1 + frontend/src/pages/PageBuilderDashboard.vue | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/MainMenu.vue b/frontend/src/components/MainMenu.vue index 259919a4b..f3a7af583 100644 --- a/frontend/src/components/MainMenu.vue +++ b/frontend/src/components/MainMenu.vue @@ -28,10 +28,14 @@ icon: isDark ? 'sun' : 'moon', }, { label: 'Settings', onClick: () => $emit('showSettings'), icon: 'settings' }, + { - label: 'Apps', - component: AppsMenu, - icon: 'grid', + label: 'Help', + onClick: () => { + // @ts-ignore + window.open('https://t.me/frappebuilder'); + }, + icon: 'info', }, ], }, @@ -66,7 +70,6 @@ diff --git a/frontend/src/utils/useComponentStore.ts b/frontend/src/utils/useComponentStore.ts index 3921ac424..785c17834 100644 --- a/frontend/src/utils/useComponentStore.ts +++ b/frontend/src/utils/useComponentStore.ts @@ -15,6 +15,7 @@ const useComponentStore = defineStore("componentStore", { componentMap: >new Map(), componentDocMap: >new Map(), fetchingComponent: new Set(), + selectedComponent: null as string | null, }), actions: { async editComponent(block?: Block | null, componentName?: string) { From 71064bb2f31af99970613e0b8a210035ea7f50c9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 20 Jan 2025 12:52:39 +0530 Subject: [PATCH 18/48] fix: Distance of padding handlers 2 (thickness of border) + 2 (half of the height of handler) + 6 (distance from the edge) = 10px --- frontend/src/components/PaddingHandler.vue | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/PaddingHandler.vue b/frontend/src/components/PaddingHandler.vue index 2c50991d7..aba565dff 100644 --- a/frontend/src/components/PaddingHandler.vue +++ b/frontend/src/components/PaddingHandler.vue @@ -192,7 +192,7 @@ const topHandle = computed(() => { return { width: width, height: height, - bottom: `clamp(-20px, calc(-6px * ${canvasProps.scale}), -8px)`, + bottom: `clamp(-20px, calc(-10px * ${canvasProps.scale}), -6px)`, left: `calc(50% - ${width / 2}px)`, }; }); @@ -203,7 +203,7 @@ const bottomHandle = computed(() => { return { width: width, height: height, - top: `clamp(-20px, calc(-6px * ${canvasProps.scale}), -8px)`, + top: `clamp(-20px, calc(-10px * ${canvasProps.scale}), -6px)`, left: `calc(50% - ${width / 2}px)`, }; }); @@ -214,7 +214,7 @@ const leftHandle = computed(() => { return { width: width, height: height, - right: `clamp(-20px, calc(-6px * ${canvasProps.scale}), -8px)`, + right: `clamp(-20px, calc(-10px * ${canvasProps.scale}), -6px)`, top: `calc(50% - ${height / 2}px)`, }; }); @@ -225,7 +225,7 @@ const rightHandle = computed(() => { return { width: width, height: height, - left: `clamp(-20px, calc(-6px * ${canvasProps.scale}), -8px)`, + left: `clamp(-20px, calc(-10px * ${canvasProps.scale}), -6px)`, top: `calc(50% - ${height / 2}px)`, }; }); From c8d26aa89d2766d356039c0ab653bc411d346c28 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 20 Jan 2025 13:13:45 +0530 Subject: [PATCH 19/48] fix: update develop version --- builder/__init__.py | 2 +- builder/hooks.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/builder/__init__.py b/builder/__init__.py index 6c7936ab3..eb436f1c7 100644 --- a/builder/__init__.py +++ b/builder/__init__.py @@ -1 +1 @@ -__version__ = "1.0.0-dev" +__version__ = "2.0.0-dev" diff --git a/builder/hooks.py b/builder/hooks.py index 3f18dac7c..c8882e454 100644 --- a/builder/hooks.py +++ b/builder/hooks.py @@ -9,8 +9,6 @@ app_email = "suraj@frappe.io" app_license = "GNU Affero General Public License v3.0" -develop_version = "1.x.x-develop" - # Includes in # ------------------ # include js, css files in header of desk.html From 5102e26946d34a504900527af61079c6d7bb1fb1 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 20 Jan 2025 15:34:51 +0530 Subject: [PATCH 20/48] fix(text): Do not remove editable mode while selecting colors --- frontend/src/components/TextBlock.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TextBlock.vue b/frontend/src/components/TextBlock.vue index 68b579bb1..1f10043e8 100644 --- a/frontend/src/components/TextBlock.vue +++ b/frontend/src/components/TextBlock.vue @@ -119,8 +119,10 @@ } " v-on-click-outside=" - () => { - store.editableBlock = null; + (e) => { + if ((e.target as HTMLElement).closest('.canvas-container')) { + store.editableBlock = null; + } } " @mouseup="selectionTriggered = false" From d080e8b55778c3c8d0dde0486d0db36a5541f287 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 20 Jan 2025 19:33:19 +0530 Subject: [PATCH 21/48] fix: Show padding/margin handlers for link block as well --- frontend/src/components/BlockEditor.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/BlockEditor.vue b/frontend/src/components/BlockEditor.vue index 3ed099f4d..a109614b1 100644 --- a/frontend/src/components/BlockEditor.vue +++ b/frontend/src/components/BlockEditor.vue @@ -96,7 +96,7 @@ const showPaddingHandler = computed(() => { !props.editable && !blockController.multipleBlocksSelected() && !props.block.isSVG() && - !props.block.isText() + (!props.block.isText() || (props.block.isLink() && props.block.hasChildren())) ); }); @@ -107,7 +107,7 @@ const showMarginHandler = computed(() => { !resizing.value && !props.editable && !blockController.multipleBlocksSelected() && - !props.block.isText() + (!props.block.isText() || (props.block.isLink() && props.block.hasChildren())) ); }); From 437d09c7a0057ec69ec9920814545ca9db77f882 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 21 Jan 2025 14:43:59 +0530 Subject: [PATCH 22/48] fix: Do not show chevron for hidden elements --- frontend/src/components/BlockLayers.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/BlockLayers.vue b/frontend/src/components/BlockLayers.vue index da27a8218..4939e9251 100644 --- a/frontend/src/components/BlockLayers.vue +++ b/frontend/src/components/BlockLayers.vue @@ -24,7 +24,7 @@ Date: Tue, 21 Jan 2025 15:27:51 +0530 Subject: [PATCH 23/48] fix: Duplicate scripts while duplicating a page --- builder/api.py | 20 ++++++++++++++++++++ frontend/src/store.ts | 40 +++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/builder/api.py b/builder/api.py index 3593dea1f..a04bab424 100644 --- a/builder/api.py +++ b/builder/api.py @@ -223,3 +223,23 @@ def update_page_folder(pages: list[str], folder_name: str) -> None: frappe.throw("You do not have permission to update page folder.") for page in pages: frappe.db.set_value("Builder Page", page, "project_folder", folder_name, update_modified=False) + + +@frappe.whitelist() +def duplicate_page(page_name: str): + if not frappe.has_permission("Builder Page", ptype="write"): + frappe.throw("You do not have permission to duplicate a page.") + page = frappe.get_doc("Builder Page", page_name) + new_page = frappe.copy_doc(page) + del new_page.page_name + new_page.route = None + client_scripts = page.client_scripts + new_page.client_scripts = [] + for script in client_scripts: + builder_script = frappe.get_doc("Builder Client Script", script.builder_script) + new_script = frappe.copy_doc(builder_script) + new_script.name = f"{builder_script.name}-copy" + new_script.insert(ignore_permissions=True) + new_page.append("client_scripts", {"builder_script": new_script.name}) + new_page.insert() + return new_page diff --git a/frontend/src/store.ts b/frontend/src/store.ts index cfd31e3a7..ada19b592 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -4,7 +4,7 @@ import { posthog } from "@/telemetry"; import { BuilderSettings } from "@/types/Builder/BuilderSettings"; import useComponentStore from "@/utils/useComponentStore"; import { UseRefHistoryReturn, useStorage } from "@vueuse/core"; -import { createDocumentResource } from "frappe-ui"; +import { createDocumentResource, createResource } from "frappe-ui"; import { defineStore } from "pinia"; import { nextTick } from "vue"; import { toast } from "vue-sonner"; @@ -276,27 +276,25 @@ const useStore = defineStore("store", { } }, async duplicatePage(page: BuilderPage) { - const webPageResource = await createDocumentResource({ - doctype: "Builder Page", - name: page.page_name, - auto: true, - }); - await webPageResource.get.promise; - - const pageCopy = webPageResource.doc as BuilderPage; - pageCopy.page_title = `${pageCopy.page_title} (Copy)`; - delete pageCopy.page_name; - delete pageCopy.route; - toast.promise(webPages.insert.submit(pageCopy), { - loading: "Duplicating page", - success: async (page: BuilderPage) => { - // load page and refresh - router.push({ name: "builder", params: { pageId: page.page_name } }).then(() => { - router.go(0); - }); - return "Page duplicated"; + toast.promise( + createResource({ + url: "builder.api.duplicate_page", + method: "POST", + params: { + page_name: page.name, + }, + }).fetch(), + { + loading: "Duplicating page", + success: async (page: BuilderPage) => { + // load page and refresh + router.push({ name: "builder", params: { pageId: page.page_name } }).then(() => { + router.go(0); + }); + return "Page duplicated"; + }, }, - }); + ); }, deletePage: async (page: BuilderPage) => { const confirmed = await confirm( From a39faad22c70aac5c0f494e793a43424d8cfe6f2 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 22 Jan 2025 17:17:30 +0530 Subject: [PATCH 24/48] fix: Purple bordered handlers for blocks extended with component --- frontend/src/components/BlockEditor.vue | 2 +- frontend/src/components/BorderRadiusHandler.vue | 5 ++++- frontend/src/components/BoxResizer.vue | 3 +++ frontend/src/components/BuilderAssets.vue | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/BlockEditor.vue b/frontend/src/components/BlockEditor.vue index a109614b1..76424007a 100644 --- a/frontend/src/components/BlockEditor.vue +++ b/frontend/src/components/BlockEditor.vue @@ -162,7 +162,7 @@ const getStyleClasses = computed(() => { if (movable.value && !props.block.isRoot()) { classes.push("cursor-grab"); } - if (Boolean(props.block.extendedFromComponent)) { + if (props.block.isExtendedFromComponent()) { classes.push("ring-purple-400"); } else { classes.push("ring-blue-400"); diff --git a/frontend/src/components/BorderRadiusHandler.vue b/frontend/src/components/BorderRadiusHandler.vue index 77154df23..eb53ff2b1 100644 --- a/frontend/src/components/BorderRadiusHandler.vue +++ b/frontend/src/components/BorderRadiusHandler.vue @@ -2,7 +2,10 @@
diff --git a/frontend/src/components/BuilderAssets.vue b/frontend/src/components/BuilderAssets.vue index bcc9590c5..7927f297a 100644 --- a/frontend/src/components/BuilderAssets.vue +++ b/frontend/src/components/BuilderAssets.vue @@ -25,7 +25,7 @@ store.fragmentData.fragmentId === component.name || componentStore.selectedComponent === component.component_id, }"> -
+

{{ component.component_name }} From 0da533d7b3cda99866bd79e70d416db3a2ec7ffc Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 23 Jan 2025 11:38:32 +0530 Subject: [PATCH 25/48] fix: Context menu for block with blockIds starting with number --- frontend/src/utils/useBlockEventHandlers.ts | 2 +- frontend/src/utils/useComponentStore.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/src/utils/useBlockEventHandlers.ts b/frontend/src/utils/useBlockEventHandlers.ts index d1f85e0ed..c5cd269d4 100644 --- a/frontend/src/utils/useBlockEventHandlers.ts +++ b/frontend/src/utils/useBlockEventHandlers.ts @@ -85,7 +85,7 @@ export function useBlockEventHandlers() { selectBlock(e); nextTick(() => { document - .querySelector(`.editor[data-block-id=${blockId}]`) + .querySelector(`.editor[data-block-id="${blockId}"]`) ?.dispatchEvent(new MouseEvent("contextmenu", e)); }); } diff --git a/frontend/src/utils/useComponentStore.ts b/frontend/src/utils/useComponentStore.ts index 785c17834..3765fd605 100644 --- a/frontend/src/utils/useComponentStore.ts +++ b/frontend/src/utils/useComponentStore.ts @@ -36,8 +36,7 @@ const useComponentStore = defineStore("componentStore", { block: getBlockObject(block), }) .then((data: BuilderComponent) => { - this.componentDocMap.set(data.name, data); - this.componentMap.set(data.name, markRaw(getBlockInstance(data.block))); + this.setComponentMap(data); toast.success("Component saved!"); }); }, From 68ea0a9b82793ef95b2543dbdc5f477528115fae Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 23 Jan 2025 12:41:22 +0530 Subject: [PATCH 26/48] fix(detach-component): Only detach first level of component --- frontend/src/utils/helpers.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/utils/helpers.ts b/frontend/src/utils/helpers.ts index 406c77b11..6878a178d 100644 --- a/frontend/src/utils/helpers.ts +++ b/frontend/src/utils/helpers.ts @@ -282,8 +282,16 @@ function isCtrlOrCmd(e: KeyboardEvent | MouseEvent) { return e.ctrlKey || e.metaKey; } -const detachBlockFromComponent = (block: Block) => { +const detachBlockFromComponent = (block: Block, componentId: null | string) => { + if (!componentId) { + componentId = block.extendedFromComponent as string; + } const blockCopy = getBlockCopy(block, true); + + if (block.extendedFromComponent && block.extendedFromComponent != componentId) { + return blockCopy; + } + const component = block.referenceComponent; blockCopy.element = block?.getElement(); blockCopy.attributes = block.getAttributes(); @@ -309,7 +317,7 @@ const detachBlockFromComponent = (block: Block) => { delete blockCopy.extendedFromComponent; delete blockCopy.isChildOfComponent; delete blockCopy.referenceBlockId; - blockCopy.children = blockCopy.children.map(detachBlockFromComponent); + blockCopy.children = blockCopy.children.map((block) => detachBlockFromComponent(block, componentId)); return getBlockInstance(blockCopy); }; From 7f556a7b743f5fb6b31c34b1032dba75b7fe0374 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 23 Jan 2025 12:48:07 +0530 Subject: [PATCH 27/48] fix: Simplify component creation --- .../src/components/Modals/NewComponent.vue | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/Modals/NewComponent.vue b/frontend/src/components/Modals/NewComponent.vue index 7e33abe36..44d4a1f60 100644 --- a/frontend/src/components/Modals/NewComponent.vue +++ b/frontend/src/components/Modals/NewComponent.vue @@ -47,24 +47,21 @@ const componentProperties = ref({ isGlobalComponent: 0, }); -const createComponentHandler = (close: () => void) => { +const createComponentHandler = async (context: { close: () => void }) => { const blockCopy = getBlockCopy(props.block, true); blockCopy.removeStyle("left"); blockCopy.removeStyle("top"); blockCopy.removeStyle("position"); - webComponent.insert - .submit({ - block: getBlockString(blockCopy), - component_name: componentProperties.value.componentName, - for_web_page: componentProperties.value.isGlobalComponent ? null : store.selectedPage, - }) - .then(async (data: BuilderComponent) => { - posthog.capture("builder_component_created", { component_name: data.name }); - componentStore.setComponentMap(data); - const block = store.activeCanvas?.findBlock(props.block.blockId); - if (!block) return; - block.extendFromComponent(data.name); - }); - close(); + const componentData = (await webComponent.insert.submit({ + block: getBlockString(blockCopy), + component_name: componentProperties.value.componentName, + for_web_page: componentProperties.value.isGlobalComponent ? null : store.selectedPage, + })) as BuilderComponent; + posthog.capture("builder_component_created", { component_name: componentData.name }); + componentStore.setComponentMap(componentData); + const block = store.activeCanvas?.findBlock(props.block.blockId); + if (!block) return; + block.extendFromComponent(componentData.name); + context.close(); }; From 0c72d04a11db385d44a41e66ee9be31adf80b685 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 23 Jan 2025 14:52:40 +0530 Subject: [PATCH 28/48] fix: Retain overriden values while creating nested component --- frontend/src/utils/block.ts | 33 ++++++++++++++++--------- frontend/src/utils/useComponentStore.ts | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/frontend/src/utils/block.ts b/frontend/src/utils/block.ts index dfd341d96..1ded025d2 100644 --- a/frontend/src/utils/block.ts +++ b/frontend/src/utils/block.ts @@ -47,6 +47,7 @@ class Block implements BlockOptions { visibilityCondition?: string; elementBeforeConversion?: string; parentBlock: Block | null; + // @ts-expect-error referenceComponent: Block | null; customAttributes: BlockAttributeMap; constructor(options: BlockOptions) { @@ -62,16 +63,24 @@ class Block implements BlockOptions { if (this.extendedFromComponent) { componentStore.loadComponent(this.extendedFromComponent); } - this.referenceComponent = computed(() => { - if (this.extendedFromComponent) { - return markRaw(componentStore.getComponentBlock(this.extendedFromComponent as string)) || null; - } else if (this.isChildOfComponent) { - const componentBlock = componentStore.getComponentBlock(this.isChildOfComponent as string); - const componentBlockInstance = findBlock(this.referenceBlockId as string, [componentBlock]); - return componentBlockInstance ? markRaw(componentBlockInstance) : null; - } - return null; - }) as unknown as Block | null; + // ToDo: Investigate this + // This fixes a weird case where referenceComponent used to return null even if the extendedFromComponent was set mostyl because of the reactive transformation of block during block instance creation. + // still not entirely clear about this weird behavior + Object.defineProperty(this, "referenceComponent", { + value: computed(() => { + if (this.extendedFromComponent) { + return markRaw(componentStore.getComponentBlock(this.extendedFromComponent as string)) || null; + } else if (this.isChildOfComponent) { + const componentBlock = componentStore.getComponentBlock(this.isChildOfComponent as string); + const componentBlockInstance = findBlock(this.referenceBlockId as string, [componentBlock]); + return componentBlockInstance ? markRaw(componentBlockInstance) : null; + } + return null; + }), + writable: false, + enumerable: false, + configurable: true, + }); this.dataKey = options.dataKey || null; @@ -657,6 +666,8 @@ class Block implements BlockOptions { } extendFromComponent(componentName: string) { this.extendedFromComponent = componentName; + // @ts-expect-error + this.referenceComponent?.effect?.run(); const component = this.referenceComponent as Block; if (component) { extendWithComponent(this, componentName, component.children); @@ -895,7 +906,7 @@ function extendWithComponent( componentChildren: Block[], resetOverrides: boolean = true, ) { - resetBlock(block, true, resetOverrides); + resetBlock(block, false, resetOverrides); block.children?.forEach((child, index) => { child.isChildOfComponent = extendedFromComponent; let componentChild = componentChildren[index]; diff --git a/frontend/src/utils/useComponentStore.ts b/frontend/src/utils/useComponentStore.ts index 785c17834..c7177b6d8 100644 --- a/frontend/src/utils/useComponentStore.ts +++ b/frontend/src/utils/useComponentStore.ts @@ -138,7 +138,7 @@ const useComponentStore = defineStore("componentStore", { }); }, getComponentName(componentId: string) { - let componentObj = webComponent.getRow(componentId); + let componentObj = this.componentDocMap.get(componentId); if (!componentObj) { return componentId; } From 89704bf387b99022ee585016d4b4523524c1b1ef Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 23 Jan 2025 15:48:10 +0530 Subject: [PATCH 29/48] fix: Reset component properties on save --- frontend/src/components/Modals/NewComponent.vue | 2 ++ frontend/src/utils/block.ts | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Modals/NewComponent.vue b/frontend/src/components/Modals/NewComponent.vue index 44d4a1f60..8805983fa 100644 --- a/frontend/src/components/Modals/NewComponent.vue +++ b/frontend/src/components/Modals/NewComponent.vue @@ -62,6 +62,8 @@ const createComponentHandler = async (context: { close: () => void }) => { const block = store.activeCanvas?.findBlock(props.block.blockId); if (!block) return; block.extendFromComponent(componentData.name); + componentProperties.value.componentName = ""; + componentProperties.value.isGlobalComponent = 0; context.close(); }; diff --git a/frontend/src/utils/block.ts b/frontend/src/utils/block.ts index 1ded025d2..f74bccb43 100644 --- a/frontend/src/utils/block.ts +++ b/frontend/src/utils/block.ts @@ -63,9 +63,8 @@ class Block implements BlockOptions { if (this.extendedFromComponent) { componentStore.loadComponent(this.extendedFromComponent); } - // ToDo: Investigate this - // This fixes a weird case where referenceComponent used to return null even if the extendedFromComponent was set mostyl because of the reactive transformation of block during block instance creation. - // still not entirely clear about this weird behavior + // TODO: Investigate this + // This fixes a weird case where referenceComponent used to return null even if the extendedFromComponent was set mostyl because of the reactive transformation of block during block instance creation. Still not entirely clear about this weird behavior Object.defineProperty(this, "referenceComponent", { value: computed(() => { if (this.extendedFromComponent) { From b8767b92e2200bfb0ab98313357d59d35eae4929 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 24 Jan 2025 12:24:37 +0530 Subject: [PATCH 30/48] fix: Handle invalid dataURL or InvalidCharacterException --- frontend/src/utils/block.ts | 12 +++++++----- frontend/src/utils/helpers.ts | 21 +++++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/frontend/src/utils/block.ts b/frontend/src/utils/block.ts index f74bccb43..941e9cc27 100644 --- a/frontend/src/utils/block.ts +++ b/frontend/src/utils/block.ts @@ -120,12 +120,14 @@ class Block implements BlockOptions { // if src is base64, convert it to a file const src = this.getAttribute("src") as string; if (src && src.startsWith("data:image")) { - this.setAttribute("src", ""); - options.src = ""; const file = dataURLtoFile(src, "image.png"); - uploadImage(file, true).then((obj) => { - this.setAttribute("src", obj.fileURL); - }); + if (file) { + this.setAttribute("src", ""); + options.src = ""; + uploadImage(file, true).then((obj) => { + this.setAttribute("src", obj.fileURL); + }); + } } } } diff --git a/frontend/src/utils/helpers.ts b/frontend/src/utils/helpers.ts index 6878a178d..098d25886 100644 --- a/frontend/src/utils/helpers.ts +++ b/frontend/src/utils/helpers.ts @@ -391,15 +391,20 @@ async function uploadImage(file: File, silent = false) { } function dataURLtoFile(dataurl: string, filename: string) { - let arr = dataurl.split(","), - mime = arr[0].match(/:(.*?);/)?.[1], - bstr = atob(arr[1]), - n = bstr.length, - u8arr = new Uint8Array(n); - while (n--) { - u8arr[n] = bstr.charCodeAt(n); + try { + let arr = dataurl.split(","), + mime = arr[0].match(/:(.*?);/)?.[1], + bstr = atob(arr[1]), + n = bstr.length, + u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + return new File([u8arr], filename, { type: mime }); + } catch (error) { + console.error(`Failed to convert dataURL ${dataurl} to file.`); + return null; } - return new File([u8arr], filename, { type: mime }); } declare global { From e6c0e248abcb4882909d3e77d78f6871becf1f8d Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sun, 26 Jan 2025 09:36:18 +0530 Subject: [PATCH 31/48] refactor: Simplify BlockProperties.vue by moving each section code to separate files --- frontend/src/components/BlockProperties.vue | 1240 +---------------- .../CustomAttributesSection.ts | 26 + .../BlockPropertySections/DataKeySection.ts | 55 + .../DimenstionSection.ts | 78 ++ .../ImageOptionsSection.ts | 87 ++ .../BlockPropertySections/LayoutSection.ts | 63 + .../BlockPropertySections/LinkSection.ts | 82 ++ .../BlockPropertySections/OptionsSection.ts | 239 ++++ .../BlockPropertySections/PositionSection.ts | 26 + .../BlockPropertySections/RawStyleSection.ts | 38 + .../BlockPropertySections/SpacingSection.ts | 45 + .../BlockPropertySections/StyleSection.ts | 182 +++ .../TypographySection.ts | 203 +++ .../VideoOptionsSection.ts | 130 ++ 14 files changed, 1281 insertions(+), 1213 deletions(-) create mode 100644 frontend/src/components/BlockPropertySections/CustomAttributesSection.ts create mode 100644 frontend/src/components/BlockPropertySections/DataKeySection.ts create mode 100644 frontend/src/components/BlockPropertySections/DimenstionSection.ts create mode 100644 frontend/src/components/BlockPropertySections/ImageOptionsSection.ts create mode 100644 frontend/src/components/BlockPropertySections/LayoutSection.ts create mode 100644 frontend/src/components/BlockPropertySections/LinkSection.ts create mode 100644 frontend/src/components/BlockPropertySections/OptionsSection.ts create mode 100644 frontend/src/components/BlockPropertySections/PositionSection.ts create mode 100644 frontend/src/components/BlockPropertySections/RawStyleSection.ts create mode 100644 frontend/src/components/BlockPropertySections/SpacingSection.ts create mode 100644 frontend/src/components/BlockPropertySections/StyleSection.ts create mode 100644 frontend/src/components/BlockPropertySections/TypographySection.ts create mode 100644 frontend/src/components/BlockPropertySections/VideoOptionsSection.ts diff --git a/frontend/src/components/BlockProperties.vue b/frontend/src/components/BlockProperties.vue index 0973002a4..61fd828aa 100644 --- a/frontend/src/components/BlockProperties.vue +++ b/frontend/src/components/BlockProperties.vue @@ -32,30 +32,24 @@

diff --git a/frontend/src/components/BlockPropertySections/CustomAttributesSection.ts b/frontend/src/components/BlockPropertySections/CustomAttributesSection.ts new file mode 100644 index 000000000..d1744f1b2 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/CustomAttributesSection.ts @@ -0,0 +1,26 @@ +import ObjectEditor from "@/components/ObjectEditor.vue"; +import blockController from "@/utils/blockController"; +import { computed } from "vue"; + +const customAttributesSectionProperties = [ + { + component: ObjectEditor, + getProps: () => { + return { + obj: blockController.getCustomAttributes() as Record, + }; + }, + searchKeyWords: "Attributes, CustomAttributes, Custom Attributes, HTML Attributes, Data Attributes", + events: { + "update:obj": (obj: Record) => blockController.setCustomAttributes(obj), + }, + }, +]; + +export default { + name: "HTML Attributes", + properties: customAttributesSectionProperties, + collapsed: computed(() => { + return Object.keys(blockController.getCustomAttributes()).length === 0; + }), +}; diff --git a/frontend/src/components/BlockPropertySections/DataKeySection.ts b/frontend/src/components/BlockPropertySections/DataKeySection.ts new file mode 100644 index 000000000..56b98e17c --- /dev/null +++ b/frontend/src/components/BlockPropertySections/DataKeySection.ts @@ -0,0 +1,55 @@ +import InlineInput from "@/components/Controls/InlineInput.vue"; +import blockController from "@/utils/blockController"; +import { computed } from "vue"; + +const dataKeySectionProperties = [ + { + component: InlineInput, + getProps: () => { + return { + label: "Key", + modelValue: blockController.getDataKey("key"), + }; + }, + searchKeyWords: "Key, DataKey, Data Key", + events: { + "update:modelValue": (val: string) => blockController.setDataKey("key", val), + }, + }, + { + component: InlineInput, + condition: () => !blockController.isRepeater(), + getProps: () => { + return { + label: "Type", + modelValue: blockController.getDataKey("type"), + }; + }, + searchKeyWords: "Type, DataType, Data Type", + events: { + "update:modelValue": (val: string) => blockController.setDataKey("type", val), + }, + }, + { + component: InlineInput, + condition: () => !blockController.isRepeater(), + getProps: () => { + return { + label: "Property", + modelValue: blockController.getDataKey("property"), + }; + }, + searchKeyWords: "Property, DataProperty, Data Property", + events: { + "update:modelValue": (val: string) => blockController.setDataKey("property", val), + }, + }, +]; + +export default { + name: "Data Key", + properties: dataKeySectionProperties, + collapsed: computed(() => { + return !blockController.getDataKey("key") && !blockController.isRepeater(); + }), +}; diff --git a/frontend/src/components/BlockPropertySections/DimenstionSection.ts b/frontend/src/components/BlockPropertySections/DimenstionSection.ts new file mode 100644 index 000000000..5a0e2ff2c --- /dev/null +++ b/frontend/src/components/BlockPropertySections/DimenstionSection.ts @@ -0,0 +1,78 @@ +import DimensionInput from "@/components/DimensionInput.vue"; + +const dimensionSectionProperties = [ + { + component: DimensionInput, + searchKeyWords: "Width", + getProps: () => { + return { + label: "Width", + property: "width", + }; + }, + }, + { + component: DimensionInput, + searchKeyWords: "Min, Width, MinWidth, Min Width", + getProps: () => { + return { + label: "Min Width", + property: "minWidth", + }; + }, + }, + { + component: DimensionInput, + searchKeyWords: "Max, Width, MaxWidth, Max Width", + getProps: () => { + return { + label: "Max Width", + property: "maxWidth", + }; + }, + }, + { + component: "hr", + getProps: () => { + return { + class: "border-outline-gray-1", + }; + }, + searchKeyWords: "", + }, + { + component: DimensionInput, + searchKeyWords: "Height", + getProps: () => { + return { + label: "Height", + property: "height", + }; + }, + }, + { + component: DimensionInput, + searchKeyWords: "Min, Height, MinHeight, Min Height", + getProps: () => { + return { + label: "Min Height", + property: "minHeight", + }; + }, + }, + { + component: DimensionInput, + searchKeyWords: "Max, Height, MaxHeight, Max Height", + getProps: () => { + return { + label: "Max Height", + property: "maxHeight", + }; + }, + }, +]; + +export default { + name: "Dimension", + properties: dimensionSectionProperties, +}; diff --git a/frontend/src/components/BlockPropertySections/ImageOptionsSection.ts b/frontend/src/components/BlockPropertySections/ImageOptionsSection.ts new file mode 100644 index 000000000..6f5c62255 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/ImageOptionsSection.ts @@ -0,0 +1,87 @@ +import InlineInput from "@/components/Controls/InlineInput.vue"; +import ImageUploadInput from "@/components/ImageUploadInput.vue"; +import blockController from "@/utils/blockController"; +import { Button, createResource } from "frappe-ui"; +import { toast } from "vue-sonner"; + +const imageOptionsSectionProperties = [ + { + component: ImageUploadInput, + getProps: () => { + return { + label: "Image URL", + imageURL: blockController.getAttribute("src"), + imageFit: blockController.getStyle("objectFit"), + }; + }, + events: { + "update:imageURL": (val: string) => blockController.setAttribute("src", val), + "update:imageFit": (val: StyleValue) => blockController.setStyle("objectFit", val), + }, + searchKeyWords: "Image, URL, Src, Fit, ObjectFit, Object Fit, Fill, Contain, Cover", + }, + { + component: Button, + getProps: () => { + return { + label: "Convert to WebP", + class: "text-base self-end", + }; + }, + innerText: "Convert to WebP", + searchKeyWords: "Convert, webp, Convert to webp, image, src, url", + events: { + click: () => { + const block = blockController.getSelectedBlocks()[0]; + const convertToWebP = createResource({ + url: "/api/method/builder.api.convert_to_webp", + params: { + image_url: block.getAttribute("src"), + }, + }); + toast.promise( + convertToWebP.fetch().then((res: string) => { + block.setAttribute("src", res); + }), + { + loading: "Converting...", + success: () => "Image converted to WebP", + error: () => "Failed to convert image to WebP", + }, + ); + }, + }, + condition: () => { + if (!blockController.isImage()) { + return false; + } + if ( + [".jpg", ".jpeg", ".png"].some((ext) => + ((blockController.getAttribute("src") as string) || ("" as string)).toLowerCase().endsWith(ext), + ) + ) { + return true; + } + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Alt Text", + modelValue: blockController.getAttribute("alt"), + }; + }, + searchKeyWords: "Alt, Text, AltText, Alternate Text", + events: { + "update:modelValue": (val: string) => blockController.setAttribute("alt", val), + }, + condition: () => blockController.isImage(), + }, +]; + +export default { + name: "Image Options", + properties: imageOptionsSectionProperties, + condition: () => blockController.isImage(), +}; diff --git a/frontend/src/components/BlockPropertySections/LayoutSection.ts b/frontend/src/components/BlockPropertySections/LayoutSection.ts new file mode 100644 index 000000000..b2674bcfa --- /dev/null +++ b/frontend/src/components/BlockPropertySections/LayoutSection.ts @@ -0,0 +1,63 @@ +import BlockFlexLayoutHandler from "@/components/BlockFlexLayoutHandler.vue"; +import BlockGridLayoutHandler from "@/components/BlockGridLayoutHandler.vue"; +import OptionToggle from "@/components/Controls/OptionToggle.vue"; +import blockController from "@/utils/blockController"; + +const layoutSectionProperties = [ + { + component: OptionToggle, + getProps: () => { + return { + label: "Type", + options: [ + { + label: "Stack", + value: "flex", + }, + { + label: "Grid", + value: "grid", + }, + ], + modelValue: blockController.getStyle("display"), + }; + }, + searchKeyWords: "Layout, Display, Flex, Grid, Flexbox, Flex Box, FlexBox", + events: { + "update:modelValue": (val: StyleValue) => { + blockController.setStyle("display", val); + if (val === "grid") { + if (!blockController.getStyle("gridTemplateColumns")) { + blockController.setStyle("gridTemplateColumns", "repeat(2, minmax(200px, 1fr))"); + } + if (!blockController.getStyle("gap")) { + blockController.setStyle("gap", "10px"); + } + if (blockController.getStyle("height")) { + if (blockController.getSelectedBlocks()[0].hasChildren()) { + blockController.setStyle("height", null); + } + } + } + }, + }, + }, + { + component: BlockGridLayoutHandler, + getProps: () => {}, + searchKeyWords: + "Layout, Grid, GridTemplate, Grid Template, GridGap, Grid Gap, GridRow, Grid Row, GridColumn, Grid Column", + }, + { + component: BlockFlexLayoutHandler, + getProps: () => {}, + searchKeyWords: + "Layout, Flex, Flexbox, Flex Box, FlexBox, Justify, Space Between, Flex Grow, Flex Shrink, Flex Basis, Align Items, Align Content, Align Self, Flex Direction, Flex Wrap, Flex Flow, Flex Grow, Flex Shrink, Flex Basis, Gap", + }, +]; + +export default { + name: "Layout", + properties: layoutSectionProperties, + condition: () => !blockController.multipleBlocksSelected(), +}; diff --git a/frontend/src/components/BlockPropertySections/LinkSection.ts b/frontend/src/components/BlockPropertySections/LinkSection.ts new file mode 100644 index 000000000..393f54c51 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/LinkSection.ts @@ -0,0 +1,82 @@ +import InlineInput from "@/components/Controls/InlineInput.vue"; +import { webPages } from "@/data/webPage"; +import { BuilderPage } from "@/types/Builder/BuilderPage"; +import blockController from "@/utils/blockController"; +import { computed, nextTick } from "vue"; + +const linkSectionProperties = [ + { + component: InlineInput, + getProps: () => { + return { + label: "Link To", + type: "autocomplete", + showInputAsOption: true, + options: (webPages.data || []) + .filter((page: BuilderPage) => { + return page.route && !page.dynamic_route; + }) + .map((page: BuilderPage) => { + return { + value: `/${page.route}`, + label: `/${page.route}`, + }; + }), + modelValue: blockController.getAttribute("href"), + }; + }, + searchKeyWords: "Link, Href, URL", + events: { + "update:modelValue": async (val: string) => { + if (val && !blockController.isLink()) { + blockController.convertToLink(); + await nextTick(); + await nextTick(); + } + if (!val && blockController.isLink()) { + blockController.unsetLink(); + } else { + blockController.setAttribute("href", val); + } + }, + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Opens in", + type: "select", + options: [ + { + value: "_self", + label: "Same Tab", + }, + { + value: "_blank", + label: "New Tab", + }, + ], + modelValue: blockController.getAttribute("target") || "_self", + }; + }, + searchKeyWords: "Link, Target, Opens in, OpensIn, Opens In, New Tab", + events: { + "update:modelValue": (val: string) => { + if (val === "_self") { + blockController.removeAttribute("target"); + } else { + blockController.setAttribute("target", val); + } + }, + }, + condition: () => blockController.getAttribute("href"), + }, +]; + +export default { + name: "Link", + properties: linkSectionProperties, + collapsed: computed(() => !blockController.isLink()), + condition: () => !blockController.multipleBlocksSelected(), +}; diff --git a/frontend/src/components/BlockPropertySections/OptionsSection.ts b/frontend/src/components/BlockPropertySections/OptionsSection.ts new file mode 100644 index 000000000..2d2653861 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/OptionsSection.ts @@ -0,0 +1,239 @@ +import CodeEditor from "@/components/Controls/CodeEditor.vue"; +import InlineInput from "@/components/Controls/InlineInput.vue"; +import OptionToggle from "@/components/Controls/OptionToggle.vue"; +import blockController from "@/utils/blockController"; + +const setClasses = (val: string) => { + const classes = val.split(",").map((c) => c.trim()); + blockController.setClasses(classes); +}; + +const optionsSectionProperties = [ + { + component: InlineInput, + getProps: () => { + return { + label: "Tag", + type: "select", + options: [ + "aside", + "article", + "span", + "div", + "section", + "button", + "p", + "a", + "input", + "hr", + "form", + "textarea", + "nav", + "header", + "footer", + "label", + "select", + "option", + "blockquote", + "cite", + ], + modelValue: blockController.getKeyValue("element"), + }; + }, + searchKeyWords: + "Tag, Element, TagName, Tag Name, ElementName, Element Name, header, footer, nav, input, form, textarea, button, p, a, div, span, section, hr, TagType, Tag Type, ElementType, Element Type", + events: { + "update:modelValue": (val: string) => blockController.setKeyValue("element", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Input Type", + type: "select", + options: ["text", "number", "email", "password", "date", "time", "search", "tel", "url", "color"], + modelValue: blockController.getAttribute("type") || "text", + }; + }, + searchKeyWords: + "Input, Type, InputType, Input Type, Text, Number, Email, Password, Date, Time, Search, Tel, Url, Color, tag", + events: { + "update:modelValue": (val: string) => blockController.setAttribute("type", val), + }, + condition: () => blockController.isInput(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Placeholder", + modelValue: blockController.getAttribute("placeholder"), + }; + }, + searchKeyWords: + "Placeholder, Input, PlaceholderText, Placeholder Text, form, input, text, number, email, password, date, time, search, tel, url, color, tag", + events: { + "update:modelValue": (val: string) => blockController.setAttribute("placeholder", val), + }, + condition: () => blockController.isInput(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Content", + // @ts-ignore + modelValue: blockController.getSelectedBlocks()[0]?.__proto__?.editor?.getText(), + }; + }, + searchKeyWords: "Content, Text, ContentText, Content Text", + events: { + "update:modelValue": (val: string) => blockController.setKeyValue("innerHTML", val), + }, + condition: () => blockController.isText() || blockController.isButton(), + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Visibility", + options: [ + { + label: "Visible", + value: "flex", + }, + { + label: "Hidden", + value: "none", + }, + ], + modelValue: blockController.getStyle("display") || "flex", + }; + }, + searchKeyWords: "Visibility, Display, Visible, Hidden, Flex, None, hide, show", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("display", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Overflow X", + type: "select", + options: [ + { + label: "Auto", + value: "auto", + }, + { + label: "Visible", + value: "visible", + }, + { + label: "Hidden", + value: "hidden", + }, + { + label: "Scroll", + value: "scroll", + }, + ], + modelValue: blockController.getStyle("overflowX") || blockController.getStyle("overflow"), + }; + }, + searchKeyWords: + "Overflow, X, OverflowX, Overflow X, Auto, Visible, Hide, Scroll, horizontal scroll, horizontalScroll", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("overflowX", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Overflow Y", + type: "select", + options: [ + { + label: "Auto", + value: "auto", + }, + { + label: "Visible", + value: "visible", + }, + { + label: "Hidden", + value: "hidden", + }, + { + label: "Scroll", + value: "scroll", + }, + ], + modelValue: blockController.getStyle("overflowY") || blockController.getStyle("overflow"), + }; + }, + searchKeyWords: + "Overflow, Y, OverflowY, Overflow Y, Auto, Visible, Hide, Scroll, vertical scroll, verticalScroll", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("overflowY", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Class", + modelValue: blockController.getClasses().join(", "), + }; + }, + searchKeyWords: "Class, ClassName, Class Name", + events: { + "update:modelValue": (val: string) => setClasses(val || ""), + }, + condition: () => !blockController.multipleBlocksSelected(), + }, + { + component: CodeEditor, + getProps: () => { + return { + label: "HTML", + type: "HTML", + autofocus: false, + modelValue: blockController.getInnerHTML() || "", + }; + }, + searchKeyWords: "HTML, InnerHTML, Inner HTML", + events: { + "update:modelValue": (val: string) => { + blockController.setInnerHTML(val); + }, + }, + condition: () => + blockController.isHTML() || (blockController.getInnerHTML() && !blockController.isText()), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Condition", + modelValue: blockController.getKeyValue("visibilityCondition"), + description: + "Visibility condition to show/hide the block based on a condition. Pass a boolean variable created in your Data Script.
Note: This is only evaluated in the preview mode.", + }; + }, + searchKeyWords: + "Condition, Visibility, VisibilityCondition, Visibility Condition, show, hide, display, hideIf, showIf", + events: { + "update:modelValue": (val: string) => blockController.setKeyValue("visibilityCondition", val), + }, + }, +]; + +export default { + name: "Options", + properties: optionsSectionProperties, +}; diff --git a/frontend/src/components/BlockPropertySections/PositionSection.ts b/frontend/src/components/BlockPropertySections/PositionSection.ts new file mode 100644 index 000000000..40bc75662 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/PositionSection.ts @@ -0,0 +1,26 @@ +import BlockPositionHandler from "@/components/BlockPositionHandler.vue"; +import blockController from "@/utils/blockController"; +import { computed } from "vue"; + +const positionSectionProperties = [ + { + component: BlockPositionHandler, + searchKeyWords: + "Position, Top, Right, Bottom, Left, PositionTop, Position Top, PositionRight, Position Right, PositionBottom, Position Bottom, PositionLeft, Position Left, Free, Fixed, Absolute, Relative, Sticky", + getProps: () => {}, + }, +]; + +export default { + name: "Position", + properties: positionSectionProperties, + condition: () => !blockController.multipleBlocksSelected() && !blockController.isRoot(), + collapsed: computed(() => { + return ( + !blockController.getStyle("top") && + !blockController.getStyle("right") && + !blockController.getStyle("bottom") && + !blockController.getStyle("left") + ); + }), +}; diff --git a/frontend/src/components/BlockPropertySections/RawStyleSection.ts b/frontend/src/components/BlockPropertySections/RawStyleSection.ts new file mode 100644 index 000000000..2f1759382 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/RawStyleSection.ts @@ -0,0 +1,38 @@ +import ObjectEditor from "@/components/ObjectEditor.vue"; +import blockController from "@/utils/blockController"; +import { computed } from "vue"; + +const rawStyleSectionProperties = [ + { + component: ObjectEditor, + getProps: () => { + return { + obj: blockController.getRawStyles() as Record, + description: ` + Note: +
+
+ - Raw styles get applied across all devices +
+ - State based styles are supported (e.g. hover, focus, visited) +
+ Syntax: hover:color, focus:color, etc. +
+ - State styles are only activated in preview mode + `, + }; + }, + searchKeyWords: "Raw, RawStyle, Raw Style, CSS, Style, Styles", + events: { + "update:obj": (obj: Record) => blockController.setRawStyles(obj), + }, + }, +]; + +export default { + name: "Raw Style", + properties: rawStyleSectionProperties, + collapsed: computed(() => { + return Object.keys(blockController.getRawStyles()).length === 0; + }), +}; diff --git a/frontend/src/components/BlockPropertySections/SpacingSection.ts b/frontend/src/components/BlockPropertySections/SpacingSection.ts new file mode 100644 index 000000000..4b1e39059 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/SpacingSection.ts @@ -0,0 +1,45 @@ +import InlineInput from "@/components/Controls/InlineInput.vue"; +import blockController from "@/utils/blockController"; +import { computed } from "vue"; + +const spacingSectionProperties = [ + { + component: InlineInput, + searchKeyWords: "Margin, Top, MarginTop, Margin Top", + getProps: () => { + return { + label: "Margin", + modelValue: blockController.getMargin(), + }; + }, + events: { + "update:modelValue": (val: string) => blockController.setMargin(val), + }, + condition: () => !blockController.isRoot(), + }, + { + component: InlineInput, + searchKeyWords: "Padding, Top, PaddingTop, Padding Top", + getProps: () => { + return { + label: "Padding", + modelValue: blockController.getPadding(), + }; + }, + events: { + "update:modelValue": (val: string) => blockController.setPadding(val), + }, + }, +]; + +export default { + name: "Spacing", + properties: spacingSectionProperties, + collapsed: computed( + () => + !blockController.getStyle("marginTop") && + !blockController.getStyle("paddingTop") && + !blockController.getStyle("marginBottom") && + !blockController.getStyle("paddingBottom"), + ), +}; diff --git a/frontend/src/components/BlockPropertySections/StyleSection.ts b/frontend/src/components/BlockPropertySections/StyleSection.ts new file mode 100644 index 000000000..293f03fd6 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/StyleSection.ts @@ -0,0 +1,182 @@ +import BackgroundHandler from "@/components/BackgroundHandler.vue"; +import ColorInput from "@/components/Controls/ColorInput.vue"; +import InlineInput from "@/components/Controls/InlineInput.vue"; +import blockController from "@/utils/blockController"; + +const styleSectionProperties = [ + { + component: ColorInput, + getProps: () => { + return { + label: "BG Color", + value: blockController.getStyle("background"), + }; + }, + searchKeyWords: "Background, BackgroundColor, Background Color, BG, BGColor, BG Color", + events: { + change: (val: StyleValue) => blockController.setStyle("background", val), + }, + }, + { + component: ColorInput, + getProps: () => { + return { + label: "Text Color", + value: blockController.getTextColor(), + }; + }, + searchKeyWords: "Text, Color, TextColor, Text Color", + events: { + change: (val: string) => blockController.setTextColor(val), + }, + }, + { + component: ColorInput, + getProps: () => { + return { + label: "Border Color", + value: blockController.getStyle("borderColor"), + }; + }, + searchKeyWords: "Border, Color, BorderColor, Border Color", + events: { + change: (val: StyleValue) => { + blockController.setStyle("borderColor", val); + if (val) { + if (!blockController.getStyle("borderWidth")) { + blockController.setStyle("borderWidth", "1px"); + blockController.setStyle("borderStyle", "solid"); + } + } else { + blockController.setStyle("borderWidth", null); + blockController.setStyle("borderStyle", null); + } + }, + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Border Width", + modelValue: blockController.getStyle("borderWidth"), + enableSlider: true, + unitOptions: ["px", "%", "em", "rem"], + minValue: 0, + }; + }, + searchKeyWords: "Border, Width, BorderWidth, Border Width", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("borderWidth", val), + }, + condition: () => blockController.getStyle("borderColor") || blockController.getStyle("borderWidth"), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Border Style", + modelValue: blockController.getStyle("borderStyle"), + type: "select", + options: [ + { + value: "solid", + label: "Solid", + }, + { + value: "dashed", + label: "Dashed", + }, + { + value: "dotted", + label: "Dotted", + }, + ], + }; + }, + searchKeyWords: "Border, Style, BorderStyle, Border Style, Solid, Dashed, Dotted", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("borderStyle", val), + }, + condition: () => blockController.getStyle("borderColor"), + }, + { + component: BackgroundHandler, + getProps: () => {}, + searchKeyWords: + "Background, BackgroundImage, Background Image, Background Position, Background Repeat, Background Size, BG, BGImage, BG Image, BGPosition, BG Position, BGRepeat, BG Repeat, BGSize, BG Size", + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Shadow", + type: "select", + options: [ + { + value: null, + label: "None", + }, + { + label: "Small", + value: + "rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 1px 2px 0px, rgba(0, 0, 0, 0.05) 0px 1px 3px 0px", + }, + { + label: "Medium", + value: + "rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px", + }, + { + label: "Large", + value: + "rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 20px 25px -5px, rgba(0, 0, 0, 0.1) 0px 10px 10px -5px", + }, + ], + modelValue: blockController.getStyle("boxShadow"), + }; + }, + searchKeyWords: "Shadow, BoxShadow, Box Shadow", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("boxShadow", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Radius", + modelValue: blockController.getStyle("borderRadius"), + enableSlider: true, + unitOptions: ["px", "%"], + minValue: 0, + }; + }, + searchKeyWords: "Border, Radius, BorderRadius, Border Radius", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("borderRadius", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Z-Index", + modelValue: blockController.getStyle("zIndex"), + }; + }, + searchKeyWords: "Z, Index, ZIndex, Z Index", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("zIndex", val), + }, + condition: () => + !blockController.multipleBlocksSelected() && + !blockController.isRoot() && + blockController.getStyle("position") !== "static", + }, +]; + +export default { + name: "Style", + properties: styleSectionProperties, +}; diff --git a/frontend/src/components/BlockPropertySections/TypographySection.ts b/frontend/src/components/BlockPropertySections/TypographySection.ts new file mode 100644 index 000000000..08f5e1675 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/TypographySection.ts @@ -0,0 +1,203 @@ +import FontUploader from "@/components/Controls/FontUploader.vue"; +import InlineInput from "@/components/Controls/InlineInput.vue"; +import OptionToggle from "@/components/Controls/OptionToggle.vue"; +import userFonts from "@/data/userFonts"; +import { UserFont } from "@/types/Builder/UserFont"; +import blockController from "@/utils/blockController"; +import { setFont as _setFont, fontList, getFontWeightOptions } from "@/utils/fontManager"; + +const setFont = (font: string) => { + _setFont(font, null).then(() => { + blockController.setFontFamily(font); + }); +}; + +const typographySectionProperties = [ + { + component: InlineInput, + getProps: () => { + return { + label: "Family", + type: "autocomplete", + getOptions: (filterString: string) => { + const fontOptions = [] as { label: string; value: string }[]; + userFonts.data.forEach((font: UserFont) => { + if (fontOptions.length >= 20) { + return; + } + const fontName = font.font_name as string; + if (fontName.toLowerCase().includes(filterString.toLowerCase()) || !filterString) { + fontOptions.push({ + label: fontName, + value: fontName, + }); + } + }); + if (fontOptions.length) { + fontOptions.unshift({ + label: "Custom", + value: "_separator_1", + }); + fontOptions.push({ + label: "Default", + value: "_separator_2", + }); + } + fontList.items.forEach((font) => { + if (fontOptions.length >= 20) { + return; + } + if (font.family.toLowerCase().includes(filterString.toLowerCase()) || !filterString) { + fontOptions.push({ + label: font.family, + value: font.family, + }); + } + }); + return fontOptions; + }, + actionButton: { + component: FontUploader, + }, + modelValue: blockController.getFontFamily(), + }; + }, + searchKeyWords: "Font, Family, FontFamily", + events: { + "update:modelValue": (val: string) => setFont(val), + }, + condition: () => blockController.isText() || blockController.isContainer(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Weight", + modelValue: blockController.getStyle("fontWeight"), + type: "autocomplete", + options: getFontWeightOptions((blockController.getStyle("fontFamily") || "Inter") as string), + }; + }, + searchKeyWords: "Font, Weight, FontWeight", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("fontWeight", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Size", + modelValue: blockController.getStyle("fontSize"), + enableSlider: true, + minValue: 1, + }; + }, + searchKeyWords: "Font, Size, FontSize", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("fontSize", val), + }, + condition: () => blockController.isText() || blockController.isInput(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Height", + modelValue: blockController.getStyle("lineHeight"), + }; + }, + searchKeyWords: "Font, Height, LineHeight, Line Height", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("lineHeight", val), + }, + condition: () => blockController.isText(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Letter", + modelValue: blockController.getStyle("letterSpacing"), + }; + }, + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("letterSpacing", val), + }, + searchKeyWords: "Font, Letter, LetterSpacing, Letter Spacing", + condition: () => blockController.isText(), + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Transform", + modelValue: blockController.getStyle("textTransform"), + type: "select", + options: [ + { + value: null, + label: "None", + }, + { + value: "uppercase", + label: "Uppercase", + }, + { + value: "lowercase", + label: "Lowercase", + }, + { + value: "capitalize", + label: "Capitalize", + }, + ], + }; + }, + searchKeyWords: "Font, Transform, TextTransform, Text Transform, Capitalize, Uppercase, Lowercase", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("textTransform", val), + }, + condition: () => blockController.isText(), + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Align", + options: [ + { + label: "Left", + value: "left", + icon: "align-left", + hideLabel: true, + }, + { + label: "Center", + value: "center", + icon: "align-center", + hideLabel: true, + }, + { + label: "Right", + value: "right", + icon: "align-right", + hideLabel: true, + }, + ], + modelValue: blockController.getStyle("textAlign") || "left", + }; + }, + searchKeyWords: "Font, Align, TextAlign, Text Align, Left, Center, Right, Justify", + events: { + "update:modelValue": (val: StyleValue) => blockController.setStyle("textAlign", val), + }, + condition: () => blockController.isText(), + }, +]; + +export default { + name: "Typography", + properties: typographySectionProperties, + condition: () => blockController.isText() || blockController.isContainer() || blockController.isInput(), +}; diff --git a/frontend/src/components/BlockPropertySections/VideoOptionsSection.ts b/frontend/src/components/BlockPropertySections/VideoOptionsSection.ts new file mode 100644 index 000000000..a0ae6c742 --- /dev/null +++ b/frontend/src/components/BlockPropertySections/VideoOptionsSection.ts @@ -0,0 +1,130 @@ +import InlineInput from "@/components/Controls/InlineInput.vue"; +import OptionToggle from "@/components/Controls/OptionToggle.vue"; +import blockController from "@/utils/blockController"; + +const videoOptionsSectionProperties = [ + { + component: InlineInput, + getProps: () => { + return { + label: "Video URL", + modelValue: blockController.getAttribute("src"), + }; + }, + searchKeyWords: "Video, URL, Src", + events: { + "update:modelValue": (val: string) => blockController.setAttribute("src", val), + }, + }, + { + component: InlineInput, + getProps: () => { + return { + label: "Poster", + modelValue: blockController.getAttribute("poster"), + }; + }, + searchKeyWords: "Poster", + events: { + "update:modelValue": (val: string) => blockController.setAttribute("poster", val), + }, + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Controls", + options: [ + { + label: "Show", + value: "true", + }, + { + label: "Hide", + value: "false", + }, + ], + modelValue: blockController.getAttribute("controls") === "" ? "true" : "false", + }; + }, + searchKeyWords: "Controls, volume, play, pause, stop, mute, unmute, fullscreen, full screen", + events: { + "update:modelValue": (val: boolean) => blockController.toggleAttribute("controls"), + }, + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Autoplay", + options: [ + { + label: "Yes", + value: "true", + }, + { + label: "No", + value: "false", + }, + ], + modelValue: blockController.getAttribute("autoplay") === "" ? "true" : "false", + }; + }, + searchKeyWords: "Autoplay, Auto Play", + events: { + "update:modelValue": (val: boolean) => blockController.toggleAttribute("autoplay"), + }, + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Muted", + options: [ + { + label: "Yes", + value: "true", + }, + { + label: "No", + value: "false", + }, + ], + modelValue: blockController.getAttribute("muted") === "" ? "true" : "false", + }; + }, + searchKeyWords: "Muted", + events: { + "update:modelValue": (val: boolean) => blockController.toggleAttribute("muted"), + }, + }, + { + component: OptionToggle, + getProps: () => { + return { + label: "Loop", + options: [ + { + label: "Yes", + value: "true", + }, + { + label: "No", + value: "false", + }, + ], + modelValue: blockController.getAttribute("loop") === "" ? "true" : "false", + }; + }, + searchKeyWords: "Loop", + events: { + "update:modelValue": (val: boolean) => blockController.toggleAttribute("loop"), + }, + }, +]; + +export default { + name: "Video Options", + properties: videoOptionsSectionProperties, + condition: () => blockController.isVideo(), +}; From da2c5d0fbf062cf218b92ac3f2f5f3e60ec7e137 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Sun, 26 Jan 2025 21:51:15 +0530 Subject: [PATCH 32/48] feat: Add "cut" event handler --- frontend/src/utils/useBuilderEvents.ts | 61 ++++++++++++++++---------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/frontend/src/utils/useBuilderEvents.ts b/frontend/src/utils/useBuilderEvents.ts index 1bc06a9fd..c16a6fa25 100644 --- a/frontend/src/utils/useBuilderEvents.ts +++ b/frontend/src/utils/useBuilderEvents.ts @@ -51,32 +51,16 @@ export function useBuilderEvents( ); useEventListener(document, "copy", (e) => { - if (isTargetEditable(e)) return; + copySelectedBlocksToClipboard(e); + }); + + useEventListener(document, "cut", (e) => { + copySelectedBlocksToClipboard(e); if (store.activeCanvas?.selectedBlocks.length) { - e.preventDefault(); - const componentDocuments: BuilderComponent[] = []; for (const block of store.activeCanvas?.selectedBlocks) { - const components = block.getUsedComponentNames(); - for (const componentName of components) { - const component = componentStore.getComponent(componentName); - if (component) { - componentDocuments.push(component); - } - } + store.activeCanvas?.removeBlock(block, true); } - - const blocksToCopy = store.activeCanvas?.selectedBlocks.map((block) => { - if (!Boolean(block.extendedFromComponent) && block.isChildOfComponent) { - return detachBlockFromComponent(block); - } - return getCopyWithoutParent(block); - }); - // just copy non components - const dataToCopy = { - blocks: blocksToCopy, - components: componentDocuments, - }; - copyToClipboard(dataToCopy, e, "builder-copied-blocks"); + clearSelection(); } }); @@ -463,3 +447,34 @@ const clearSelection = () => { document.activeElement.blur(); } }; + +const copySelectedBlocksToClipboard = (e: ClipboardEvent) => { + if (isTargetEditable(e)) return; + if (store.activeCanvas?.selectedBlocks.length) { + e.preventDefault(); + const componentDocuments: BuilderComponent[] = []; + for (const block of store.activeCanvas?.selectedBlocks) { + const components = block.getUsedComponentNames(); + for (const componentName of components) { + const component = componentStore.getComponent(componentName); + if (component) { + componentDocuments.push(component); + } + } + } + + const blocksToCopy = store.activeCanvas?.selectedBlocks.map((block) => { + if (!Boolean(block.extendedFromComponent) && block.isChildOfComponent) { + return detachBlockFromComponent(block, null); + } + return getCopyWithoutParent(block); + }); + + // just copy non components + const dataToCopy = { + blocks: blocksToCopy, + components: componentDocuments, + }; + copyToClipboard(dataToCopy, e, "builder-copied-blocks"); + } +}; From 0393bc2b0a228e233498776c5014296f805d7085 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 12:44:48 +0530 Subject: [PATCH 33/48] fix: Auto close dialogs on route change --- frontend/src/components/AlertDialog.vue | 2 +- frontend/src/components/Controls/Dialog.vue | 29 +++++++++++++++++++ .../src/components/Modals/NewComponent.vue | 2 +- frontend/src/components/Modals/NewFolder.vue | 2 +- .../src/components/Modals/SelectFolder.vue | 2 +- frontend/src/components/PageScript.vue | 2 +- frontend/src/pages/PageBuilder.vue | 2 +- 7 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 frontend/src/components/Controls/Dialog.vue diff --git a/frontend/src/components/AlertDialog.vue b/frontend/src/components/AlertDialog.vue index 9f9f6c1db..aa90ff159 100644 --- a/frontend/src/components/AlertDialog.vue +++ b/frontend/src/components/AlertDialog.vue @@ -12,7 +12,7 @@ diff --git a/frontend/src/components/Modals/NewComponent.vue b/frontend/src/components/Modals/NewComponent.vue index 8805983fa..25778ae32 100644 --- a/frontend/src/components/Modals/NewComponent.vue +++ b/frontend/src/components/Modals/NewComponent.vue @@ -25,6 +25,7 @@ diff --git a/frontend/src/utils/helpers.ts b/frontend/src/utils/helpers.ts index 098d25886..b309751a4 100644 --- a/frontend/src/utils/helpers.ts +++ b/frontend/src/utils/helpers.ts @@ -99,6 +99,9 @@ async function confirm(message: string, title: string = "Confirm"): Promise { + resolve(false); + }, }); }); } diff --git a/yarn.lock b/yarn.lock index 43d672d7d..c1a7cb3d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -63,6 +63,28 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@bundled-es-modules/cookie@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz#b41376af6a06b3e32a15241d927b840a9b4de507" + integrity sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw== + dependencies: + cookie "^0.7.2" + +"@bundled-es-modules/statuses@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872" + integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg== + dependencies: + statuses "^2.0.1" + +"@bundled-es-modules/tough-cookie@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3" + integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw== + dependencies: + "@types/tough-cookie" "^4.0.5" + tough-cookie "^4.1.4" + "@codemirror/commands@^6.3.0": version "6.6.0" resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.6.0.tgz#d308f143fe1b8896ca25fdb855f66acdaf019dd4" @@ -168,221 +190,111 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== -"@esbuild/android-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" - integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== - "@esbuild/android-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== -"@esbuild/android-arm@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" - integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== - "@esbuild/android-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== -"@esbuild/android-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" - integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== - "@esbuild/android-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== -"@esbuild/darwin-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" - integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== - "@esbuild/darwin-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== -"@esbuild/darwin-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" - integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== - "@esbuild/darwin-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== -"@esbuild/freebsd-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" - integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== - "@esbuild/freebsd-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== -"@esbuild/freebsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" - integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== - "@esbuild/freebsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== -"@esbuild/linux-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" - integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== - "@esbuild/linux-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== -"@esbuild/linux-arm@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" - integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== - "@esbuild/linux-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== -"@esbuild/linux-ia32@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" - integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== - "@esbuild/linux-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== -"@esbuild/linux-loong64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" - integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== - "@esbuild/linux-loong64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== -"@esbuild/linux-mips64el@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" - integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== - "@esbuild/linux-mips64el@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== -"@esbuild/linux-ppc64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" - integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== - "@esbuild/linux-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== -"@esbuild/linux-riscv64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" - integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== - "@esbuild/linux-riscv64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== -"@esbuild/linux-s390x@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" - integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== - "@esbuild/linux-s390x@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== -"@esbuild/linux-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" - integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== - "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== -"@esbuild/netbsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" - integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== - "@esbuild/netbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== -"@esbuild/openbsd-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" - integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== - "@esbuild/openbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== -"@esbuild/sunos-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" - integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== - "@esbuild/sunos-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== -"@esbuild/win32-arm64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" - integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== - "@esbuild/win32-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== -"@esbuild/win32-ia32@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" - integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== - "@esbuild/win32-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== -"@esbuild/win32-x64@0.18.20": - version "0.18.20" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" - integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== - "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" @@ -483,7 +395,7 @@ "@histoire/shared" "^0.17.17" "@histoire/vendors" "^0.17.17" -"@histoire/plugin-vue@^0.17.14": +"@histoire/plugin-vue@^0.17.17": version "0.17.17" resolved "https://registry.yarnpkg.com/@histoire/plugin-vue/-/plugin-vue-0.17.17.tgz#65cde4685738c06edf0f36b23b93f966a1f642c3" integrity sha512-O5h/Ww6IT2CygVVT4onN27IZt11Z2qE8XeHeXJCEese3dxnnVWRhjMpsaWAU5XqgfjKNAiALJk86b49/6NQaRg== @@ -532,6 +444,39 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@inquirer/confirm@^5.0.0": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.3.tgz#c1ad57663f54758981811ccb86f823072ddf5c1a" + integrity sha512-fuF9laMmHoOgWapF9h9hv6opA5WvmGFHsTYGCmuFxcghIhEhb3dN0CdQR4BUMqa2H506NCj8cGX4jwMsE4t6dA== + dependencies: + "@inquirer/core" "^10.1.4" + "@inquirer/type" "^3.0.2" + +"@inquirer/core@^10.1.4": + version "10.1.4" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.1.4.tgz#02394e68d894021935caca0d10fc68fd4f3a3ead" + integrity sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w== + dependencies: + "@inquirer/figures" "^1.0.9" + "@inquirer/type" "^3.0.2" + ansi-escapes "^4.3.2" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.9.tgz#9d8128f8274cde4ca009ca8547337cab3f37a4a3" + integrity sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ== + +"@inquirer/type@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.2.tgz#baff9f8d70947181deb36772cd9a5b6876d3e60c" + integrity sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g== + "@internationalized/date@^3.5.4": version "3.5.5" resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.5.tgz#7d34cb9da35127f98dd669fc926bb37e771e177f" @@ -618,6 +563,18 @@ dependencies: "@lezer/common" "^1.0.0" +"@mswjs/interceptors@^0.37.0": + version "0.37.5" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.37.5.tgz#9ce40c56be02b43fcbdb51b63f47e69fc4aaabe6" + integrity sha512-AAwRb5vXFcY4L+FvZ7LZusDuZ0vEe0Zm8ohn1FM6/X7A3bj4mqmkAcGRWuvC2JwSygNwHAAmMnAI73vPHeqsHA== + dependencies: + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/logger" "^0.3.0" + "@open-draft/until" "^2.0.0" + is-node-process "^1.2.0" + outvariant "^1.4.3" + strict-event-emitter "^0.5.1" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -639,6 +596,24 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@open-draft/deferred-promise@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" + integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== + +"@open-draft/logger@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954" + integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== + dependencies: + is-node-process "^1.2.0" + outvariant "^1.4.0" + +"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" + integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -1029,11 +1004,21 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + "@types/estree@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/estree@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/flexsearch@^0.7.6": version "0.7.6" resolved "https://registry.yarnpkg.com/@types/flexsearch/-/flexsearch-0.7.6.tgz#240c11d16825c56833ec0c66eb1de3ea0e162a49" @@ -1091,6 +1076,16 @@ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.8.tgz#518609aefb797da19bf222feb199e8f653ff7627" integrity sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg== +"@types/statuses@^2.0.4": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63" + integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A== + +"@types/tough-cookie@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + "@types/web-bluetooth@^0.0.20": version "0.0.20" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" @@ -1118,6 +1113,65 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz#057d2ded94c4e71b94e9814f92dcd9306317aa46" integrity sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw== +"@vitest/expect@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.8.tgz#13fad0e8d5a0bf0feb675dcf1d1f1a36a1773bc1" + integrity sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw== + dependencies: + "@vitest/spy" "2.1.8" + "@vitest/utils" "2.1.8" + chai "^5.1.2" + tinyrainbow "^1.2.0" + +"@vitest/mocker@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.8.tgz#51dec42ac244e949d20009249e033e274e323f73" + integrity sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA== + dependencies: + "@vitest/spy" "2.1.8" + estree-walker "^3.0.3" + magic-string "^0.30.12" + +"@vitest/pretty-format@2.1.8", "@vitest/pretty-format@^2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.8.tgz#88f47726e5d0cf4ba873d50c135b02e4395e2bca" + integrity sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/runner@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.8.tgz#b0e2dd29ca49c25e9323ea2a45a5125d8729759f" + integrity sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg== + dependencies: + "@vitest/utils" "2.1.8" + pathe "^1.1.2" + +"@vitest/snapshot@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.8.tgz#d5dc204f4b95dc8b5e468b455dfc99000047d2de" + integrity sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg== + dependencies: + "@vitest/pretty-format" "2.1.8" + magic-string "^0.30.12" + pathe "^1.1.2" + +"@vitest/spy@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.8.tgz#bc41af3e1e6a41ae3b67e51f09724136b88fa447" + integrity sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg== + dependencies: + tinyspy "^3.0.2" + +"@vitest/utils@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.8.tgz#f8ef85525f3362ebd37fd25d268745108d6ae388" + integrity sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA== + dependencies: + "@vitest/pretty-format" "2.1.8" + loupe "^3.1.2" + tinyrainbow "^1.2.0" + "@vue/compiler-core@3.4.38": version "3.4.38" resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.38.tgz#326dfe3c92fa2b0f1dc9b39a948a231980253496" @@ -1379,7 +1433,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.3.0: +ansi-escapes@^4.3.0, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -1535,6 +1589,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -1738,6 +1797,17 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +chai@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -1769,6 +1839,11 @@ change-case@^4.1.2: snake-case "^3.0.4" tslib "^2.0.3" +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + check-more-types@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" @@ -1848,6 +1923,20 @@ cli-truncate@^4.0.0: slice-ansi "^5.0.0" string-width "^7.0.0" +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -1931,6 +2020,11 @@ constant-case@^3.0.4: tslib "^2.0.3" upper-case "^2.0.2" +cookie@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + core-js@^3.1.3: version "3.38.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" @@ -1946,13 +2040,6 @@ crelt@^1.0.0, crelt@^1.0.5: resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72" integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g== -cross-fetch@^3.1.5: - version "3.1.8" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" - integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== - dependencies: - node-fetch "^2.6.12" - cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2106,11 +2193,23 @@ debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.7: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + decimal.js@^10.4.2: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -2355,6 +2454,11 @@ es-errors@^1.2.1, es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== +es-module-lexer@^1.5.4: + version "1.6.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" + integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== + es-object-atoms@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" @@ -2387,34 +2491,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@^0.18.10: - version "0.18.20" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" - integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== - optionalDependencies: - "@esbuild/android-arm" "0.18.20" - "@esbuild/android-arm64" "0.18.20" - "@esbuild/android-x64" "0.18.20" - "@esbuild/darwin-arm64" "0.18.20" - "@esbuild/darwin-x64" "0.18.20" - "@esbuild/freebsd-arm64" "0.18.20" - "@esbuild/freebsd-x64" "0.18.20" - "@esbuild/linux-arm" "0.18.20" - "@esbuild/linux-arm64" "0.18.20" - "@esbuild/linux-ia32" "0.18.20" - "@esbuild/linux-loong64" "0.18.20" - "@esbuild/linux-mips64el" "0.18.20" - "@esbuild/linux-ppc64" "0.18.20" - "@esbuild/linux-riscv64" "0.18.20" - "@esbuild/linux-s390x" "0.18.20" - "@esbuild/linux-x64" "0.18.20" - "@esbuild/netbsd-x64" "0.18.20" - "@esbuild/openbsd-x64" "0.18.20" - "@esbuild/sunos-x64" "0.18.20" - "@esbuild/win32-arm64" "0.18.20" - "@esbuild/win32-ia32" "0.18.20" - "@esbuild/win32-x64" "0.18.20" - esbuild@^0.21.3: version "0.21.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" @@ -2444,6 +2520,11 @@ esbuild@^0.21.3: "@esbuild/win32-ia32" "0.21.5" "@esbuild/win32-x64" "0.21.5" +escalade@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escalade@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" @@ -2623,6 +2704,13 @@ estree-walker@^2.0.2: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2675,6 +2763,11 @@ executable@^4.1.1: dependencies: pify "^2.2.0" +expect-type@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75" + integrity sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA== + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -2909,6 +3002,11 @@ functions-have-names@^1.2.3: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-east-asian-width@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" @@ -3048,6 +3146,11 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +graphql@^16.8.1: + version "16.10.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.10.0.tgz#24c01ae0af6b11ea87bf55694429198aaa8e220c" + integrity sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -3107,7 +3210,12 @@ header-case@^2.0.4: capital-case "^1.0.4" tslib "^2.0.3" -histoire@^0.17.14: +headers-polyfill@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" + integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== + +histoire@^0.17.17: version "0.17.17" resolved "https://registry.yarnpkg.com/histoire/-/histoire-0.17.17.tgz#3325344d0e3342938de38175ad82d91dec4fd235" integrity sha512-DAwY4sgIoP7NGE5ldaws2d3RWz4OOQcwhS8elRMiA2euqzLvDU2IXm+ZjeDDFVtGkvmQNQyfZBDKLCLHfRkSUg== @@ -3369,6 +3477,11 @@ is-negative-zero@^2.0.3: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== +is-node-process@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" + integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== + is-number-object@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" @@ -3756,6 +3869,11 @@ log-update@^6.1.0: strip-ansi "^7.1.0" wrap-ansi "^9.0.0" +loupe@^3.1.0, loupe@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -3782,6 +3900,13 @@ magic-string@^0.30.11: dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" +magic-string@^0.30.12: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + markdown-it-anchor@^8.6.7: version "8.6.7" resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz#ee6926daf3ad1ed5e4e3968b1740eef1c6399634" @@ -3939,11 +4064,40 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +msw@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.7.0.tgz#d13ff87f7e018fc4c359800ff72ba5017033fb56" + integrity sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw== + dependencies: + "@bundled-es-modules/cookie" "^2.0.1" + "@bundled-es-modules/statuses" "^1.0.1" + "@bundled-es-modules/tough-cookie" "^0.1.6" + "@inquirer/confirm" "^5.0.0" + "@mswjs/interceptors" "^0.37.0" + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/until" "^2.1.0" + "@types/cookie" "^0.6.0" + "@types/statuses" "^2.0.4" + graphql "^16.8.1" + headers-polyfill "^4.0.2" + is-node-process "^1.2.0" + outvariant "^1.4.3" + path-to-regexp "^6.3.0" + picocolors "^1.1.1" + strict-event-emitter "^0.5.1" + type-fest "^4.26.1" + yargs "^17.7.2" + +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + mz@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" @@ -3958,6 +4112,11 @@ nanoid@^3.3.7: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +nanoid@^3.3.8: + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== + nanoid@^5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.7.tgz#6452e8c5a816861fd9d2b898399f7e5fd6944cc6" @@ -3976,13 +4135,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-fetch@^2.6.12: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-releases@^2.0.18: version "2.0.18" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" @@ -4162,6 +4314,11 @@ ospath@^1.2.2: resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== +outvariant@^1.4.0, outvariant@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873" + integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== + p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -4264,6 +4421,11 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-to-regexp@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4274,6 +4436,11 @@ pathe@^1.1.1, pathe@^1.1.2: resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" @@ -4388,7 +4555,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.40, postcss@^8.4.41, postcss@^8.4.5: +postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.40, postcss@^8.4.41, postcss@^8.4.5: version "8.4.41" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== @@ -4397,6 +4564,15 @@ postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.27, postcss@^8.4.40, postcss@^8.4 picocolors "^1.0.1" source-map-js "^1.2.0" +postcss@^8.4.43: + version "8.5.1" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214" + integrity sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ== + dependencies: + nanoid "^3.3.8" + picocolors "^1.1.1" + source-map-js "^1.2.1" + postcss@^8.4.48: version "8.4.49" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" @@ -4696,6 +4872,11 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -4748,13 +4929,6 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup@^3.27.1: - version "3.29.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" - integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== - optionalDependencies: - fsevents "~2.3.2" - rollup@^4.20.0: version "4.21.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.21.0.tgz#28db5f5c556a5180361d35009979ccc749560b9d" @@ -4930,6 +5104,11 @@ side-channel@^1.0.4: get-intrinsic "^1.2.4" object-inspect "^1.13.1" +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== + signal-exit@^3.0.2: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -5054,11 +5233,31 @@ sshpk@^1.14.1: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== + +statuses@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +std-env@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.0.tgz#b56ffc1baf1a29dcc80a3bdf11d7fca7c315e7d5" + integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== + +strict-event-emitter@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93" + integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== + string-argv@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" @@ -5073,7 +5272,7 @@ string-argv@~0.3.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5290,6 +5489,31 @@ tiny-inflate@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== +tinybench@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" + integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== + +tinyexec@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2" + integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== + +tinypool@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.2.tgz#706193cc532f4c100f66aa00b01c42173d9051b2" + integrity sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA== + +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== + tippy.js@^6.3.7: version "6.3.7" resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c" @@ -5319,7 +5543,7 @@ totalist@^3.0.0: resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== -tough-cookie@^4.1.2, tough-cookie@^4.1.3: +tough-cookie@^4.1.2, tough-cookie@^4.1.3, tough-cookie@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== @@ -5336,11 +5560,6 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" @@ -5390,6 +5609,11 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^4.26.1: + version "4.33.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.33.0.tgz#2da0c135b9afa76cf8b18ecfd4f260ecd414a432" + integrity sha512-s6zVrxuyKbbAsSAD5ZPTB77q4YIdRctkTbJ2/Dqlinwz+8ooH2gd+YA7VA6Pa93KML9GockVvoxjZ2vHP+mu8g== + typed-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" @@ -5550,6 +5774,17 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vite-node@2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.8.tgz#9495ca17652f6f7f95ca7c4b568a235e0c8dbac5" + integrity sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg== + dependencies: + cac "^6.7.14" + debug "^4.3.7" + es-module-lexer "^1.5.4" + pathe "^1.1.2" + vite "^5.0.0" + vite-node@^0.34.6: version "0.34.7" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.34.7.tgz#9fbcaf5597826d224e6301a486027faa22c2b09c" @@ -5573,16 +5808,42 @@ vite-node@^0.34.6: optionalDependencies: fsevents "~2.3.3" -vite@^4.1.0: - version "4.5.3" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.3.tgz#d88a4529ea58bae97294c7e2e6f0eab39a50fb1a" - integrity sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg== +vite@^5.0.0, vite@^5.1.8: + version "5.4.14" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408" + integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA== dependencies: - esbuild "^0.18.10" - postcss "^8.4.27" - rollup "^3.27.1" + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" optionalDependencies: - fsevents "~2.3.2" + fsevents "~2.3.3" + +vitest@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.8.tgz#2e6a00bc24833574d535c96d6602fb64163092fa" + integrity sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ== + dependencies: + "@vitest/expect" "2.1.8" + "@vitest/mocker" "2.1.8" + "@vitest/pretty-format" "^2.1.8" + "@vitest/runner" "2.1.8" + "@vitest/snapshot" "2.1.8" + "@vitest/spy" "2.1.8" + "@vitest/utils" "2.1.8" + chai "^5.1.2" + debug "^4.3.7" + expect-type "^1.1.0" + magic-string "^0.30.12" + pathe "^1.1.2" + std-env "^3.8.0" + tinybench "^2.9.0" + tinyexec "^0.3.1" + tinypool "^1.0.1" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.1.8" + why-is-node-running "^2.3.0" vue-demi@>=0.13.0, vue-demi@>=0.14.8, vue-demi@^0.14.10: version "0.14.10" @@ -5667,11 +5928,6 @@ webfontloader@^1.6.28: resolved "https://registry.yarnpkg.com/webfontloader/-/webfontloader-1.6.28.tgz#db786129253cb6e8eae54c2fb05f870af6675bae" integrity sha512-Egb0oFEga6f+nSgasH3E0M405Pzn6y3/9tOVanv/DLfa1YBIgcv90L18YyWnvXkRbIM17v5Kv6IT2N6g1x5tvQ== -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" @@ -5697,14 +5953,6 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -5734,6 +5982,14 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +why-is-node-running@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" + integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== + dependencies: + siginfo "^2.0.0" + stackback "0.0.2" + word-wrap@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -5814,11 +6070,34 @@ xmlhttprequest-ssl@~2.0.0: resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67" integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yaml@^2.3.4, yaml@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" @@ -5831,3 +6110,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" + integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== From 079a423f22fe5276ef9c577cb3b6bdae512fc0f4 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 15:44:49 +0530 Subject: [PATCH 36/48] fix: Canvas dirty state --- frontend/src/components/BuilderCanvas.vue | 2 +- frontend/src/store.ts | 2 +- frontend/src/utils/useCanvasUtils.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/BuilderCanvas.vue b/frontend/src/components/BuilderCanvas.vue index b8b4a31c6..605ce2b8f 100644 --- a/frontend/src/components/BuilderCanvas.vue +++ b/frontend/src/components/BuilderCanvas.vue @@ -99,7 +99,6 @@ const canvasContainer = ref(null); const canvas = ref(null); const showBlocks = ref(false); const overlay = ref(null); -const isDirty = ref(false); const props = defineProps({ blockData: { @@ -176,6 +175,7 @@ const { scrollBlockIntoView, removeBlock, findBlock, + isDirty, } = useCanvasUtils(canvasProps, canvasContainer, canvas, block, selectedBlockIds, history); const { isOverDropZone } = useCanvasDropZone( diff --git a/frontend/src/store.ts b/frontend/src/store.ts index ada19b592..8ee2837c5 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -302,8 +302,8 @@ const useStore = defineStore("store", { ); if (confirmed) { await webPages.delete.submit(page.name); + toast.success("Page deleted successfully"); } - toast.success("Page deleted successfully"); }, async publishPage(openInBrowser = true) { await this.waitTillPageIsSaved(); diff --git a/frontend/src/utils/useCanvasUtils.ts b/frontend/src/utils/useCanvasUtils.ts index 70565343a..9657a96da 100644 --- a/frontend/src/utils/useCanvasUtils.ts +++ b/frontend/src/utils/useCanvasUtils.ts @@ -283,5 +283,6 @@ export function useCanvasUtils( clearCanvas, getRootBlock, setupHistory, + isDirty, }; } From a196aebb71f5e49665f56d00f8579d73a3064e62 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 16:00:04 +0530 Subject: [PATCH 37/48] fix: Internal links should not have target _blank --- frontend/src/components/TextBlock.vue | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/TextBlock.vue b/frontend/src/components/TextBlock.vue index 1f10043e8..851f2edd8 100644 --- a/frontend/src/components/TextBlock.vue +++ b/frontend/src/components/TextBlock.vue @@ -350,10 +350,15 @@ const setLink = (value: string | null) => { if (!value && !textLink.value) { editor.value?.chain().focus().unsetLink().run(); } else { + const href = value || textLink.value; + const isExternal = href.startsWith("http") || href.startsWith("//"); editor.value ?.chain() .focus() - .setLink({ href: value || textLink.value }) + .setLink({ + href, + target: isExternal ? "_blank" : null, + }) .run(); textLink.value = ""; } From 37ecde3809e3c12699b1a6b33e9106e5266d0eb0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 18:14:30 +0530 Subject: [PATCH 38/48] fix: Do not set target while setting link --- frontend/src/components/TextBlock.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/TextBlock.vue b/frontend/src/components/TextBlock.vue index 851f2edd8..fc9b25a2f 100644 --- a/frontend/src/components/TextBlock.vue +++ b/frontend/src/components/TextBlock.vue @@ -351,13 +351,13 @@ const setLink = (value: string | null) => { editor.value?.chain().focus().unsetLink().run(); } else { const href = value || textLink.value; - const isExternal = href.startsWith("http") || href.startsWith("//"); + // const isExternal = href.startsWith("http") || href.startsWith("//"); editor.value ?.chain() .focus() .setLink({ href, - target: isExternal ? "_blank" : null, + target: null, }) .run(); textLink.value = ""; From 4fe7d269298c03fe05a8030cf5f3e313087e6c73 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 18:53:09 +0530 Subject: [PATCH 39/48] fix: Do no remove block on "cut" if block is in edit mode closes: https://github.com/frappe/builder/issues/303 --- frontend/src/utils/useBuilderEvents.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/utils/useBuilderEvents.ts b/frontend/src/utils/useBuilderEvents.ts index c16a6fa25..dadc080aa 100644 --- a/frontend/src/utils/useBuilderEvents.ts +++ b/frontend/src/utils/useBuilderEvents.ts @@ -55,6 +55,7 @@ export function useBuilderEvents( }); useEventListener(document, "cut", (e) => { + if (isTargetEditable(e)) return; copySelectedBlocksToClipboard(e); if (store.activeCanvas?.selectedBlocks.length) { for (const block of store.activeCanvas?.selectedBlocks) { From 0d60256341713bfcd44148b7db064657a8e3c8d0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 19:02:00 +0530 Subject: [PATCH 40/48] fix: Open HTML editor on dblclick stopped working after https://github.com/frappe/builder/pull/276 --- frontend/src/utils/useBlockEventHandlers.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/utils/useBlockEventHandlers.ts b/frontend/src/utils/useBlockEventHandlers.ts index c5cd269d4..6cd91e584 100644 --- a/frontend/src/utils/useBlockEventHandlers.ts +++ b/frontend/src/utils/useBlockEventHandlers.ts @@ -38,7 +38,9 @@ export function useBlockEventHandlers() { // dblclick on container adds text block or selects text block if only one child let children = block.getChildren(); if (block.isHTML()) { - // editor.value?.element.dispatchEvent(new MouseEvent("dblclick", e)); + document + .querySelector(`.editor[data-block-id="${block.blockId}"]`) + ?.dispatchEvent(new MouseEvent("dblclick", e)); e.stopPropagation(); } else if (block.isContainer()) { if (!children.length) { From 00e7acf2ce69db4e09378bb98c8434fce9553a67 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 27 Jan 2025 21:59:49 +0530 Subject: [PATCH 41/48] fix: Use overridden Dialog - to autoclose on route change --- frontend/src/components/BuilderToolbar.vue | 4 ++-- frontend/src/components/Modals/NewBlockTemplate.vue | 3 ++- frontend/src/pages/PageBuilderDashboard.vue | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/BuilderToolbar.vue b/frontend/src/components/BuilderToolbar.vue index 95c9c650a..27f31d40f 100644 --- a/frontend/src/components/BuilderToolbar.vue +++ b/frontend/src/components/BuilderToolbar.vue @@ -119,7 +119,6 @@ v-model="showSettingsDialog" style="z-index: 40" class="[&>div>div[id^=headlessui-dialog-panel]]:my-3" - :disableOutsideClickToClose="true" :options="{ title: 'Settings', size: '5xl', @@ -162,7 +161,8 @@ import SettingsGearIcon from "@/components/Icons/SettingsGear.vue"; import { webPages } from "@/data/webPage"; import { BuilderPage } from "@/types/Builder/BuilderPage"; import { getTextContent } from "@/utils/helpers"; -import { Dialog, Tooltip } from "frappe-ui"; +import { Tooltip } from "frappe-ui"; +import Dialog from "@/components/Controls/Dialog.vue"; import Popover from "frappe-ui/src/components/Popover.vue"; import { computed, ref } from "vue"; import { toast } from "vue-sonner"; diff --git a/frontend/src/components/Modals/NewBlockTemplate.vue b/frontend/src/components/Modals/NewBlockTemplate.vue index 26d6cd711..d74be7abd 100644 --- a/frontend/src/components/Modals/NewBlockTemplate.vue +++ b/frontend/src/components/Modals/NewBlockTemplate.vue @@ -62,7 +62,8 @@ diff --git a/frontend/src/pages/PagePreview.vue b/frontend/src/pages/PagePreview.vue index d948205bd..940159ac7 100644 --- a/frontend/src/pages/PagePreview.vue +++ b/frontend/src/pages/PagePreview.vue @@ -24,24 +24,7 @@ }" />
- - {{ publishing ? "Publishing" : "Publish" }} - +