From d2fa02a6f4c55c947e556b799a9d2bf5da5626f0 Mon Sep 17 00:00:00 2001 From: Mateusz Russak Date: Fri, 15 Mar 2024 13:45:12 +0100 Subject: [PATCH] feat: added reusable component goto parent button --- ui/src/builder/BuilderApp.vue | 7 ++- ui/src/builder/BuilderSettings.vue | 9 ++-- ui/src/builder/BuilderSettingsActions.vue | 50 +++++++++++++++++++ ui/src/builder/helpers.ts | 12 +++++ ui/src/builder/useDragDropComponent.ts | 5 +- ui/src/core/index.ts | 27 +++++++++- ui/src/core_components/other/CoreReusable.vue | 27 +++++++++- ui/src/renderer/ComponentProxy.vue | 5 +- 8 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 ui/src/builder/BuilderSettingsActions.vue create mode 100644 ui/src/builder/helpers.ts diff --git a/ui/src/builder/BuilderApp.vue b/ui/src/builder/BuilderApp.vue index fc22df680..e50b735ac 100644 --- a/ui/src/builder/BuilderApp.vue +++ b/ui/src/builder/BuilderApp.vue @@ -134,6 +134,7 @@ import BuilderInstanceTracker from "./BuilderInstanceTracker.vue"; import BuilderInsertionOverlay from "./BuilderInsertionOverlay.vue"; import BuilderInsertionLabel from "./BuilderInsertionLabel.vue"; import { isPlatformMac } from "../core/detectPlatform"; +import { getClosestComponent } from "./helpers"; const ss = inject(injectionKeys.core); const ssbm = inject(injectionKeys.builderManager); @@ -252,7 +253,8 @@ function handleRendererDrop(ev: DragEvent) { function handleRendererClick(ev: PointerEvent): void { if (builderMode.value === "preview") return; - const targetEl: HTMLElement = (ev.target as HTMLElement).closest( + const targetEl: HTMLElement = getClosestComponent( + ev.target as HTMLElement, "[data-streamsync-id]", ); if (!targetEl) return; @@ -268,7 +270,8 @@ function handleRendererClick(ev: PointerEvent): void { const handleRendererDragStart = (ev: DragEvent) => { if (builderMode.value === "preview") return; - const targetEl: HTMLElement = (ev.target as HTMLElement).closest( + const targetEl: HTMLElement = getClosestComponent( + ev.target as HTMLElement, "[data-streamsync-id]", ); diff --git a/ui/src/builder/BuilderSettings.vue b/ui/src/builder/BuilderSettings.vue index f9fc3e0c1..8b9104d5d 100644 --- a/ui/src/builder/BuilderSettings.vue +++ b/ui/src/builder/BuilderSettings.vue @@ -38,6 +38,7 @@
+ @@ -58,6 +59,7 @@ import injectionKeys from "../injectionKeys"; import BuilderSettingsHandlers from "./BuilderSettingsHandlers.vue"; import BuilderSettingsProperties from "./BuilderSettingsProperties.vue"; +import BuilderSettingsActions from "./BuilderSettingsActions.vue"; import BuilderSettingsBinding from "./BuilderSettingsBinding.vue"; import BuilderSettingsVisibility from "./BuilderSettingsVisibility.vue"; import BuilderCopyText from "./BuilderCopyText.vue"; @@ -67,12 +69,7 @@ const ssbm = inject(injectionKeys.builderManager); const docsActive = ref(false); const component = computed(() => ss.getComponentById(ssbm.getSelectedId())); - -const componentDefinition = computed(() => { - const { type } = component.value; - const definition = ss.getComponentDefinition(type); - return definition; -}); +const componentDefinition = ss.getComponentDefinitionById(component.value.id); const closeSettings = () => { ssbm.setSelection(null); diff --git a/ui/src/builder/BuilderSettingsActions.vue b/ui/src/builder/BuilderSettingsActions.vue new file mode 100644 index 000000000..8e4d92fc9 --- /dev/null +++ b/ui/src/builder/BuilderSettingsActions.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/ui/src/builder/helpers.ts b/ui/src/builder/helpers.ts new file mode 100644 index 000000000..bc041ffb6 --- /dev/null +++ b/ui/src/builder/helpers.ts @@ -0,0 +1,12 @@ + +export function getClosestComponent(target: HTMLElement, selector: string): HTMLElement { + const ignore: HTMLElement = (target as HTMLElement).closest( + ".streamsync-ignore", + ); + if (ignore) { + target = ignore; + } + + return (target as HTMLElement).closest(selector); +} + diff --git a/ui/src/builder/useDragDropComponent.ts b/ui/src/builder/useDragDropComponent.ts index 00f1fb6b3..fa837cb1d 100644 --- a/ui/src/builder/useDragDropComponent.ts +++ b/ui/src/builder/useDragDropComponent.ts @@ -1,4 +1,5 @@ import { Ref, ref } from "vue"; +import { getClosestComponent } from "./helpers"; import { Core, Component } from "../streamsyncTypes"; import { CANDIDATE_CONFIRMATION_DELAY_MS } from "./builderManager"; @@ -44,9 +45,9 @@ export function useDragDropComponent(ss: Core) { function getIdFromElement(el: HTMLElement) { // Elements inside a cage aren't taken into account for insertion - const cageEl = el.closest("[data-streamsync-cage]"); + const cageEl = getClosestComponent(el, "[data-streamsync-cage]"); const startEl = cageEl ?? el; - const targetEl: HTMLElement = startEl.closest("[data-streamsync-id]"); + const targetEl: HTMLElement = getClosestComponent(startEl, "[data-streamsync-id]"); if (!targetEl) return; return targetEl.dataset.streamsyncId; } diff --git a/ui/src/core/index.ts b/ui/src/core/index.ts index 31e28016d..a468acbcb 100644 --- a/ui/src/core/index.ts +++ b/ui/src/core/index.ts @@ -24,8 +24,9 @@ const KEEP_ALIVE_DELAY_MS = 60000; export function generateCore() { let sessionId: string = null; const sessionTimestamp: Ref = ref(null); - const componentDefinitionOverrides: Ref> = - ref({}); + const componentDefinitionOverrides: Ref< + Partial + > = ref({}); const mode: Ref<"run" | "edit"> = ref(null); const runCode: Ref = ref(null); const components: Ref = ref({}); @@ -567,6 +568,26 @@ export function generateCore() { return (componentDefinitionOverrides.value[componentId] = patch); } + function getInstancePath(componentId: Component["id"]): InstancePath { + const path = []; + let currentId = componentId; + while (currentId) { + const component = components.value[currentId]; + path.unshift({ componentId: component.id, instanceNumber: 0 }); + currentId = component.parentId; + } + return path; + } + function getComponentPageId(componentId: Component["id"]): Component["id"] { + let currentId = componentId; + while (currentId) { + const component = components.value[currentId]; + if (component.type == "page") return component.id; + currentId = component.parentId; + } + return null; + } + const core = { webSocket, syncHealth, @@ -596,6 +617,8 @@ export function generateCore() { isChildOf, getComponentDefinitionById, setComponentDefinitionById, + getInstancePath, + getComponentPageId, }; return core; diff --git a/ui/src/core_components/other/CoreReusable.vue b/ui/src/core_components/other/CoreReusable.vue index 5457bbcb0..0551587af 100644 --- a/ui/src/core_components/other/CoreReusable.vue +++ b/ui/src/core_components/other/CoreReusable.vue @@ -4,7 +4,7 @@