From 8ccb90cf082becec5e7e391404030093eb0d35d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 12:19:12 +0200 Subject: [PATCH 01/10] chore: initial commit From d4231b938ea5579935a713356dd6adcf2f866fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 15:21:21 +0200 Subject: [PATCH 02/10] feat: initial changes --- code/.gitignore | 5 +- .../actions/images-tool/images-tool.ts | 3 + .../home-showcase-animation.tsx | 131 ------ code/components/home/home.tsx | 105 +++-- .../{home-components => home}/login-form.tsx | 18 +- .../elements-tree/elements-tree.tsx | 6 +- .../room-components/help/help-drawer.tsx | 9 +- .../room-components/overlay/room-header.tsx | 396 +++++++++--------- .../room-components/overlay/tools-overlay.tsx | 27 ++ code/components/utils/logo.tsx | 1 + code/package.json | 8 +- 11 files changed, 326 insertions(+), 383 deletions(-) delete mode 100644 code/components/home-components/home-showcase-animation.tsx rename code/components/{home-components => home}/login-form.tsx (89%) diff --git a/code/.gitignore b/code/.gitignore index ee2b2e3..ba07807 100644 --- a/code/.gitignore +++ b/code/.gitignore @@ -41,4 +41,7 @@ yarn-error.log* next-env.d.ts .npmrc -certificates \ No newline at end of file +certificates + +server.cert +server.key \ No newline at end of file diff --git a/code/components/actions/images-tool/images-tool.ts b/code/components/actions/images-tool/images-tool.ts index cd0ea4a..85fe2b5 100644 --- a/code/components/actions/images-tool/images-tool.ts +++ b/code/components/actions/images-tool/images-tool.ts @@ -126,6 +126,7 @@ export class ImagesToolAction extends WeaveAction { }; this.preloadImgs[imageId] = new Image(); + this.preloadImgs[imageId].crossOrigin = "anonymous"; this.preloadImgs[imageId].onerror = () => { this.instance.emitEvent( "onImageLoadEnd", @@ -148,6 +149,8 @@ export class ImagesToolAction extends WeaveAction { this.instance.emitEvent("imageLoaded"); }; + console.log("Loading image", this.preloadImgs[imageId]); + this.preloadImgs[imageId].src = imageURL; } diff --git a/code/components/home-components/home-showcase-animation.tsx b/code/components/home-components/home-showcase-animation.tsx deleted file mode 100644 index 04e94da..0000000 --- a/code/components/home-components/home-showcase-animation.tsx +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) -// -// SPDX-License-Identifier: Apache-2.0 - -"use client"; - -import type React from "react"; -import { motion } from "framer-motion"; - -const draw = { - hidden: { pathLength: 0, opacity: 0 }, - visible: (i: number) => { - const delay = 1 + i * 0.5; - return { - pathLength: 1, - opacity: 1, - transition: { - pathLength: { delay, type: "spring", duration: 1.5, bounce: 0 }, - opacity: { delay, duration: 0.01 }, - }, - }; - }, -}; - -export const HomeShowCaseAnimation: React.FC = () => { - return ( - - - - - - - - - - - - - - - ); -}; diff --git a/code/components/home/home.tsx b/code/components/home/home.tsx index edc6deb..7bf9b4f 100644 --- a/code/components/home/home.tsx +++ b/code/components/home/home.tsx @@ -8,26 +8,28 @@ import React from "react"; import { Toaster } from "@/components/ui/sonner"; import { motion } from "motion/react"; import { Logo } from "@/components/utils/logo"; -import LoginForm from "../home-components/login-form"; +import LoginForm from "./login-form"; import { Button } from "../ui/button"; -import { Github, Book } from "lucide-react"; +import { Info, Eye, EyeOff, ExternalLink, X } from "lucide-react"; import { DOCUMENTATION_URL, GITHUB_URL } from "@/lib/constants"; import weavePackage from "../../node_modules/@inditextech/weave-sdk/package.json"; import weaveReactHelperPackage from "../../node_modules/@inditextech/weave-react/package.json"; import weaveStorePackage from "../../node_modules/@inditextech/weave-store-azure-web-pubsub/package.json"; export const Home = () => { + const [showDetails, setShowDetails] = React.useState(false); + return ( <> -
+
-
-
+
+
{ transition={{ duration: 0.5, delay: 0.2 }} className="flex flex-col items-end justify-center" > -

+

SHOWCASE

@@ -43,8 +45,8 @@ export const Home = () => {
-
-
+
+
+
-
-
-
- @inditextech/weave-sdk -
-
- - v{weavePackage.version} - -
-
- @inditextech/weave-react + {showDetails && ( +
+
+
+ + Dependencies Used +
+
-
- - v{weaveReactHelperPackage.version} - -
-
- @inditextech/weave-store-azure-web-pubsub -
-
- - v{weaveStorePackage.version} - +
+
+ @inditextech/weave-sdk +
+
+ + v{weavePackage.version} + +
+
+ @inditextech/weave-react +
+
+ + v{weaveReactHelperPackage.version} + +
+
+ @inditextech/weave-store-azure-web-pubsub +
+
+ + v{weaveStorePackage.version} + +
-
+ )}
diff --git a/code/components/home-components/login-form.tsx b/code/components/home/login-form.tsx similarity index 89% rename from code/components/home-components/login-form.tsx rename to code/components/home/login-form.tsx index c4c09aa..3492d5f 100644 --- a/code/components/home-components/login-form.tsx +++ b/code/components/home/login-form.tsx @@ -39,13 +39,20 @@ const formSchema = z .required(); function LoginForm() { + const roomRef = React.useRef(null); + const router = useRouter(); const setRoom = useCollaborationRoom((state) => state.setRoom); const setUser = useCollaborationRoom((state) => state.setUser); + React.useEffect(() => { + roomRef.current?.focus(); + }, []); + const form = useForm>({ resolver: zodResolver(formSchema), + defaultValues: { username: "", roomId: "", @@ -72,7 +79,7 @@ function LoginForm() { initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.5, delay: 0.4 }} - className="w-full max-w-md" + className="w-full max-w-md flex justify-center items-start" >
( - + Room name @@ -103,7 +111,7 @@ function LoginForm() { name="username" render={({ field }) => ( - + Username @@ -120,7 +128,7 @@ function LoginForm() {
diff --git a/code/components/room-components/elements-tree/elements-tree.tsx b/code/components/room-components/elements-tree/elements-tree.tsx index 9cb5964..b6766b8 100644 --- a/code/components/room-components/elements-tree/elements-tree.tsx +++ b/code/components/room-components/elements-tree/elements-tree.tsx @@ -285,7 +285,11 @@ export const ElementsTree = () => { const stage = instance.getStage(); const node = stage.findOne(`#${items[0]}`); - if (node && !instance.allNodesLocked([node])) { + if ( + node && + !instance.allNodesLocked([node]) && + instance.allNodesVisible([node]) + ) { instance.selectNodesByKey(items); } }} diff --git a/code/components/room-components/help/help-drawer.tsx b/code/components/room-components/help/help-drawer.tsx index 5740426..6c5509e 100644 --- a/code/components/room-components/help/help-drawer.tsx +++ b/code/components/room-components/help/help-drawer.tsx @@ -31,7 +31,7 @@ export const HelpDrawerTrigger = () => { const os = useGetOs(); const keyboardShortcutsVisible = useCollaborationRoom( - (state) => state.drawer.keyboardShortcuts.visible, + (state) => state.drawer.keyboardShortcuts.visible ); const setShowDrawer = useCollaborationRoom((state) => state.setShowDrawer); @@ -40,14 +40,15 @@ export const HelpDrawerTrigger = () => { onClick={() => { setShowDrawer( DRAWER_ELEMENTS.keyboardShortcuts, - !keyboardShortcutsVisible, + !keyboardShortcutsVisible ); }} className="w-full text-foreground cursor-pointer hover:rounded-none" > Keyboard shortcuts - {[SYSTEM_OS.MAC as string].includes(os) ? "⌘ K" : "Ctrl K"} + {[SYSTEM_OS.MAC as string].includes(os) && "⌥ ⌘ C"} + {[SYSTEM_OS.WINDOWS as string].includes(os) && "Alt Ctrl C"} ); @@ -55,7 +56,7 @@ export const HelpDrawerTrigger = () => { export const HelpDrawer = () => { const keyboardShortcutsVisible = useCollaborationRoom( - (state) => state.drawer.keyboardShortcuts.visible, + (state) => state.drawer.keyboardShortcuts.visible ); const setShowDrawer = useCollaborationRoom((state) => state.setShowDrawer); diff --git a/code/components/room-components/overlay/room-header.tsx b/code/components/room-components/overlay/room-header.tsx index 8633c23..5fd12e3 100644 --- a/code/components/room-components/overlay/room-header.tsx +++ b/code/components/room-components/overlay/room-header.tsx @@ -29,14 +29,11 @@ import { import { Logo } from "@/components/utils/logo"; import { Image as ImageIcon, - LogOut, ChevronDown, ChevronUp, Grid3X3Icon, GripIcon, Braces, - Github, - Book, MousePointer2, Check, Grid2X2Check, @@ -48,7 +45,9 @@ import { PencilRuler, PanelRight, ShieldCheck, - ShieldX, + ExternalLink, + LogOut, + MonitorCog, } from "lucide-react"; import { WEAVE_GRID_TYPES, @@ -68,14 +67,13 @@ import { GITHUB_URL, SIDEBAR_ELEMENTS, } from "@/lib/constants"; -import weavePackage from "../../../node_modules/@inditextech/weave-sdk/package.json"; -import weaveReactHelperPackage from "../../../node_modules/@inditextech/weave-react/package.json"; -import weaveStorePackage from "../../../node_modules/@inditextech/weave-store-azure-web-pubsub/package.json"; import { WEAVE_STORE_CONNECTION_STATUS } from "@inditextech/weave-types"; import { useIACapabilities } from "@/store/ia"; import { LlmSetupDialog } from "./llm-setup"; +import { useGetOs } from "../hooks/use-get-os"; export function RoomHeader() { + const os = useGetOs(); const router = useRouter(); const instance = useWeave((state) => state.instance); @@ -215,7 +213,7 @@ export function RoomHeader() { } )} > -
+
{ @@ -232,7 +230,7 @@ export function RoomHeader() { )} >
-
+
{menuOpen ? ( @@ -252,21 +250,6 @@ export function RoomHeader() { sideOffset={9} className="font-inter rounded-none" > - - Debug - - - - Print state to console - - {SYSTEM_OS.MAC ? "⌥ ⌘ C" : "Alt Ctrl C"} - - - - IA Capabilities @@ -288,19 +271,19 @@ export function RoomHeader() { )} {!iaEnabled && ( <> - - Disabled + + Setup )}
+ Interface - + + + Export as image + + + + + Grid + + - Hide grid + Hide ) : ( <> - Show grid + Show )}
@@ -357,7 +358,7 @@ export function RoomHeader() { >
- Grid as dots + Dots
{gridType === WEAVE_GRID_TYPES.DOTS && ( @@ -378,7 +379,7 @@ export function RoomHeader() { >
- Grid as lines + Lines
{gridType === WEAVE_GRID_TYPES.LINES && ( @@ -399,64 +400,55 @@ export function RoomHeader() { } onClick={handleExportToImage} > - Export room as image - - - { - window.open(GITHUB_URL, "_blank", "noopener,noreferrer"); - }} - > - Code repository - - { - window.open( - DOCUMENTATION_URL, - "_blank", - "noopener,noreferrer" - ); - }} - > - Documentation + Export as image - Weave.js dependencies versions + Other - -
- @inditextech/weave-sdk - - v{weavePackage.version} - -
-
- -
- @inditextech/weave-react - - v{weaveReactHelperPackage.version} - -
-
- -
- @inditextech/weave-store-azure-web-pubsub - - v{weaveStorePackage.version} - -
-
+ + { + window.open(GITHUB_URL, "_blank", "noopener,noreferrer"); + }} + > + GitHub + + { + window.open( + DOCUMENTATION_URL, + "_blank", + "noopener,noreferrer" + ); + }} + > + Documentation + + - - Exit room - + + + + Print state to console + + {[SYSTEM_OS.MAC as string].includes(os) && "⌥ ⌘ C"} + {[SYSTEM_OS.WINDOWS as string].includes(os) && + "Alt Ctrl C"} + + + + Exit room + + @@ -481,7 +473,7 @@ export function RoomHeader() { } )} > -
+
@@ -489,34 +481,131 @@ export function RoomHeader() {
- - -
- { - setSidebarsMenuOpen(open); - }} - > - + + +
+ { + setSidebarsMenuOpen(open); + }} + > + + + + + + + + Toolbars + + + + + { + e.preventDefault(); + }} + align="end" + side="bottom" + alignOffset={0} + sideOffset={19} + className="font-inter rounded-none" + > + + Available Toolbars + + + { + sidebarToggle(SIDEBAR_ELEMENTS.images); + }} + > + Images + + {SYSTEM_OS.MAC ? "⌥ ⌘ I" : "Alt Ctrl I"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.frames); + }} + > + Frames + + {SYSTEM_OS.MAC ? "⌥ ⌘ F" : "Alt Ctrl F"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.colorTokens); + }} + > + Color tokens + + {SYSTEM_OS.MAC ? "⌥ ⌘ O" : "Alt Ctrl O"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.nodesTree); + }} + > + Elements tree + + {SYSTEM_OS.MAC ? "⌥ ⌘ E" : "Alt Ctrl E"} + + + + + + + +
diff --git a/code/components/room-components/overlay/tools-overlay.tsx b/code/components/room-components/overlay/tools-overlay.tsx index bd536cd..7141839 100644 --- a/code/components/room-components/overlay/tools-overlay.tsx +++ b/code/components/room-components/overlay/tools-overlay.tsx @@ -548,6 +548,33 @@ export function ToolsOverlay() { tooltipSide="top" tooltipAlign="center" /> + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "imageTool"} + onClick={() => { + triggerTool("imageTool", { + imageURL: "http://localhost:8081/assets/model.jpg", + }); + }} + label={ +
+

Add an image (cross-origin)

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> } diff --git a/code/components/utils/logo.tsx b/code/components/utils/logo.tsx index 734e390..3de202a 100644 --- a/code/components/utils/logo.tsx +++ b/code/components/utils/logo.tsx @@ -42,6 +42,7 @@ export function Logo({ src={src} width={width} height={height} + priority className={cn(`object-cover`, { ["w-[calc(345px*0.6)] h-[calc(40px*0.6)]"]: kind === "landscape", ["w-11 h-11"]: kind === "large", diff --git a/code/package.json b/code/package.json index 2db53ef..1e5f580 100644 --- a/code/package.json +++ b/code/package.json @@ -34,10 +34,10 @@ "@commitlint/cli": "19.4.0", "@commitlint/config-conventional": "19.2.2", "@hookform/resolvers": "^4.1.3", - "@inditextech/weave-react": "0.35.0", - "@inditextech/weave-sdk": "0.35.0", - "@inditextech/weave-store-azure-web-pubsub": "0.35.0", - "@inditextech/weave-store-websockets": "0.35.0", + "@inditextech/weave-react": "0.37.0", + "@inditextech/weave-sdk": "0.37.0", + "@inditextech/weave-store-azure-web-pubsub": "0.37.0", + "@inditextech/weave-store-websockets": "0.37.0", "@next/env": "^15.2.1", "@radix-ui/react-accordion": "^1.2.10", "@radix-ui/react-avatar": "^1.1.3", From 4e8783b149f8abefe5e9e375db5d74ab423c5de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 15:27:22 +0200 Subject: [PATCH 03/10] chore: update weave dependencies --- code/package-lock.json | 606 +++++++++++++++++++++++++++-------------- 1 file changed, 402 insertions(+), 204 deletions(-) diff --git a/code/package-lock.json b/code/package-lock.json index 464b9be..a99cf56 100644 --- a/code/package-lock.json +++ b/code/package-lock.json @@ -12,10 +12,10 @@ "@commitlint/cli": "19.4.0", "@commitlint/config-conventional": "19.2.2", "@hookform/resolvers": "^4.1.3", - "@inditextech/weave-react": "0.35.0", - "@inditextech/weave-sdk": "0.35.0", - "@inditextech/weave-store-azure-web-pubsub": "0.35.0", - "@inditextech/weave-store-websockets": "0.35.0", + "@inditextech/weave-react": "0.37.0", + "@inditextech/weave-sdk": "0.37.0", + "@inditextech/weave-store-azure-web-pubsub": "0.37.0", + "@inditextech/weave-store-websockets": "0.37.0", "@next/env": "^15.2.1", "@radix-ui/react-accordion": "^1.2.10", "@radix-ui/react-avatar": "^1.1.3", @@ -178,6 +178,17 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/core-paging": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz", + "integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@azure/core-rest-pipeline": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.21.0.tgz", @@ -219,6 +230,27 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/identity": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.10.2.tgz", + "integrity": "sha512-Uth4vz0j+fkXCkbvutChUj03PDCokjbC6Wk9JT8hHEUtpy/EurNKAseb3+gO6Zi9VYBvwt61pgbzn1ovk942Qg==", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.5.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@azure/logger": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.2.0.tgz", @@ -231,13 +263,54 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/msal-browser": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.14.0.tgz", + "integrity": "sha512-6VB06LypBS0Cf/dSUwRZse/eGnfAHwDof7GpCfoo3JjnruSN40jFBw+QXZd1ox5OLC6633EdWRRz+TGeHMEspg==", + "dependencies": { + "@azure/msal-common": "15.8.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.8.0.tgz", + "integrity": "sha512-gYqq9MsWT/KZh8iTG37DkGv+wgfllgImTMB++Z83qn75M5eZ0cMX5kSSXdJqHbFm1qxaYydv+2kiVyA9ksN9pA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.6.2.tgz", + "integrity": "sha512-lfZtncCSmKvW31Bh3iUBkeTf+Myt85YsamMkGNZ0ayTO5MirOGBgTa3BgUth0kWFBQuhZIRfi5B95INZ+ppkjw==", + "dependencies": { + "@azure/msal-common": "15.8.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@azure/msal-node/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@azure/web-pubsub": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@azure/web-pubsub/-/web-pubsub-1.1.4.tgz", - "integrity": "sha512-ePRe4OtKmexm5ZJd3D9+JhSuP4XovNaZ8eJftUBoYJca6msl5Qna99dcq+eKJc/pPMXHEMSw+3+FWnSbTDMkkA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@azure/web-pubsub/-/web-pubsub-1.2.0.tgz", + "integrity": "sha512-s5QYFVpXy6fl8ppv1vTKyTTgOaKo7fx9WGxORRQukKKZovuOXA1jQ3zdRIBF9DjwggZCqwxHzbzZrUJYmelK2w==", "dependencies": { "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.2", + "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.0", "@azure/core-tracing": "^1.2.0", "@azure/logger": "^1.1.4", @@ -1817,9 +1890,9 @@ } }, "node_modules/@inditextech/weave-react": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@inditextech/weave-react/-/weave-react-0.35.0.tgz", - "integrity": "sha512-LG6D8BNM7cx/PySxY7mMYD46LvRAWwt8v3SoeDZjxRpRA7x4RegPUog+k/sB2s7S0XytseEEnoAnq2z10+O+fw==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@inditextech/weave-react/-/weave-react-0.37.0.tgz", + "integrity": "sha512-baHQIBCIcg4U4sh85LG1I6Nr+ZLKcfLBPaDxl+4UnLm8eNRv7tWBm2OXYm+XdKvRQatDHWhwwuaA53SolETVYg==", "dependencies": { "@syncedstore/core": "0.6.0", "konva": "9.3.20", @@ -1838,11 +1911,11 @@ } }, "node_modules/@inditextech/weave-sdk": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@inditextech/weave-sdk/-/weave-sdk-0.35.0.tgz", - "integrity": "sha512-dy43VHDp5bmZKhBR5H+Ike4NckoazRSppPHX5BsYQ7dYJtc77gjgXvjiSkaJR+7U7YWY6chzDBLWTn4uUepeKA==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@inditextech/weave-sdk/-/weave-sdk-0.37.0.tgz", + "integrity": "sha512-LUSKXX079T/iU2eU8VxPQk2XmYgOFD24oEQtC8hRUclydUZMyKl0a+sGOvVOCtCfhmVvWrr44BTWnLzrHOV04A==", "dependencies": { - "@inditextech/weave-types": "0.35.0", + "@inditextech/weave-types": "0.37.0", "@syncedstore/core": "0.6.0", "canvas": "3.1.0", "konva": "9.3.20", @@ -1859,11 +1932,12 @@ } }, "node_modules/@inditextech/weave-store-azure-web-pubsub": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@inditextech/weave-store-azure-web-pubsub/-/weave-store-azure-web-pubsub-0.35.0.tgz", - "integrity": "sha512-sZ36BSlLlQli/zNi058rKxhXZKN5HbdfMcPW+QzjrNh2U04iX51hueZdiEobaHCZVqukUheWSzxEM7QqWlEHwQ==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@inditextech/weave-store-azure-web-pubsub/-/weave-store-azure-web-pubsub-0.37.0.tgz", + "integrity": "sha512-1W8hz1dJgZ0Gdl6i0RbpfYj13rSscXtywmrAnn4Qj0+/w28JSnwG7dN2I1p7BopefgaXnsjaL+W5QB1YawX7RQ==", "dependencies": { - "@azure/web-pubsub": "1.1.4", + "@azure/identity": "4.10.2", + "@azure/web-pubsub": "1.2.0", "@syncedstore/core": "0.6.0", "buffer": "6.0.3", "konva": "9.3.20", @@ -1882,9 +1956,9 @@ } }, "node_modules/@inditextech/weave-store-websockets": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@inditextech/weave-store-websockets/-/weave-store-websockets-0.35.0.tgz", - "integrity": "sha512-dfPXM+NpFB6pauyJU7LeaNXXtfgObhjVIvdSgcutKZflJVzCNqO+aDcDEbpP3xzGbuqwqHaq6ouwji9tFyMO5Q==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@inditextech/weave-store-websockets/-/weave-store-websockets-0.37.0.tgz", + "integrity": "sha512-Q2RdYxGm2IUxOSMfk823e+mnrv0NQVLE5Jg8bJum23zG2XRsLxDr13ZcSAgQxb27qEziehkKxgbgvHlzwBNpxw==", "dependencies": { "@syncedstore/core": "0.6.0", "konva": "9.3.20", @@ -1902,9 +1976,9 @@ } }, "node_modules/@inditextech/weave-types": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@inditextech/weave-types/-/weave-types-0.35.0.tgz", - "integrity": "sha512-SsDqC5hkgvkrbOOo0r5IHOSK6Cih8jU9yj7cOB9oPNCaV5Jr94Cp58mtj+hQX6PecqdmoIc8Jyz61kTj1Vbq3A==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@inditextech/weave-types/-/weave-types-0.37.0.tgz", + "integrity": "sha512-oOY9MRoOvW1cGdo1bgBaYEIHmnXXrSz6C/lZaClGwzPIJYpPplN3YykHtKaesopVr5+XZM51YXDjClWiWPeHdA==", "dependencies": { "konva": "9.3.20", "yjs": "13.6.27" @@ -3408,9 +3482,9 @@ "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz", - "integrity": "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.2.tgz", + "integrity": "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==", "cpu": [ "arm" ], @@ -3421,9 +3495,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz", - "integrity": "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.2.tgz", + "integrity": "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==", "cpu": [ "arm64" ], @@ -3434,9 +3508,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz", - "integrity": "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.2.tgz", + "integrity": "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==", "cpu": [ "arm64" ], @@ -3447,9 +3521,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz", - "integrity": "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.2.tgz", + "integrity": "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==", "cpu": [ "x64" ], @@ -3460,9 +3534,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz", - "integrity": "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.2.tgz", + "integrity": "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==", "cpu": [ "arm64" ], @@ -3473,9 +3547,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz", - "integrity": "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.2.tgz", + "integrity": "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==", "cpu": [ "x64" ], @@ -3486,9 +3560,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz", - "integrity": "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.2.tgz", + "integrity": "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==", "cpu": [ "arm" ], @@ -3499,9 +3573,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz", - "integrity": "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.2.tgz", + "integrity": "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==", "cpu": [ "arm" ], @@ -3512,9 +3586,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz", - "integrity": "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.2.tgz", + "integrity": "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==", "cpu": [ "arm64" ], @@ -3525,9 +3599,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz", - "integrity": "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.2.tgz", + "integrity": "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==", "cpu": [ "arm64" ], @@ -3538,9 +3612,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz", - "integrity": "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.2.tgz", + "integrity": "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==", "cpu": [ "loong64" ], @@ -3551,9 +3625,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz", - "integrity": "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.2.tgz", + "integrity": "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==", "cpu": [ "ppc64" ], @@ -3564,9 +3638,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz", - "integrity": "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.2.tgz", + "integrity": "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==", "cpu": [ "riscv64" ], @@ -3577,9 +3651,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz", - "integrity": "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.2.tgz", + "integrity": "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==", "cpu": [ "riscv64" ], @@ -3590,9 +3664,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz", - "integrity": "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.2.tgz", + "integrity": "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==", "cpu": [ "s390x" ], @@ -3603,9 +3677,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz", - "integrity": "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.2.tgz", + "integrity": "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==", "cpu": [ "x64" ], @@ -3616,9 +3690,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz", - "integrity": "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.2.tgz", + "integrity": "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==", "cpu": [ "x64" ], @@ -3629,9 +3703,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz", - "integrity": "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.2.tgz", + "integrity": "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==", "cpu": [ "arm64" ], @@ -3642,9 +3716,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz", - "integrity": "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.2.tgz", + "integrity": "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==", "cpu": [ "ia32" ], @@ -3655,9 +3729,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz", - "integrity": "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.2.tgz", + "integrity": "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==", "cpu": [ "x64" ], @@ -4564,9 +4638,9 @@ "dev": true }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.10.1.tgz", - "integrity": "sha512-zohDKXT1Ok0yhbVGff4YAg9HUs5ietG5GpvJBPFSApZnGe7uf2cd26DRhKZbn0Be6xHUZrSzP+RAgMmzyc71EA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.0.tgz", + "integrity": "sha512-LRw5BW29sYj9NsQC6QoqeLVQhEa+BwVINYyMlcve+6stwdBsSt5UB7zw4UZB4+4PNqIVilHoMaPWCb/KhABHQw==", "cpu": [ "arm" ], @@ -4577,9 +4651,9 @@ ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.10.1.tgz", - "integrity": "sha512-tAN6k5UrTd4nicpA7s2PbjR/jagpDzAmvXFjbpTazUe5FRsFxVcBlS1F5Lzp5jtWU6bdiqRhSvd4X8rdpCffeA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.0.tgz", + "integrity": "sha512-zYX8D2zcWCAHqghA8tPjbp7LwjVXbIZP++mpU/Mrf5jUVlk3BWIxkeB8yYzZi5GpFSlqMcRZQxQqbMI0c2lASQ==", "cpu": [ "arm64" ], @@ -4590,9 +4664,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.10.1.tgz", - "integrity": "sha512-+FCsag8WkauI4dQ50XumCXdfvDCZEpMUnvZDsKMxfOisnEklpDFXc6ThY0WqybBYZbiwR5tWcFaZmI0G6b4vrg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.0.tgz", + "integrity": "sha512-YsYOT049hevAY/lTYD77GhRs885EXPeAfExG5KenqMJ417nYLS2N/kpRpYbABhFZBVQn+2uRPasTe4ypmYoo3w==", "cpu": [ "arm64" ], @@ -4603,9 +4677,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.10.1.tgz", - "integrity": "sha512-qYKGGm5wk71ONcXTMZ0+J11qQeOAPz3nw6VtqrBUUELRyXFyvK8cHhHsLBFR4GHnilc2pgY1HTB2TvdW9wO26Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.0.tgz", + "integrity": "sha512-PSjvk3OZf1aZImdGY5xj9ClFG3bC4gnSSYWrt+id0UAv+GwwVldhpMFjAga8SpMo2T1GjV9UKwM+QCsQCQmtdA==", "cpu": [ "x64" ], @@ -4616,9 +4690,9 @@ ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.10.1.tgz", - "integrity": "sha512-hOHMAhbvIQ63gkpgeNsXcWPSyvXH7ZEyeg254hY0Lp/hX8NdW+FsUWq73g9946Pc/BrcVI/I3C1cmZ4RCX9bNw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.0.tgz", + "integrity": "sha512-KC/iFaEN/wsTVYnHClyHh5RSYA9PpuGfqkFua45r4sweXpC0KHZ+BYY7ikfcGPt5w1lMpR1gneFzuqWLQxsRKg==", "cpu": [ "x64" ], @@ -4629,9 +4703,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.10.1.tgz", - "integrity": "sha512-6ds7+zzHJgTDmpe0gmFcOTvSUhG5oZukkt+cCsSb3k4Uiz2yEQB4iCRITX2hBwSW+p8gAieAfecITjgqCkswXw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.0.tgz", + "integrity": "sha512-CDh/0v8uot43cB4yKtDL9CVY8pbPnMV0dHyQCE4lFz6PW/+9tS0i9eqP5a91PAqEBVMqH1ycu+k8rP6wQU846w==", "cpu": [ "arm" ], @@ -4642,9 +4716,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.10.1.tgz", - "integrity": "sha512-P7A0G2/jW00diNJyFeq4W9/nxovD62Ay8CMP4UK9OymC7qO7rG1a8Upad68/bdfpIOn7KSp7Aj/6lEW3yyznAA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.0.tgz", + "integrity": "sha512-+TE7epATDSnvwr3L/hNHX3wQ8KQYB+jSDTdywycg3qDqvavRP8/HX9qdq/rMcnaRDn4EOtallb3vL/5wCWGCkw==", "cpu": [ "arm" ], @@ -4655,9 +4729,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.10.1.tgz", - "integrity": "sha512-Cg6xzdkrpltcTPO4At+A79zkC7gPDQIgosJmVV8M104ImB6KZi1MrNXgDYIAfkhUYjPzjNooEDFRAwwPadS7ZA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.0.tgz", + "integrity": "sha512-VBAYGg3VahofpQ+L4k/ZO8TSICIbUKKTaMYOWHWfuYBFqPbSkArZZLezw3xd27fQkxX4BaLGb/RKnW0dH9Y/UA==", "cpu": [ "arm64" ], @@ -4668,9 +4742,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.10.1.tgz", - "integrity": "sha512-aNeg99bVkXa4lt+oZbjNRPC8ZpjJTKxijg/wILrJdzNyAymO2UC/HUK1UfDjt6T7U5p/mK24T3CYOi3/+YEQSA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.0.tgz", + "integrity": "sha512-9IgGFUUb02J1hqdRAHXpZHIeUHRrbnGo6vrRbz0fREH7g+rzQy53/IBSyadZ/LG5iqMxukriNPu4hEMUn+uWEg==", "cpu": [ "arm64" ], @@ -4681,9 +4755,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.10.1.tgz", - "integrity": "sha512-ylz5ojeXrkPrtnzVhpCO+YegG63/aKhkoTlY8PfMfBfLaUG8v6m6iqrL7sBUKdVBgOB4kSTUPt9efQdA/Y3Z/w==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.0.tgz", + "integrity": "sha512-LR4iQ/LPjMfivpL2bQ9kmm3UnTas3U+umcCnq/CV7HAkukVdHxrDD1wwx74MIWbbgzQTLPYY7Ur2MnnvkYJCBQ==", "cpu": [ "ppc64" ], @@ -4694,9 +4768,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.10.1.tgz", - "integrity": "sha512-xcWyhmJfXXOxK7lvE4+rLwBq+on83svlc0AIypfe6x4sMJR+S4oD7n9OynaQShfj2SufPw2KJAotnsNb+4nN2g==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.0.tgz", + "integrity": "sha512-HCupFQwMrRhrOg7YHrobbB5ADg0Q8RNiuefqMHVsdhEy9lLyXm/CxsCXeLJdrg27NAPsCaMDtdlm8Z2X8x91Tg==", "cpu": [ "riscv64" ], @@ -4707,9 +4781,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.10.1.tgz", - "integrity": "sha512-mW9JZAdOCyorgi1eLJr4gX7xS67WNG9XNPYj5P8VuttK72XNsmdw9yhOO4tDANMgiLXFiSFaiL1gEpoNtRPw/A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.0.tgz", + "integrity": "sha512-Ckxy76A5xgjWa4FNrzcKul5qFMWgP5JSQ5YKd0XakmWOddPLSkQT+uAvUpQNnFGNbgKzv90DyQlxPDYPQ4nd6A==", "cpu": [ "riscv64" ], @@ -4720,9 +4794,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.10.1.tgz", - "integrity": "sha512-NZGKhBy6xkJ0k09cWNZz4DnhBcGlhDd3W+j7EYoNvf5TSwj2K6kbmfqTWITEgkvjsMUjm1wsrc4IJaH6VtjyHQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.0.tgz", + "integrity": "sha512-HfO0PUCCRte2pMJmVyxPI+eqT7KuV3Fnvn2RPvMe5mOzb2BJKf4/Vth8sSt9cerQboMaTVpbxyYjjLBWIuI5BQ==", "cpu": [ "s390x" ], @@ -4733,9 +4807,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.10.1.tgz", - "integrity": "sha512-VsjgckJ0gNMw7p0d8In6uPYr+s0p16yrT2rvG4v2jUpEMYkpnfnCiALa9SWshbvlGjKQ98Q2x19agm3iFk8w8Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.0.tgz", + "integrity": "sha512-9PZdjP7tLOEjpXHS6+B/RNqtfVUyDEmaViPOuSqcbomLdkJnalt5RKQ1tr2m16+qAufV0aDkfhXtoO7DQos/jg==", "cpu": [ "x64" ], @@ -4746,9 +4820,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.10.1.tgz", - "integrity": "sha512-idMnajMeejnaFi0Mx9UTLSYFDAOTfAEP7VjXNgxKApso3Eu2Njs0p2V95nNIyFi4oQVGFmIuCkoznAXtF/Zbmw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.0.tgz", + "integrity": "sha512-qkE99ieiSKMnFJY/EfyGKVtNra52/k+lVF/PbO4EL5nU6AdvG4XhtJ+WHojAJP7ID9BNIra/yd75EHndewNRfA==", "cpu": [ "x64" ], @@ -4759,9 +4833,9 @@ ] }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.10.1.tgz", - "integrity": "sha512-7jyhjIRNFjzlr8x5pth6Oi9hv3a7ubcVYm2GBFinkBQKcFhw4nIs5BtauSNtDW1dPIGrxF0ciynCZqzxMrYMsg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.0.tgz", + "integrity": "sha512-MjXek8UL9tIX34gymvQLecz2hMaQzOlaqYJJBomwm1gsvK2F7hF+YqJJ2tRyBDTv9EZJGMt4KlKkSD/gZWCOiw==", "cpu": [ "wasm32" ], @@ -4775,9 +4849,9 @@ } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.10.1.tgz", - "integrity": "sha512-TY79+N+Gkoo7E99K+zmsKNeiuNJYlclZJtKqsHSls8We2iGhgxtletVsiBYie93MSTDRDMI8pkBZJlIJSZPrdA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.0.tgz", + "integrity": "sha512-9LT6zIGO7CHybiQSh7DnQGwFMZvVr0kUjah6qQfkH2ghucxPV6e71sUXJdSM4Ba0MaGE6DC/NwWf7mJmc3DAng==", "cpu": [ "arm64" ], @@ -4788,9 +4862,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.10.1.tgz", - "integrity": "sha512-BAJN5PEPlEV+1m8+PCtFoKm3LQ1P57B4Z+0+efU0NzmCaGk7pUaOxuPgl+m3eufVeeNBKiPDltG0sSB9qEfCxw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.0.tgz", + "integrity": "sha512-HYchBYOZ7WN266VjoGm20xFv5EonG/ODURRgwl9EZT7Bq1nLEs6VKJddzfFdXEAho0wfFlt8L/xIiE29Pmy1RA==", "cpu": [ "ia32" ], @@ -4801,9 +4875,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.10.1.tgz", - "integrity": "sha512-2v3erKKmmCyIVvvhI2nF15qEbdBpISTq44m9pyd5gfIJB1PN94oePTLWEd82XUbIbvKhv76xTSeUQSCOGesLeg==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.0.tgz", + "integrity": "sha512-+oLKLHw3I1UQo4MeHfoLYF+e6YBa8p5vYUw3Rgt7IDzCs+57vIZqQlIo62NDpYM0VG6BjWOwnzBczMvbtH8hag==", "cpu": [ "x64" ], @@ -5457,6 +5531,20 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -5533,9 +5621,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001726", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", - "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", "funding": [ { "type": "opencollective", @@ -6029,9 +6117,9 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "dev": true }, "node_modules/decompress-response": { @@ -6071,6 +6159,32 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -6088,6 +6202,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", @@ -7208,9 +7333,9 @@ } }, "node_modules/expect-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", - "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, "engines": { "node": ">=12.0.0" @@ -8190,6 +8315,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -8252,6 +8391,23 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-map": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", @@ -8482,6 +8638,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", @@ -9912,6 +10082,23 @@ "protobufjs": "^7.2.4" } }, + "node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/open-file-explorer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/open-file-explorer/-/open-file-explorer-1.0.2.tgz", @@ -10180,9 +10367,9 @@ } }, "node_modules/postprocessing": { - "version": "6.37.5", - "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.37.5.tgz", - "integrity": "sha512-nP3MOpwkhUVtlKSqZ2RsBIcNuAP/JqwKQo+u975PahpBknY/nIxf9FEVZ5FAB2Nyjve96CARfNjDkiqEhxOrhw==", + "version": "6.37.6", + "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.37.6.tgz", + "integrity": "sha512-KrdKLf1257RkoIk3z3nhRS0aToKrX2xJgtR0lbnOQUjd+1I4GVNv1gQYsQlfRglvEXjpzrwqOA5fXfoDBimadg==", "peerDependencies": { "three": ">= 0.157.0 < 0.179.0" } @@ -10392,9 +10579,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.59.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.59.0.tgz", - "integrity": "sha512-kmkek2/8grqarTJExFNjy+RXDIP8yM+QTl3QL6m6Q8b2bih4ltmiXxH7T9n+yXNK477xPh5yZT/6vD8sYGzJTA==", + "version": "7.60.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.60.0.tgz", + "integrity": "sha512-SBrYOvMbDB7cV8ZfNpaiLcgjH/a1c7aK0lK+aNigpf4xWLO8q+o4tcvVurv3c4EOyzn/3dCsYt4GKD42VvJ/+A==", "engines": { "node": ">=18.0.0" }, @@ -10724,9 +10911,9 @@ } }, "node_modules/rollup": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz", - "integrity": "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==", + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.2.tgz", + "integrity": "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==", "dev": true, "dependencies": { "@types/estree": "1.0.8" @@ -10739,26 +10926,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.44.1", - "@rollup/rollup-android-arm64": "4.44.1", - "@rollup/rollup-darwin-arm64": "4.44.1", - "@rollup/rollup-darwin-x64": "4.44.1", - "@rollup/rollup-freebsd-arm64": "4.44.1", - "@rollup/rollup-freebsd-x64": "4.44.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.44.1", - "@rollup/rollup-linux-arm-musleabihf": "4.44.1", - "@rollup/rollup-linux-arm64-gnu": "4.44.1", - "@rollup/rollup-linux-arm64-musl": "4.44.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.44.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1", - "@rollup/rollup-linux-riscv64-gnu": "4.44.1", - "@rollup/rollup-linux-riscv64-musl": "4.44.1", - "@rollup/rollup-linux-s390x-gnu": "4.44.1", - "@rollup/rollup-linux-x64-gnu": "4.44.1", - "@rollup/rollup-linux-x64-musl": "4.44.1", - "@rollup/rollup-win32-arm64-msvc": "4.44.1", - "@rollup/rollup-win32-ia32-msvc": "4.44.1", - "@rollup/rollup-win32-x64-msvc": "4.44.1", + "@rollup/rollup-android-arm-eabi": "4.44.2", + "@rollup/rollup-android-arm64": "4.44.2", + "@rollup/rollup-darwin-arm64": "4.44.2", + "@rollup/rollup-darwin-x64": "4.44.2", + "@rollup/rollup-freebsd-arm64": "4.44.2", + "@rollup/rollup-freebsd-x64": "4.44.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", + "@rollup/rollup-linux-arm-musleabihf": "4.44.2", + "@rollup/rollup-linux-arm64-gnu": "4.44.2", + "@rollup/rollup-linux-arm64-musl": "4.44.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-musl": "4.44.2", + "@rollup/rollup-linux-s390x-gnu": "4.44.2", + "@rollup/rollup-linux-x64-gnu": "4.44.2", + "@rollup/rollup-linux-x64-musl": "4.44.2", + "@rollup/rollup-win32-arm64-msvc": "4.44.2", + "@rollup/rollup-win32-ia32-msvc": "4.44.2", + "@rollup/rollup-win32-x64-msvc": "4.44.2", "fsevents": "~2.3.2" } }, @@ -10768,6 +10955,17 @@ "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", "dev": true }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12177,9 +12375,9 @@ } }, "node_modules/unrs-resolver": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.10.1.tgz", - "integrity": "sha512-EFrL7Hw4kmhZdwWO3dwwFJo6hO3FXuQ6Bg8BK/faHZ9m1YxqBS31BNSTxklIQkxK/4LlV8zTYnPsIRLBzTzjCA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.0.tgz", + "integrity": "sha512-uw3hCGO/RdAEAb4zgJ3C/v6KIAFFOtBoxR86b2Ejc5TnH7HrhTWJR2o0A9ullC3eWMegKQCw/arQ/JivywQzkg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -12189,25 +12387,25 @@ "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.10.1", - "@unrs/resolver-binding-android-arm64": "1.10.1", - "@unrs/resolver-binding-darwin-arm64": "1.10.1", - "@unrs/resolver-binding-darwin-x64": "1.10.1", - "@unrs/resolver-binding-freebsd-x64": "1.10.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.10.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.10.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.10.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.10.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.10.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.10.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.10.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.10.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.10.1", - "@unrs/resolver-binding-linux-x64-musl": "1.10.1", - "@unrs/resolver-binding-wasm32-wasi": "1.10.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.10.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.10.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.10.1" + "@unrs/resolver-binding-android-arm-eabi": "1.11.0", + "@unrs/resolver-binding-android-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-arm64": "1.11.0", + "@unrs/resolver-binding-darwin-x64": "1.11.0", + "@unrs/resolver-binding-freebsd-x64": "1.11.0", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.0", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.0", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.0", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.0", + "@unrs/resolver-binding-linux-x64-musl": "1.11.0", + "@unrs/resolver-binding-wasm32-wasi": "1.11.0", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.0", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.0", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.0" } }, "node_modules/update-browserslist-db": { @@ -13028,9 +13226,9 @@ } }, "node_modules/zod": { - "version": "3.25.72", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.72.tgz", - "integrity": "sha512-Cl+fe4dNL4XumOBNBsr0lHfA80PQiZXHI4xEMTEr8gt6aGz92t3lBA32e71j9+JeF/VAYvdfBnuwJs+BMx/BrA==", + "version": "3.25.75", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.75.tgz", + "integrity": "sha512-OhpzAmVzabPOL6C3A3gpAifqr9MqihV/Msx3gor2b2kviCgcb+HM9SEOpMWwwNp9MRunWnhtAKUoo0AHhjyPPg==", "funding": { "url": "https://github.com/sponsors/colinhacks" } From 65b038896798077d61110f272d317ed87c40e9b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 15:29:19 +0200 Subject: [PATCH 04/10] chore: deploy wf changes --- .github/workflows/code-deploy.yml | 50 +++++++++---------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/.github/workflows/code-deploy.yml b/.github/workflows/code-deploy.yml index d5c8582..0977955 100644 --- a/.github/workflows/code-deploy.yml +++ b/.github/workflows/code-deploy.yml @@ -16,7 +16,9 @@ on: required: true type: choice options: + - azure-develop - azure-development + - azure-pro - azure-production default: "azure-development" @@ -28,7 +30,7 @@ jobs: deploy: name: Deploy to Container Apps runs-on: ubuntu-24.04 - environment: ${{ github.event.inputs.ENVIRONMENT && github.event.inputs.ENVIRONMENT || 'azure-development' }} + environment: ${{ github.event.inputs.ENVIRONMENT && github.event.inputs.ENVIRONMENT || 'azure-develop' }} env: AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} @@ -38,8 +40,8 @@ jobs: AZURE_ACR_NAME: ${{ vars.AZURE_ACR_NAME }} AZURE_CONTAINER_ENVIRONMENT_NAME: ${{ vars.AZURE_CONTAINER_ENVIRONMENT_NAME }} AZURE_RESOURCE_GROUP: ${{ vars.AZURE_RESOURCE_GROUP }} - AZURE_CONTAINER_NAME: "weavejs-frontend" - AZURE_CONTAINER_NAME_BACKEND: "weavejs-backend" + AZURE_CONTAINER_NAME: "frontend" + AZURE_CONTAINER_NAME_BACKEND: "backend" AZURE_IDENTITY_ID: ${{ secrets.AZURE_IDENTITY_ID }} NEXT_PUBLIC_API_ENDPOINT: ${{ vars.NEXT_PUBLIC_API_ENDPOINT }} NEXT_PUBLIC_API_V2_ENDPOINT: ${{ vars.NEXT_PUBLIC_API_V2_ENDPOINT }} @@ -99,38 +101,14 @@ jobs: - name: Deploy uses: azure/cli@v2 + env: + GITHUB_SHA: ${{ github.sha }} with: - azcliversion: latest inlineScript: | - az containerapp create \ - --name $AZURE_CONTAINER_NAME \ - --resource-group $AZURE_RESOURCE_GROUP \ - --environment $AZURE_CONTAINER_ENVIRONMENT_NAME \ - --image $AZURE_ACR_NAME.azurecr.io/$AZURE_CONTAINER_NAME:${{ github.sha }} \ - --target-port 8080 \ - --ingress external \ - --registry-server $AZURE_ACR_NAME.azurecr.io \ - --user-assigned "$AZURE_IDENTITY_ID" \ - --registry-identity "$AZURE_IDENTITY_ID" \ - --min-replicas 1 \ - --max-replicas 2 \ - --scale-rule-name http-rule \ - --scale-rule-type http \ - --scale-rule-http-concurrency 10 \ - --query properties.configuration.ingress.fqdn - - - name: Add CDN IP Access Restrictions - run: | - echo "Adding CDN IP access restrictions..." - COUNT=1 - for IP in $(echo "$CDN_IP_LIST" | tr ',' '\n'); do - echo "Adding IP rule $IP" - az containerapp ingress access-restriction set \ - --name $AZURE_CONTAINER_NAME \ - --resource-group $AZURE_RESOURCE_GROUP \ - --rule-name "rule-$COUNT" \ - --ip-address $IP \ - --description "IP allow $COUNT" \ - --action Allow - ((COUNT++)) - done + azcliversion: latest + az containerapp update \ + --name $AZURE_CONTAINER_NAME \ + --resource-group $AZURE_RESOURCE_GROUP \ + --image $AZURE_ACR_NAME.azurecr.io/$AZURE_CONTAINER_NAME:$GITHUB_SHA \ + --revision-suffix $GITHUB_SHA \ + --query properties.configuration.ingress.fqdn From 73b81adaec27338e022963c9bdd4cdd6096e5ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 15:30:16 +0200 Subject: [PATCH 05/10] chore: fix sonarqube issues --- code/components/room-components/overlay/room-header.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/components/room-components/overlay/room-header.tsx b/code/components/room-components/overlay/room-header.tsx index 5fd12e3..e5cc5b4 100644 --- a/code/components/room-components/overlay/room-header.tsx +++ b/code/components/room-components/overlay/room-header.tsx @@ -306,7 +306,7 @@ export function RoomHeader() { Date: Mon, 7 Jul 2025 15:32:03 +0200 Subject: [PATCH 06/10] chore: fix deploy wf --- .github/workflows/code-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/code-deploy.yml b/.github/workflows/code-deploy.yml index 0977955..1ed361b 100644 --- a/.github/workflows/code-deploy.yml +++ b/.github/workflows/code-deploy.yml @@ -104,8 +104,8 @@ jobs: env: GITHUB_SHA: ${{ github.sha }} with: - inlineScript: | azcliversion: latest + inlineScript: | az containerapp update \ --name $AZURE_CONTAINER_NAME \ --resource-group $AZURE_RESOURCE_GROUP \ From 6b3d30591906275b22406ae4a3bdb3864571b080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Mon, 7 Jul 2025 16:26:29 +0200 Subject: [PATCH 07/10] chore: support for health-checks --- code/app/v1/liveness/route.ts | 12 ++++++++++++ code/app/v1/readiness/route.ts | 12 ++++++++++++ code/app/v1/startup/route.ts | 12 ++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 code/app/v1/liveness/route.ts create mode 100644 code/app/v1/readiness/route.ts create mode 100644 code/app/v1/startup/route.ts diff --git a/code/app/v1/liveness/route.ts b/code/app/v1/liveness/route.ts new file mode 100644 index 0000000..3244632 --- /dev/null +++ b/code/app/v1/liveness/route.ts @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +export async function GET() { + return Response.json( + { status: "OK" }, + { + status: 200, + } + ); +} diff --git a/code/app/v1/readiness/route.ts b/code/app/v1/readiness/route.ts new file mode 100644 index 0000000..3244632 --- /dev/null +++ b/code/app/v1/readiness/route.ts @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +export async function GET() { + return Response.json( + { status: "OK" }, + { + status: 200, + } + ); +} diff --git a/code/app/v1/startup/route.ts b/code/app/v1/startup/route.ts new file mode 100644 index 0000000..3244632 --- /dev/null +++ b/code/app/v1/startup/route.ts @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +export async function GET() { + return Response.json( + { status: "OK" }, + { + status: 200, + } + ); +} From 7ee77b9f00982199ba8952008effe8b86761dd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesus=20Manuel=20Pi=C3=B1eiro=20Cid?= Date: Tue, 8 Jul 2025 18:10:28 +0200 Subject: [PATCH 08/10] chore: update UI --- code/components/home/home.tsx | 14 +- code/components/home/login-form.tsx | 2 +- .../room-components/connection-status.tsx | 14 +- .../hooks/use-keyboard-handler.tsx | 2 +- .../room-components/overlay/divider.tsx | 3 + .../overlay/hooks/use-images-tools.tsx | 134 + .../overlay/hooks/use-shapes-tools.tsx | 124 + .../overlay/hooks/use-strokes-tools.tsx | 92 + .../room-components/overlay/llm-popup-v2.tsx | 8 +- .../overlay/node-properties.tsx | 18 + .../room-components/overlay/room-header.tsx | 212 +- .../overlay/tools-overlay.mouse.tsx | 886 +++ .../overlay/tools-overlay.touch.tsx | 936 ++++ .../room-components/overlay/tools-overlay.tsx | 557 +- .../overlay/tools-triggers/move-tool.tsx | 73 + .../toolbar/toolbar-button.tsx | 21 +- .../toolbar/toolbar-divider.tsx | 27 + .../room-components/toolbar/toolbar.tsx | 5 +- code/components/ui/input.tsx | 6 +- code/components/ui/textarea.tsx | 2 +- code/package-lock.json | 4746 ++++------------- code/package.json | 6 +- 22 files changed, 3548 insertions(+), 4340 deletions(-) create mode 100644 code/components/room-components/overlay/hooks/use-images-tools.tsx create mode 100644 code/components/room-components/overlay/hooks/use-shapes-tools.tsx create mode 100644 code/components/room-components/overlay/hooks/use-strokes-tools.tsx create mode 100644 code/components/room-components/overlay/tools-overlay.mouse.tsx create mode 100644 code/components/room-components/overlay/tools-overlay.touch.tsx create mode 100644 code/components/room-components/overlay/tools-triggers/move-tool.tsx create mode 100644 code/components/room-components/toolbar/toolbar-divider.tsx diff --git a/code/components/home/home.tsx b/code/components/home/home.tsx index 7bf9b4f..7e04e45 100644 --- a/code/components/home/home.tsx +++ b/code/components/home/home.tsx @@ -26,10 +26,10 @@ export const Home = () => { initial={{ opacity: 0, y: -100 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }} - className="relative flex h-full w-full flex-col items-center justify-start md:justify-center overflow-scroll" + className="relative flex h-full w-full flex-col items-center justify-start lg:justify-center overflow-scroll" > -
-
+
+
{
-
+
-
-
+
+
{showDetails && ( -
+
diff --git a/code/components/home/login-form.tsx b/code/components/home/login-form.tsx index 3492d5f..3e2df19 100644 --- a/code/components/home/login-form.tsx +++ b/code/components/home/login-form.tsx @@ -79,7 +79,7 @@ function LoginForm() { initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} transition={{ duration: 0.5, delay: 0.4 }} - className="w-full max-w-md flex justify-center items-start" + className="w-full flex justify-center items-start" >
- connected + + connected + )} {weaveConnectionStatus === WEAVE_STORE_CONNECTION_STATUS.CONNECTING && ( <> - + connecting @@ -51,14 +53,16 @@ export const ConnectionStatus = ({ {weaveConnectionStatus === WEAVE_STORE_CONNECTION_STATUS.ERROR && ( <> - error + + error + )} {weaveConnectionStatus === WEAVE_STORE_CONNECTION_STATUS.DISCONNECTED && ( <> - + disconnected diff --git a/code/components/room-components/hooks/use-keyboard-handler.tsx b/code/components/room-components/hooks/use-keyboard-handler.tsx index 5576aca..f23138f 100644 --- a/code/components/room-components/hooks/use-keyboard-handler.tsx +++ b/code/components/room-components/hooks/use-keyboard-handler.tsx @@ -164,7 +164,7 @@ export function useKeyboardHandler() { () => { triggerTool("colorTokenTool"); }, - ["KeyP"], + ["KeyK"], (e) => !(e.ctrlKey || e.metaKey) ); diff --git a/code/components/room-components/overlay/divider.tsx b/code/components/room-components/overlay/divider.tsx index d4c35c7..b302bc2 100644 --- a/code/components/room-components/overlay/divider.tsx +++ b/code/components/room-components/overlay/divider.tsx @@ -8,11 +8,13 @@ type DividerSize = "normal" | "small"; type DividerColor = "normal" | "black"; type DividerProps = { + className?: string; size?: DividerSize; color?: DividerColor; }; export function Divider({ + className, size = "normal", color = "normal", }: Readonly) { @@ -28,6 +30,7 @@ export function Divider({ ["bg-[#c9c9c9]"]: color === "normal", ["bg-black"]: color === "black", }, + className )} >
); diff --git a/code/components/room-components/overlay/hooks/use-images-tools.tsx b/code/components/room-components/overlay/hooks/use-images-tools.tsx new file mode 100644 index 0000000..58e97f5 --- /dev/null +++ b/code/components/room-components/overlay/hooks/use-images-tools.tsx @@ -0,0 +1,134 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +import React from "react"; +import { ShortcutElement } from "../../help/shortcut-element"; +import { SYSTEM_OS } from "@/lib/utils"; +import { useWeave } from "@inditextech/weave-react"; +import { Image, ImagePlus, Images } from "lucide-react"; +import { useIACapabilities } from "@/store/ia"; +import { useCollaborationRoom } from "@/store/store"; + +export const useImagesTools = () => { + const instance = useWeave((state) => state.instance); + const actualAction = useWeave((state) => state.actions.actual); + + const imagesLLMPopupType = useIACapabilities((state) => state.llmPopup.type); + const imagesLLMPopupVisible = useIACapabilities( + (state) => state.llmPopup.visible + ); + const setImagesLLMPopupType = useIACapabilities( + (state) => state.setImagesLLMPopupType + ); + const setImagesLLMPopupVisible = useIACapabilities( + (state) => state.setImagesLLMPopupVisible + ); + + const setShowSelectFileImage = useCollaborationRoom( + (state) => state.setShowSelectFileImage + ); + const setShowSelectFilesImages = useCollaborationRoom( + (state) => state.setShowSelectFilesImages + ); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + const IMAGES_TOOLS: Record< + string, + { + icon: React.JSX.Element; + label: React.JSX.Element; + onClick: () => void; + active: () => boolean; + } + > = React.useMemo( + () => ({ + imageTool: { + // eslint-disable-next-line jsx-a11y/alt-text + icon: , + label: ( +
+

Image tool

+ +
+ ), + onClick: () => { + triggerTool("imageTool"); + setShowSelectFileImage(true); + }, + active: () => actualAction === "imageTool", + }, + imagesTool: { + icon: , + label: ( +
+

Images tool

+ +
+ ), + onClick: () => { + setShowSelectFilesImages(true); + }, + active: () => actualAction === "imagesTool", + }, + generateImageTool: { + icon: , + label: ( +
+

Generate Image tool

+ +
+ ), + onClick: () => { + setImagesLLMPopupType("create"); + if (imagesLLMPopupType === "create") { + setImagesLLMPopupVisible(!imagesLLMPopupVisible); + } else { + setImagesLLMPopupVisible(true); + } + }, + active: () => imagesLLMPopupVisible && imagesLLMPopupType === "create", + }, + }), + [ + actualAction, + imagesLLMPopupType, + imagesLLMPopupVisible, + setImagesLLMPopupType, + setImagesLLMPopupVisible, + setShowSelectFileImage, + setShowSelectFilesImages, + triggerTool, + ] + ); + + return IMAGES_TOOLS; +}; diff --git a/code/components/room-components/overlay/hooks/use-shapes-tools.tsx b/code/components/room-components/overlay/hooks/use-shapes-tools.tsx new file mode 100644 index 0000000..df40ce9 --- /dev/null +++ b/code/components/room-components/overlay/hooks/use-shapes-tools.tsx @@ -0,0 +1,124 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +import { Circle, Hexagon, Square, Star } from "lucide-react"; +import React from "react"; +import { ShortcutElement } from "../../help/shortcut-element"; +import { SYSTEM_OS } from "@/lib/utils"; +import { useWeave } from "@inditextech/weave-react"; + +export const useShapesTools = () => { + const instance = useWeave((state) => state.instance); + const actualAction = useWeave((state) => state.actions.actual); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + const SHAPES_TOOLS: Record< + string, + { + icon: React.JSX.Element; + label: React.JSX.Element; + onClick: () => void; + active: () => boolean; + } + > = React.useMemo( + () => ({ + rectangleTool: { + icon: , + label: ( +
+

Rectangle tool

+ +
+ ), + onClick: () => triggerTool("rectangleTool"), + active: () => actualAction === "rectangleTool", + }, + ellipseTool: { + icon: , + label: ( +
+

Ellipsis tool

+ +
+ ), + onClick: () => triggerTool("ellipseTool"), + active: () => actualAction === "ellipseTool", + }, + regularPolygonTool: { + icon: , + label: ( +
+

Regular Polygon tool

+ +
+ ), + onClick: () => triggerTool("regularPolygonTool"), + active: () => actualAction === "regularPolygonTool", + }, + starTool: { + icon: , + label: ( +
+

Star tool

+ +
+ ), + onClick: () => triggerTool("starTool"), + active: () => actualAction === "starTool", + }, + colorTokenTool: { + icon: , + label: ( +
+

Color Token Reference tool

+ +
+ ), + onClick: () => triggerTool("colorTokenTool"), + active: () => actualAction === "colorTokenTool", + }, + }), + [actualAction, triggerTool] + ); + + return SHAPES_TOOLS; +}; diff --git a/code/components/room-components/overlay/hooks/use-strokes-tools.tsx b/code/components/room-components/overlay/hooks/use-strokes-tools.tsx new file mode 100644 index 0000000..5931374 --- /dev/null +++ b/code/components/room-components/overlay/hooks/use-strokes-tools.tsx @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +import { ArrowUpRight, Brush, PenTool } from "lucide-react"; +import React from "react"; +import { ShortcutElement } from "../../help/shortcut-element"; +import { SYSTEM_OS } from "@/lib/utils"; +import { useWeave } from "@inditextech/weave-react"; + +export const useStrokesTools = () => { + const instance = useWeave((state) => state.instance); + const actualAction = useWeave((state) => state.actions.actual); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + const STROKES_TOOLS: Record< + string, + { + icon: React.JSX.Element; + label: React.JSX.Element; + onClick: () => void; + active: () => boolean; + } + > = React.useMemo( + () => ({ + penTool: { + icon: , + label: ( +
+

Pen tool

+ +
+ ), + onClick: () => triggerTool("penTool"), + active: () => actualAction === "penTool", + }, + brushTool: { + icon: , + label: ( +
+

Brush tool

+ +
+ ), + onClick: () => triggerTool("brushTool"), + active: () => actualAction === "brushTool", + }, + arrowTool: { + icon: , + label: ( +
+

Arrow tool

+ +
+ ), + onClick: () => triggerTool("arrowTool"), + active: () => actualAction === "arrowTool", + }, + }), + [actualAction, triggerTool] + ); + + return STROKES_TOOLS; +}; diff --git a/code/components/room-components/overlay/llm-popup-v2.tsx b/code/components/room-components/overlay/llm-popup-v2.tsx index 6bad7cb..a3f795c 100644 --- a/code/components/room-components/overlay/llm-popup-v2.tsx +++ b/code/components/room-components/overlay/llm-popup-v2.tsx @@ -332,10 +332,10 @@ export function LLMGenerationV2Popup() {
- {imagesLLMPopupType === "create" && "Create an Image with AI"} - {imagesLLMPopupType === "edit-prompt" && "Edit with AI"} - {imagesLLMPopupType === "edit-mask" && "Edit with AI"} - {imagesLLMPopupType === "edit-variation" && "Edit with AI"} + {imagesLLMPopupType === "create" && "Generate an Image"} + {imagesLLMPopupType === "edit-prompt" && "Edit an Image"} + {imagesLLMPopupType === "edit-mask" && "Edit an Image"} + {imagesLLMPopupType === "edit-variation" && "Edit an Image"}
-
diff --git a/code/components/room-components/overlay/tools-overlay.mouse.tsx b/code/components/room-components/overlay/tools-overlay.mouse.tsx new file mode 100644 index 0000000..e4ab50a --- /dev/null +++ b/code/components/room-components/overlay/tools-overlay.mouse.tsx @@ -0,0 +1,886 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +"use client"; + +import React from "react"; +import { Vector2d } from "konva/lib/types"; +import { ToolbarButton } from "../toolbar/toolbar-button"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { postImage } from "@/api/post-image"; +import { + Brush, + Image, + Images, + PenTool, + Square, + Type, + Frame, + MousePointer, + Tags, + Undo, + Redo, + Eraser, + Circle, + Star, + ArrowUpRight, + Hexagon, + ImagePlus, + PencilRuler, + ListTree, + SwatchBook, + Projector, + PanelRight, + ChevronDown, + ChevronUp, +} from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + DropdownMenuShortcut, +} from "@/components/ui/dropdown-menu"; +import { useWeave } from "@inditextech/weave-react"; +import { Toolbar } from "../toolbar/toolbar"; +import { motion } from "framer-motion"; +import { topElementVariants } from "./variants"; +import { SidebarActive, useCollaborationRoom } from "@/store/store"; +import { ShortcutElement } from "../help/shortcut-element"; +import { cn, SYSTEM_OS } from "@/lib/utils"; +import { useKeyboardHandler } from "../hooks/use-keyboard-handler"; +import { WEAVE_STORE_CONNECTION_STATUS } from "@inditextech/weave-types"; +import { useIACapabilities } from "@/store/ia"; +import { MoveToolTrigger } from "./tools-triggers/move-tool"; +import { SIDEBAR_ELEMENTS } from "@/lib/constants"; +import { ToolbarDivider } from "../toolbar/toolbar-divider"; +import { useShapesTools } from "./hooks/use-shapes-tools"; +import { useStrokesTools } from "./hooks/use-strokes-tools"; +import { useImagesTools } from "./hooks/use-images-tools"; + +export function ToolsOverlayMouse() { + useKeyboardHandler(); + + const [actualShapeTool, setActualShapeTool] = React.useState("rectangleTool"); + const [actualStrokesTool, setActualStrokesTool] = React.useState("penTool"); + const [actualImagesTool, setActualImagesTool] = React.useState("imageTool"); + const [shapesMenuOpen, setShapesMenuOpen] = React.useState(false); + const [strokesMenuOpen, setStrokesMenuOpen] = React.useState(false); + const [imagesMenuOpen, setImagesMenuOpen] = React.useState(false); + const [sidebarsMenuOpen, setSidebarsMenuOpen] = React.useState(false); + + const instance = useWeave((state) => state.instance); + const actualAction = useWeave((state) => state.actions.actual); + const canUndo = useWeave((state) => state.undoRedo.canUndo); + const canRedo = useWeave((state) => state.undoRedo.canRedo); + const weaveConnectionStatus = useWeave((state) => state.connection.status); + const node = useWeave((state) => state.selection.node); + const nodes = useWeave((state) => state.selection.nodes); + + const nodeCreateProps = useCollaborationRoom( + (state) => state.nodeProperties.createProps + ); + const setSidebarActive = useCollaborationRoom( + (state) => state.setSidebarActive + ); + const room = useCollaborationRoom((state) => state.room); + const showUI = useCollaborationRoom((state) => state.ui.show); + const setUploadingImage = useCollaborationRoom( + (state) => state.setUploadingImage + ); + const imagesLLMPopupType = useIACapabilities((state) => state.llmPopup.type); + const imagesLLMPopupVisible = useIACapabilities( + (state) => state.llmPopup.visible + ); + const setImagesLLMPopupType = useIACapabilities( + (state) => state.setImagesLLMPopupType + ); + const setImagesLLMPopupVisible = useIACapabilities( + (state) => state.setImagesLLMPopupVisible + ); + + const queryClient = useQueryClient(); + + const mutationUpload = useMutation({ + mutationFn: async (file: File) => { + return await postImage(room ?? "", file); + }, + }); + + const setShowSelectFileImage = useCollaborationRoom( + (state) => state.setShowSelectFileImage + ); + const setShowSelectFilesImages = useCollaborationRoom( + (state) => state.setShowSelectFilesImages + ); + + const sidebarToggle = React.useCallback( + (element: SidebarActive) => { + setSidebarActive(element); + }, + [setSidebarActive] + ); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + React.useEffect(() => { + const onPasteExternalImage = async ({ + position, + item, + }: { + position: Vector2d; + item: ClipboardItem; + }) => { + let blob: Blob | null = null; + if (item.types.includes("image/png")) { + blob = await item.getType("image/png"); + } + if (item.types.includes("image/jpeg")) { + blob = await item.getType("image/jpeg"); + } + if (item.types.includes("image/gif")) { + blob = await item.getType("image/gif"); + } + + if (!blob) { + return; + } + + setUploadingImage(true); + const file = new File([blob], "external.image"); + mutationUpload.mutate(file, { + onSuccess: (data) => { + const room: string = data.fileName.split("/")[0]; + const imageId = data.fileName.split("/")[1]; + + const queryKey = ["getImages", room]; + queryClient.invalidateQueries({ queryKey }); + + instance?.triggerAction( + "imageTool", + { + position, + imageURL: `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`, + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ) as any; + }, + onError: () => { + console.error("Error uploading image"); + }, + onSettled: () => { + setUploadingImage(false); + }, + }); + }; + + if (instance) { + instance.addEventListener("onPasteExternal", onPasteExternalImage); + } + + return () => { + if (instance) { + instance.removeEventListener("onPasteExternal", onPasteExternalImage); + } + }; + }, [ + instance, + queryClient, + mutationUpload, + setShowSelectFileImage, + setUploadingImage, + ]); + + const SHAPES_TOOLS = useShapesTools(); + const STROKES_TOOLS = useStrokesTools(); + const IMAGES_TOOLS = useImagesTools(); + + if (!showUI) { + return null; + } + + return ( + + + + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "selectionTool"} + onClick={() => triggerTool("selectionTool")} + label={ +
+

Selection tool

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "eraserTool"} + onClick={() => triggerTool("eraserTool")} + label={ +
+

Erase tool

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + +
+ + { + setShapesMenuOpen(open); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen((prev) => !prev); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + label={ +
+

More shapes tools

+
+ } + tooltipSideOffset={4} + tooltipSide="top" + tooltipAlign="center" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="bottom" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualShapeTool("rectangleTool"); + triggerTool("rectangleTool"); + }} + > + Rectangle tool + + {SYSTEM_OS.MAC ? "R" : "R"} + + + { + setActualShapeTool("ellipseTool"); + triggerTool("ellipseTool"); + }} + > + Ellipse tool + + {SYSTEM_OS.MAC ? "E" : "E"} + + + { + setActualShapeTool("regularPolygonTool"); + triggerTool("regularPolygonTool"); + }} + > + Regular Polygon tool + + {SYSTEM_OS.MAC ? "P" : "P"} + + + { + setActualShapeTool("starTool"); + triggerTool("starTool"); + }} + > + Star tool + + {SYSTEM_OS.MAC ? "J" : "J"} + + + { + setActualShapeTool("colorTokenTool"); + triggerTool("colorTokenTool"); + }} + > + Color Token Reference tool + + {SYSTEM_OS.MAC ? "K" : "K"} + + + +
+
+
+ + { + setShapesMenuOpen(false); + setStrokesMenuOpen(open); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen((prev) => !prev); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + label={ +
+

More strokes tools

+
+ } + tooltipSideOffset={4} + tooltipSide="top" + tooltipAlign="center" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="bottom" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualStrokesTool("penTool"); + triggerTool("penTool"); + }} + > + Pen tool + + {SYSTEM_OS.MAC ? "L" : "L"} + + + { + setActualStrokesTool("brushTool"); + triggerTool("brushTool"); + }} + > + Brush tool + + {SYSTEM_OS.MAC ? "B" : "B"} + + + { + setActualStrokesTool("arrowTool"); + triggerTool("arrowTool"); + }} + > + Arrow tool + + {SYSTEM_OS.MAC ? "A" : "A"} + + + +
+
+
+ + { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(open); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen((prev) => !prev); + setSidebarsMenuOpen(false); + }} + label={ +
+

More images tools

+
+ } + tooltipSideOffset={4} + tooltipSide="top" + tooltipAlign="center" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="bottom" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualImagesTool("imageTool"); + triggerTool("imageTool"); + setShowSelectFileImage(true); + }} + > + {/* eslint-disable-next-line jsx-a11y/alt-text */} + Image tool + + {SYSTEM_OS.MAC ? "I" : "I"} + + + { + setActualImagesTool("imagesTool"); + setShowSelectFilesImages(true); + // triggerTool("imagesTool"); + }} + > + Images tool + + {SYSTEM_OS.MAC ? "O" : "O"} + + + { + setActualImagesTool("generateImageTool"); + setImagesMenuOpen(false); + setImagesLLMPopupType("create"); + if (imagesLLMPopupType === "create") { + setImagesLLMPopupVisible(!imagesLLMPopupVisible); + } else { + setImagesLLMPopupVisible(true); + } + }} + > + Generate Image tool + + {SYSTEM_OS.MAC ? "G" : "G"} + + + +
+
+ } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "textTool"} + onClick={() => triggerTool("textTool")} + label={ +
+

Text tool

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "frameTool"} + onClick={() => triggerTool("frameTool", nodeCreateProps)} + label={ +
+

Frame tool

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + + { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(open); + }} + > + + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen((prev) => !prev); + }} + label={ +
+

Toolbars

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="bottom" + alignOffset={0} + sideOffset={8} + className="font-inter rounded-none shadow-none" + > + { + sidebarToggle(SIDEBAR_ELEMENTS.images); + }} + > + Images + + {SYSTEM_OS.MAC ? "⌥ ⌘ I" : "Alt Ctrl I"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.frames); + }} + > + Frames + + {SYSTEM_OS.MAC ? "⌥ ⌘ F" : "Alt Ctrl F"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.colorTokens); + }} + > + Color tokens + + {SYSTEM_OS.MAC ? "⌥ ⌘ O" : "Alt Ctrl O"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.nodesTree); + }} + > + Elements tree + + {SYSTEM_OS.MAC ? "⌥ ⌘ E" : "Alt Ctrl E"} + + + +
+ } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED || + !actualAction || + (!node && !nodes) || + (!node && nodes && nodes.length < 2) + } + onClick={() => { + setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, "right"); + }} + label={ +
+

Node Properties

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + + } + disabled={ + !canUndo || + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + if (instance) { + const actualStore = instance.getStore(); + actualStore.undoStateStep(); + } + }} + label={ +
+

Undo latest changes

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> + } + disabled={ + !canRedo || + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + if (instance) { + const actualStore = instance.getStore(); + actualStore.redoStateStep(); + } + }} + label={ +
+

Redo latest changes

+ +
+ } + tooltipSide="top" + tooltipAlign="center" + /> +
+
+ ); +} diff --git a/code/components/room-components/overlay/tools-overlay.touch.tsx b/code/components/room-components/overlay/tools-overlay.touch.tsx new file mode 100644 index 0000000..8d4c48a --- /dev/null +++ b/code/components/room-components/overlay/tools-overlay.touch.tsx @@ -0,0 +1,936 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +"use client"; + +import React from "react"; +import { Vector2d } from "konva/lib/types"; +import { ToolbarButton } from "../toolbar/toolbar-button"; +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { postImage } from "@/api/post-image"; +import { + Brush, + Image, + Images, + PenTool, + Square, + Type, + Frame, + MousePointer, + Tags, + Undo, + Redo, + Eraser, + Circle, + Star, + ArrowUpRight, + Hexagon, + ImagePlus, + ChevronRight, + ChevronLeft, + PencilRuler, + ListTree, + SwatchBook, + Projector, + PanelRight, +} from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + DropdownMenuShortcut, +} from "@/components/ui/dropdown-menu"; +import { useWeave } from "@inditextech/weave-react"; +import { Toolbar } from "../toolbar/toolbar"; +import { motion } from "framer-motion"; +import { leftElementVariants } from "./variants"; +import { SidebarActive, useCollaborationRoom } from "@/store/store"; +import { ShortcutElement } from "../help/shortcut-element"; +import { cn, SYSTEM_OS } from "@/lib/utils"; +import { useKeyboardHandler } from "../hooks/use-keyboard-handler"; +import { WEAVE_STORE_CONNECTION_STATUS } from "@inditextech/weave-types"; +import { useIACapabilities } from "@/store/ia"; +import { MoveToolTrigger } from "./tools-triggers/move-tool"; +import { SIDEBAR_ELEMENTS } from "@/lib/constants"; +import { ToolbarDivider } from "../toolbar/toolbar-divider"; +import { useShapesTools } from "./hooks/use-shapes-tools"; +import { useStrokesTools } from "./hooks/use-strokes-tools"; +import { useImagesTools } from "./hooks/use-images-tools"; + +export function ToolsOverlayTouch() { + useKeyboardHandler(); + + const [actualShapeTool, setActualShapeTool] = React.useState("rectangleTool"); + const [actualStrokesTool, setActualStrokesTool] = React.useState("penTool"); + const [actualImagesTool, setActualImagesTool] = React.useState("imageTool"); + const [shapesMenuOpen, setShapesMenuOpen] = React.useState(false); + const [strokesMenuOpen, setStrokesMenuOpen] = React.useState(false); + const [imagesMenuOpen, setImagesMenuOpen] = React.useState(false); + const [sidebarsMenuOpen, setSidebarsMenuOpen] = React.useState(false); + + const instance = useWeave((state) => state.instance); + const actualAction = useWeave((state) => state.actions.actual); + const canUndo = useWeave((state) => state.undoRedo.canUndo); + const canRedo = useWeave((state) => state.undoRedo.canRedo); + const weaveConnectionStatus = useWeave((state) => state.connection.status); + const node = useWeave((state) => state.selection.node); + const nodes = useWeave((state) => state.selection.nodes); + + const nodeCreateProps = useCollaborationRoom( + (state) => state.nodeProperties.createProps + ); + const setSidebarActive = useCollaborationRoom( + (state) => state.setSidebarActive + ); + const room = useCollaborationRoom((state) => state.room); + const showUI = useCollaborationRoom((state) => state.ui.show); + const setUploadingImage = useCollaborationRoom( + (state) => state.setUploadingImage + ); + const imagesLLMPopupType = useIACapabilities((state) => state.llmPopup.type); + const imagesLLMPopupVisible = useIACapabilities( + (state) => state.llmPopup.visible + ); + const setImagesLLMPopupType = useIACapabilities( + (state) => state.setImagesLLMPopupType + ); + const setImagesLLMPopupVisible = useIACapabilities( + (state) => state.setImagesLLMPopupVisible + ); + + const queryClient = useQueryClient(); + + const mutationUpload = useMutation({ + mutationFn: async (file: File) => { + return await postImage(room ?? "", file); + }, + }); + + const setShowSelectFileImage = useCollaborationRoom( + (state) => state.setShowSelectFileImage + ); + const setShowSelectFilesImages = useCollaborationRoom( + (state) => state.setShowSelectFilesImages + ); + + const sidebarToggle = React.useCallback( + (element: SidebarActive) => { + setSidebarActive(element); + }, + [setSidebarActive] + ); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + React.useEffect(() => { + const onPasteExternalImage = async ({ + position, + item, + }: { + position: Vector2d; + item: ClipboardItem; + }) => { + let blob: Blob | null = null; + if (item.types.includes("image/png")) { + blob = await item.getType("image/png"); + } + if (item.types.includes("image/jpeg")) { + blob = await item.getType("image/jpeg"); + } + if (item.types.includes("image/gif")) { + blob = await item.getType("image/gif"); + } + + if (!blob) { + return; + } + + setUploadingImage(true); + const file = new File([blob], "external.image"); + mutationUpload.mutate(file, { + onSuccess: (data) => { + const room: string = data.fileName.split("/")[0]; + const imageId = data.fileName.split("/")[1]; + + const queryKey = ["getImages", room]; + queryClient.invalidateQueries({ queryKey }); + + instance?.triggerAction( + "imageTool", + { + position, + imageURL: `${process.env.NEXT_PUBLIC_API_ENDPOINT}/weavejs/rooms/${room}/images/${imageId}`, + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ) as any; + }, + onError: () => { + console.error("Error uploading image"); + }, + onSettled: () => { + setUploadingImage(false); + }, + }); + }; + + if (instance) { + instance.addEventListener("onPasteExternal", onPasteExternalImage); + } + + return () => { + if (instance) { + instance.removeEventListener("onPasteExternal", onPasteExternalImage); + } + }; + }, [ + instance, + queryClient, + mutationUpload, + setShowSelectFileImage, + setUploadingImage, + ]); + + const SHAPES_TOOLS = useShapesTools(); + const STROKES_TOOLS = useStrokesTools(); + const IMAGES_TOOLS = useImagesTools(); + + if (!showUI) { + return null; + } + + return ( + + + } + disabled={ + !canRedo || + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + if (instance) { + const actualStore = instance.getStore(); + actualStore.redoStateStep(); + } + }} + label={ +
+

Redo latest changes

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + } + disabled={ + !canUndo || + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + if (instance) { + const actualStore = instance.getStore(); + actualStore.undoStateStep(); + } + }} + label={ +
+

Undo latest changes

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + + { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(open); + }} + > + + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen((prev) => !prev); + }} + label={ +
+

Toolbars

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="left" + alignOffset={0} + sideOffset={8} + className="font-inter rounded-none shadow-none" + > + { + sidebarToggle(SIDEBAR_ELEMENTS.images); + setSidebarsMenuOpen(false); + }} + onClick={() => { + sidebarToggle(SIDEBAR_ELEMENTS.images); + setSidebarsMenuOpen(false); + }} + > + Images + + {SYSTEM_OS.MAC ? "⌥ ⌘ I" : "Alt Ctrl I"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.frames); + setSidebarsMenuOpen(false); + }} + onClick={() => { + sidebarToggle(SIDEBAR_ELEMENTS.frames); + setSidebarsMenuOpen(false); + }} + > + Frames + + {SYSTEM_OS.MAC ? "⌥ ⌘ F" : "Alt Ctrl F"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.colorTokens); + setSidebarsMenuOpen(false); + }} + onClick={() => { + sidebarToggle(SIDEBAR_ELEMENTS.colorTokens); + setSidebarsMenuOpen(false); + }} + > + Color tokens + + {SYSTEM_OS.MAC ? "⌥ ⌘ O" : "Alt Ctrl O"} + + + { + sidebarToggle(SIDEBAR_ELEMENTS.nodesTree); + setSidebarsMenuOpen(false); + }} + onClick={() => { + sidebarToggle(SIDEBAR_ELEMENTS.nodesTree); + setSidebarsMenuOpen(false); + }} + > + Elements tree + + {SYSTEM_OS.MAC ? "⌥ ⌘ E" : "Alt Ctrl E"} + + + +
+ } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED || + !actualAction || + (!node && !nodes) || + (!node && nodes && nodes.length < 2) + } + onClick={() => { + setSidebarActive(SIDEBAR_ELEMENTS.nodeProperties, "right"); + }} + label={ +
+

Node Properties

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "frameTool"} + onClick={() => triggerTool("frameTool", nodeCreateProps)} + label={ +
+

Add a frame

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "textTool"} + onClick={() => triggerTool("textTool")} + label={ +
+

Add text

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + +
+ + { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen(open); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen(false); + setImagesMenuOpen((prev) => !prev); + setSidebarsMenuOpen(false); + }} + label={ +
+

More images tools

+
+ } + tooltipSide="right" + tooltipAlign="start" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="right" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualImagesTool("imageTool"); + triggerTool("imageTool"); + setShowSelectFileImage(true); + }} + > + {/* eslint-disable-next-line jsx-a11y/alt-text */} + Image tool + + {SYSTEM_OS.MAC ? "I" : "I"} + + + { + setActualImagesTool("imagesTool"); + setShowSelectFilesImages(true); + // triggerTool("imagesTool"); + }} + > + Images tool + + {SYSTEM_OS.MAC ? "O" : "O"} + + + { + setActualImagesTool("generateImageTool"); + setImagesMenuOpen(false); + setImagesLLMPopupType("create"); + if (imagesLLMPopupType === "create") { + setImagesLLMPopupVisible(!imagesLLMPopupVisible); + } else { + setImagesLLMPopupVisible(true); + } + }} + > + Generate Image tool + + {SYSTEM_OS.MAC ? "G" : "G"} + + + +
+
+
+ + { + setShapesMenuOpen(false); + setStrokesMenuOpen(open); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen(false); + setStrokesMenuOpen((prev) => !prev); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + label={ +
+

More strokes tools

+
+ } + tooltipSide="right" + tooltipAlign="start" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="right" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualStrokesTool("penTool"); + triggerTool("penTool"); + }} + onClick={() => { + setActualStrokesTool("penTool"); + triggerTool("penTool"); + }} + > + Pen tool + + {SYSTEM_OS.MAC ? "L" : "L"} + + + { + setActualStrokesTool("brushTool"); + triggerTool("penTool"); + }} + onClick={() => { + setActualStrokesTool("brushTool"); + triggerTool("brushTool"); + }} + > + Brush tool + + {SYSTEM_OS.MAC ? "B" : "B"} + + + { + setActualStrokesTool("arrowTool"); + triggerTool("arrowTool"); + }} + onClick={() => { + setActualStrokesTool("arrowTool"); + triggerTool("arrowTool"); + }} + > + Arrow tool + + {SYSTEM_OS.MAC ? "A" : "A"} + + + +
+
+
+ + { + setShapesMenuOpen(open); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + > + + + ) : ( + + ) + } + disabled={ + weaveConnectionStatus !== + WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + onClick={() => { + setShapesMenuOpen((prev) => !prev); + setStrokesMenuOpen(false); + setImagesMenuOpen(false); + setSidebarsMenuOpen(false); + }} + label={ +
+

More shapes tools

+
+ } + tooltipSide="right" + tooltipAlign="start" + /> +
+ { + e.preventDefault(); + }} + align="start" + side="right" + alignOffset={0} + sideOffset={3} + className="font-inter rounded-none shadow-none" + > + { + setActualShapeTool("rectangleTool"); + triggerTool("rectangleTool"); + }} + onClick={() => { + setActualShapeTool("rectangleTool"); + triggerTool("rectangleTool"); + }} + > + Rectangle tool + + {SYSTEM_OS.MAC ? "R" : "R"} + + + { + setActualShapeTool("ellipseTool"); + triggerTool("ellipseTool"); + }} + onClick={() => { + setActualShapeTool("ellipseTool"); + triggerTool("ellipseTool"); + }} + > + Ellipse tool + + {SYSTEM_OS.MAC ? "E" : "E"} + + + { + setActualShapeTool("regularPolygonTool"); + triggerTool("regularPolygonTool"); + }} + onClick={() => { + setActualShapeTool("regularPolygonTool"); + triggerTool("regularPolygonTool"); + }} + > + Regular Polygon tool + + {SYSTEM_OS.MAC ? "P" : "P"} + + + { + setActualShapeTool("starTool"); + triggerTool("starTool"); + }} + onClick={() => { + setActualShapeTool("starTool"); + triggerTool("starTool"); + }} + > + Star tool + + {SYSTEM_OS.MAC ? "J" : "J"} + + + { + setActualShapeTool("colorTokenTool"); + triggerTool("colorTokenTool"); + }} + onClick={() => { + setActualShapeTool("colorTokenTool"); + triggerTool("colorTokenTool"); + }} + > + Color Token Reference tool + + {SYSTEM_OS.MAC ? "K" : "K"} + + + +
+
+ + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "eraserTool"} + onClick={() => triggerTool("eraserTool")} + label={ +
+

Erase

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "selectionTool"} + onClick={() => triggerTool("selectionTool")} + label={ +
+

Selection

+ +
+ } + tooltipSide="right" + tooltipAlign="center" + /> + +
+
+ ); +} diff --git a/code/components/room-components/overlay/tools-overlay.tsx b/code/components/room-components/overlay/tools-overlay.tsx index 7141839..bcd2c1c 100644 --- a/code/components/room-components/overlay/tools-overlay.tsx +++ b/code/components/room-components/overlay/tools-overlay.tsx @@ -9,28 +9,7 @@ import { Vector2d } from "konva/lib/types"; import { ToolbarButton } from "../toolbar/toolbar-button"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { postImage } from "@/api/post-image"; -import { - Brush, - Image, - Images, - PenTool, - Square, - Type, - Frame, - MousePointer, - Hand, - Tags, - Undo, - Redo, - Eraser, - Circle, - Star, - ArrowUpRight, - Hexagon, - ImagePlus, - CircleSlash2, - SprayCan, -} from "lucide-react"; +import { Eraser, CircleSlash2, SprayCan } from "lucide-react"; import { useWeave } from "@inditextech/weave-react"; import { Toolbar } from "../toolbar/toolbar"; import { motion } from "framer-motion"; @@ -41,27 +20,18 @@ import { SYSTEM_OS } from "@/lib/utils"; import { useKeyboardHandler } from "../hooks/use-keyboard-handler"; import { WEAVE_STORE_CONNECTION_STATUS } from "@inditextech/weave-types"; import { useIACapabilities } from "@/store/ia"; - -function ToolbarDivider() { - return ( -
-
-
- ); -} +import { ToolsOverlayTouch } from "./tools-overlay.touch"; +import { MoveToolTrigger } from "./tools-triggers/move-tool"; +import { ToolbarDivider } from "../toolbar/toolbar-divider"; +import { ToolsOverlayMouse } from "./tools-overlay.mouse"; export function ToolsOverlay() { useKeyboardHandler(); const instance = useWeave((state) => state.instance); const actualAction = useWeave((state) => state.actions.actual); - const canUndo = useWeave((state) => state.undoRedo.canUndo); - const canRedo = useWeave((state) => state.undoRedo.canRedo); const weaveConnectionStatus = useWeave((state) => state.connection.status); - const nodeCreateProps = useCollaborationRoom( - (state) => state.nodeProperties.createProps - ); const room = useCollaborationRoom((state) => state.room); const showUI = useCollaborationRoom((state) => state.ui.show); const setUploadingImage = useCollaborationRoom( @@ -72,12 +42,6 @@ export function ToolsOverlay() { const imagesLLMPopupVisible = useIACapabilities( (state) => state.llmPopup.visible ); - const setImagesLLMPopupType = useIACapabilities( - (state) => state.setImagesLLMPopupType - ); - const setImagesLLMPopupVisible = useIACapabilities( - (state) => state.setImagesLLMPopupVisible - ); const queryClient = useQueryClient(); @@ -90,9 +54,6 @@ export function ToolsOverlay() { const setShowSelectFileImage = useCollaborationRoom( (state) => state.setShowSelectFileImage ); - const setShowSelectFilesImages = useCollaborationRoom( - (state) => state.setShowSelectFilesImages - ); const triggerTool = React.useCallback( (toolName: string, params?: unknown) => { @@ -209,7 +170,7 @@ export function ToolsOverlay() { }} label={
-

Free hand mask

+

Free Hand Mask tool

-

Regular mask

+

Regular Mask tool

triggerTool("maskEraserTool")} label={
-

Erase mask

+

Erase Mask tool

} tooltipSide="top" @@ -269,503 +230,9 @@ export function ToolsOverlay() { } return ( - - - - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "selectionTool"} - onClick={() => triggerTool("selectionTool")} - label={ -
-

Selection

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "eraserTool"} - onClick={() => triggerTool("eraserTool")} - label={ -
-

Erase

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "rectangleTool"} - onClick={() => triggerTool("rectangleTool")} - label={ -
-

Add a rectangle

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "ellipseTool"} - onClick={() => triggerTool("ellipseTool")} - label={ -
-

Add a ellipsis

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "regularPolygonTool"} - onClick={() => triggerTool("regularPolygonTool")} - label={ -
-

Add a regular polygon

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "penTool"} - onClick={() => triggerTool("penTool")} - label={ -
-

Add a line

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "brushTool"} - onClick={() => triggerTool("brushTool")} - label={ -
-

Free draw

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "textTool"} - onClick={() => triggerTool("textTool")} - label={ -
-

Add text

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "starTool"} - onClick={() => triggerTool("starTool")} - label={ -
-

Add a star

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "arrowTool"} - onClick={() => triggerTool("arrowTool")} - label={ -
-

Add a arrow

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "frameTool"} - onClick={() => triggerTool("frameTool", nodeCreateProps)} - label={ -
-

Add a frame

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "imageTool"} - onClick={() => { - triggerTool("imageTool"); - setShowSelectFileImage(true); - }} - label={ -
-

Add an image

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "imageTool"} - onClick={() => { - triggerTool("imageTool", { - imageURL: "http://localhost:8081/assets/model.jpg", - }); - }} - label={ -
-

Add an image (cross-origin)

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "imagesTool"} - onClick={() => { - // triggerTool("imagesTool"); - setShowSelectFilesImages(true); - }} - label={ -
-

Add images

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - active={imagesLLMPopupVisible && imagesLLMPopupType === "create"} - disabled={ - !aiEnabled || - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - onClick={() => { - setImagesLLMPopupType("create"); - if (imagesLLMPopupType === "create") { - setImagesLLMPopupVisible(!imagesLLMPopupVisible); - } else { - setImagesLLMPopupVisible(true); - } - }} - label={ -
-

Generate image with AI

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "colorTokenTool"} - onClick={() => triggerTool("colorTokenTool")} - label={ -
-

Add color token reference

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - - } - disabled={ - !canUndo || - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - onClick={() => { - if (instance) { - const actualStore = instance.getStore(); - actualStore.undoStateStep(); - } - }} - label={ -
-

Undo latest changes

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - } - disabled={ - !canRedo || - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - onClick={() => { - if (instance) { - const actualStore = instance.getStore(); - actualStore.redoStateStep(); - } - }} - label={ -
-

Redo latest changes

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> -
-
+ <> + + + ); } - -const MoveToolTrigger = () => { - const instance = useWeave((state) => state.instance); - const weaveConnectionStatus = useWeave((state) => state.connection.status); - const actualAction = useWeave((state) => state.actions.actual); - - const imagesLLMPopupVisible = useIACapabilities( - (state) => state.llmPopup.visible - ); - - const triggerTool = React.useCallback( - (toolName: string, params?: unknown) => { - if (instance && actualAction !== toolName) { - instance.triggerAction(toolName, params); - return; - } - if (instance && actualAction === toolName) { - instance.cancelAction(toolName); - return; - } - }, - [instance, actualAction] - ); - - return ( - } - disabled={ - weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED - } - active={actualAction === "moveTool"} - onClick={() => { - if (imagesLLMPopupVisible) { - triggerTool("moveTool", { - triggerSelectionTool: false, - }); - } else { - triggerTool("moveTool"); - } - }} - label={ -
-

Move

- -
- } - tooltipSide="top" - tooltipAlign="center" - /> - ); -}; diff --git a/code/components/room-components/overlay/tools-triggers/move-tool.tsx b/code/components/room-components/overlay/tools-triggers/move-tool.tsx new file mode 100644 index 0000000..ea7999d --- /dev/null +++ b/code/components/room-components/overlay/tools-triggers/move-tool.tsx @@ -0,0 +1,73 @@ +import React from "react"; +import { useWeave } from "@inditextech/weave-react"; +import { useIACapabilities } from "@/store/ia"; +import { ToolbarButton } from "../../toolbar/toolbar-button"; +import { Hand } from "lucide-react"; +import { ShortcutElement } from "../../help/shortcut-element"; +import { WEAVE_STORE_CONNECTION_STATUS } from "@inditextech/weave-types"; +import { SYSTEM_OS } from "@/lib/utils"; + +type MoveToolTriggerProps = { + tooltipSide?: "top" | "bottom" | "left" | "right"; + tooltipAlign?: "start" | "center" | "end"; +}; + +export const MoveToolTrigger = ({ + tooltipSide = "top", + tooltipAlign = "center", +}: Readonly) => { + const instance = useWeave((state) => state.instance); + const weaveConnectionStatus = useWeave((state) => state.connection.status); + const actualAction = useWeave((state) => state.actions.actual); + + const imagesLLMPopupVisible = useIACapabilities( + (state) => state.llmPopup.visible + ); + + const triggerTool = React.useCallback( + (toolName: string, params?: unknown) => { + if (instance && actualAction !== toolName) { + instance.triggerAction(toolName, params); + return; + } + if (instance && actualAction === toolName) { + instance.cancelAction(toolName); + return; + } + }, + [instance, actualAction] + ); + + return ( + } + disabled={ + weaveConnectionStatus !== WEAVE_STORE_CONNECTION_STATUS.CONNECTED + } + active={actualAction === "moveTool"} + onClick={() => { + if (imagesLLMPopupVisible) { + triggerTool("moveTool", { + triggerSelectionTool: false, + }); + } else { + triggerTool("moveTool"); + } + }} + label={ +
+

Move tool

+ +
+ } + tooltipSide={tooltipSide} + tooltipAlign={tooltipAlign} + /> + ); +}; diff --git a/code/components/room-components/toolbar/toolbar-button.tsx b/code/components/room-components/toolbar/toolbar-button.tsx index 98d7f2f..6e78a56 100644 --- a/code/components/room-components/toolbar/toolbar-button.tsx +++ b/code/components/room-components/toolbar/toolbar-button.tsx @@ -5,6 +5,7 @@ "use client"; import React from "react"; +import { LongPressEventType, useLongPress } from "use-long-press"; import { cn } from "@/lib/utils"; import { Tooltip, @@ -22,6 +23,7 @@ type ToolbarButtonProps = { active?: boolean; disabled?: boolean; label?: React.ReactNode; + tooltipSideOffset?: number; tooltipSide?: "top" | "bottom" | "left" | "right"; tooltipAlign?: "start" | "center" | "end"; }; @@ -39,13 +41,23 @@ export const ToolbarButton = React.forwardRef< onClick, disabled = false, active = false, + tooltipSideOffset = 8, tooltipSide = "right", tooltipAlign = "center", }, - forwardedRef, + forwardedRef ) => { const selectionActive = useWeave((state) => state.selection.active); + const bind = useLongPress( + () => { + alert("Long pressed!"); + }, + { + detect: "pointer" as LongPressEventType, + } + ); + return ( @@ -63,10 +75,11 @@ export const ToolbarButton = React.forwardRef< ["pointer-events-none cursor-default text-black opacity-50"]: disabled, }, - className, + className )} disabled={disabled} onClick={onClick} + {...bind()} > {icon} @@ -74,7 +87,7 @@ export const ToolbarButton = React.forwardRef< {label} @@ -82,7 +95,7 @@ export const ToolbarButton = React.forwardRef< ); - }, + } ); ToolbarButton.displayName = "ToolbarButton"; diff --git a/code/components/room-components/toolbar/toolbar-divider.tsx b/code/components/room-components/toolbar/toolbar-divider.tsx new file mode 100644 index 0000000..620c97f --- /dev/null +++ b/code/components/room-components/toolbar/toolbar-divider.tsx @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2025 2025 INDUSTRIA DE DISEÑO TEXTIL S.A. (INDITEX S.A.) +// +// SPDX-License-Identifier: Apache-2.0 + +"use client"; + +import { cn } from "@/lib/utils"; +import React from "react"; + +type ToolbarDividerProps = { + orientation?: "vertical" | "horizontal"; +}; + +export function ToolbarDivider({ + orientation = "vertical", +}: Readonly) { + return ( +
+
+
+ ); +} diff --git a/code/components/room-components/toolbar/toolbar.tsx b/code/components/room-components/toolbar/toolbar.tsx index 29230c1..b716f92 100644 --- a/code/components/room-components/toolbar/toolbar.tsx +++ b/code/components/room-components/toolbar/toolbar.tsx @@ -9,11 +9,13 @@ import { useWeave } from "@inditextech/weave-react"; import React from "react"; type ToolbarProps = { + className?: string; children: React.ReactNode; orientation?: "horizontal" | "vertical"; }; export const Toolbar = ({ + className, children, orientation = "vertical", }: Readonly) => { @@ -26,9 +28,10 @@ export const Toolbar = ({ { ["pointer-events-none"]: selectionActive, ["pointer-events-auto"]: !selectionActive, - ["flex"]: orientation === "horizontal", + ["flex flex-row"]: orientation === "horizontal", ["flex flex-col"]: orientation === "vertical", }, + className )} > {children} diff --git a/code/components/ui/input.tsx b/code/components/ui/input.tsx index 625334e..7911129 100644 --- a/code/components/ui/input.tsx +++ b/code/components/ui/input.tsx @@ -14,15 +14,15 @@ const Input = React.forwardRef>( type={type} data-slot="input" className={cn( - "border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", + "border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 lg:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", - className, + className )} {...props} /> ); - }, + } ); Input.displayName = "Input"; diff --git a/code/components/ui/textarea.tsx b/code/components/ui/textarea.tsx index 3e0a795..a71ed7e 100644 --- a/code/components/ui/textarea.tsx +++ b/code/components/ui/textarea.tsx @@ -11,7 +11,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {