From ae7d80a10c4e25ba98808e0bf30f61be370ae4c9 Mon Sep 17 00:00:00 2001 From: sukuwc Date: Wed, 16 Sep 2026 15:06:57 +0200 Subject: [PATCH 1/6] Add "Show in folder" to profile/preset context menu Sends the local file's config over to grid-editor via postMessage, which resolves the path and reveals it in Finder/Explorer via shell.showItemInFolder. Disabled when the config has no local file (cloud-only). Requires the showItemInFolder IPC handler added in grid-editor (intechstudio/grid-editor#1621). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01619XN25FUTzqut4YbzZPQr --- src/lib/components/tree/ConfigTree.svelte | 14 ++++++++++++++ .../tree/ProfileCloudTreeItem.svelte | 8 +++++++- src/lib/configmanager/ConfigManager.ts | 18 ++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/lib/components/tree/ConfigTree.svelte b/src/lib/components/tree/ConfigTree.svelte index 641d384..306fb5b 100644 --- a/src/lib/components/tree/ConfigTree.svelte +++ b/src/lib/components/tree/ConfigTree.svelte @@ -255,6 +255,19 @@ }; } + function getItemCtxOptions(node: AbstractTreeNode): ContextMenuOptions { + const { item } = get(node).data as Tree.ItemData; + return { + items: [ + { + text: [`Show in folder`, ``], + handler: () => get(config_manager)?.showConfigInFolder(item), + isDisabled: () => !get(config_manager)?.hasLocalFile(item), + }, + ], + }; + } + function getItemCount(item: AbstractTreeNode) { const { type, children } = get(item); @@ -309,6 +322,7 @@ compatible={data.compatible} selected={data.item.id === $selected_config?.id} {expanded} + ctxOptions={getItemCtxOptions(item)} on:drag-start={() => handleDragStart(item)} on:drag-end={() => handleDragEnd(item)} on:click={() => handleClick(item)} diff --git a/src/lib/components/tree/ProfileCloudTreeItem.svelte b/src/lib/components/tree/ProfileCloudTreeItem.svelte index 0b22b29..7013950 100644 --- a/src/lib/components/tree/ProfileCloudTreeItem.svelte +++ b/src/lib/components/tree/ProfileCloudTreeItem.svelte @@ -14,7 +14,11 @@ } from "./TreeNode.svelte"; import { createEventDispatcher } from "svelte"; - import { SvgIcon } from "@intechstudio/grid-uikit"; + import { + SvgIcon, + contextTarget, + type ContextMenuOptions, + } from "@intechstudio/grid-uikit"; const dispatch = createEventDispatcher(); export let selected: boolean; @@ -23,6 +27,7 @@ export let item: AbstractTreeNode; export let itemProps: any; export let itemFunction: any; + export let ctxOptions: ContextMenuOptions = { items: [] }; type WithProfileCloudData = T & ProfileCloudCardData; @@ -46,6 +51,7 @@ id={$item.id} class="{selected ? 'border-selected' : 'border-unselected'} button" draggable="true" + use:contextTarget={ctxOptions} on:click={handleClick} on:dragstart={handleDragStart} on:dragend={handleDragEnd} diff --git a/src/lib/configmanager/ConfigManager.ts b/src/lib/configmanager/ConfigManager.ts index 3e9dafb..6b86152 100644 --- a/src/lib/configmanager/ConfigManager.ts +++ b/src/lib/configmanager/ConfigManager.ts @@ -29,6 +29,8 @@ export interface ConfigManager { changeCloudVisibility(config: Config, visibility: boolean): Promise; getCurrentOwnerId(): string | null | undefined; getConfigCloudId(config: Config): string | undefined; + hasLocalFile(config: Config): boolean; + showConfigInFolder(config: Config): Promise; configs: Readable; } @@ -330,6 +332,20 @@ export function createConfigManager(observer: { return appConfigIdToConfigMap.get(config.id)?.cloud?.id; } + function hasLocalFile(config: Config): boolean { + return appConfigIdToConfigMap.get(config.id)?.local !== undefined; + } + + async function showConfigInFolder(config: Config) { + const localConfig = appConfigIdToConfigMap.get(config.id)?.local; + if (!localConfig) return; + + await parentIframeCommunication({ + windowPostMessageName: "showConfigInFolder", + dataForParent: { config: localConfig }, + }); + } + return { cancel, deleteConfig, @@ -338,6 +354,8 @@ export function createConfigManager(observer: { changeCloudVisibility, getCurrentOwnerId, getConfigCloudId, + hasLocalFile, + showConfigInFolder, configs: derived(configs, ($configs) => { return $configs.map((item) => Object.freeze({ ...item })); }), From e1872d9a8da4e4e3402b48b2f04bfe28aec73d97 Mon Sep 17 00:00:00 2001 From: sukuwc Date: Wed, 16 Sep 2026 15:41:13 +0200 Subject: [PATCH 2/6] Move icon buttons and tooltips onto shared grid-uikit components Bumps @intechstudio/grid-uikit to 1.20260916.1336 and switches every ad-hoc `` (UserLogin, EditorLayout, ConfigCardDisplay, ConfigCardBrowser) onto the shared IconButton, and every local tooltip action import onto grid-uikit's own (now-exported) copy, deleting the duplicate lib/actions/tooltip.ts. Along the way: - Delete/Overwrite's flag-swapped "confirm"/"apply" button is replaced by IconButton's new tooltipButtons (Cancel/Confirm popup), with tooltipExtendedText showing "Delete/Overwrite ''?" once the buttons are visible. - The single sync-config button that swapped icon/tooltip/action based on state is replaced by three always-visible IconButtons (Create a copy / Download / Upload), each disabled unless it applies. - The one-off "Copied to clipboard!" popup (linkFlag + fade transition) is replaced by a real sendLogMessage toast to grid-editor's logger. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01619XN25FUTzqut4YbzZPQr --- package-lock.json | 8 +- package.json | 2 +- src/lib/actions/tooltip.ts | 27 ---- src/routes/BrowserLayout.svelte | 7 +- src/routes/ConfigCardBrowser.svelte | 99 ++++---------- src/routes/ConfigCardDisplay.svelte | 97 ++++---------- src/routes/EditorLayout.svelte | 193 ++++++++++++---------------- src/routes/UserLogin.svelte | 33 ++--- 8 files changed, 150 insertions(+), 316 deletions(-) delete mode 100644 src/lib/actions/tooltip.ts diff --git a/package-lock.json b/package-lock.json index 8c35d04..ab0f64e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@intechstudio/grid-protocol": "1.20260828.1315", - "@intechstudio/grid-uikit": "1.20260825.1204", + "@intechstudio/grid-uikit": "1.20260916.1336", "@melt-ui/svelte": "^0.86.6", "firebase": "^12.2.1", "marked": "^12.0.2", @@ -1255,9 +1255,9 @@ } }, "node_modules/@intechstudio/grid-uikit": { - "version": "1.20260825.1204", - "resolved": "https://registry.npmjs.org/@intechstudio/grid-uikit/-/grid-uikit-1.20260825.1204.tgz", - "integrity": "sha512-hLfy/dVbIDTTU/R6Gl3Kkn2K5MsSO97Xww9mx67AHmI8XImH6hA1VxJ/Gu3wki26azPfwW/f28n9nc/KfBSYfQ==", + "version": "1.20260916.1336", + "resolved": "https://registry.npmjs.org/@intechstudio/grid-uikit/-/grid-uikit-1.20260916.1336.tgz", + "integrity": "sha512-WxLp19ZNQZSa2h2E2cN9RPe4iqp32cAamPk8Py4Zv1ehwuMPtOsBUZq2DG/daupdVYJW49/MCndvnujGURjRug==", "dependencies": { "@melt-ui/svelte": "^0.86.6", "color-convert": "^2.0.1", diff --git a/package.json b/package.json index 9b9585e..1482b11 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "type": "module", "dependencies": { "@intechstudio/grid-protocol": "1.20260828.1315", - "@intechstudio/grid-uikit": "1.20260825.1204", + "@intechstudio/grid-uikit": "1.20260916.1336", "@melt-ui/svelte": "^0.86.6", "firebase": "^12.2.1", "marked": "^12.0.2", diff --git a/src/lib/actions/tooltip.ts b/src/lib/actions/tooltip.ts deleted file mode 100644 index bce7fdb..0000000 --- a/src/lib/actions/tooltip.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { Action } from "svelte/action"; -import { MoltenTooltip } from "@intechstudio/grid-uikit"; -import { mount } from "svelte"; - -export const tooltip: Action = ( - node: HTMLElement, - options: any, -): any => { - if (typeof options === "undefined") { - return; - } - - const sibling = document.createElement("div"); - node.parentNode?.insertBefore(sibling, node.nextSibling); - - options.referenceElement = node; - - setTimeout(() => { - mount(MoltenTooltip, { target: sibling, props: options }); - }); - - return { - destroy() { - sibling.remove(); - }, - }; -}; diff --git a/src/routes/BrowserLayout.svelte b/src/routes/BrowserLayout.svelte index a6242b3..b012dbb 100644 --- a/src/routes/BrowserLayout.svelte +++ b/src/routes/BrowserLayout.svelte @@ -9,9 +9,12 @@ type ConfigManager, createConfigManager, } from "../lib/configmanager/ConfigManager"; - import { tooltip } from "../lib/actions/tooltip"; import ConfigCardBrowser from "./ConfigCardBrowser.svelte"; - import { MeltCheckbox, MoltenPushButton } from "@intechstudio/grid-uikit"; + import { + MeltCheckbox, + MoltenPushButton, + tooltip, + } from "@intechstudio/grid-uikit"; import configuration from "../../Configuration.json"; let selectedConfigIndex: number | undefined = undefined; diff --git a/src/routes/ConfigCardBrowser.svelte b/src/routes/ConfigCardBrowser.svelte index f7117f5..6e3cf34 100644 --- a/src/routes/ConfigCardBrowser.svelte +++ b/src/routes/ConfigCardBrowser.svelte @@ -1,14 +1,12 @@