From e3eb8d007fd7da2ee6119431546ae6fc0908f5b5 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 28 Apr 2026 15:56:03 +0200 Subject: [PATCH 01/88] feat: update @code0-tech/triangulum dependency to version 0.14.0 and adjust peer dependencies --- package-lock.json | 128 ++++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 46 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3dd954a5..1ab3a4ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.13.3", + "@code0-tech/triangulum": "^0.14.0", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", @@ -113,6 +113,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -279,7 +280,6 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -376,9 +376,9 @@ "peer": true }, "node_modules/@code0-tech/triangulum": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.13.3.tgz", - "integrity": "sha512-k7ShwIJSaSaSUjpPtJ++O6sLCO0ihUMetoygPyesiZRODyejtBGB/ZsjkS+ZkGUZDpcFyqj7myy7aLal8UCv5Q==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.0.tgz", + "integrity": "sha512-blro7Ye4iPwsz8iSYchWphohX+MK4iIsy62RHvErDT3q34JbOq6GbMzVq7ZdKMJ5Mbd38q9eeXd4ROTi0fQmVw==", "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2462825049-b5d5dce99ef9bf2f81df41d896ec36fa5e28559c", "@typescript/vfs": "^1.6.4", @@ -391,6 +391,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.0.tgz", "integrity": "sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -403,7 +404,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.2.tgz", "integrity": "sha512-vvX1fsih9HledO1c9zdotZYUZnE4xV0m6i3m25s5DIfXofuprk6cRcLUZvSk3CASUbwjQX21tOGbkY2BH8TpnQ==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", @@ -442,6 +442,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.1.tgz", "integrity": "sha512-Fa6xkSiuGKc8XC8Cn96T+TQHYj4ZZ7RdFmXA3i9xe/3hLHfwPZdM+dqfX0Cp0zQklBKhVD8Yzc8LS45rkqcwpQ==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.23.0", @@ -456,6 +457,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.5.tgz", "integrity": "sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.35.0", @@ -467,7 +469,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.6.0.tgz", "integrity": "sha512-koFuNXcDvyyotWcgOnZGmY7LZqEOXZaaxD/j6n18TCLx2/9HieZJ5H6hs1g8FiRxBD0DNfs0nXn17g872RmYdw==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.37.0", @@ -479,6 +480,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.4.tgz", "integrity": "sha512-8y7xqG/hpB53l25CIoit9/ngxdfoG+fx+V3SHBrinnhOtLvKHRyAJJuHzkWrR4YXXLX8eXBsejgAAxHUOdW1yw==", "license": "MIT", + "peer": true, "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } @@ -488,7 +490,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz", "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", @@ -501,6 +502,7 @@ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.39.14.tgz", "integrity": "sha512-WJcvgHm/6Q7dvGT0YFv/6PSkoc36QlR0VCESS6x9tGsnF1lWLmmYxOgX3HH6v8fo6AvSLgpcs+H0Olre6MKXlg==", "license": "MIT", + "peer": true, "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", @@ -692,7 +694,6 @@ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", "license": "MIT", - "peer": true, "dependencies": { "@floating-ui/utils": "^0.2.10" } @@ -702,7 +703,6 @@ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", "license": "MIT", - "peer": true, "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" @@ -713,7 +713,6 @@ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", "license": "MIT", - "peer": true, "dependencies": { "@floating-ui/dom": "^1.7.4" }, @@ -726,8 +725,7 @@ "version": "0.2.10", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", @@ -1337,7 +1335,6 @@ "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", "license": "MIT", - "peer": true, "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", @@ -1569,6 +1566,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -1578,6 +1576,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.214.0.tgz", "integrity": "sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/api": "^1.3.0" }, @@ -1688,6 +1687,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.214.0.tgz", "integrity": "sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/api-logs": "0.214.0", "import-in-the-middle": "^3.0.0", @@ -1778,6 +1778,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.1.tgz", "integrity": "sha512-lID/vxSuKWXM55XhAKNoYXu9Cutoq5hFdkbTdI/zDKQktXzcWBVhNsOkiZFTMU9UtEWuGRNe0HUgmsFldIdxVA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/semantic-conventions": "^1.29.0" @@ -1794,6 +1795,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.214.0.tgz", "integrity": "sha512-zf6acnScjhsaBUU22zXZ/sLWim1dfhUAbGXdMmHmNG3LfBnQ3DKsOCITb2IZwoUsNNMTogqFKBnlIPPftUgGwA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/api-logs": "0.214.0", "@opentelemetry/core": "2.6.1", @@ -1812,6 +1814,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.6.1.tgz", "integrity": "sha512-9t9hJHX15meBy2NmTJxL+NJfXmnausR2xUDvE19XQce0Qi/GBtDGamU8nS1RMbdgDmhgpm3VaOu2+fiS/SfTpQ==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1" @@ -1828,6 +1831,7 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.6.1.tgz", "integrity": "sha512-r86ut4T1e8vNwB35CqCcKd45yzqH6/6Wzvpk2/cZB8PsPLlZFTvrh8yfOS3CYZYcUmAx4hHTZJ8AO8Dj8nrdhw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@opentelemetry/core": "2.6.1", "@opentelemetry/resources": "2.6.1", @@ -2229,22 +2233,19 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, @@ -2299,7 +2300,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", @@ -2326,7 +2326,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2342,7 +2341,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2424,7 +2422,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2440,7 +2437,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", @@ -2498,7 +2494,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -2514,7 +2509,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", @@ -2572,7 +2566,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -2591,7 +2584,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", @@ -2667,7 +2659,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", "license": "MIT", - "peer": true, "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", @@ -2700,7 +2691,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" @@ -2725,7 +2715,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" @@ -2750,7 +2739,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-slot": "1.2.3" }, @@ -2807,7 +2795,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", @@ -2871,7 +2858,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, @@ -2921,7 +2907,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", @@ -3012,7 +2997,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3028,7 +3012,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" @@ -3048,7 +3031,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -3067,7 +3049,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, @@ -3086,7 +3067,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", "license": "MIT", - "peer": true, "dependencies": { "use-sync-external-store": "^1.5.0" }, @@ -3105,7 +3085,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3121,7 +3100,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3137,7 +3115,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/rect": "1.1.1" }, @@ -3156,7 +3133,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, @@ -3175,7 +3151,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", "license": "MIT", - "peer": true, "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, @@ -3198,8 +3173,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@rtsao/scc": { "version": "1.1.0", @@ -3222,7 +3196,6 @@ "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.41.1.tgz", "integrity": "sha512-OaRnVbRmH2nHtFeg+RmMJ/7m2oBIF9XCJAUD5gQnMrpK9f05ydj8MZrAf3NZQqOXyxGN1UBL0D5IKLLEUfr74Q==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/codecalm" @@ -3260,15 +3233,13 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/d3-drag": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/d3-selection": "*" } @@ -3278,7 +3249,6 @@ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "license": "MIT", - "peer": true, "dependencies": { "@types/d3-color": "*" } @@ -3287,15 +3257,13 @@ "version": "3.0.11", "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/d3-transition": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", "license": "MIT", - "peer": true, "dependencies": { "@types/d3-selection": "*" } @@ -3305,7 +3273,6 @@ "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", "license": "MIT", - "peer": true, "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" @@ -3354,6 +3321,7 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3364,6 +3332,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -3413,6 +3382,7 @@ "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.52.0", "@typescript-eslint/types": "8.52.0", @@ -3655,7 +3625,6 @@ "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.25.4.tgz", "integrity": "sha512-YzNwkm0AbPv1EXhCHYR5v0nqfemG2jEB0Z3Att4rBYqKrlG7AA9Rhjc3IyBaOzsBu18wtrp9/+uhTyu7TXSRng==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/commands": "^6.0.0", @@ -4081,7 +4050,6 @@ "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.74.tgz", "integrity": "sha512-7v7B/PkiVrkdZzSbL+inGAo6tkR/WQHHG0/jhSvLQToCsfa8YubOGmBYd1s08tpKpihdHDZFwzQZeR69QSBb4Q==", "license": "MIT", - "peer": true, "dependencies": { "@types/d3-drag": "^3.0.7", "@types/d3-interpolate": "^3.0.4", @@ -4099,6 +4067,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4147,7 +4116,6 @@ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.0" }, @@ -4398,6 +4366,7 @@ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/types": "^7.26.0" } @@ -4465,6 +4434,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4574,8 +4544,7 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/client-only": { "version": "0.0.1", @@ -4605,7 +4574,6 @@ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/commands": "^6.0.0", @@ -4655,14 +4623,14 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -4672,7 +4640,6 @@ "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -4682,7 +4649,6 @@ "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", "license": "ISC", - "peer": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" @@ -4696,7 +4662,6 @@ "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=12" } @@ -4706,7 +4671,6 @@ "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "license": "ISC", - "peer": true, "dependencies": { "d3-color": "1 - 3" }, @@ -4729,7 +4693,6 @@ "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -4739,7 +4702,6 @@ "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "license": "ISC", - "peer": true, "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", @@ -4759,7 +4721,6 @@ "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", "license": "ISC", - "peer": true, "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", @@ -4919,8 +4880,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/doctrine": { "version": "2.1.0", @@ -5170,6 +5130,7 @@ "integrity": "sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -5338,6 +5299,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -5870,7 +5832,6 @@ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -5968,7 +5929,6 @@ "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz", "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==", "license": "MIT", - "peer": true, "peerDependencies": { "csstype": "^3.0.10" } @@ -5991,6 +5951,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.13.2.tgz", "integrity": "sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig==", "license": "MIT", + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -7361,6 +7322,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -7370,6 +7332,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -7399,7 +7362,6 @@ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", "license": "MIT", - "peer": true, "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", @@ -7425,7 +7387,6 @@ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "license": "MIT", - "peer": true, "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" @@ -7459,7 +7420,6 @@ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "license": "MIT", - "peer": true, "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" @@ -7633,6 +7593,7 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -7697,6 +7658,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", "license": "MIT", + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.1.5", @@ -8191,6 +8153,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -8352,6 +8315,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8490,7 +8454,6 @@ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.0.0" }, @@ -8524,7 +8487,6 @@ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "license": "MIT", - "peer": true, "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -8547,7 +8509,6 @@ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -8699,6 +8660,7 @@ "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -8720,14 +8682,14 @@ "version": "0.16.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.16.1.tgz", "integrity": "sha512-dpvY17vxYIW3+bNrP0ClUlaiY0CiIRK3tnoLaGoQsQcY9/I/NpzIWQ7tQNhbV7LacQMpCII6wVzuL3tuWOyfuA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/zustand": { "version": "4.5.7", "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", "license": "MIT", - "peer": true, "dependencies": { "use-sync-external-store": "^1.2.2" }, diff --git a/package.json b/package.json index 638069b0..05ec1be3 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.13.3", + "@code0-tech/triangulum": "^0.14.0", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", From 3f0d73c16348ce6b0922d47557701fc870192a01 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 08:27:57 +0200 Subject: [PATCH 02/88] feat: update @code0-tech/triangulum dependency to version 0.14.1 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1ab3a4ed..62ae25f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.0", + "@code0-tech/triangulum": "^0.14.1", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", @@ -376,9 +376,9 @@ "peer": true }, "node_modules/@code0-tech/triangulum": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.0.tgz", - "integrity": "sha512-blro7Ye4iPwsz8iSYchWphohX+MK4iIsy62RHvErDT3q34JbOq6GbMzVq7ZdKMJ5Mbd38q9eeXd4ROTi0fQmVw==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.1.tgz", + "integrity": "sha512-oObwhooeANzQccxccPLchm6Ku7jEAXhcCmf36QZgtYPTqo4B+j9Z2waUmDaWRcMgG+yHHoIe+NcocslF64B0sg==", "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2462825049-b5d5dce99ef9bf2f81df41d896ec36fa5e28559c", "@typescript/vfs": "^1.6.4", diff --git a/package.json b/package.json index 05ec1be3..ece4727d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.0", + "@code0-tech/triangulum": "^0.14.1", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", From 00240d0abe6590ed7d20ae2536188357b6fbdbee Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 08:28:13 +0200 Subject: [PATCH 03/88] feat: refactor DataTypeInputComponent to use NodeSchema and simplify input handling --- .../inputs/DataTypeInputComponent.tsx | 60 ++-------- .../json/DataTypeJSONInputComponent.tsx | 1 - .../text/DataTypeTextInputComponent.tsx | 20 +--- .../ce/src/flow/components/Flow.worker.js | 27 ++--- .../flow/components/FlowWorkerProvider.tsx | 14 ++- .../panels/FlowPanelControlComponent.tsx | 1 - .../ce/src/flow/hooks/Flow.edges.hook.ts | 73 ++++-------- .../ce/src/flow/hooks/Flow.nodes.hook.ts | 77 ++++++------- .../files/FunctionFileTriggerComponent.tsx | 1 - .../function/hooks/Function.schema.hook.ts | 55 +++++++++ .../hooks/FunctionNode.selected.hook.ts | 6 +- .../hooks/FunctionNodeSuggestions.hook.tsx | 104 ------------------ .../FunctionReferenceSuggestions.hook.tsx | 63 ----------- .../hooks/FunctionSuggestion.hook.tsx | 73 ------------ .../hooks/FunctionValueSuggestions.hook.tsx | 49 --------- 15 files changed, 143 insertions(+), 481 deletions(-) create mode 100644 src/packages/ce/src/function/hooks/Function.schema.hook.ts delete mode 100644 src/packages/ce/src/function/hooks/FunctionNodeSuggestions.hook.tsx delete mode 100644 src/packages/ce/src/function/hooks/FunctionReferenceSuggestions.hook.tsx delete mode 100644 src/packages/ce/src/function/hooks/FunctionSuggestion.hook.tsx delete mode 100644 src/packages/ce/src/function/hooks/FunctionValueSuggestions.hook.tsx diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 34bcee9e..7541b70a 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -1,71 +1,29 @@ -import {Flow, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; import React from "react"; import {DataTypeTextInputComponent} from "./text/DataTypeTextInputComponent"; -import {InputProps, useService, useStore} from "@code0-tech/pictor"; -import {FlowService} from "@edition/flow/services/Flow.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import {FunctionService} from "@edition/function/services/Function.service"; -import {DataTypeVariant, getTypesFromFunction, getTypeVariant} from "@code0-tech/triangulum"; +import {InputProps} from "@code0-tech/pictor"; import {DataTypeJSONInputComponent} from "@edition/datatype/components/inputs/json/DataTypeJSONInputComponent"; +import {NodeSchema} from "@code0-tech/triangulum"; export interface DataTypeInputComponentProps extends Omit, "wrapperComponent" | "type"> { - flowId: Flow['id'] - nodeId?: NodeFunction['id'] //TODO if undefined we need to get infos from trigger - parameterIndex: number + schema: NodeSchema clearable?: boolean onClear?: (event: React.MouseEvent) => void } export const DataTypeInputComponent: React.FC = (props) => { - const {flowId, nodeId, parameterIndex, ...rest} = props + const {schema, ...rest} = props - const flowService = useService(FlowService) - const flowStore = useStore(FlowService) - const dataTypeStore = useStore(DatatypeService) - const dataTypeService = useService(DatatypeService) - const functionStore = useStore(FunctionService) - const functionService = useService(FunctionService) - - const flow = React.useMemo( - () => flowId ? flowService.getById(flowId) : undefined, - [flowStore, flowId] - ) - - const node = React.useMemo( - () => nodeId && flowId ? flowService.getNodeById(flowId, nodeId) : undefined, - [flowStore, flowId, nodeId] - ) - - const functionDefinition = React.useMemo( - () => node ? functionService.getById(node?.functionDefinition?.id) : undefined, - [functionStore, node] - ) - - const types = React.useMemo( - () => nodeId ? getTypesFromFunction(functionDefinition!) : undefined, - [functionDefinition, nodeId] - ) - - const dataTypeVariant = React.useMemo( - () => types ? getTypeVariant(types.parameters[parameterIndex], dataTypeService.values())[0].variant : undefined, - [dataTypeStore, types] - ) - - switch (dataTypeVariant) { - case DataTypeVariant.ARRAY: - case DataTypeVariant.OBJECT: + switch (schema.schema.input) { + case "data": + case "list": return default: return } diff --git a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx index 0d4ae35c..f21a5616 100644 --- a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx @@ -6,7 +6,6 @@ import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; import {LiteralValue, NodeFunction, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types"; import {NodeBadgeComponent} from "../../badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "../../badges/ReferenceBadgeComponent"; -import {useSuggestions} from "@edition/function/hooks/FunctionSuggestion.hook"; import { Button, Card, diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index f8382205..0112c282 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -1,18 +1,14 @@ import React from "react"; -import {ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; import {NodeBadgeComponent} from "../../badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "../../badges/ReferenceBadgeComponent"; import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; import {InputSyntaxSegment, MenuItem, Text, TextInput, useService} from "@code0-tech/pictor"; import {FunctionService} from "@edition/function/services/Function.service"; import {FlowService} from "@edition/flow/services/Flow.service"; -import {FlowTypeService} from "@edition/flowtype/services/FlowType.service"; -import {useSuggestions} from "@edition/function/hooks/FunctionSuggestion.hook"; import { FunctionSuggestionMenuFooterComponent } from "@edition/function/components/suggestion/FunctionSuggestionMenuFooterComponent"; import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; -import {FunctionSuggestion} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps @@ -101,13 +97,6 @@ export const DataTypeTextInputComponent: React.FC { - return flowService.getById(flowId) - }, [flowService, flowId]) - - const suggestions = rest.suggestions || useSuggestions(flowId, nodeId, parameterIndex) const transformSyntax = React.useCallback((value: string | null): InputSyntaxSegment[] => { @@ -147,18 +136,15 @@ export const DataTypeTextInputComponent: React.FC, + , value ) } if (value?.__typename === "ReferenceValue") { - const node = (value as ReferenceValue).nodeFunctionId === "gid://sagittarius/NodeFunction/-1" ? flowTypeService.getById(flow?.type?.id) : functionService.getById(flowService.getNodeById(flowId, (value as ReferenceValue).nodeFunctionId)?.functionDefinition?.id) return buildBlockSegment( - , + , value ) } @@ -177,7 +163,7 @@ export const DataTypeTextInputComponent: React.FC diff --git a/src/packages/ce/src/flow/components/Flow.worker.js b/src/packages/ce/src/flow/components/Flow.worker.js index 115918fd..c9622710 100644 --- a/src/packages/ce/src/flow/components/Flow.worker.js +++ b/src/packages/ce/src/flow/components/Flow.worker.js @@ -1,10 +1,4 @@ -import { - getFlowValidation, - getNodeSuggestions, - getReferenceSuggestions, getTypeFromValue, - getTypesFromNode, getTypeVariant, getValueFromType, - getValueSuggestions -} from "@code0-tech/triangulum"; +import {getFlowValidation, getSignatureSchema, getTypeFromValue, getValueFromType} from "@code0-tech/triangulum"; import {InspectionSeverity} from "../../../../core/src/util/inspection"; const errorResult = ( @@ -22,7 +16,7 @@ const errorResult = ( }) addEventListener("message", (event) => { - const { id, action, payload } = event.data; + const {id, action, payload} = event.data; let result; try { @@ -33,16 +27,16 @@ addEventListener("message", (event) => { errorResult(diagnostic.nodeId, diagnostic.parameterIndex, diagnostic.message)); break; case 'value_suggestions': - result = getValueSuggestions(payload.type, payload.dataTypes); + result = []; break; case 'reference_suggestions': - result = getReferenceSuggestions(payload.flow, payload.nodeId, payload.parameterIndex, payload.functions, payload.dataTypes); + result = []; break; case 'node_suggestions': - result = getNodeSuggestions(payload.type, payload.functions, payload.dataTypes); + result = []; break; case 'node_type_extraction': - result = getTypesFromNode(payload.node, payload.functions, payload.dataTypes); + result = {}; break; case 'type_extraction': result = getTypeFromValue(payload.value, payload.dataTypes); @@ -51,13 +45,16 @@ addEventListener("message", (event) => { result = getValueFromType(payload.type, payload.dataTypes); break; case 'type_variant': - result = getTypeVariant(payload.type, payload.dataTypes); + result = 0; + break; + case 'schema': + result = getSignatureSchema(payload.flow, payload.dataTypes, payload.functions, payload.nodeId); break; } - postMessage({ id, data: result }); + postMessage({id, data: result}); } catch (error) { - postMessage({ id, error: error.message }); + postMessage({id, error: error.message}); } }); diff --git a/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx b/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx index 0f8d3ed2..7db4d7fe 100644 --- a/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx +++ b/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx @@ -1,6 +1,6 @@ import React from "react" import {DataType, Flow, FunctionDefinition, LiteralValue, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; -import {TypeVariantResult} from "@code0-tech/triangulum/dist/extraction/getTypeVariant"; +import {NodeSchema} from "@code0-tech/triangulum"; interface Deferred { resolve: (value: any) => void @@ -16,6 +16,7 @@ type FlowWorkerActions = | "type_extraction" | "value_extraction" | "type_variant" + | "schema" interface FlowWorkerValidationPayload { flow: Flow @@ -63,6 +64,13 @@ interface FlowWorkerTypeExtractionPayload { dataTypes: DataType[] } +interface FlowWorkerSchemaPayload { + flow: Flow + dataTypes: DataType[] + functions: FunctionDefinition[] + nodeId?: NodeFunction['id'] +} + type FlowWorkerPayload = FlowWorkerValidationPayload | FlowWorkerValueSuggestionsPayload @@ -173,5 +181,5 @@ export const useTypeExtractionAction = () => export const useValueExtractionAction = () => useWorkerAction("value_extraction"); -export const useTypeVariantAction = () => - useWorkerAction("type_variant"); \ No newline at end of file +export const useSchemaAction = () => + useWorkerAction("schema"); \ No newline at end of file diff --git a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx index e795a26f..2af406b8 100644 --- a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx +++ b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx @@ -15,7 +15,6 @@ import {Panel} from "@xyflow/react"; import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; import {FunctionSuggestionMenuComponent} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent"; import {FlowService} from "@edition/flow/services/Flow.service"; -import {useNodeSuggestions} from "@edition/function/hooks/FunctionNodeSuggestions.hook"; import {SuggestionDialogComponent} from "@edition/function/components/suggestion/SuggestionDialogComponent"; import {FunctionSuggestion} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; import {Suggestion} from "@edition/function/components/suggestion/Suggestion.util"; diff --git a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts index 6bda679d..74f6f31c 100644 --- a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts @@ -4,29 +4,25 @@ import type {Flow, Namespace, NamespaceProject, NodeFunction} from "@code0-tech/ import {hashToColor, useService, useStore} from "@code0-tech/pictor"; import {FlowService} from "@edition/flow/services/Flow.service"; import {FunctionService} from "@edition/function/services/Function.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import {DataTypeVariant, getTypesFromFunction, getTypesFromNode, getTypeVariant} from "@code0-tech/triangulum"; import {FALLBACK_FUNCTION_PARAMETER_NAME} from "@core/util/fallback-translations"; +import {FlowBuilderEdgeDataProps} from "@edition/flow/components/builder/FlowBuilderEdgeComponent"; // @ts-ignore -export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], projectId?: NamespaceProject['id']): Edge[] => { +export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], projectId?: NamespaceProject['id']): Edge[] => { const flowService = useService(FlowService); const flowStore = useStore(FlowService) const functionService = useService(FunctionService); const functionStore = useStore(FunctionService) - const dataTypeService = useService(DatatypeService); - const dataTypeStore = useStore(DatatypeService) const flow = React.useMemo(() => flowService.getById(flowId, {namespaceId, projectId}), [flowId, flowStore]) return React.useMemo(() => { if (!flow) return [] if (functionStore.length <= 0) return [] - if (dataTypeStore.length <= 0) return [] // @ts-ignore - const edges: Edge[] = [] + const edges: Edge[] = [] const groupsWithValue = new Map(); @@ -89,65 +85,38 @@ export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], proj } } - const types = getTypesFromFunction(functionService.getById(node.functionDefinition?.id)!); - node.parameters?.nodes?.forEach((param, index) => { const parameterValue = param?.value; const parameterDefinition = functionService.getById(node.functionDefinition?.id!!)?.parameterDefinitions?.nodes?.[index]; - const variant = getTypeVariant(types.parameters[index], dataTypeService.values())[0].variant; if (!parameterValue) return - if (variant === DataTypeVariant.NODE) { - if (parameterValue && parameterValue.__typename === "NodeFunctionIdWrapper") { - - const groupId = `${node.id}-group-${idCounter++}`; - - edges.push({ - id: `${node.id}-${groupId}-param-${index}`, - source: node.id!, - target: groupId, - deletable: false, - selectable: false, - animated: true, - label: parameterDefinition?.names!![0]?.content ?? FALLBACK_FUNCTION_PARAMETER_NAME, - data: { - color: hashToColor(parameterValue?.id || ""), - type: 'group', - flowId: flowId, - parentNodeId: parentNode?.id - }, - }); - - (groupsWithValue.get(node.id!) ?? (groupsWithValue.set(node.id!, []), groupsWithValue.get(node.id!)!)).push(groupId); - - traverse( - flowService.getNodeById(flowId, parameterValue.id)!, - node, - true - ); - } - } else if (parameterValue && parameterValue.__typename === "NodeFunctionIdWrapper") { - const subFnId = traverse( - flowService.getNodeById(flowId, parameterValue.id)!, - node, - true - ); + if (parameterValue && parameterValue.__typename === "NodeFunctionIdWrapper") { + + const groupId = `${node.id}-group-${idCounter++}`; edges.push({ - id: `${subFnId}-${node.id}-param-${index}`, - source: subFnId, - target: node.id!, - targetHandle: `param-${index}`, - animated: true, + id: `${node.id}-${groupId}-param-${index}`, + source: node.id!, + target: groupId, deletable: false, selectable: false, + animated: true, + label: parameterDefinition?.names!![0]?.content ?? FALLBACK_FUNCTION_PARAMETER_NAME, data: { color: hashToColor(parameterValue?.id || ""), - type: 'parameter', + type: 'group', flowId: flowId, parentNodeId: parentNode?.id }, }); + + (groupsWithValue.get(node.id!) ?? (groupsWithValue.set(node.id!, []), groupsWithValue.get(node.id!)!)).push(groupId); + + traverse( + flowService.getNodeById(flowId, parameterValue.id)!, + node, + true + ); } }); @@ -163,5 +132,5 @@ export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], proj } return edges - }, [flow, flowStore, functionStore, dataTypeStore]); + }, [flow, flowStore, functionStore]); }; \ No newline at end of file diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index 56c68c2e..61806b40 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -4,9 +4,7 @@ import React from "react"; import {hashToColor, useService, useStore} from "@code0-tech/pictor"; import {FlowService} from "@edition/flow/services/Flow.service"; import {FunctionService} from "@edition/function/services/Function.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; import {FunctionNodeComponentProps} from "@edition/function/components/nodes/FunctionNodeComponent"; -import {DataTypeVariant, getTypesFromFunction, getTypesFromNode, getTypeVariant} from "@code0-tech/triangulum"; export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], projectId?: NamespaceProject["id"]): Node[] => { @@ -14,15 +12,15 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const flowStore = useStore(FlowService) const functionService = useService(FunctionService) const functionStore = useStore(FunctionService) - const dataTypeService = useService(DatatypeService) - const dataTypeStore = useStore(DatatypeService) - const flow = React.useMemo(() => flowService.getById(flowId, {namespaceId, projectId}), [flowId, flowStore]); + const flow = React.useMemo( + () => flowService.getById(flowId, {namespaceId, projectId}), + [flowId, flowStore] + ) return React.useMemo(() => { if (!flow) return [] if (functionStore.length <= 0) return [] - if (dataTypeStore.length <= 0) return [] const nodes: Node[] = []; const visited = new Set(); @@ -45,8 +43,6 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const traverse = ( node: NodeFunction, - isParameter = false, - parentId?: NodeFunction['id'], parentGroup?: string ) => { if (!node?.id) return; @@ -66,57 +62,46 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], extent: parentGroup ? "parent" : undefined, data: { nodeId: nodeId, - isParameter: isParameter, flowId: flowId, - parentNodeId: isParameter ? parentId : undefined, index: ++globalIndex, color: hashToColor(nodeId), }, }); } - const types = getTypesFromFunction(functionDefinition!); - - node.parameters?.nodes?.forEach((param, index) => { + node.parameters?.nodes?.forEach((param) => { const value = param?.value; if (!value || value.__typename !== "NodeFunctionIdWrapper") return; - - const variant = getTypeVariant(types.parameters[index], dataTypeService.values())[0].variant; - - if (variant === DataTypeVariant.NODE) { - const groupId = `${nodeId}-group-${groupCounter++}`; - - if (!visited.has(groupId)) { - visited.add(groupId); - - nodes.push({ - id: groupId, - type: "group", - position: {x: 0, y: 0}, - draggable: false, - parentId: parentGroup, - extent: parentGroup ? "parent" : undefined, - data: { - isParameter: true, - parentNodeId: nodeId, - nodeId: nodeId, - flowId: flowId, - color: hashToColor(value?.id ?? ""), - }, - }); - } - - const child = flowService.getNodeById(flowId, value.id); - if (child) traverse(child, false, undefined, groupId); - } else { - const child = flowService.getNodeById(flowId, value.id); - if (child) traverse(child, true, nodeId, parentGroup); + + const groupId = `${nodeId}-group-${groupCounter++}`; + + if (!visited.has(groupId)) { + visited.add(groupId); + + nodes.push({ + id: groupId, + type: "group", + position: {x: 0, y: 0}, + draggable: false, + parentId: parentGroup, + extent: parentGroup ? "parent" : undefined, + data: { + isParameter: true, + parentNodeId: nodeId, + nodeId: nodeId, + flowId: flowId, + color: hashToColor(value?.id ?? ""), + }, + }); } + + const child = flowService.getNodeById(flowId, value.id); + if (child) traverse(child, groupId); }); if (node.nextNodeId) { const next = flowService.getNodeById(flow.id, node.nextNodeId); - if (next) traverse(next, false, undefined, parentGroup); + if (next) traverse(next, parentGroup); } }; @@ -126,5 +111,5 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], } return nodes; - }, [flow, flowStore, functionStore, dataTypeStore]); + }, [flow, flowStore, functionStore]); }; \ No newline at end of file diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 9ce07e48..012f8257 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -5,7 +5,6 @@ import {FlowTypeService} from "@edition/flowtype/services/FlowType.service"; import {FlowService} from "@edition/flow/services/Flow.service"; import {useFlowValidation} from "@edition/flow/hooks/Flow.validation.hook"; import {DataTypeInputComponent} from "@edition/datatype/components/inputs/DataTypeInputComponent"; -import {getTypesFromFunction} from "@code0-tech/triangulum"; import {DataTypeTypeInputComponent} from "@edition/datatype/components/inputs/datatype/DataTypeTypeInputComponent"; import { FALLBACK_FLOW_TYPE_DESCRIPTION, diff --git a/src/packages/ce/src/function/hooks/Function.schema.hook.ts b/src/packages/ce/src/function/hooks/Function.schema.hook.ts new file mode 100644 index 00000000..2d17bd84 --- /dev/null +++ b/src/packages/ce/src/function/hooks/Function.schema.hook.ts @@ -0,0 +1,55 @@ +import type {Flow} from "@code0-tech/sagittarius-graphql-types"; +import {useService, useStore} from "@code0-tech/pictor"; +import {FlowService} from "@edition/flow/services/Flow.service"; +import React from "react"; +import {useSchemaAction} from "@edition/flow/components/FlowWorkerProvider"; +import {DatatypeService} from "@edition/datatype/services/Datatype.service"; +import {FunctionService} from "@edition/function/services/Function.service"; +import {NodeSchema} from "@code0-tech/triangulum"; + +export const useFlowSchema = ( + flowId: Flow['id'] +) => { + const flowService = useService(FlowService) + const flowStore = useStore(FlowService) + const dataTypeStore = useStore(DatatypeService) + const dataTypeService = useService(DatatypeService) + const functionService = useService(FunctionService) + const functionStore = useStore(FunctionService) + const {execute} = useSchemaAction() + + const [schema, setSchema] = React.useState([]); + + const flow = React.useMemo( + () => flowService.getById(flowId), + [flowId, flowService, flowStore] + ) + + const dataTypes = React.useMemo( + () => dataTypeService.values(), + [dataTypeStore, dataTypeService] + ) + + const functions = React.useMemo( + () => functionService.values(), + [functionStore, functionService] + ) + + React.useEffect(() => { + if (!flow) return + + const schemas = flow.nodes?.nodes?.map(node => { + return execute({ + flow, + dataTypes, + functions, + nodeId: node?.id + }) + }) + + Promise.all(schemas!).then((value) => setSchema(value as NodeSchema[])) + + }, [flow, dataTypes, functions]) + + return schema +} diff --git a/src/packages/ce/src/function/hooks/FunctionNode.selected.hook.ts b/src/packages/ce/src/function/hooks/FunctionNode.selected.hook.ts index 223c02bb..93e9208d 100644 --- a/src/packages/ce/src/function/hooks/FunctionNode.selected.hook.ts +++ b/src/packages/ce/src/function/hooks/FunctionNode.selected.hook.ts @@ -8,20 +8,16 @@ export const useSelectedFunctionNode = () => { } export const setSelectedFunctionNode = (nodeId: string, reactFlow: ReturnType) => { - reactFlow.setNodes((nodes) => nodes.map((node) => ({ ...node, selected: node.id === nodeId, })) ) - reactFlow.fitView({ nodes: [{id: nodeId}], duration: 250, maxZoom: reactFlow.getZoom(), minZoom: 1, }); - - -} \ No newline at end of file +} diff --git a/src/packages/ce/src/function/hooks/FunctionNodeSuggestions.hook.tsx b/src/packages/ce/src/function/hooks/FunctionNodeSuggestions.hook.tsx deleted file mode 100644 index 3b5c0d28..00000000 --- a/src/packages/ce/src/function/hooks/FunctionNodeSuggestions.hook.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { - FunctionSuggestion, - FunctionSuggestionType -} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; -import {useService, useStore} from "@code0-tech/pictor"; -import {FunctionService} from "@edition/function/services/Function.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import React from "react"; -import {useTypeVariantAction} from "@edition/flow/components/FlowWorkerProvider"; -import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; - -export const useNodeSuggestions = ( - type?: string | null, -): FunctionSuggestion[] => { - - const functionStore = useStore(FunctionService) - const functionService = useService(FunctionService) - const dataTypeStore = useStore(DatatypeService) - const dataTypeService = useService(DatatypeService) - - const [suggestions, setSuggestions] = React.useState([]) - const [typeVariant, setTypeVariant] = React.useState(undefined) - //const {execute} = useNodeSuggestionsAction() - const variantAction = useTypeVariantAction() - - const functions = React.useMemo(() => functionService.values(), [functionStore]); - const dataTypes = React.useMemo(() => dataTypeService.values(), [dataTypeStore]); - - React.useEffect(() => { - - if (type === null) return - - const timeout = setTimeout(() => { - variantAction.execute({ - type: type as string, - dataTypes - }).then(value => { - setTypeVariant(value?.[0]?.variant) - }) - }, 200); - - return () => clearTimeout(timeout); - - }, [type, dataTypes]) - - React.useEffect(() => { - - if (type !== null && typeVariant === undefined) return - if (type !== null && typeVariant != 4) return - - const nodes = functionService.values().map(f => ({ - __typename: "NodeFunction", - id: `gid://sagittarius/NodeFunction/1`, - functionDefinition: { - __typename: "FunctionDefinition", - id: f.id, - identifier: f.identifier, - }, - parameters: { - __typename: "NodeParameterConnection", - nodes: (f.parameterDefinitions?.nodes || []).map(p => ({ - __typename: "NodeParameter", - parameterDefinition: { - __typename: "ParameterDefinition", - id: p?.id, - identifier: p?.identifier - }, - value: p?.defaultValue ? { - __typename: "LiteralValue", - value: p.defaultValue.value - } : null - })) - } - })) - - setSuggestions(nodes) - - }, [type, typeVariant, functions, dataTypes]) - - return React.useMemo(() => suggestions.sort((a, b) => { - const [rA, pA, fA] = a?.functionDefinition!!.identifier!!.split("::"); - const [rB, pB, fB] = b?.functionDefinition!!.identifier!!.split("::"); - - const runtimeCmp = rA.localeCompare(rB); - if (runtimeCmp !== 0) return runtimeCmp; - - const packageCmp = pA.localeCompare(pB); - if (packageCmp !== 0) return packageCmp; - - return fA.localeCompare(fB); - }).map(suggestion => { - - const functionDefinition = functionService.getById(suggestion.functionDefinition?.id) - return { - path: [], - type: FunctionSuggestionType.FUNCTION, - displayText: [functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME], - value: suggestion, - icon: functionDefinition?.displayIcon || "", - aliases: functionDefinition?.aliases?.map((a) => a.content).flatMap(a => a?.split(";") ?? ""), - description: functionDefinition?.descriptions?.[0]?.content || "", - } - }), [suggestions]); -} diff --git a/src/packages/ce/src/function/hooks/FunctionReferenceSuggestions.hook.tsx b/src/packages/ce/src/function/hooks/FunctionReferenceSuggestions.hook.tsx deleted file mode 100644 index 29802241..00000000 --- a/src/packages/ce/src/function/hooks/FunctionReferenceSuggestions.hook.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import {Flow, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; -import { - FunctionSuggestion, - FunctionSuggestionType -} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; -import {useService, useStore} from "@code0-tech/pictor"; -import {FunctionService} from "@edition/function/services/Function.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import {FlowService} from "@edition/flow/services/Flow.service"; -import React from "react"; -import {useReferenceSuggestionsAction} from "@edition/flow/components/FlowWorkerProvider"; - -export const useReferenceSuggestions = ( - flowId: Flow['id'], - nodeId?: NodeFunction['id'], - parameterIndex?: number, -): FunctionSuggestion[] => { - - const flowService = useService(FlowService) - const flowStore = useStore(FlowService) - const functionStore = useStore(FunctionService) - const functionService = useService(FunctionService) - const dataTypeStore = useStore(DatatypeService) - const dataTypeService = useService(DatatypeService) - - const {execute} = useReferenceSuggestionsAction() - const [suggestions, setSuggestions] = React.useState([]) - - const flow = React.useMemo( - () => flowService.getById(flowId), - [flowId, flowStore] - ) - const functions = React.useMemo(() => functionService.values(), [functionStore]); - const dataTypes = React.useMemo(() => dataTypeService.values(), [dataTypeStore]); - - React.useEffect(() => { - if (typeof parameterIndex != "number" || !flow || !nodeId) return; - - const timeout = setTimeout(() => { - execute({ - flow, - nodeId, - parameterIndex, - functions, - dataTypes - }).then(value => { - setSuggestions(value as any[]) - }) - }, 200); - - return () => clearTimeout(timeout); - }, [flow?.editedAt, nodeId, parameterIndex, functions, dataTypes]) - - return React.useMemo(() => suggestions.map(suggestion => { - - return { - path: [], - type: FunctionSuggestionType.REF_OBJECT, - displayText: [`${suggestion.referencePath?.map((path: any) => path.path).join(".") ?? ""}`], - value: suggestion, - } - }), [suggestions]); -} diff --git a/src/packages/ce/src/function/hooks/FunctionSuggestion.hook.tsx b/src/packages/ce/src/function/hooks/FunctionSuggestion.hook.tsx deleted file mode 100644 index c012a623..00000000 --- a/src/packages/ce/src/function/hooks/FunctionSuggestion.hook.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from "react"; -import type {Flow, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; -import {useValueSuggestions} from "./FunctionValueSuggestions.hook"; -import {useReferenceSuggestions} from "./FunctionReferenceSuggestions.hook"; -import {useNodeSuggestions} from "./FunctionNodeSuggestions.hook"; -import {useService, useStore} from "@code0-tech/pictor"; -import {FunctionSuggestion} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; -import {FunctionService} from "@edition/function/services/Function.service"; -import {FlowService} from "@edition/flow/services/Flow.service"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import {useNodeTypeExtractionAction} from "@edition/flow/components/FlowWorkerProvider"; - -//TODO: deep type search -//TODO: calculate FUNCTION_COMBINATION deepness max 2 - -export const useSuggestions = ( - flowId: Flow['id'], - nodeId?: NodeFunction['id'], - parameterIndex?: number -): FunctionSuggestion[] => { - - const functionService = useService(FunctionService) - const functionStore = useStore(FunctionService) - const flowService = useService(FlowService) - const flowStore = useStore(FlowService) - const dataTypeStore = useStore(DatatypeService) - const dataTypeService = useService(DatatypeService) - - const {execute} = useNodeTypeExtractionAction() - const [types, setTypes] = React.useState(null); - - const node = React.useMemo( - () => flowService.getNodeById(flowId, nodeId), - [flowId, flowStore, nodeId] - ) - - const functions = React.useMemo( - () => functionService.values(), - [functionStore] - ) - - const dataTypes = React.useMemo( - () => dataTypeService.values(), - [dataTypeStore] - ) - - React.useEffect(() => { - if (!node) return - const timeout = setTimeout(() => { - execute({ - node: node, - dataTypes: dataTypes, - functions: functions - }).then(value => { - setTypes(value) - }) - }, 200); - - return () => clearTimeout(timeout); - }, [node, functions, dataTypes]) - - const valueSuggestions = useValueSuggestions(types?.parameters?.[parameterIndex ?? 0]) - const refObjectSuggestions = useReferenceSuggestions(flowId, nodeId, parameterIndex) - const functionSuggestions = (node && typeof parameterIndex === "number") || (!node && typeof parameterIndex != "number") ? useNodeSuggestions(types?.parameters?.[parameterIndex ?? 0]) : [] - - return React.useMemo(() => { - return [ - ...valueSuggestions, - ...refObjectSuggestions, - ...functionSuggestions - ].sort() - }, [valueSuggestions, refObjectSuggestions, functionSuggestions]) -} diff --git a/src/packages/ce/src/function/hooks/FunctionValueSuggestions.hook.tsx b/src/packages/ce/src/function/hooks/FunctionValueSuggestions.hook.tsx deleted file mode 100644 index 4229c317..00000000 --- a/src/packages/ce/src/function/hooks/FunctionValueSuggestions.hook.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { - FunctionSuggestion, - FunctionSuggestionType -} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; -import {useService, useStore} from "@code0-tech/pictor"; -import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -import React from "react"; -import {useValueSuggestionsAction} from "@edition/flow/components/FlowWorkerProvider"; - -export const useValueSuggestions = ( - type?: string -): FunctionSuggestion[] => { - - const dataTypeStore = useStore(DatatypeService) - const dataTypeService = useService(DatatypeService) - - const {execute} = useValueSuggestionsAction() - const [suggestions, setSuggestions] = React.useState([]) - - const dataTypes = React.useMemo(() => dataTypeService.values(), [dataTypeStore]); - - React.useEffect(() => { - if (!type) { - setSuggestions([]) - return; - } - - const timeout = setTimeout(() => { - execute({ - type, - dataTypes - }).then(value => { - setSuggestions(value as any[]) - }) - }, 200); - - return () => clearTimeout(timeout); - }, [type, dataTypes]) - - return React.useMemo(() => suggestions.map(suggestion => { - - return { - path: [], - type: FunctionSuggestionType.VALUE, - displayText: [suggestion.value as string], - value: suggestion, - } - }), [suggestions]); -} From e95d3f1fd273b1cab1232704ab3d6173fa7c2622 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 08:28:36 +0200 Subject: [PATCH 04/88] feat: update NEXT_PUBLIC_PICTOR_VERSION to 0.6.4 --- .env.local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.local b/.env.local index 72d9814f..8485a960 100644 --- a/.env.local +++ b/.env.local @@ -4,7 +4,7 @@ NEXT_PUBLIC_EDITION=ce SAGITTARIUS_GRAPHQL_URL=http://localhost:3010/graphql NEXT_PUBLIC_SCULPTOR_VERSION=0.0.0 -NEXT_PUBLIC_PICTOR_VERSION=0.6.0 +NEXT_PUBLIC_PICTOR_VERSION=0.6.4 NEXT_PUBLIC_ALLOWED_REDIRECT_DOMAINS=*.code0.tech,*.codezero.build NEXT_PUBLIC_OTEL_SERVICE_NAME=#"sculptor-client" From cadfd4a6cb8cc046eb4a2eb37f534d95b221c1aa Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:38:34 +0200 Subject: [PATCH 05/88] feat: made schema optional --- .../src/datatype/components/inputs/DataTypeInputComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 7541b70a..345a8d1a 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -14,7 +14,7 @@ export const DataTypeInputComponent: React.FC = (pr const {schema, ...rest} = props - switch (schema.schema.input) { + switch (schema?.schema?.input) { case "data": case "list": return Date: Wed, 29 Apr 2026 12:39:16 +0200 Subject: [PATCH 06/88] feat: schema generation for complete flow and parse into node --- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 8 +++++++- .../hooks/Flow.schema.hook.ts} | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) rename src/packages/ce/src/{function/hooks/Function.schema.hook.ts => flow/hooks/Flow.schema.hook.ts} (98%) diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index 61806b40..06ec6bfb 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -5,6 +5,7 @@ import {hashToColor, useService, useStore} from "@code0-tech/pictor"; import {FlowService} from "@edition/flow/services/Flow.service"; import {FunctionService} from "@edition/function/services/Function.service"; import {FunctionNodeComponentProps} from "@edition/function/components/nodes/FunctionNodeComponent"; +import {useFlowSchema} from "@edition/flow/hooks/Flow.schema.hook"; export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], projectId?: NamespaceProject["id"]): Node[] => { @@ -18,6 +19,8 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], [flowId, flowStore] ) + const flowSchema = useFlowSchema(flowId) + return React.useMemo(() => { if (!flow) return [] if (functionStore.length <= 0) return [] @@ -38,6 +41,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], flowId: flowId, nodeId: undefined, color: hashToColor(flowId!), + schema: flowSchema?.find(nodeSchema => !nodeSchema.nodeId)! }, }); @@ -65,6 +69,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], flowId: flowId, index: ++globalIndex, color: hashToColor(nodeId), + schema: flowSchema?.find(nodeSchema => nodeSchema?.nodeId == node.id)! }, }); } @@ -87,10 +92,11 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], extent: parentGroup ? "parent" : undefined, data: { isParameter: true, - parentNodeId: nodeId, + //parentNodeId: nodeId, nodeId: nodeId, flowId: flowId, color: hashToColor(value?.id ?? ""), + schema: flowSchema?.find(nodeSchema => nodeSchema?.nodeId == node.id)! }, }); } diff --git a/src/packages/ce/src/function/hooks/Function.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts similarity index 98% rename from src/packages/ce/src/function/hooks/Function.schema.hook.ts rename to src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index 2d17bd84..1c717473 100644 --- a/src/packages/ce/src/function/hooks/Function.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -9,7 +9,7 @@ import {NodeSchema} from "@code0-tech/triangulum"; export const useFlowSchema = ( flowId: Flow['id'] -) => { +): NodeSchema[] | undefined => { const flowService = useService(FlowService) const flowStore = useStore(FlowService) const dataTypeStore = useStore(DatatypeService) From 81bc39ea7a7df7243cc9c83f5b5c27c11774b8ac Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:39:59 +0200 Subject: [PATCH 07/88] feat: imports --- .../flow/components/builder/FlowBuilderComponent.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx index 7c62b4b5..a8b5700e 100644 --- a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx +++ b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx @@ -4,11 +4,9 @@ import { Edge, Node, ReactFlow, - ReactFlowProvider, useEdgesState, useNodesState, - useReactFlow, useStore, - useUpdateNodeInternals, + useReactFlow, useUpdateNodeInternals, ViewportPortal } from "@xyflow/react"; import React from "react"; @@ -19,7 +17,7 @@ import {Flow, type Namespace, type NamespaceProject} from "@code0-tech/sagittari import {LineWobble} from 'ldrs/react' import 'ldrs/react/LineWobble.css' import {useFlowNodes} from "@edition/flow/hooks/Flow.nodes.hook"; -import {ComponentProps, mergeComponentProps, Spacing, Text, useService} from "@code0-tech/pictor"; +import {ComponentProps, mergeComponentProps, Spacing, Text} from "@code0-tech/pictor"; import {FunctionNodeDefaultComponent} from "@edition/function/components/nodes/FunctionNodeDefaultComponent"; import {FunctionNodeGroupComponent} from "@edition/function/components/nodes/FunctionNodeGroupComponent"; import {FunctionNodeTriggerComponent} from "@edition/function/components/nodes/FunctionNodeTriggerComponent"; @@ -28,8 +26,6 @@ import {FlowPanelSizeComponent} from "@edition/flow/components/panels/FlowPanelS import {FlowPanelLayoutComponent} from "@edition/flow/components/panels/FlowPanelLayoutComponent"; import {FlowPanelControlComponent} from "@edition/flow/components/panels/FlowPanelControlComponent"; import {FlowPanelUpdateComponent} from "@edition/flow/components/panels/FlowPanelUpdateComponent"; -import {FileTabsService} from "@code0-tech/pictor/dist/components/file-tabs/FileTabs.service"; -import {FlowPanelExportComponent} from "@edition/flow/components/panels/FlowPanelExportComponent"; import {FunctionNodeSquareComponent} from "@edition/function/components/nodes/FunctionNodeSquareComponent"; /** @@ -616,7 +612,7 @@ export const FlowBuilderComponent: React.FC = (props) => { const InternalFlowBuilder: React.FC = (props) => { const {flowId, namespaceId, projectId, ...rest} = props - const { setCenter, getInternalNode, getZoom } = useReactFlow(); + const {setCenter, getInternalNode, getZoom} = useReactFlow(); const nodeTypes = React.useMemo(() => ({ default: FunctionNodeDefaultComponent, From 8868044ddce57738185952a9a326b95f3b234495 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:40:19 +0200 Subject: [PATCH 08/88] feat: reimplement function suggestions --- .../src/flow/components/panels/FlowPanelControlComponent.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx index 2af406b8..cedc9ac0 100644 --- a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx +++ b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx @@ -20,6 +20,7 @@ import {FunctionSuggestion} from "@edition/function/components/suggestion/Functi import {Suggestion} from "@edition/function/components/suggestion/Suggestion.util"; import {useHotkeys} from "react-hotkeys-hook"; import {useSelectedFunctionNode} from "@edition/function/hooks/FunctionNode.selected.hook"; +import {useFunctionSuggestions} from "@edition/function/hooks/Function.suggestion.hook"; export interface FlowPanelControlComponentProps { flowId: Flow['id'] @@ -40,7 +41,7 @@ export const FlowPanelControlComponent: React.FC //memoized values const selectedNode = useSelectedFunctionNode() - const result = useNodeSuggestions(null) + const result = useFunctionSuggestions() //callbacks const deleteActiveNode = React.useCallback(() => { @@ -54,7 +55,7 @@ export const FlowPanelControlComponent: React.FC const addNodeToFlow = React.useCallback((suggestion: FunctionSuggestion | Suggestion) => { if (flowId && suggestion.value.__typename === "NodeFunction" && selectedNode?.id.includes("NodeFunction")) { startTransition(async () => { - await flowService.addNextNodeById(flowId, selectedNode.id as NodeFunction['id'], suggestion.value as NodeFunction) + await flowService.addNextNodeById(flowId, selectedNode?.id as NodeFunction['id'], suggestion.value as NodeFunction) }) } else if (suggestion.value.__typename === "NodeFunction") { startTransition(async () => { From c78b6fd2322c8d2c1ed8d11fcd9f502d29989fb3 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:40:25 +0200 Subject: [PATCH 09/88] feat: reimplement function suggestions --- .../hooks/Function.suggestion.hook.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/packages/ce/src/function/hooks/Function.suggestion.hook.ts diff --git a/src/packages/ce/src/function/hooks/Function.suggestion.hook.ts b/src/packages/ce/src/function/hooks/Function.suggestion.hook.ts new file mode 100644 index 00000000..190b4553 --- /dev/null +++ b/src/packages/ce/src/function/hooks/Function.suggestion.hook.ts @@ -0,0 +1,68 @@ +import {useService, useStore} from "@code0-tech/pictor"; +import {FunctionService} from "@edition/function/services/Function.service"; +import {NodeFunction} from "@code0-tech/sagittarius-graphql-types"; +import React from "react"; +import {FunctionSuggestionType} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; +import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; + +export const useFunctionSuggestions = () => { + + const functionService = useService(FunctionService) + const functionStore = useStore(FunctionService) + + const functions = React.useMemo( + () => functionService.values(), + [functionStore, functionService] + ) + + const nodes: NodeFunction[] = React.useMemo( + () => functions.map(funktion => ({ + __typename: "NodeFunction", + id: "gid://sagittarius/NodeFunction/1", + functionDefinition: funktion, + parameters: { + __typename: "NodeParameterConnection", + nodes: (funktion.parameterDefinitions?.nodes || []).map(p => ({ + __typename: "NodeParameter", + parameterDefinition: { + __typename: "ParameterDefinition", + id: p?.id, + identifier: p?.identifier + }, + value: p?.defaultValue ? { + __typename: "LiteralValue", + value: p.defaultValue.value + } : null + })) + } + })), + [functions] + ) + + + return React.useMemo(() => nodes.sort((a, b) => { + const [rA, pA, fA] = a?.functionDefinition!!.identifier!!.split("::"); + const [rB, pB, fB] = b?.functionDefinition!!.identifier!!.split("::"); + + const runtimeCmp = rA.localeCompare(rB); + if (runtimeCmp !== 0) return runtimeCmp; + + const packageCmp = pA.localeCompare(pB); + if (packageCmp !== 0) return packageCmp; + + return fA.localeCompare(fB); + }).map(suggestion => { + + const functionDefinition = functionService.getById(suggestion.functionDefinition?.id) + return { + path: [], + type: FunctionSuggestionType.FUNCTION, + displayText: [functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME], + value: suggestion, + icon: functionDefinition?.displayIcon || "", + aliases: functionDefinition?.aliases?.map((a) => a.content).flatMap(a => a?.split(";") ?? ""), + description: functionDefinition?.descriptions?.[0]?.content || "", + } + }), [nodes]); + +} \ No newline at end of file From ec66c5a37fc8fbd325892b9f76f717c399a212c2 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:41:20 +0200 Subject: [PATCH 10/88] feat: removing hard coded input type, because it will be changed to a real parameter --- .../files/FunctionFileTriggerComponent.tsx | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 012f8257..450d2b1a 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -33,13 +33,8 @@ export const FunctionFileTriggerComponent: React.FC = React.useMemo(() => { - const values: Record = { - "inputType": flowInputType || flowTypeInputType - } + const values: Record = {} definition?.flowTypeSettings?.forEach((setting, index) => { const flowSetting = instance.settings?.nodes?.[index] values[setting.id!] = flowSetting?.value?.__typename === "LiteralValue" ? (flowSetting?.value.value) : (flowSetting?.value) @@ -116,19 +111,6 @@ export const FunctionFileTriggerComponent: React.FC Settings - - { - - (flowInputType && flowInputType != "void") && (flowTypeInputType && flowTypeInputType != "void") ? - validate()} - {...inputs.getInputProps("inputType")} - /> : null - - } {definition?.flowTypeSettings?.map((settingDefinition, index) => { From 72589011d51135f97b257df9eebed94b34fa75de Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:41:58 +0200 Subject: [PATCH 11/88] feat: adding node schema to react flow node props --- .../ce/src/function/components/nodes/FunctionNodeComponent.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts b/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts index b93c3390..fbdd9b14 100644 --- a/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts +++ b/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts @@ -1,9 +1,11 @@ import {Flow, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; import {Component} from "@code0-tech/pictor"; +import {NodeSchema} from "@code0-tech/triangulum"; export interface FunctionNodeComponentProps extends Record, Component { - nodeId: NodeFunction['id'] + nodeId?: NodeFunction['id'] flowId: Flow['id'] + schema: NodeSchema color: string parentNodeId?: NodeFunction['id'] isParameter?: boolean From 85d6a045afe87985eee278e7550044a1c05765ff Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 12:42:19 +0200 Subject: [PATCH 12/88] feat: adding schema to input --- .../function/components/files/FunctionFileDefaultComponent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 99991381..45f54800 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -148,6 +148,7 @@ export const FunctionFileDefaultComponent: React.FC { //TODO this should be debounced From 980ae82ec78423f4ebd0834fcd9bd28f9e6f30fc Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 13:39:23 +0200 Subject: [PATCH 13/88] feat: remove type --- .../components/inputs/DataTypeInputComponent.tsx | 2 +- .../panels/FlowPanelControlComponent.tsx | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 345a8d1a..2a6dee60 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -4,7 +4,7 @@ import {InputProps} from "@code0-tech/pictor"; import {DataTypeJSONInputComponent} from "@edition/datatype/components/inputs/json/DataTypeJSONInputComponent"; import {NodeSchema} from "@code0-tech/triangulum"; -export interface DataTypeInputComponentProps extends Omit, "wrapperComponent" | "type"> { +export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { schema: NodeSchema clearable?: boolean onClear?: (event: React.MouseEvent) => void diff --git a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx index cedc9ac0..b61286a0 100644 --- a/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx +++ b/src/packages/ce/src/flow/components/panels/FlowPanelControlComponent.tsx @@ -13,7 +13,6 @@ import { } from "@code0-tech/pictor"; import {Panel} from "@xyflow/react"; import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; -import {FunctionSuggestionMenuComponent} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent"; import {FlowService} from "@edition/flow/services/Flow.service"; import {SuggestionDialogComponent} from "@edition/function/components/suggestion/SuggestionDialogComponent"; import {FunctionSuggestion} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; @@ -107,7 +106,7 @@ export const FlowPanelControlComponent: React.FC }} color={"secondary"}> - Add next node (experimental) + Add next node Shift + A @@ -118,17 +117,6 @@ export const FlowPanelControlComponent: React.FC } - - Add next node - - }/> From a48c953f4c09eb6781bed3f19afc4067f798cf1f Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 13:39:54 +0200 Subject: [PATCH 14/88] feat: get suggestions from schema --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 0112c282..6072a826 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -93,11 +93,15 @@ export const splitTextAndObjects = (input: string) => { export const DataTypeTextInputComponent: React.FC = (props) => { - const {flowId, nodeId, parameterIndex, ...rest} = props + const {flowId, nodeId, parameterIndex, schema, ...rest} = props const functionService = useService(FunctionService) const flowService = useService(FlowService) + const suggestions = schema?.schema?.suggestions + + console.log(suggestions) + const transformSyntax = React.useCallback((value: string | null): InputSyntaxSegment[] => { const textValue = (value === null || value === undefined ? value : String(value ?? ""))! From d519c87c3dc3f381030e19e1eaf0c393081c61f7 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 13:40:27 +0200 Subject: [PATCH 15/88] feat: adding schema to dep --- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index 06ec6bfb..e55c7375 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -117,5 +117,5 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], } return nodes; - }, [flow, flowStore, functionStore]); + }, [flow, flowStore, functionStore, flowSchema]); }; \ No newline at end of file From 3c889bcb2622519669cc9f454a41aee5b563d3dc Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 13:41:03 +0200 Subject: [PATCH 16/88] feat: adding trigger schema --- src/packages/ce/src/flow/hooks/Flow.schema.hook.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index 1c717473..e88b3540 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -38,6 +38,12 @@ export const useFlowSchema = ( React.useEffect(() => { if (!flow) return + const triggerSchema = execute({ + flow, + dataTypes, + functions + }) + const schemas = flow.nodes?.nodes?.map(node => { return execute({ flow, @@ -47,9 +53,12 @@ export const useFlowSchema = ( }) }) - Promise.all(schemas!).then((value) => setSchema(value as NodeSchema[])) + Promise.all([triggerSchema!, ...schemas!]).then((value) => { + console.log(value) + setSchema(value as NodeSchema[]) + }) - }, [flow, dataTypes, functions]) + }, [flow, flowStore, dataTypes, functions]) return schema } From da295686437e5020002711b746142e7e7311678f Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 13:43:13 +0200 Subject: [PATCH 17/88] feat: getting node and schema --- .../components/files/FunctionFileTriggerComponent.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 450d2b1a..a6407dd4 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -12,6 +12,7 @@ import { FALLBACK_FLOW_TYPE_SETTING_DESCRIPTION, FALLBACK_FLOW_TYPE_SETTING_NAME } from "@core/util/fallback-translations"; +import {useNodes} from "@xyflow/react"; export interface FunctionFileTriggerComponentProps { instance: Flow @@ -42,6 +43,8 @@ export const FunctionFileTriggerComponent: React.FC value.id == instance.id) + const triggerValidation = React.useMemo( () => validation?.find(v => v.nodeId === null && v.parameterIndex === null), [validation] @@ -126,6 +129,7 @@ export const FunctionFileTriggerComponent: React.FC { From d6dd4690a2438b026bcc6e963e0bef7c074a214a Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 22:02:29 +0200 Subject: [PATCH 18/88] feat: update schema action to support array of NodeSchema --- src/packages/ce/src/flow/components/FlowWorkerProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx b/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx index 7db4d7fe..98414ba7 100644 --- a/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx +++ b/src/packages/ce/src/flow/components/FlowWorkerProvider.tsx @@ -182,4 +182,4 @@ export const useValueExtractionAction = () => useWorkerAction("value_extraction"); export const useSchemaAction = () => - useWorkerAction("schema"); \ No newline at end of file + useWorkerAction("schema"); \ No newline at end of file From 3ee23fca5c2497e791921c1a67440874fe434cf0 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 22:02:35 +0200 Subject: [PATCH 19/88] feat: update FunctionNodeComponent to support array of NodeSchema --- .../ce/src/function/components/nodes/FunctionNodeComponent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts b/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts index fbdd9b14..c1c1dd15 100644 --- a/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts +++ b/src/packages/ce/src/function/components/nodes/FunctionNodeComponent.ts @@ -5,7 +5,7 @@ import {NodeSchema} from "@code0-tech/triangulum"; export interface FunctionNodeComponentProps extends Record, Component { nodeId?: NodeFunction['id'] flowId: Flow['id'] - schema: NodeSchema + schema: NodeSchema[] color: string parentNodeId?: NodeFunction['id'] isParameter?: boolean From 03c786780b42caa413751e91a0ff21eabdfb0a2e Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 22:02:41 +0200 Subject: [PATCH 20/88] feat: update useFlowSchema to support namespace and project IDs --- .../ce/src/flow/hooks/Flow.schema.hook.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index e88b3540..8dc62af0 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -1,4 +1,4 @@ -import type {Flow} from "@code0-tech/sagittarius-graphql-types"; +import type {Flow, Namespace, NamespaceProject} from "@code0-tech/sagittarius-graphql-types"; import {useService, useStore} from "@code0-tech/pictor"; import {FlowService} from "@edition/flow/services/Flow.service"; import React from "react"; @@ -8,8 +8,10 @@ import {FunctionService} from "@edition/function/services/Function.service"; import {NodeSchema} from "@code0-tech/triangulum"; export const useFlowSchema = ( - flowId: Flow['id'] -): NodeSchema[] | undefined => { + flowId: Flow['id'], + namespaceId: Namespace['id'], + projectId: NamespaceProject['id'], +): NodeSchema[][] | undefined => { const flowService = useService(FlowService) const flowStore = useStore(FlowService) const dataTypeStore = useStore(DatatypeService) @@ -18,10 +20,10 @@ export const useFlowSchema = ( const functionStore = useStore(FunctionService) const {execute} = useSchemaAction() - const [schema, setSchema] = React.useState([]); + const [schema, setSchema] = React.useState([]); const flow = React.useMemo( - () => flowService.getById(flowId), + () => flowService.getById(flowId, {namespaceId, projectId}), [flowId, flowService, flowStore] ) @@ -54,11 +56,10 @@ export const useFlowSchema = ( }) Promise.all([triggerSchema!, ...schemas!]).then((value) => { - console.log(value) - setSchema(value as NodeSchema[]) + setSchema(value as NodeSchema[][]) }) - }, [flow, flowStore, dataTypes, functions]) + }, [functions, dataTypes, flow]) return schema } From 023198b04a35a22dab69e9e4161ed794e5e20de2 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 29 Apr 2026 22:02:49 +0200 Subject: [PATCH 21/88] feat: update DataTypeTextInputComponent and Flow.nodes.hook to enhance schema handling --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 2 +- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 5 +++-- .../components/files/FunctionFileTriggerComponent.tsx | 8 +++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 6072a826..6cb81e2c 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -167,7 +167,7 @@ export const DataTypeTextInputComponent: React.FC diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index e55c7375..5a1843fe 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -19,11 +19,12 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], [flowId, flowStore] ) - const flowSchema = useFlowSchema(flowId) + const flowSchema = useFlowSchema(flowId, namespaceId, projectId) return React.useMemo(() => { if (!flow) return [] if (functionStore.length <= 0) return [] + if ((flowSchema?.length ?? 0) <= 0) return [] const nodes: Node[] = []; const visited = new Set(); @@ -41,7 +42,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], flowId: flowId, nodeId: undefined, color: hashToColor(flowId!), - schema: flowSchema?.find(nodeSchema => !nodeSchema.nodeId)! + schema: flowSchema?.filter(nodeSchema => nodeSchema.some(schema => !schema.nodeId))?.flat()! }, }); diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index a6407dd4..580d8c1f 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -5,7 +5,6 @@ import {FlowTypeService} from "@edition/flowtype/services/FlowType.service"; import {FlowService} from "@edition/flow/services/Flow.service"; import {useFlowValidation} from "@edition/flow/hooks/Flow.validation.hook"; import {DataTypeInputComponent} from "@edition/datatype/components/inputs/DataTypeInputComponent"; -import {DataTypeTypeInputComponent} from "@edition/datatype/components/inputs/datatype/DataTypeTypeInputComponent"; import { FALLBACK_FLOW_TYPE_DESCRIPTION, FALLBACK_FLOW_TYPE_NAME, @@ -100,6 +99,8 @@ export const FunctionFileTriggerComponent: React.FC {definition?.names?.[0]?.content ?? FALLBACK_FLOW_TYPE_NAME} @@ -125,11 +126,8 @@ export const FunctionFileTriggerComponent: React.FC {/*@ts-ignore*/} { From 1885c846bde72b6b82c2203ac49a6b81f6662d22 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 13:25:05 +0200 Subject: [PATCH 22/88] feat: adding suggestions --- .../inputs/DataTypeInputComponent.tsx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 2a6dee60..3e7ef836 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -3,6 +3,13 @@ import {DataTypeTextInputComponent} from "./text/DataTypeTextInputComponent"; import {InputProps} from "@code0-tech/pictor"; import {DataTypeJSONInputComponent} from "@edition/datatype/components/inputs/json/DataTypeJSONInputComponent"; import {NodeSchema} from "@code0-tech/triangulum"; +import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; +import { + FunctionSuggestion, + FunctionSuggestionType +} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; +import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; +import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { schema: NodeSchema @@ -14,15 +21,29 @@ export const DataTypeInputComponent: React.FC = (pr const {schema, ...rest} = props + const suggestions = schema?.schema?.suggestions as (NodeFunction | ReferenceValue | LiteralValue)[] + const functionSuggestions: FunctionSuggestion[] = suggestions?.map((suggest: (NodeFunction | ReferenceValue | LiteralValue)) => { + + return { + type: suggest.__typename === "NodeFunction" ? FunctionSuggestionType.FUNCTION : suggest.__typename === "ReferenceValue" ? FunctionSuggestionType.REF_OBJECT : FunctionSuggestionType.VALUE, + value: suggest, + displayText: suggest.__typename === "NodeFunction" ? suggest.functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME : suggest?.value, + path: [] + } + + }) ?? [] + switch (schema?.schema?.input) { case "data": case "list": return default: return From 1b04138e239643845c7b042d17ce1dd690c22253 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 13:25:23 +0200 Subject: [PATCH 23/88] feat: removing old suggestion logic --- .../components/inputs/json/DataTypeJSONInputComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx index f21a5616..bcaba056 100644 --- a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx @@ -42,7 +42,7 @@ export const DataTypeJSONInputComponent: React.FC(null) const [collapsedState, setCollapsedStateRaw] = React.useState>({}) From 8df40aefc870381338398a5affecc704365eb061 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 13:25:36 +0200 Subject: [PATCH 24/88] feat: removing old suggestion logic --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 6cb81e2c..b1cd9c47 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -98,10 +98,6 @@ export const DataTypeTextInputComponent: React.FC { const textValue = (value === null || value === undefined ? value : String(value ?? ""))! @@ -167,7 +163,6 @@ export const DataTypeTextInputComponent: React.FC From e1a1894ee10e38c292da255f2fa78a014cefd8a7 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 13:26:38 +0200 Subject: [PATCH 25/88] feat: parsing in correct schema to node --- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index 5a1843fe..a12239c4 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -16,7 +16,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const flow = React.useMemo( () => flowService.getById(flowId, {namespaceId, projectId}), - [flowId, flowStore] + [flowId, flowStore, flowService] ) const flowSchema = useFlowSchema(flowId, namespaceId, projectId) @@ -24,7 +24,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], return React.useMemo(() => { if (!flow) return [] if (functionStore.length <= 0) return [] - if ((flowSchema?.length ?? 0) <= 0) return [] + if ((flowSchema?.some(s => !s))) return [] const nodes: Node[] = []; const visited = new Set(); @@ -42,7 +42,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], flowId: flowId, nodeId: undefined, color: hashToColor(flowId!), - schema: flowSchema?.filter(nodeSchema => nodeSchema.some(schema => !schema.nodeId))?.flat()! + schema: flowSchema?.filter(nodeSchema => nodeSchema?.some(schema => !schema.nodeId))?.flat()! }, }); @@ -70,7 +70,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], flowId: flowId, index: ++globalIndex, color: hashToColor(nodeId), - schema: flowSchema?.find(nodeSchema => nodeSchema?.nodeId == node.id)! + schema: flowSchema?.filter(nodeSchema => nodeSchema?.some(schema => schema.nodeId === node.id))?.flat()! }, }); } @@ -97,7 +97,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], nodeId: nodeId, flowId: flowId, color: hashToColor(value?.id ?? ""), - schema: flowSchema?.find(nodeSchema => nodeSchema?.nodeId == node.id)! + schema: [] }, }); } From ab6d173cf0b09d309c2f603dba90fe569b1527d8 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 13:27:50 +0200 Subject: [PATCH 26/88] feat: using flow node to get schema --- .../components/files/FunctionFileDefaultComponent.tsx | 8 ++++---- .../components/files/FunctionFileTriggerComponent.tsx | 2 -- .../function/components/files/FunctionFilesComponent.tsx | 2 ++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 45f54800..15321a8e 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -16,6 +16,7 @@ import { FALLBACK_FUNCTION_PARAMETER_DESCRIPTION, FALLBACK_FUNCTION_PARAMETER_NAME } from "@core/util/fallback-translations"; +import {useNodes} from "@xyflow/react"; export interface FunctionFileDefaultComponentProps { node: NodeFunction @@ -44,6 +45,8 @@ export const FunctionFileDefaultComponent: React.FC value.id == node.id) + const nodeValidation = React.useMemo( () => validation?.find(v => v.nodeId === node.id && v.parameterIndex === null), [validation] @@ -143,12 +146,9 @@ export const FunctionFileDefaultComponent: React.FC {/*@ts-ignore*/} { //TODO this should be debounced diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 580d8c1f..188bef2c 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -99,8 +99,6 @@ export const FunctionFileTriggerComponent: React.FC {definition?.names?.[0]?.content ?? FALLBACK_FLOW_TYPE_NAME} diff --git a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx index d9e0e76f..ccdb189c 100644 --- a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx @@ -174,6 +174,8 @@ export const FunctionFilesComponent: React.FC = (pr nodes?.map(node => { return From 1963c75c94e390b0a06628becbc54b48ef911737 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 14:36:06 +0200 Subject: [PATCH 27/88] feat: increase schema generation performance --- src/packages/ce/src/flow/hooks/Flow.schema.hook.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index 8dc62af0..342a2560 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -39,6 +39,8 @@ export const useFlowSchema = ( React.useEffect(() => { if (!flow) return + if (dataTypes.length <= 0) return + if (functions.length <= 0) return const triggerSchema = execute({ flow, @@ -61,5 +63,5 @@ export const useFlowSchema = ( }, [functions, dataTypes, flow]) - return schema + return React.useMemo(() => schema, []) } From d1478936d69ea4e754dba48e7820e4f7df78100b Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 14:48:27 +0200 Subject: [PATCH 28/88] feat: profile ux selectable improvement --- .../src/user/components/UserMenuComponent.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/packages/ce/src/user/components/UserMenuComponent.tsx b/src/packages/ce/src/user/components/UserMenuComponent.tsx index f88b67dc..0b4c1885 100644 --- a/src/packages/ce/src/user/components/UserMenuComponent.tsx +++ b/src/packages/ce/src/user/components/UserMenuComponent.tsx @@ -3,7 +3,7 @@ import React from "react" import {Scalars} from "@code0-tech/sagittarius-graphql-types"; import { - Avatar, + Avatar, Button, Flex, Menu, MenuContent, @@ -29,19 +29,21 @@ const UserMenuComponent: React.FC = props => { return ( - - - - - {currentUser?.username} - - - {currentUser?.email} - - + From 6a98810de2db2181175b949a86b522b9d325c1b0 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 30 Apr 2026 15:07:06 +0200 Subject: [PATCH 29/88] feat: performance --- src/packages/ce/src/flow/hooks/Flow.edges.hook.ts | 2 +- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 2 +- src/packages/ce/src/flow/hooks/Flow.schema.hook.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts index 74f6f31c..45a79abe 100644 --- a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts @@ -132,5 +132,5 @@ export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], proj } return edges - }, [flow, flowStore, functionStore]); + }, [functionStore?.lenght]); }; \ No newline at end of file diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index a12239c4..6136a4d7 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -118,5 +118,5 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], } return nodes; - }, [flow, flowStore, functionStore, flowSchema]); + }, [flow?.id, functionStore?.lenght, flowSchema?.length]); }; \ No newline at end of file diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index 342a2560..6b72ce2b 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -61,7 +61,7 @@ export const useFlowSchema = ( setSchema(value as NodeSchema[][]) }) - }, [functions, dataTypes, flow]) + }, [functions.length, dataTypes.length]) return React.useMemo(() => schema, []) } From e7e0c19b0b67876dc8e2665772ea7b7148b2e854 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 2 May 2026 00:28:48 +0200 Subject: [PATCH 30/88] feat: update dependency in edges hook for improved reactivity --- src/packages/ce/src/flow/hooks/Flow.edges.hook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts index 45a79abe..1e5106df 100644 --- a/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.edges.hook.ts @@ -132,5 +132,5 @@ export const useEdges = (flowId: Flow['id'], namespaceId?: Namespace['id'], proj } return edges - }, [functionStore?.lenght]); + }, [flow?.editedAt, functionStore.length]); }; \ No newline at end of file From 6a717cf2a6c725aadbf8d32df9869c62bb5ee82b Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 2 May 2026 00:28:52 +0200 Subject: [PATCH 31/88] feat: enhance flow node handling with state management and effect hooks --- .../ce/src/flow/hooks/Flow.nodes.hook.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index 6136a4d7..fda87207 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -1,6 +1,6 @@ import {Node} from "@xyflow/react"; import type {Flow, Namespace, NamespaceProject, NodeFunction} from "@code0-tech/sagittarius-graphql-types"; -import React from "react"; +import React, {useState} from "react"; import {hashToColor, useService, useStore} from "@code0-tech/pictor"; import {FlowService} from "@edition/flow/services/Flow.service"; import {FunctionService} from "@edition/function/services/Function.service"; @@ -14,26 +14,26 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const functionService = useService(FunctionService) const functionStore = useStore(FunctionService) + const [nodes, setNodes] = useState[]>([]) + const flow = React.useMemo( () => flowService.getById(flowId, {namespaceId, projectId}), - [flowId, flowStore, flowService] + [flowId, flowStore.length, flowService] ) const flowSchema = useFlowSchema(flowId, namespaceId, projectId) - return React.useMemo(() => { - if (!flow) return [] - if (functionStore.length <= 0) return [] - if ((flowSchema?.some(s => !s))) return [] + React.useEffect(() => { + if (!flow) return + if (functionStore.length <= 0) return - const nodes: Node[] = []; const visited = new Set(); let groupCounter = 0; let globalIndex = 0; // Trigger node (ID == flow.id -> edge compatible) - nodes.push({ + setNodes(prevState => [{ id: `${flow.id}`, type: "trigger", position: {x: 0, y: 0}, @@ -44,13 +44,13 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], color: hashToColor(flowId!), schema: flowSchema?.filter(nodeSchema => nodeSchema?.some(schema => !schema.nodeId))?.flat()! }, - }); + }]) const traverse = ( node: NodeFunction, parentGroup?: string ) => { - if (!node?.id) return; + if (!node?.id) return const functionDefinition = functionService.getById(node.functionDefinition?.id) const nodeId = node.id; @@ -58,7 +58,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], if (!visited.has(nodeId)) { visited.add(nodeId); - nodes.push({ + setNodes(prevState => [...prevState, { id: nodeId, type: functionDefinition && "design" in functionDefinition ? functionDefinition?.design as string : "default", position: {x: 0, y: 0}, @@ -72,7 +72,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], color: hashToColor(nodeId), schema: flowSchema?.filter(nodeSchema => nodeSchema?.some(schema => schema.nodeId === node.id))?.flat()! }, - }); + }]) } node.parameters?.nodes?.forEach((param) => { @@ -84,7 +84,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], if (!visited.has(groupId)) { visited.add(groupId); - nodes.push({ + setNodes(prevState => [...prevState, { id: groupId, type: "group", position: {x: 0, y: 0}, @@ -99,7 +99,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], color: hashToColor(value?.id ?? ""), schema: [] }, - }); + }]) } const child = flowService.getNodeById(flowId, value.id); @@ -116,7 +116,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const start = flowService.getNodeById(flow.id, flow.startingNodeId); if (start) traverse(start); } + }, [flowStore, functionStore.length, flowSchema?.length]); - return nodes; - }, [flow?.id, functionStore?.lenght, flowSchema?.length]); + return nodes }; \ No newline at end of file From fb16169742baa61390771a418e85b39c6906753d Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 2 May 2026 00:28:56 +0200 Subject: [PATCH 32/88] feat: update schema hook dependencies for improved reactivity --- src/packages/ce/src/flow/hooks/Flow.schema.hook.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index 6b72ce2b..a4a79556 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -61,7 +61,7 @@ export const useFlowSchema = ( setSchema(value as NodeSchema[][]) }) - }, [functions.length, dataTypes.length]) + }, [functions.length, dataTypes.length, flowStore]) - return React.useMemo(() => schema, []) + return schema } From 959b097dd7891ecca0e2e84282a3a15f63061425 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:53:51 +0200 Subject: [PATCH 33/88] feat: add boolean input component with suggestion and validation support --- .../boolean/DataTypeBooleanInputComponent.tsx | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx new file mode 100644 index 00000000..c6d07046 --- /dev/null +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -0,0 +1,78 @@ +import React from "react"; +import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; +import { + Button, + Card, + Flex, + InputDescription, + InputLabel, + InputMessage, + SegmentedControl, + SegmentedControlItem, + Text +} from "@code0-tech/pictor"; +import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; +import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; +import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; +import {FunctionSuggestionMenuComponent} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent"; +import {IconAlignLeft, IconX} from "@tabler/icons-react"; + +export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps + +export const DataTypeBooleanInputComponent: React.FC = (props) => { + + const {suggestions, value, title, description, formValidation, onChange} = props + + return <> + {title} + {description} + + + + + Boolean + + + { + formValidation?.setValue(suggestion) + onChange?.({} as any) + }} + triggerContent={}/> + + + + + {value?.__typename === "NodeFunction" || value?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : value?.__typename === "ReferenceValue" ? ( + + ) : ( + { + formValidation?.setValue(value === "true" ? "true" : (value == "false") ? "false" : undefined) + onChange?.({} as any) + }}> + + True + + + False + + + )} + + + {!formValidation?.valid && formValidation?.notValidMessage && ( + {formValidation.notValidMessage} + )} + + +} \ No newline at end of file From adf8eb1f47ef5deb3680e78c54e42d32b8fe8faf Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:53:55 +0200 Subject: [PATCH 34/88] feat: add boolean input component support in data type input --- .../components/inputs/DataTypeInputComponent.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 3e7ef836..900d855e 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -10,6 +10,7 @@ import { } from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; +import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent"; export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { schema: NodeSchema @@ -27,7 +28,7 @@ export const DataTypeInputComponent: React.FC = (pr return { type: suggest.__typename === "NodeFunction" ? FunctionSuggestionType.FUNCTION : suggest.__typename === "ReferenceValue" ? FunctionSuggestionType.REF_OBJECT : FunctionSuggestionType.VALUE, value: suggest, - displayText: suggest.__typename === "NodeFunction" ? suggest.functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME : suggest?.value, + displayText: suggest.__typename === "NodeFunction" ? suggest.functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME : suggest.__typename === "LiteralValue" ? suggest?.value : "", path: [] } @@ -41,6 +42,13 @@ export const DataTypeInputComponent: React.FC = (pr suggestions={toInputSuggestions(functionSuggestions)} {...rest} /> + case "boolean": + case "select": + return default: return Date: Sun, 3 May 2026 15:53:59 +0200 Subject: [PATCH 35/88] feat: refactor DataTypeJSONInputComponent to simplify state management and remove unused parameters --- .../json/DataTypeJSONInputComponent.tsx | 44 ++----------------- 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx index bcaba056..d99534e4 100644 --- a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx @@ -36,35 +36,18 @@ export type DataTypeJSONInputComponentProps = DataTypeInputComponentProps export const DataTypeJSONInputComponent: React.FC = (props) => { - const {flowId, nodeId, parameterIndex, title, description, formValidation, onChange} = props + const {schema, title, description, formValidation, onChange} = props const flowService = useService(FlowService) const flowStore = useStore(FlowService) - const initialNullValue = useValue(flowId, nodeId, parameterIndex) const suggestions = [] const [editDialogOpen, setEditDialogOpen] = React.useState(false) const [editEntry, setEditEntry] = React.useState(null) const [collapsedState, setCollapsedStateRaw] = React.useState>({}) - const node = React.useMemo( - () => flowService.getNodeById(flowId, nodeId), - [flowStore, flowId, nodeId] - ) - - const parameter = React.useMemo( - () => node?.parameters?.nodes?.[parameterIndex], - [node] - ) - const initialValue: NodeParameterValue | null = React.useMemo(() => { - if (!parameter?.value || (parameter?.value?.__typename === "LiteralValue" && parameter.value.value == null)) { - return initialNullValue - } - return parameter?.value - }, [initialNullValue, parameter]) - - const [value, setValue] = React.useState(initialValue) + const [value, setValue] = React.useState(null) const setCollapsedState = (path: string[], collapsed: boolean) => { setCollapsedStateRaw(prev => ({...prev, [path.join(".")]: collapsed})) @@ -75,23 +58,6 @@ export const DataTypeJSONInputComponent: React.FC { - if (!parameter?.value || (parameter?.value?.__typename === "LiteralValue" && parameter.value.value == null)) { - formValidation?.setValue(initialNullValue) - setValue(initialNullValue) - // @ts-ignore - onChange?.() - } - }, [initialNullValue]) - - const handleClear = React.useCallback(() => { - formValidation?.setValue(initialNullValue) - setValue(initialNullValue) - setEditEntry(null) - // @ts-ignore - onChange?.() - }, [initialNullValue]) - return ( <> {value?.__typename === "LiteralValue" && ( @@ -117,8 +83,7 @@ export const DataTypeJSONInputComponent: React.FC{"Object"} - { + { formValidation?.setValue(suggestion.value) setValue(suggestion.value) // @ts-ignore @@ -136,8 +101,7 @@ export const DataTypeJSONInputComponent: React.FC setEditDialogOpen(true)}> - From f68e474bc56e80dd0f9e63b48adbb57894a50160 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:04 +0200 Subject: [PATCH 36/88] feat: simplify DataTypeTextInputComponent by removing unused props --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index b1cd9c47..7ed0d5d2 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -8,7 +8,6 @@ import {FlowService} from "@edition/flow/services/Flow.service"; import { FunctionSuggestionMenuFooterComponent } from "@edition/function/components/suggestion/FunctionSuggestionMenuFooterComponent"; -import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps @@ -93,7 +92,7 @@ export const splitTextAndObjects = (input: string) => { export const DataTypeTextInputComponent: React.FC = (props) => { - const {flowId, nodeId, parameterIndex, schema, ...rest} = props + const {schema, ...rest} = props const functionService = useService(FunctionService) const flowService = useService(FlowService) From 10863fee9af8d71c0ae8ebd13079404a360b4c7e Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:08 +0200 Subject: [PATCH 37/88] feat: enhance flow node hook to improve reactivity and prevent unnecessary updates --- src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts index fda87207..4432092d 100644 --- a/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.nodes.hook.ts @@ -26,6 +26,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], React.useEffect(() => { if (!flow) return if (functionStore.length <= 0) return + if ((flowSchema?.length ?? 0) < (flow.nodes?.nodes?.length ?? 1)) return; const visited = new Set(); @@ -33,7 +34,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], let globalIndex = 0; // Trigger node (ID == flow.id -> edge compatible) - setNodes(prevState => [{ + setNodes(() => [{ id: `${flow.id}`, type: "trigger", position: {x: 0, y: 0}, @@ -116,7 +117,7 @@ export const useFlowNodes = (flowId: Flow["id"], namespaceId?: Namespace["id"], const start = flowService.getNodeById(flow.id, flow.startingNodeId); if (start) traverse(start); } - }, [flowStore, functionStore.length, flowSchema?.length]); + }, [flowStore, flow?.editedAt, functionStore.length, flowSchema]); return nodes }; \ No newline at end of file From 3375af07dbd356b0612f05f8708f69002156aeb3 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:11 +0200 Subject: [PATCH 38/88] feat: update flow node hook dependencies to include flow edit timestamp and node count --- src/packages/ce/src/flow/hooks/Flow.schema.hook.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts index a4a79556..fd84c45b 100644 --- a/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.schema.hook.ts @@ -61,7 +61,7 @@ export const useFlowSchema = ( setSchema(value as NodeSchema[][]) }) - }, [functions.length, dataTypes.length, flowStore]) + }, [functions.length, dataTypes.length, flowStore, flow?.editedAt, flow?.nodes?.nodes?.length]) return schema } From 18bce4e3ce429d0f74bc311c3aad2bc1988531c6 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:15 +0200 Subject: [PATCH 39/88] feat: update schema type in DataTypeInputComponent for improved type safety --- .../components/files/FunctionFileDefaultComponent.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 15321a8e..123f2af8 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -17,6 +17,7 @@ import { FALLBACK_FUNCTION_PARAMETER_NAME } from "@core/util/fallback-translations"; import {useNodes} from "@xyflow/react"; +import {NodeSchema} from "@code0-tech/triangulum"; export interface FunctionFileDefaultComponentProps { node: NodeFunction @@ -72,11 +73,11 @@ export const FunctionFileDefaultComponent: React.FC p?.id === parameterDefinition?.id) if (typeof parameterIndex !== "number") return if (!changedParameters.current.has(parameterIndex)) continue; - const nodeParameter = node.parameters?.nodes?.[parameterIndex] const value = values[parameterDefinition!.id!] - const previousValue = nodeParameter?.value as NodeParameterValue const syntaxValue = (value?.[0]?.type == "block" || value?.[0]?.type == "text" ? value?.[0]?.value : value) ?? null as NodeFunction | LiteralValue | ReferenceValue | null + console.log(syntaxValue) + if (!syntaxValue || !value || (Array.isArray(syntaxValue) && Array.from(syntaxValue).length <= 0)) { await flowService.setParameterValue(flowId, node.id!!, parameterIndex, undefined, definition); continue; @@ -147,7 +148,7 @@ export const FunctionFileDefaultComponent: React.FC { From 1a59fcc7aa251bcd668a2e51c5bab2c5c692b2b4 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:19 +0200 Subject: [PATCH 40/88] feat: enhance type safety in FunctionFileTriggerComponent by refining schema type --- .../function/components/files/FunctionFileTriggerComponent.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 188bef2c..64472d44 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -12,6 +12,7 @@ import { FALLBACK_FLOW_TYPE_SETTING_NAME } from "@core/util/fallback-translations"; import {useNodes} from "@xyflow/react"; +import {NodeSchema} from "@code0-tech/triangulum"; export interface FunctionFileTriggerComponentProps { instance: Flow @@ -125,7 +126,7 @@ export const FunctionFileTriggerComponent: React.FC { From 0dec4789e4ee891c76972b956b3435d21dda554f Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:23 +0200 Subject: [PATCH 41/88] feat: refine suggestions type in FunctionSuggestionMenuComponent for improved consistency --- .../FunctionSuggestionMenuComponent.tsx | 39 +++---------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/src/packages/ce/src/function/components/suggestion/FunctionSuggestionMenuComponent.tsx b/src/packages/ce/src/function/components/suggestion/FunctionSuggestionMenuComponent.tsx index cc9bf704..6bfce813 100644 --- a/src/packages/ce/src/function/components/suggestion/FunctionSuggestionMenuComponent.tsx +++ b/src/packages/ce/src/function/components/suggestion/FunctionSuggestionMenuComponent.tsx @@ -3,7 +3,7 @@ import {FunctionSuggestion} from "./FunctionSuggestionComponent.view"; import {toInputSuggestions} from "./FunctionSuggestionMenuComponent.util"; import {FunctionSuggestionSearchBarComponent} from "./FunctionSuggestionSearchBarComponent"; import { - Card, + Card, InputSuggestion, InputSuggestionMenuContent, InputSuggestionMenuContentItems, InputSuggestionMenuContentItemsHandle, @@ -14,7 +14,7 @@ import { export interface FunctionSuggestionMenuComponentProps { triggerContent: React.ReactNode - suggestions?: FunctionSuggestion[] + suggestions?: InputSuggestion[] onSuggestionSelect?: (suggestion: FunctionSuggestion) => void } @@ -22,46 +22,17 @@ export const FunctionSuggestionMenuComponent: React.FC null} = props - const menuRef = React.useRef(null); // Ref to suggestion list - const [stateSuggestions, setStateSuggestions] = React.useState(suggestions) - - React.useEffect(() => { - setStateSuggestions(suggestions) - }, [suggestions]) - return {triggerContent} - - { - - if (event.key === "ArrowDown") { - event.preventDefault(); - menuRef.current?.focusFirstItem(); // Navigate down - } else if (event.key === "ArrowUp") { - event.preventDefault(); - menuRef.current?.focusLastItem(); // Navigate up - } - - // @ts-ignore - const searchTerm = event.target.value - setStateSuggestions(suggestions.filter(suggestion => { - return suggestion.displayText.some(text => { - return text.includes(searchTerm) - }) - })) - event.preventDefault() - return false - }}/> + { - onSuggestionSelect(suggestion.valueData as FunctionSuggestion) + onSuggestionSelect(suggestion.value) }} /> From e02260d248331b039ac0c66f2a9e2613760a1022 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sun, 3 May 2026 15:54:29 +0200 Subject: [PATCH 42/88] feat: update @code0-tech/triangulum dependency to version 0.14.2 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62ae25f7..c7c45f8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.1", + "@code0-tech/triangulum": "^0.14.2", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", @@ -376,9 +376,9 @@ "peer": true }, "node_modules/@code0-tech/triangulum": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.1.tgz", - "integrity": "sha512-oObwhooeANzQccxccPLchm6Ku7jEAXhcCmf36QZgtYPTqo4B+j9Z2waUmDaWRcMgG+yHHoIe+NcocslF64B0sg==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.2.tgz", + "integrity": "sha512-p9Hs3I1LQwT+DJz0cTj12lkhXm1hOSqQT6w1sbPQQVn3VTcttIBq/lmIAXG9rnAJMA8yBDkCXSSa5H8FO8gshw==", "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2462825049-b5d5dce99ef9bf2f81df41d896ec36fa5e28559c", "@typescript/vfs": "^1.6.4", diff --git a/package.json b/package.json index ece4727d..7a3b0675 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "@apollo/client": "^4.0.9", "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.1", + "@code0-tech/triangulum": "^0.14.2", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", From 399127ab3749d7aece1b13def20ae12a4d6052f0 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Mon, 4 May 2026 23:46:33 +0200 Subject: [PATCH 43/88] feat: implement DataTypeSelectInputComponent and integrate into DataTypeInputComponent --- src/app/global.scss | 4 + .../inputs/DataTypeInputComponent.tsx | 7 +- .../boolean/DataTypeBooleanInputComponent.tsx | 85 +++---- .../select/DataTypeSelectInputComponent.tsx | 77 +++++++ .../text/DataTypeTextInputComponent.tsx | 211 +++++------------- .../files/FunctionFileDefaultComponent.tsx | 87 +++----- .../files/FunctionFilesComponent.tsx | 2 - 7 files changed, 209 insertions(+), 264 deletions(-) create mode 100644 src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx diff --git a/src/app/global.scss b/src/app/global.scss index 97d13f8e..e982382d 100644 --- a/src/app/global.scss +++ b/src/app/global.scss @@ -18,4 +18,8 @@ a { &:hover { text-decoration: underline; } +} + +.scroll-area__viewport > div { + display: block !important; } \ No newline at end of file diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 900d855e..3fe8b282 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -11,6 +11,7 @@ import { import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent"; +import {DataTypeSelectInputComponent} from "@edition/datatype/components/inputs/select/DataTypeSelectInputComponent"; export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { schema: NodeSchema @@ -43,12 +44,16 @@ export const DataTypeInputComponent: React.FC = (pr {...rest} /> case "boolean": - case "select": return + case "select": + return default: return = (props) => { - const {suggestions, value, title, description, formValidation, onChange} = props + const {suggestions, initialValue, title, description, formValidation, onChange} = props return <> {title} {description} - - - - - Boolean - - - { - formValidation?.setValue(suggestion) - onChange?.({} as any) - }} - triggerContent={}/> - + - - - {value?.__typename === "NodeFunction" || value?.__typename === "NodeFunctionIdWrapper" ? ( - - ) : value?.__typename === "ReferenceValue" ? ( - - ) : ( - { - formValidation?.setValue(value === "true" ? "true" : (value == "false") ? "false" : undefined) - onChange?.({} as any) - }}> + ) : ( + + ) + } rightType={"action"}> + {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : initialValue?.__typename === "ReferenceValue" ? ( + + ) : ( +
+ { + formValidation?.setValue(value === "true" ? "true" : (value == "false") ? "false" : undefined) + onChange?.({} as any) + }}> True @@ -67,12 +53,9 @@ export const DataTypeBooleanInputComponent: React.FC - )} - - - {!formValidation?.valid && formValidation?.notValidMessage && ( - {formValidation.notValidMessage} - )} +
+ )} + } \ No newline at end of file diff --git a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx new file mode 100644 index 00000000..59b26b81 --- /dev/null +++ b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx @@ -0,0 +1,77 @@ +import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; +import React from "react"; +import {useDebounce} from "use-debounce"; +import { + Button, + Flex, + InputDescription, + InputLabel, + SelectContent, + SelectInput, + SelectItem, + SelectItemText, + SelectPortal, + SelectTrigger, + SelectValue, + SelectViewport +} from "@code0-tech/pictor"; +import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; +import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; +import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; +import {IconChevronDown, IconVariable, IconX} from "@tabler/icons-react"; + + +export type DataTypeSelectInputComponentProps = DataTypeInputComponentProps + +export const DataTypeSelectInputComponent: React.FC = (props) => { + + const {formValidation, title, initialValue, description, suggestions, onChange} = props + + const defaultValue = React.useMemo(() => initialValue, []) + const [value, setValue] = useDebounce(defaultValue, 200) + + React.useEffect(() => { + onChange?.({} as any) + }, [value]) + + return React.useMemo(() => <> + {title} + {description} + {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : initialValue?.__typename === "ReferenceValue" ? ( + + ) : ( + { + formValidation?.setValue(value); + setValue(value ?? "") + }} placeholder={"sd"} right={ + + } rightType={"action"}> + + + + + + + + + + {suggestions?.filter((suggest) => suggest?.value.__typename === "LiteralValue").map((suggest) => { + return + + + {suggest?.children} + + + + })} + + + + + )} + , [formValidation]) +} \ No newline at end of file diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 7ed0d5d2..bfa15e10 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -1,168 +1,61 @@ import React from "react"; -import {NodeBadgeComponent} from "../../badges/NodeBadgeComponent"; -import {ReferenceBadgeComponent} from "../../badges/ReferenceBadgeComponent"; import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; -import {InputSyntaxSegment, MenuItem, Text, TextInput, useService} from "@code0-tech/pictor"; -import {FunctionService} from "@edition/function/services/Function.service"; -import {FlowService} from "@edition/flow/services/Flow.service"; -import { - FunctionSuggestionMenuFooterComponent -} from "@edition/function/components/suggestion/FunctionSuggestionMenuFooterComponent"; +import {Button, EditorInput, hashToColor, InputDescription, InputLabel} from "@code0-tech/pictor"; +import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; +import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; +import {StreamLanguage} from "@codemirror/language"; +import {tags} from "@lezer/highlight"; +import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; +import {IconVariable, IconX} from "@tabler/icons-react"; +import {useDebounce} from "use-debounce"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps -export const splitTextAndObjects = (input: string) => { - const result: (string | Record)[] = [] - - let currentText = "" - let currentObject = "" - let braceLevel = 0 - let inString: '"' | "'" | "" = "" - let escaped = false - - const pushText = () => { - if (currentText) result.push(currentText) - currentText = "" - } - - const parseObject = (value: string) => { - try { - return JSON.parse(value) - } catch { - try { - return JSON.parse( - value - .replace(/'/g, `"`) - .replace(/([{,]\s*)([A-Za-z_$][\w$]*)(\s*:)/g, `$1"$2"$3`) - ) - } catch { - return {} - } - } - } - - input.split("").forEach(char => { - if (braceLevel > 0) { - currentObject += char - - if (escaped) { - escaped = false - return - } - - if (char === "\\") { - escaped = true - return - } - - if (inString) { - if (char === inString) inString = "" - return - } - - if (char === `"` || char === `'`) { - inString = char as any - return - } - - if (char === "{") braceLevel++ - if (char === "}") braceLevel-- - - if (braceLevel === 0) { - result.push(parseObject(currentObject)) - currentObject = "" - } - - return - } - - if (char === "{") { - pushText() - braceLevel = 1 - currentObject = "{" - return - } - - currentText += char - }) - - pushText() - return result -} - export const DataTypeTextInputComponent: React.FC = (props) => { - const {schema, ...rest} = props - - const functionService = useService(FunctionService) - const flowService = useService(FlowService) - - const transformSyntax = React.useCallback((value: string | null): InputSyntaxSegment[] => { - - const textValue = (value === null || value === undefined ? value : String(value ?? ""))! - let cursor = 0 - - const buildTextSegment = (text: string): InputSyntaxSegment => { - const segment = { - type: "text", - value: text, - start: cursor, - end: cursor + text.length, - visualLength: text.length, - content: text, - } as InputSyntaxSegment - cursor += text.length - return segment - } - - const buildBlockSegment = (node: React.ReactNode, value: Record): InputSyntaxSegment => { - const segment = { - type: "block", - value: value, - start: cursor, - end: cursor + JSON.stringify(value).length, - visualLength: 1, - content: node, - } as InputSyntaxSegment - cursor += JSON.stringify(value).length - return segment - } - - return splitTextAndObjects(textValue).map(value => { - - if (typeof value !== "object") { - return buildTextSegment(value) - } - - if (value?.__typename === "NodeFunctionIdWrapper" || value?.__typename === "NodeFunction") { - return buildBlockSegment( - , - value - ) - } - - if (value?.__typename === "ReferenceValue") { - return buildBlockSegment( - , - value + const {formValidation, title, initialValue, description, suggestions, onChange} = props + + const defaultValue = React.useMemo(() => initialValue, []) + const [value, setValue] = useDebounce(defaultValue, 200) + + React.useEffect(() => { + onChange?.({} as any) + }, [value]) + + return React.useMemo(() => <> + {title} + {description} + {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : initialValue?.__typename === "ReferenceValue" ? ( + + ) : ( + { + formValidation?.setValue(value); + setValue(value ?? "") + }} placeholder={"sd"} language={StreamLanguage.define({ + token(stream) { + stream.next() + return null; + } + })} tokenStyles={[ + {tag: tags.keyword, color: hashToColor("bracket")}, + ]} right={ + (suggestions?.length ?? 0) > 0 ? ( + + + + + ) : ( + ) - } - - if (value?.__typename === "LiteralValue") { - return buildTextSegment(value.value) - } - - return buildTextSegment(value as any as string) - }) - }, [functionService, flowService]) - - return No suggestion found} - suggestionsFooter={} - filterSuggestionsByLastToken - enforceUniqueSuggestions - validationUsesSyntax - transformSyntax={transformSyntax} - {...rest} - - /> + } rightType={"action"}/> + )} + , [formValidation]) } diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 123f2af8..4eb70f5a 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -1,12 +1,6 @@ -import React, {startTransition} from "react"; +import React from "react"; import {Alert, InputSyntaxSegment, Spacing, Text, useForm, useService} from "@code0-tech/pictor"; -import { - Flow, - LiteralValue, - NodeFunction, - NodeParameterValue, - ReferenceValue -} from "@code0-tech/sagittarius-graphql-types"; +import {Flow, LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; import {useFlowValidation} from "@edition/flow/hooks/Flow.validation.hook"; import {FlowService} from "@edition/flow/services/Flow.service"; import {DataTypeInputComponent} from "@edition/datatype/components/inputs/DataTypeInputComponent"; @@ -68,47 +62,43 @@ export const FunctionFileDefaultComponent: React.FC { - startTransition(async () => { - for (const parameterDefinition of definition?.parameterDefinitions?.nodes!) { - const parameterIndex = definition?.parameterDefinitions?.nodes?.findIndex(p => p?.id === parameterDefinition?.id) - if (typeof parameterIndex !== "number") return - if (!changedParameters.current.has(parameterIndex)) continue; - const value = values[parameterDefinition!.id!] - const syntaxValue = (value?.[0]?.type == "block" || value?.[0]?.type == "text" ? value?.[0]?.value : value) ?? null as NodeFunction | LiteralValue | ReferenceValue | null - - console.log(syntaxValue) - - if (!syntaxValue || !value || (Array.isArray(syntaxValue) && Array.from(syntaxValue).length <= 0)) { - await flowService.setParameterValue(flowId, node.id!!, parameterIndex, undefined, definition); + for (const parameterDefinition of definition?.parameterDefinitions?.nodes ?? []) { + const parameterIndex = definition?.parameterDefinitions?.nodes?.findIndex(p => p?.id === parameterDefinition?.id) + if (typeof parameterIndex !== "number") return + //if (!changedParameters.current.has(parameterIndex)) continue; + const value = values[parameterDefinition!.id!] + const syntaxValue = (value?.[0]?.type == "block" || value?.[0]?.type == "text" ? value?.[0]?.value : value) ?? null as NodeFunction | LiteralValue | ReferenceValue | null + + if (!syntaxValue || !value || (Array.isArray(syntaxValue) && Array.from(syntaxValue).length <= 0)) { + flowService.setParameterValue(flowId, node.id!!, parameterIndex, undefined, definition); + continue; + } + + try { + const parsedSyntaxValue = JSON.parse(syntaxValue) + if (!parsedSyntaxValue?.__typename) { + flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { + __typename: "LiteralValue", + value: parsedSyntaxValue + } : undefined, definition); continue; } - - try { - const parsedSyntaxValue = JSON.parse(syntaxValue) - if (!parsedSyntaxValue?.__typename) { - await flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { - __typename: "LiteralValue", - value: parsedSyntaxValue - } : undefined, definition); - continue; - } - } catch (e) { - if (!syntaxValue?.__typename) { - await flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { - __typename: "LiteralValue", - value: syntaxValue, - } : undefined, definition); - continue; - } + } catch (e) { + if (!syntaxValue?.__typename) { + flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { + __typename: "LiteralValue", + value: syntaxValue, + } : undefined, definition); + continue; } + } - const parsedSyntaxValue = typeof syntaxValue === "object" ? syntaxValue : JSON.parse(syntaxValue) + const parsedSyntaxValue = typeof syntaxValue === "object" ? syntaxValue : JSON.parse(syntaxValue) - await flowService.setParameterValue(flowId, node.id!!, parameterIndex, parsedSyntaxValue.__typename === "LiteralValue" ? (!!parsedSyntaxValue.value ? parsedSyntaxValue : undefined) : parsedSyntaxValue, definition); - } - changedParameters.current.clear() - }) - }, [flowService]) + flowService.setParameterValue(flowId, node.id!!, parameterIndex, parsedSyntaxValue.__typename === "LiteralValue" ? (!!parsedSyntaxValue.value ? parsedSyntaxValue : undefined) : parsedSyntaxValue, definition); + } + changedParameters.current.clear() + }, [flowService, definition]) const [inputs, validate] = useForm>({ useInitialValidation: true, @@ -120,7 +110,7 @@ export const FunctionFileDefaultComponent: React.FC { validate() - }, [validation]) + }, [validation?.length]) return <> {definition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME} @@ -145,17 +135,12 @@ export const FunctionFileDefaultComponent: React.FC - {/*@ts-ignore*/} { - //TODO this should be debounced - changedParameters.current.add(index) - validate() - }} + onChange={() => validate()} {...inputs.getInputProps(parameterDefinition.id!)} /> diff --git a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx index ccdb189c..d9e0e76f 100644 --- a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx @@ -174,8 +174,6 @@ export const FunctionFilesComponent: React.FC = (pr nodes?.map(node => { return From 1921400db7c6b2d251e2749f239bb8fd9a2d26de Mon Sep 17 00:00:00 2001 From: nicosammito Date: Mon, 4 May 2026 23:46:38 +0200 Subject: [PATCH 44/88] feat: update @code0-tech/pictor to version 0.7.1 and @code0-tech/triangulum to version 0.14.3 --- package-lock.json | 61 ++++++++++++++++++++++++++++++++++++++++------- package.json | 4 ++-- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7c45f8c..e7a809a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "0.0.0", "dependencies": { "@apollo/client": "^4.0.9", - "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.2", + "@code0-tech/pictor": "^0.7.1", + "@code0-tech/triangulum": "^0.14.3", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", @@ -333,9 +333,9 @@ } }, "node_modules/@code0-tech/pictor": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@code0-tech/pictor/-/pictor-0.6.4.tgz", - "integrity": "sha512-WYEjlRGQeVFmU3PqYjsbMwAMXi2VHkjx/LOdzOJSAVaUA2y+OZw0h9Rra+V3nH84NPy+ROqaA5MmYvc7dNz/LQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@code0-tech/pictor/-/pictor-0.7.1.tgz", + "integrity": "sha512-+ikLjqVZjAdFjHnkH8KV38KLHJpVzWLQqQiBJkSCcTscd/Zt8KenS0bAabV/HPO9Vd1XV2ATJOpRuHghVVFHTg==", "peerDependencies": { "@codemirror/autocomplete": "^6.20.0", "@codemirror/lang-json": "^6.0.2", @@ -351,6 +351,7 @@ "@radix-ui/react-one-time-password-field": "^0.1.8", "@radix-ui/react-radio-group": "^1.3.8", "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-toggle-group": "^1.1.11", "@radix-ui/react-tooltip": "^1.2.8", @@ -376,9 +377,9 @@ "peer": true }, "node_modules/@code0-tech/triangulum": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.2.tgz", - "integrity": "sha512-p9Hs3I1LQwT+DJz0cTj12lkhXm1hOSqQT6w1sbPQQVn3VTcttIBq/lmIAXG9rnAJMA8yBDkCXSSa5H8FO8gshw==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/@code0-tech/triangulum/-/triangulum-0.14.3.tgz", + "integrity": "sha512-BpYH2qHv9s8vQHQvC0P2SAlRXit4e5Krf1ICGwlFxL8nEw+ul9iO6bCqC5pEpS18Az/PI2Bvmw4Xufj4EhEsig==", "peerDependencies": { "@code0-tech/sagittarius-graphql-types": "0.0.0-experimental-2462825049-b5d5dce99ef9bf2f81df41d896ec36fa5e28559c", "@typescript/vfs": "^1.6.4", @@ -2853,6 +2854,50 @@ } } }, + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", diff --git a/package.json b/package.json index 7a3b0675..3a25a1b8 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ }, "dependencies": { "@apollo/client": "^4.0.9", - "@code0-tech/pictor": "^0.6.4", - "@code0-tech/triangulum": "^0.14.2", + "@code0-tech/pictor": "^0.7.1", + "@code0-tech/triangulum": "^0.14.3", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", "@opentelemetry/api": "^1.9.1", From 16e30fa67fa194b15e84e8e6bd2308b5aa188f46 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 01:24:11 +0200 Subject: [PATCH 45/88] feat: add debounced change handler and default value logic in DataTypeBooleanInputComponent --- .../boolean/DataTypeBooleanInputComponent.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 21b0d676..99d8eb84 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -6,6 +6,7 @@ import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/Refer import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; import {IconVariable, IconX} from "@tabler/icons-react"; import {InputWrapper} from "@code0-tech/pictor/dist/components/form/InputWrapper"; +import {useDebouncedCallback} from "use-debounce"; export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps @@ -13,7 +14,14 @@ export const DataTypeBooleanInputComponent: React.FC + const defaultValue = React.useMemo(() => typeof initialValue === "boolean" ? (initialValue ? "true" : "false") : undefined , []) + const onChangeDebounced = useDebouncedCallback(() => { + onChange?.({} as any) + }, 200) + + console.log("booldefault", defaultValue) + + return React.useMemo(() => <> {title} {description} { - formValidation?.setValue(value === "true" ? "true" : (value == "false") ? "false" : undefined) - onChange?.({} as any) + formValidation?.setValue(value) + onChangeDebounced() }}> True @@ -56,6 +65,6 @@ export const DataTypeBooleanInputComponent: React.FC )} - + , [formValidation]) } \ No newline at end of file From 84685240545bc1daf3e33e4528eddadecf56f382 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 01:24:15 +0200 Subject: [PATCH 46/88] feat: enhance DataTypeSelectInputComponent with debounced onChange handler --- .../select/DataTypeSelectInputComponent.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx index 59b26b81..72452e7f 100644 --- a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx @@ -1,6 +1,6 @@ import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; import React from "react"; -import {useDebounce} from "use-debounce"; +import {useDebounce, useDebouncedCallback} from "use-debounce"; import { Button, Flex, @@ -17,8 +17,7 @@ import { } from "@code0-tech/pictor"; import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; -import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; -import {IconChevronDown, IconVariable, IconX} from "@tabler/icons-react"; +import {IconChevronDown, IconX} from "@tabler/icons-react"; export type DataTypeSelectInputComponentProps = DataTypeInputComponentProps @@ -28,11 +27,9 @@ export const DataTypeSelectInputComponent: React.FC initialValue, []) - const [value, setValue] = useDebounce(defaultValue, 200) - - React.useEffect(() => { + const onChangeDebounced = useDebouncedCallback(() => { onChange?.({} as any) - }, [value]) + }, 200) return React.useMemo(() => <> {title} @@ -42,10 +39,7 @@ export const DataTypeSelectInputComponent: React.FC ) : ( - { - formValidation?.setValue(value); - setValue(value ?? "") - }} placeholder={"sd"} right={ + From 0109cab5f22fe114bd2287d782d394ed9303b372 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 01:24:19 +0200 Subject: [PATCH 47/88] feat: implement debounced change handler in DataTypeTextInputComponent --- .../inputs/text/DataTypeTextInputComponent.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index bfa15e10..aebc50ad 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -7,7 +7,7 @@ import {StreamLanguage} from "@codemirror/language"; import {tags} from "@lezer/highlight"; import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; import {IconVariable, IconX} from "@tabler/icons-react"; -import {useDebounce} from "use-debounce"; +import {useDebounce, useDebouncedCallback} from "use-debounce"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps @@ -15,12 +15,10 @@ export const DataTypeTextInputComponent: React.FC initialValue, []) - const [value, setValue] = useDebounce(defaultValue, 200) - - React.useEffect(() => { + const defaultValue = React.useMemo(() => initialValue ?? "", []) + const onChangeDebounced = useDebouncedCallback(() => { onChange?.({} as any) - }, [value]) + }, 200) return React.useMemo(() => <> {title} @@ -30,10 +28,7 @@ export const DataTypeTextInputComponent: React.FC ) : ( - { - formValidation?.setValue(value); - setValue(value ?? "") - }} placeholder={"sd"} language={StreamLanguage.define({ + Date: Tue, 5 May 2026 01:25:26 +0200 Subject: [PATCH 48/88] feat: update DataTypeInputComponent to use InputWrapperProps and add suggestions prop --- .../datatype/components/inputs/DataTypeInputComponent.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 3fe8b282..0bcd6e12 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -1,6 +1,5 @@ import React from "react"; import {DataTypeTextInputComponent} from "./text/DataTypeTextInputComponent"; -import {InputProps} from "@code0-tech/pictor"; import {DataTypeJSONInputComponent} from "@edition/datatype/components/inputs/json/DataTypeJSONInputComponent"; import {NodeSchema} from "@code0-tech/triangulum"; import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; @@ -12,10 +11,12 @@ import {toInputSuggestions} from "@edition/function/components/suggestion/Functi import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent"; import {DataTypeSelectInputComponent} from "@edition/datatype/components/inputs/select/DataTypeSelectInputComponent"; +import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWrapper"; -export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { +export interface DataTypeInputComponentProps extends Omit { schema: NodeSchema clearable?: boolean + suggestions?: any[] onClear?: (event: React.MouseEvent) => void } From 8af407df64e7691c74a5232c020c750ce2107266 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 01:28:20 +0200 Subject: [PATCH 49/88] feat: simplify ButtonGroup in DataTypeBooleanInputComponent by removing redundant color prop --- .../inputs/boolean/DataTypeBooleanInputComponent.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 99d8eb84..664d16f4 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -26,11 +26,11 @@ export const DataTypeBooleanInputComponent: React.FC{description} 0 ? ( - - - From c5e8f1c3db54347ebdb8cf836311e5b851d3e5cf Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 01:28:24 +0200 Subject: [PATCH 50/88] feat: update ButtonGroup in DataTypeTextInputComponent to remove redundant color prop --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index aebc50ad..b5a3f641 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -37,11 +37,11 @@ export const DataTypeTextInputComponent: React.FC 0 ? ( - - - From 0c296ad90f6a904ab843bcb123219cdb02de692f Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 13:06:23 +0200 Subject: [PATCH 51/88] feat: optimize FlowBuilderComponent by improving node measurement and view fitting logic --- .../builder/FlowBuilderComponent.tsx | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx index a8b5700e..e222f995 100644 --- a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx +++ b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx @@ -6,7 +6,8 @@ import { ReactFlow, useEdgesState, useNodesState, - useReactFlow, useUpdateNodeInternals, + useReactFlow, + useUpdateNodeInternals, ViewportPortal } from "@xyflow/react"; import React from "react"; @@ -674,28 +675,28 @@ const InternalFlowBuilder: React.FC = (props) => { return layouted.nodes as Node[]; }) + revalidateHandles(changedIds) }, [revalidateHandles]) React.useEffect(() => { - const localNodes = initialNodes.map(value => { - const nodeEls = !value.measured ? document.querySelectorAll("[data-id='" + value.id + "']") : []; - return { - ...value, - measured: { - width: value.measured?.width ?? (nodeEls[0] as any)?.clientWidth ?? 0, - height: value.measured?.height ?? (nodeEls[0] as any)?.clientHeight ?? 0, + const layouted = getCachedLayoutElements(initialNodes, new Set(initialNodes.map(n => n.id))) + setNodes(prevState => { + return initialNodes.map((n, i) => { + if (prevState[i]) { + return { + ...prevState[i], + data: initialNodes[i].data + } } - } as unknown as Node + return n + }) }) - - const layouted = getCachedLayoutElements(localNodes, new Set(localNodes.map(n => n.id))) - setNodes(layouted.nodes as Node[]) setEdges(initialEdges as Edge[]) revalidateHandles((layouted.nodes as Node[]).map(n => n.id)) - }, [initialNodes.length, initialEdges.length, revalidateHandles]) + }, [initialNodes, initialEdges.length, revalidateHandles]) React.useEffect(() => { if (didFitViewRef.current) return @@ -711,7 +712,7 @@ const InternalFlowBuilder: React.FC = (props) => { maxZoom: 1 }) setShowTree(true) - }, 1000) + }, 0) }) }) }, [nodes, didFitViewRef]) @@ -727,20 +728,12 @@ const InternalFlowBuilder: React.FC = (props) => { data-tree-visibility={showTree} proOptions={{hideAttribution: true}} onNodeClick={(_, clickedNode) => { - - const node = getInternalNode(clickedNode.id); - - if (node && node.measured.width && node.measured.height) { - const centerX = node.internals.positionAbsolute.x + node.measured.width / 2; - const centerY = node.internals.positionAbsolute.y + node.measured.height / 2; - - const currentZoom = getZoom(); - - setCenter(centerX, centerY, { - zoom: Math.max(currentZoom, 1), - duration: 250, - }).then(); - } + fitView({ + nodes: [{id: clickedNode.id}], + duration: 250, + maxZoom: getZoom(), + minZoom: 1, + }); }} nodes={nodes} edges={edges} From 4ee6924529231fa0571e65660011d929db9bf08f Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 13:06:35 +0200 Subject: [PATCH 52/88] feat: refactor FunctionFilesComponent to streamline active tab handling and improve performance --- .../components/files/FunctionFilesComponent.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx index d9e0e76f..6193d98d 100644 --- a/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFilesComponent.tsx @@ -81,8 +81,8 @@ export const FunctionFilesComponent: React.FC = (pr ) React.useEffect(() => { - if (activeTab) setSelectedFunctionNode(activeTab, reactFlow); - setTimeout(() => { + //if (activeTab) setSelectedFunctionNode(activeTab, reactFlow); + /*setTimeout(() => { const parent = document.querySelector("[data-id=" + '"' + id + '"' + "]") as HTMLDivElement const tabList = parent?.querySelector(".file-tabs__list-content") as HTMLDivElement const trigger = tabList?.querySelector("[data-value=" + '"' + activeTab + '"' + "]") as HTMLDivElement @@ -95,18 +95,21 @@ export const FunctionFilesComponent: React.FC = (pr behavior: 'smooth' }); } - }, 0) - }, [activeTab, id]) + }, 0)*/ + }, [activeTab]) React.useEffect(() => { if (selectedNode) setActiveTab(selectedNode.id) - }, [selectedNode]) + }, [selectedNode?.id]) return ( { + setActiveTab(value) + setSelectedFunctionNode(value, reactFlow) + }} > Date: Tue, 5 May 2026 13:06:48 +0200 Subject: [PATCH 53/88] feat: update PICTOR_VERSION to 0.7.0 in .env.local --- .env.local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.local b/.env.local index 8485a960..704fff2e 100644 --- a/.env.local +++ b/.env.local @@ -4,7 +4,7 @@ NEXT_PUBLIC_EDITION=ce SAGITTARIUS_GRAPHQL_URL=http://localhost:3010/graphql NEXT_PUBLIC_SCULPTOR_VERSION=0.0.0 -NEXT_PUBLIC_PICTOR_VERSION=0.6.4 +NEXT_PUBLIC_PICTOR_VERSION=0.7.0 NEXT_PUBLIC_ALLOWED_REDIRECT_DOMAINS=*.code0.tech,*.codezero.build NEXT_PUBLIC_OTEL_SERVICE_NAME=#"sculptor-client" From 4417ae499189e9d3e86db19c6a69b040fca6a908 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 16:19:09 +0200 Subject: [PATCH 54/88] feat: enhance DataTypeBooleanInputComponent to improve value handling and validation --- .../boolean/DataTypeBooleanInputComponent.tsx | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 664d16f4..5f774e52 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -7,24 +7,26 @@ import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/Butto import {IconVariable, IconX} from "@tabler/icons-react"; import {InputWrapper} from "@code0-tech/pictor/dist/components/form/InputWrapper"; import {useDebouncedCallback} from "use-debounce"; +import {LiteralValue} from "@code0-tech/sagittarius-graphql-types"; export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps export const DataTypeBooleanInputComponent: React.FC = (props) => { - const {suggestions, initialValue, title, description, formValidation, onChange} = props + const {suggestions, initialValue, title, description, formValidation} = props - const defaultValue = React.useMemo(() => typeof initialValue === "boolean" ? (initialValue ? "true" : "false") : undefined , []) - const onChangeDebounced = useDebouncedCallback(() => { - onChange?.({} as any) + const defaultValue = React.useMemo(() => initialValue, []) + const onChangeDebounced = useDebouncedCallback((value: string) => { + formValidation?.setValue?.({ + __typename: "LiteralValue", + value: value === "true" ? true : value === "false" ? false : undefined + }) }, 200) - console.log("booldefault", defaultValue) - return React.useMemo(() => <> {title} {description} - 0 ? ( - } rightType={"action"}> + + + + } + rightType={"action"}> From c6727890fef1168a3d2d7fbe797a30d04409f246 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 16:19:42 +0200 Subject: [PATCH 57/88] feat: enhance DataTypeTextInputComponent to improve value handling and validation --- .../text/DataTypeTextInputComponent.tsx | 73 +++++++++++-------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index b5a3f641..9966a755 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -7,50 +7,59 @@ import {StreamLanguage} from "@codemirror/language"; import {tags} from "@lezer/highlight"; import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; import {IconVariable, IconX} from "@tabler/icons-react"; -import {useDebounce, useDebouncedCallback} from "use-debounce"; +import {useDebouncedCallback} from "use-debounce"; +import {LiteralValue, NodeFunction, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps export const DataTypeTextInputComponent: React.FC = (props) => { - const {formValidation, title, initialValue, description, suggestions, onChange} = props + const {formValidation, title, initialValue, description, suggestions} = props - const defaultValue = React.useMemo(() => initialValue ?? "", []) - const onChangeDebounced = useDebouncedCallback(() => { - onChange?.({} as any) + const defaultValue: NodeParameterValue | NodeFunction | undefined = React.useMemo(() => initialValue ?? undefined, []) + const onChangeDebounced = useDebouncedCallback((value: string) => { + formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: value} : undefined) }, 200) return React.useMemo(() => <> {title} {description} - {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( - - ) : initialValue?.__typename === "ReferenceValue" ? ( - + {defaultValue?.__typename === "NodeFunction" || defaultValue?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : defaultValue?.__typename === "ReferenceValue" ? ( + ) : ( - 0 ? ( - - - - - ) : ( - - ) - } rightType={"action"}/> + 0 ? ( + + + + + ) : ( + + ) + } + rightType={"action"}/> )} , [formValidation]) } From d11175fcb9ec3e15c77e735837c0111a06aecc3d Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 16:19:47 +0200 Subject: [PATCH 58/88] feat: enhance FunctionFileDefaultComponent to improve value handling and validation --- .../files/FunctionFileDefaultComponent.tsx | 59 ++++++------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 4eb70f5a..5785fd9c 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -1,6 +1,12 @@ import React from "react"; -import {Alert, InputSyntaxSegment, Spacing, Text, useForm, useService} from "@code0-tech/pictor"; -import {Flow, LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; +import {Alert, Spacing, Text, useForm, useService} from "@code0-tech/pictor"; +import { + Flow, + LiteralValue, + NodeFunction, + NodeParameterValue, + ReferenceValue +} from "@code0-tech/sagittarius-graphql-types"; import {useFlowValidation} from "@edition/flow/hooks/Flow.validation.hook"; import {FlowService} from "@edition/flow/services/Flow.service"; import {DataTypeInputComponent} from "@edition/datatype/components/inputs/DataTypeInputComponent"; @@ -23,7 +29,6 @@ export const FunctionFileDefaultComponent: React.FC>(new Set()) const validation = useFlowValidation(flowId) const definition = React.useMemo( @@ -35,7 +40,7 @@ export const FunctionFileDefaultComponent: React.FC = {} definition?.parameterDefinitions?.nodes?.forEach((parameter, index) => { const nodeParameter = node.parameters?.nodes?.[index] - values[parameter!.id!] = nodeParameter?.value?.__typename === "LiteralValue" ? (typeof nodeParameter.value?.value === "object" && nodeParameter.value?.value != null ? JSON.stringify(nodeParameter.value?.value) : nodeParameter.value.value) : nodeParameter?.value != null ? JSON.stringify(nodeParameter?.value) : nodeParameter?.value + values[parameter!.id!] = nodeParameter?.value }) return values }, [node, definition]) @@ -61,46 +66,20 @@ export const FunctionFileDefaultComponent: React.FC { + const onSubmit = React.useCallback((values: Record) => { for (const parameterDefinition of definition?.parameterDefinitions?.nodes ?? []) { + const parameterIndex = definition?.parameterDefinitions?.nodes?.findIndex(p => p?.id === parameterDefinition?.id) if (typeof parameterIndex !== "number") return - //if (!changedParameters.current.has(parameterIndex)) continue; - const value = values[parameterDefinition!.id!] - const syntaxValue = (value?.[0]?.type == "block" || value?.[0]?.type == "text" ? value?.[0]?.value : value) ?? null as NodeFunction | LiteralValue | ReferenceValue | null - if (!syntaxValue || !value || (Array.isArray(syntaxValue) && Array.from(syntaxValue).length <= 0)) { - flowService.setParameterValue(flowId, node.id!!, parameterIndex, undefined, definition); - continue; - } - - try { - const parsedSyntaxValue = JSON.parse(syntaxValue) - if (!parsedSyntaxValue?.__typename) { - flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { - __typename: "LiteralValue", - value: parsedSyntaxValue - } : undefined, definition); - continue; - } - } catch (e) { - if (!syntaxValue?.__typename) { - flowService.setParameterValue(flowId, node.id!!, parameterIndex, syntaxValue ? { - __typename: "LiteralValue", - value: syntaxValue, - } : undefined, definition); - continue; - } - } - - const parsedSyntaxValue = typeof syntaxValue === "object" ? syntaxValue : JSON.parse(syntaxValue) + const value = values[parameterDefinition!.id!] + if (value?.__typename === "NodeFunctionIdWrapper") return - flowService.setParameterValue(flowId, node.id!!, parameterIndex, parsedSyntaxValue.__typename === "LiteralValue" ? (!!parsedSyntaxValue.value ? parsedSyntaxValue : undefined) : parsedSyntaxValue, definition); + flowService.setParameterValue(flowId, node.id!!, parameterIndex, (value ?? undefined) as NodeFunction | ReferenceValue | LiteralValue | undefined, definition); } - changedParameters.current.clear() }, [flowService, definition]) - const [inputs, validate] = useForm>({ + const [inputs, validate, values] = useForm>({ useInitialValidation: true, truthyValidationBeforeSubmit: false, initialValues: initialValues, @@ -108,9 +87,10 @@ export const FunctionFileDefaultComponent: React.FC { - validate() - }, [validation?.length]) + React.useEffect( + () => validate(), + [validation?.length, values] + ) return <> {definition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME} @@ -140,7 +120,6 @@ export const FunctionFileDefaultComponent: React.FC validate()} {...inputs.getInputProps(parameterDefinition.id!)} /> From bbdc467f899c1256db3f7c7a3119c50998aa5fea Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 16:20:00 +0200 Subject: [PATCH 59/88] feat: enhance FunctionFileTriggerComponent to improve value handling and validation --- .../files/FunctionFileTriggerComponent.tsx | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx index 64472d44..4f3c1069 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileTriggerComponent.tsx @@ -1,6 +1,6 @@ import React from "react"; import {Alert, InputSyntaxSegment, Spacing, Text, useForm, useService, useStore} from "@code0-tech/pictor"; -import {Flow, LiteralValue} from "@code0-tech/sagittarius-graphql-types"; +import {Flow, LiteralValue, NodeFunction, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types"; import {FlowTypeService} from "@edition/flowtype/services/FlowType.service"; import {FlowService} from "@edition/flow/services/Flow.service"; import {useFlowValidation} from "@edition/flow/hooks/Flow.validation.hook"; @@ -27,7 +27,6 @@ export const FunctionFileTriggerComponent: React.FC>(new Set()) const definition = React.useMemo( () => flowTypeService.getById(instance.type?.id!!), @@ -38,7 +37,10 @@ export const FunctionFileTriggerComponent: React.FC = {} definition?.flowTypeSettings?.forEach((setting, index) => { const flowSetting = instance.settings?.nodes?.[index] - values[setting.id!] = flowSetting?.value?.__typename === "LiteralValue" ? (flowSetting?.value.value) : (flowSetting?.value) + values[setting.id!] = { + __typename: "LiteralValue", + value: flowSetting?.value, + } }) return values }, [definition, instance]) @@ -64,31 +66,21 @@ export const FunctionFileTriggerComponent: React.FC { + const onSubmit = React.useCallback((values: Record) => { startTransition(async () => { - if (values.inputType) { - await flowService.setInputType(instance.id, values.inputType) - } for (const flowTypeSetting of definition?.flowTypeSettings ?? []) { + const index = definition?.flowTypeSettings?.findIndex(p => p?.id === flowTypeSetting?.id) if (typeof index !== "number") return - if (!changedParameters.current.has(index)) continue; - const syntaxSegment = values[flowTypeSetting.id!] - const syntaxValue = syntaxSegment?.[0]?.value ?? syntaxSegment?.value ?? syntaxSegment ?? null as LiteralValue | null + const value = values[flowTypeSetting.id!] - if (!syntaxValue || !syntaxSegment || (Array.isArray(syntaxValue) && Array.from(syntaxValue).length <= 0)) { - await flowService.setSettingValue(instance.id, index, null, flowTypeSetting.identifier) - continue; - } - - await flowService.setSettingValue(props.instance.id, index, syntaxValue, flowTypeSetting.identifier) + await flowService.setSettingValue(props.instance.id, index, value?.value, flowTypeSetting.identifier) } - changedParameters.current.clear() }) - }, [definition, changedParameters]) + }, [definition]) - const [inputs, validate] = useForm>({ + const [inputs, validate, values] = useForm>({ initialValues: initialValues, validate: settingsValidations, truthyValidationBeforeSubmit: false, @@ -96,9 +88,10 @@ export const FunctionFileTriggerComponent: React.FC { - validate() - }, [validation]) + React.useEffect( + () => validate(), + [validation?.length, values] + ) return <> {definition?.names?.[0]?.content ?? FALLBACK_FLOW_TYPE_NAME} @@ -129,11 +122,6 @@ export const FunctionFileTriggerComponent: React.FC { - //TODO this should be debounced - changedParameters.current.add(index) - validate() - }} {...inputs.getInputProps(settingDefinition.id!)} /> From b8711df7c02cd5e5742ef7930de9d0b575550273 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 18:22:20 +0200 Subject: [PATCH 60/88] feat: update DataTypeInputComponent to enhance suggestions type and simplify handling --- .../inputs/DataTypeInputComponent.tsx | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 58223bf9..97f9e410 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -16,7 +16,7 @@ import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWr export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { schema: NodeSchema clearable?: boolean - suggestions?: any[] + suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[] onClear?: (event: React.MouseEvent) => void } @@ -25,39 +25,29 @@ export const DataTypeInputComponent: React.FC = (pr const {schema, ...rest} = props const suggestions = schema?.schema?.suggestions as (NodeFunction | ReferenceValue | LiteralValue)[] - const functionSuggestions: FunctionSuggestion[] = suggestions?.map((suggest: (NodeFunction | ReferenceValue | LiteralValue)) => { - - return { - type: suggest.__typename === "NodeFunction" ? FunctionSuggestionType.FUNCTION : suggest.__typename === "ReferenceValue" ? FunctionSuggestionType.REF_OBJECT : FunctionSuggestionType.VALUE, - value: suggest, - displayText: suggest.__typename === "NodeFunction" ? suggest.functionDefinition?.names?.[0]?.content ?? FALLBACK_FUNCTION_NAME : suggest.__typename === "LiteralValue" ? suggest?.value : "", - path: [] - } - - }) ?? [] switch (schema?.schema?.input) { case "data": case "list": return case "boolean": return case "select": return default: return From 08efff8fe47b3b3aaa6b18bf890c84bcdd729b34 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 18:22:27 +0200 Subject: [PATCH 61/88] feat: enhance DataTypeSelectInputComponent to improve value selection and rendering --- .../select/DataTypeSelectInputComponent.tsx | 89 ++++++++++--------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx index c3144cb6..34e0962b 100644 --- a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx @@ -13,12 +13,12 @@ import { SelectPortal, SelectTrigger, SelectValue, - SelectViewport + SelectViewport, + Text } from "@code0-tech/pictor"; -import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; import {IconChevronDown, IconX} from "@tabler/icons-react"; -import {LiteralValue} from "@code0-tech/sagittarius-graphql-types"; +import lodash from "lodash" export type DataTypeSelectInputComponentProps = DataTypeInputComponentProps @@ -27,52 +27,61 @@ export const DataTypeSelectInputComponent: React.FC initialValue, []) + const defaultValue = React.useMemo(() => suggestions?.findIndex(suggest => { + return lodash.isEqual(suggest, initialValue) + }), [suggestions]) + const onChangeDebounced = useDebouncedCallback((value: string) => { - formValidation?.setValue?.({__typename: "LiteralValue", value: value}) + formValidation?.setValue?.(suggestions?.[Number(value)] ?? undefined) }, 200) return React.useMemo(() => <> {title} {description} - {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( - - ) : initialValue?.__typename === "ReferenceValue" ? ( - - ) : ( - - - - } - rightType={"action"}> - - - - - - - - - - {suggestions?.filter((suggest) => suggest?.value.__typename === "LiteralValue").map((suggest) => { - return + + + + } + rightType={"action"}> + + + + + + + + + + {suggestions?.map((suggest, index) => { + + if (suggest.__typename === "LiteralValue") { + return - {suggest?.children} + {(suggest)?.value} - })} - - - - - )} - , [formValidation]) + } + + if (suggest.__typename === "ReferenceValue") { + return + + + + + } + + })} + + + + + , [formValidation, defaultValue]) } \ No newline at end of file From b871baa566be060340518b118355a900c147fcf9 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 18:22:37 +0200 Subject: [PATCH 62/88] feat: add lodash and its type definitions to enhance utility functions --- package-lock.json | 15 +++++++++++++++ package.json | 2 ++ 2 files changed, 17 insertions(+) diff --git a/package-lock.json b/package-lock.json index e7a809a4..4fed461d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "graphql": "^16.12.0", "graphql-tag": "^2.12.6", "ldrs": "^1.1.9", + "lodash": "^4.18.1", "next": "16.2.3", "prettier": "^3.8.1", "react": "19.2.5", @@ -36,6 +37,7 @@ "use-debounce": "^10.1.1" }, "devDependencies": { + "@types/lodash": "^4.17.24", "@types/node": "^24.0.0", "@types/react": "^19", "@types/react-dom": "^19", @@ -3351,6 +3353,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "24.12.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", @@ -6763,6 +6772,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, "node_modules/long": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", diff --git a/package.json b/package.json index 3a25a1b8..1fd9b4a5 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "graphql": "^16.12.0", "graphql-tag": "^2.12.6", "ldrs": "^1.1.9", + "lodash": "^4.18.1", "next": "16.2.3", "prettier": "^3.8.1", "react": "19.2.5", @@ -42,6 +43,7 @@ "use-debounce": "^10.1.1" }, "devDependencies": { + "@types/lodash": "^4.17.24", "@types/node": "^24.0.0", "@types/react": "^19", "@types/react-dom": "^19", From 302accb14eba11fe5a5a9f1aecac7a6cdaad8aea Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:33:18 +0200 Subject: [PATCH 63/88] feat: enhance DataTypeBooleanInputComponent to improve value change handling and validation --- .../inputs/boolean/DataTypeBooleanInputComponent.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 5f774e52..f3079d65 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -13,7 +13,7 @@ export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps export const DataTypeBooleanInputComponent: React.FC = (props) => { - const {suggestions, initialValue, title, description, formValidation} = props + const {suggestions, initialValue, title, description, formValidation, onChange} = props const defaultValue = React.useMemo(() => initialValue, []) const onChangeDebounced = useDebouncedCallback((value: string) => { @@ -21,6 +21,10 @@ export const DataTypeBooleanInputComponent: React.FC <> From bc1770235e7e36b9fbb5bfd3ffe5167571dc6fc0 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:33:27 +0200 Subject: [PATCH 64/88] feat: update DataTypeInputComponent to enhance props and simplify input handling --- .../inputs/DataTypeInputComponent.tsx | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 97f9e410..1d3ad419 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -1,21 +1,15 @@ import React from "react"; import {DataTypeTextInputComponent} from "./text/DataTypeTextInputComponent"; -import {DataTypeJSONInputComponent} from "@edition/datatype/components/inputs/json/DataTypeJSONInputComponent"; import {NodeSchema} from "@code0-tech/triangulum"; import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; -import { - FunctionSuggestion, - FunctionSuggestionType -} from "@edition/function/components/suggestion/FunctionSuggestionComponent.view"; -import {toInputSuggestions} from "@edition/function/components/suggestion/FunctionSuggestionMenuComponent.util"; -import {FALLBACK_FUNCTION_NAME} from "@core/util/fallback-translations"; import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent"; import {DataTypeSelectInputComponent} from "@edition/datatype/components/inputs/select/DataTypeSelectInputComponent"; import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWrapper"; -export interface DataTypeInputComponentProps extends Omit, "wrapperComponent"> { +export interface DataTypeInputComponentProps extends Omit, "wrapperComponent" | "onChange"> { schema: NodeSchema clearable?: boolean + onChange?: (value: NodeParameterValue | NodeFunction | undefined) => void suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[] onClear?: (event: React.MouseEvent) => void } @@ -27,13 +21,6 @@ export const DataTypeInputComponent: React.FC = (pr const suggestions = schema?.schema?.suggestions as (NodeFunction | ReferenceValue | LiteralValue)[] switch (schema?.schema?.input) { - case "data": - case "list": - return case "boolean": return Date: Tue, 5 May 2026 23:33:47 +0200 Subject: [PATCH 65/88] feat: enhance DataTypeSelectInputComponent to support onChange prop and improve value handling --- .../inputs/select/DataTypeSelectInputComponent.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx index 34e0962b..358ce5b9 100644 --- a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx @@ -25,14 +25,15 @@ export type DataTypeSelectInputComponentProps = DataTypeInputComponentProps export const DataTypeSelectInputComponent: React.FC = (props) => { - const {formValidation, title, initialValue, description, suggestions} = props + const {formValidation, title, initialValue, description, suggestions, onChange} = props const defaultValue = React.useMemo(() => suggestions?.findIndex(suggest => { - return lodash.isEqual(suggest, initialValue) + return initialValue && lodash.isMatch(suggest, initialValue) }), [suggestions]) - const onChangeDebounced = useDebouncedCallback((value: string) => { + const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { formValidation?.setValue?.(suggestions?.[Number(value)] ?? undefined) + onChange?.(suggestions?.[Number(value)] ?? undefined) }, 200) return React.useMemo(() => <> @@ -41,10 +42,13 @@ export const DataTypeSelectInputComponent: React.FC + } @@ -77,7 +81,6 @@ export const DataTypeSelectInputComponent: React.FC } - })} From 09dafad16859940ba619d33fa220f4a3f1414400 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:33:56 +0200 Subject: [PATCH 66/88] feat: enhance DataTypeTextInputComponent to support onChange prop and improve value handling --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 9966a755..68434d1d 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -14,11 +14,12 @@ export type DataTypeTextInputComponentProps = DataTypeInputComponentProps export const DataTypeTextInputComponent: React.FC = (props) => { - const {formValidation, title, initialValue, description, suggestions} = props + const {formValidation, title, initialValue, description, suggestions, onChange} = props const defaultValue: NodeParameterValue | NodeFunction | undefined = React.useMemo(() => initialValue ?? undefined, []) const onChangeDebounced = useDebouncedCallback((value: string) => { formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: value} : undefined) + onChange?.(value ? {__typename: "LiteralValue", value: value} : undefined) }, 200) return React.useMemo(() => <> From 2d2bca6e5e707e2947201817a44b2c3106ab5661 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:34:20 +0200 Subject: [PATCH 67/88] feat: refactor useFlowValidation to optimize validation result handling and improve performance --- .../ce/src/flow/hooks/Flow.validation.hook.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/packages/ce/src/flow/hooks/Flow.validation.hook.ts b/src/packages/ce/src/flow/hooks/Flow.validation.hook.ts index a3057bb1..2a02e470 100644 --- a/src/packages/ce/src/flow/hooks/Flow.validation.hook.ts +++ b/src/packages/ce/src/flow/hooks/Flow.validation.hook.ts @@ -9,6 +9,7 @@ import {useFlowValidationAction} from "@edition/flow/components/FlowWorkerProvid const globalPendingValidations = new Map>() +//TODO: use context export const useFlowValidation = ( flowId: Flow['id'] ): ValidationResult[] | null => { @@ -32,16 +33,16 @@ export const useFlowValidation = ( React.useEffect(() => { if (!flow) return; + const key = flowId as string; - const timeout = setTimeout(() => { - const key = flowId as string; + if (globalPendingValidations.has(key)) { + globalPendingValidations.get(key)!.then(value => { + setValidationResult(value as ValidationResult[]) + }); + return; + } - if (globalPendingValidations.has(key)) { - globalPendingValidations.get(key)!.then(value => { - setValidationResult(value as ValidationResult[]) - }); - return; - } + const timeout = setTimeout(() => { const promise = execute({ flow, @@ -59,5 +60,5 @@ export const useFlowValidation = ( return () => clearTimeout(timeout); }, [flow?.editedAt, functions.length, dataTypes.length]) - return validationResult + return React.useMemo(() => validationResult, [validationResult]) } \ No newline at end of file From f3043383d750836e3e72258ef108656d7c415c87 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:34:28 +0200 Subject: [PATCH 68/88] feat: improve flowTypeId input handling by adding optional chaining for setValue --- .../ce/src/flow/components/FlowCreateDialogComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/flow/components/FlowCreateDialogComponent.tsx b/src/packages/ce/src/flow/components/FlowCreateDialogComponent.tsx index 96954df1..42ec7ea0 100644 --- a/src/packages/ce/src/flow/components/FlowCreateDialogComponent.tsx +++ b/src/packages/ce/src/flow/components/FlowCreateDialogComponent.tsx @@ -223,7 +223,7 @@ export const FlowCreateDialogComponent: React.FC const DisplayIcon = icon(flowType?.displayIcon as IconString) return { - inputs.getInputProps("flowTypeId").formValidation?.setValue(flowType.id) + inputs.getInputProps("flowTypeId").formValidation?.setValue?.(flowType.id) setSelectedFlowTypeId(flowType.id) }}> From 7d82d58098e4885240887e24d3c252ac5abc70f7 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Tue, 5 May 2026 23:34:39 +0200 Subject: [PATCH 69/88] feat: update FunctionFileDefaultComponent to improve validation handling and add onChange support --- .../components/files/FunctionFileDefaultComponent.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 5785fd9c..7082ae94 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -79,7 +79,7 @@ export const FunctionFileDefaultComponent: React.FC>({ + const [inputs, validate] = useForm>({ useInitialValidation: true, truthyValidationBeforeSubmit: false, initialValues: initialValues, @@ -88,8 +88,8 @@ export const FunctionFileDefaultComponent: React.FC validate(), - [validation?.length, values] + () => validate(undefined, false), + [validation] ) return <> @@ -120,6 +120,7 @@ export const FunctionFileDefaultComponent: React.FC validate()} {...inputs.getInputProps(parameterDefinition.id!)} /> From 510c47f13e4c83e02d3be9cbef512103e6f688ef Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 6 May 2026 00:32:34 +0200 Subject: [PATCH 70/88] feat: enhance FunctionFileDefaultComponent to track input changes and trigger validation --- .../files/FunctionFileDefaultComponent.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx index 7082ae94..f1a2a50e 100644 --- a/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx +++ b/src/packages/ce/src/function/components/files/FunctionFileDefaultComponent.tsx @@ -31,6 +31,8 @@ export const FunctionFileDefaultComponent: React.FC node.functionDefinition!, [node] @@ -79,7 +81,7 @@ export const FunctionFileDefaultComponent: React.FC>({ + const [inputs, validate, values] = useForm>({ useInitialValidation: true, truthyValidationBeforeSubmit: false, initialValues: initialValues, @@ -87,6 +89,14 @@ export const FunctionFileDefaultComponent: React.FC { + if (changedValue.current) + validate() + }, + [values] + ) + React.useEffect( () => validate(undefined, false), [validation] @@ -120,7 +130,7 @@ export const FunctionFileDefaultComponent: React.FC validate()} + onChange={() => changedValue.current = true} {...inputs.getInputProps(parameterDefinition.id!)} /> From 597ea81e2f513cfef31c08d9e0166d8b739db81c Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 6 May 2026 01:03:51 +0200 Subject: [PATCH 71/88] feat: enhance input components to support optional chaining and improve value handling --- .../boolean/DataTypeBooleanInputComponent.tsx | 28 +++++++++++-------- .../select/DataTypeSelectInputComponent.tsx | 13 +++++---- .../text/DataTypeTextInputComponent.tsx | 14 ++++++---- .../components/folder/FlowFolderComponent.tsx | 16 +++++------ 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index f3079d65..8e6f4a22 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -15,16 +15,16 @@ export const DataTypeBooleanInputComponent: React.FC initialValue, []) - const onChangeDebounced = useDebouncedCallback((value: string) => { - formValidation?.setValue?.({ - __typename: "LiteralValue", - value: value === "true" ? true : value === "false" ? false : undefined - }) - onChange?.({ + const defaultValue = React.useMemo(() => initialValue, [initialValue]) + const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { + + const boolValue: LiteralValue | undefined = value && ["true", "false"].includes(value) ? { __typename: "LiteralValue", - value: value === "true" ? true : value === "false" ? false : undefined - }) + value: value === "true" + } : undefined + + formValidation?.setValue?.(boolValue) + onChange?.(boolValue) }, 200) return React.useMemo(() => <> @@ -36,12 +36,16 @@ export const DataTypeBooleanInputComponent: React.FC - ) : ( - ) @@ -68,6 +72,6 @@ export const DataTypeBooleanInputComponent: React.FC )} - , [formValidation]) + , [formValidation, defaultValue]) } \ No newline at end of file diff --git a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx index 358ce5b9..edb8b39e 100644 --- a/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/select/DataTypeSelectInputComponent.tsx @@ -23,13 +23,14 @@ import lodash from "lodash" export type DataTypeSelectInputComponentProps = DataTypeInputComponentProps + export const DataTypeSelectInputComponent: React.FC = (props) => { const {formValidation, title, initialValue, description, suggestions, onChange} = props - const defaultValue = React.useMemo(() => suggestions?.findIndex(suggest => { - return initialValue && lodash.isMatch(suggest, initialValue) - }), [suggestions]) + const defaultValue: number = React.useMemo(() => suggestions?.findIndex(suggest => { + return initialValue && lodash.isMatch(initialValue, suggest) + }), [suggestions])! const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { formValidation?.setValue?.(suggestions?.[Number(value)] ?? undefined) @@ -39,7 +40,7 @@ export const DataTypeSelectInputComponent: React.FC <> {title} {description} - = 0 ?defaultValue?.toString() : undefined} formValidation={{...formValidation, setValue: undefined}} maw={"100%"} key={formValidation?.notValidMessage} @@ -55,7 +56,9 @@ export const DataTypeSelectInputComponent: React.FC - + + + diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 68434d1d..7acebdf7 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -16,8 +16,8 @@ export const DataTypeTextInputComponent: React.FC initialValue ?? undefined, []) - const onChangeDebounced = useDebouncedCallback((value: string) => { + const defaultValue: NodeParameterValue | NodeFunction | undefined = React.useMemo(() => initialValue ?? undefined, [initialValue]) + const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: value} : undefined) onChange?.(value ? {__typename: "LiteralValue", value: value} : undefined) }, 200) @@ -50,17 +50,21 @@ export const DataTypeTextInputComponent: React.FC - ) : ( - ) } rightType={"action"}/> )} - , [formValidation]) + , [formValidation, defaultValue]) } diff --git a/src/packages/ce/src/flow/components/folder/FlowFolderComponent.tsx b/src/packages/ce/src/flow/components/folder/FlowFolderComponent.tsx index 666136f2..3021a991 100644 --- a/src/packages/ce/src/flow/components/folder/FlowFolderComponent.tsx +++ b/src/packages/ce/src/flow/components/folder/FlowFolderComponent.tsx @@ -361,7 +361,7 @@ export const DFlowFolderItem: React.FC = (props) = type TruncateMode = "start" | "middle" | "end"; export function truncateText( - value: string, + value: string | undefined, wrapperWidth: number, mode: TruncateMode = "middle", ellipsis = "…" @@ -372,13 +372,13 @@ export function truncateText( ctx.font = "400 16px Inter, sans-serif"; const letterSpacing = -1.9; - const measure = (text: string) => - ctx.measureText(text).width + (text.length - 1) * letterSpacing; + const measure = (text: string | undefined) => + ctx.measureText(text ?? "").width + ((text?.length ?? 0) - 1) * letterSpacing; - if (measure(value) <= wrapperWidth) return value; + if (measure(value) <= wrapperWidth) return value ?? ""; let low = 0; - let high = value.length; + let high = value?.length ?? 0; let best = ellipsis; while (low <= high) { @@ -386,12 +386,12 @@ export function truncateText( let candidate: string; if (mode === "end") { - candidate = value.slice(0, mid) + ellipsis; + candidate = value?.slice(0, mid) + ellipsis; } else if (mode === "start") { - candidate = ellipsis + value.slice(value.length - mid); + candidate = ellipsis + value?.slice(value.length - mid); } else { const half = Math.floor(mid / 2); - candidate = value.slice(0, half) + ellipsis + value.slice(value.length - half); + candidate = value?.slice(0, half) + ellipsis + value?.slice(value.length - half); } const width = measure(candidate); From dd5293505ab8e9d442a7a09e0950c5e271caf8cd Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 6 May 2026 18:26:51 +0200 Subject: [PATCH 72/88] feat: enhance DataTypeBooleanInputComponent and DataTypeTextInputComponent to support suggestion menus for input values --- .../boolean/DataTypeBooleanInputComponent.tsx | 57 +++++++++++++++---- .../text/DataTypeTextInputComponent.tsx | 43 ++++++++++++-- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 8e6f4a22..873451e3 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -1,6 +1,19 @@ import React from "react"; import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; -import {Button, InputDescription, InputLabel, SegmentedControl, SegmentedControlItem} from "@code0-tech/pictor"; +import { + Button, + Flex, + InputDescription, + InputLabel, + Menu, + MenuContent, + MenuItem, + MenuPortal, + MenuTrigger, + SegmentedControl, + SegmentedControlItem, + Text +} from "@code0-tech/pictor"; import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; @@ -15,7 +28,6 @@ export const DataTypeBooleanInputComponent: React.FC initialValue, [initialValue]) const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { const boolValue: LiteralValue | undefined = value && ["true", "false"].includes(value) ? { @@ -33,9 +45,32 @@ export const DataTypeBooleanInputComponent: React.FC 0 ? ( - + + + + + + + {suggestions?.map((suggest, index) => { + if (suggest.__typename === "LiteralValue") { + return + + {(suggest)?.value.toString()} + + + } + + if (suggest.__typename === "ReferenceValue") { + return + + + } + })} + + + + + + + + + + {suggestions?.map((suggest, index) => { + if (suggest.__typename === "LiteralValue") { + return + + {(suggest)?.value.toString()} + + + } + + if (suggest.__typename === "ReferenceValue") { + return + + + } + })} + + + + + + + {suggestions?.map((suggest, index) => { + if (suggest.__typename === "LiteralValue") { + return onSelect?.(suggest)}> + + {(suggest)?.value.toString()} + + + } + + if (suggest.__typename === "ReferenceValue") { + return onSelect?.(suggest)}> + + + } + })} + + +
+ + + ) : ( + + ) + +} \ No newline at end of file From 59185cbbde4be103751601bf75f981ab159d0441 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 6 May 2026 19:07:24 +0200 Subject: [PATCH 74/88] feat: enhance DataTypeBooleanInputComponent to support additional value types and integrate input controls --- .../boolean/DataTypeBooleanInputComponent.tsx | 82 ++++--------------- 1 file changed, 17 insertions(+), 65 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 873451e3..615c08ec 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -1,26 +1,12 @@ import React from "react"; import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; -import { - Button, - Flex, - InputDescription, - InputLabel, - Menu, - MenuContent, - MenuItem, - MenuPortal, - MenuTrigger, - SegmentedControl, - SegmentedControlItem, - Text -} from "@code0-tech/pictor"; +import {InputDescription, InputLabel, SegmentedControl, SegmentedControlItem} from "@code0-tech/pictor"; import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; -import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; -import {IconVariable, IconX} from "@tabler/icons-react"; import {InputWrapper} from "@code0-tech/pictor/dist/components/form/InputWrapper"; import {useDebouncedCallback} from "use-debounce"; -import {LiteralValue} from "@code0-tech/sagittarius-graphql-types"; +import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; +import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps @@ -28,62 +14,28 @@ export const DataTypeBooleanInputComponent: React.FC { + const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | ReferenceValue | undefined) => { - const boolValue: LiteralValue | undefined = value && ["true", "false"].includes(value) ? { - __typename: "LiteralValue", - value: value === "true" - } : undefined + if (typeof value === "string") { + const boolValue: LiteralValue | undefined = value && ["true", "false"].includes(value) ? { + __typename: "LiteralValue", + value: value === "true" + } : undefined + + formValidation?.setValue?.(boolValue) + onChange?.(boolValue) + } else { + formValidation?.setValue?.(value) + onChange?.(value) + } - formValidation?.setValue?.(boolValue) - onChange?.(boolValue) }, 200) return React.useMemo(() => <> {title} {description} 0 ? ( - - - - - - - - {suggestions?.map((suggest, index) => { - if (suggest.__typename === "LiteralValue") { - return - - {(suggest)?.value.toString()} - - - } - - if (suggest.__typename === "ReferenceValue") { - return - - - } - })} - - - - - - ) : ( - - ) + } rightType={"action"}> {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( From 52a20091004a7588bf78dd23434581a29454b7c4 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Wed, 6 May 2026 19:07:29 +0200 Subject: [PATCH 75/88] feat: enhance DataTypeTextInputComponent to support additional value types and integrate input controls --- .../text/DataTypeTextInputComponent.tsx | 73 ++++--------------- 1 file changed, 13 insertions(+), 60 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 071ba52f..6aedb21a 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -1,26 +1,13 @@ import React from "react"; import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; -import { - Button, - EditorInput, - Flex, - hashToColor, - InputDescription, - InputLabel, - Menu, - MenuContent, - MenuItem, - MenuPortal, - MenuTrigger -} from "@code0-tech/pictor"; +import {EditorInput, hashToColor, InputDescription, InputLabel} from "@code0-tech/pictor"; import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; import {StreamLanguage} from "@codemirror/language"; import {tags} from "@lezer/highlight"; -import {ButtonGroup} from "@code0-tech/pictor/dist/components/button-group/ButtonGroup"; -import {IconVariable, IconX} from "@tabler/icons-react"; import {useDebouncedCallback} from "use-debounce"; -import {LiteralValue, NodeFunction, NodeParameterValue} from "@code0-tech/sagittarius-graphql-types"; +import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; +import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps @@ -29,9 +16,15 @@ export const DataTypeTextInputComponent: React.FC initialValue ?? undefined, [initialValue]) - const onChangeDebounced = useDebouncedCallback((value: string | undefined) => { - formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: value} : undefined) - onChange?.(value ? {__typename: "LiteralValue", value: value} : undefined) + const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | ReferenceValue | undefined) => { + + if (typeof value === "string") { + formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: value} : undefined) + onChange?.(value ? {__typename: "LiteralValue", value: value} : undefined) + } else { + formValidation?.setValue?.(value) + onChange?.(value) + } }, 200) return React.useMemo(() => <> @@ -57,47 +50,7 @@ export const DataTypeTextInputComponent: React.FC 0 ? ( - - - - - - - - {suggestions?.map((suggest, index) => { - if (suggest.__typename === "LiteralValue") { - return - - {(suggest)?.value.toString()} - - - } - - if (suggest.__typename === "ReferenceValue") { - return - - - } - })} - - - - - - ) : ( - - ) + } rightType={"action"}/> )} From 80dcc9e14312908c9a91a4e2b3cc843737482548 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:10:27 +0200 Subject: [PATCH 76/88] feat: refactor DataTypeBooleanInputComponent to use DataTypeInputValueComponent for improved value handling --- .../boolean/DataTypeBooleanInputComponent.tsx | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx index 615c08ec..7111d4fa 100644 --- a/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/boolean/DataTypeBooleanInputComponent.tsx @@ -1,12 +1,9 @@ import React from "react"; import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; import {InputDescription, InputLabel, SegmentedControl, SegmentedControlItem} from "@code0-tech/pictor"; -import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; -import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; -import {InputWrapper} from "@code0-tech/pictor/dist/components/form/InputWrapper"; import {useDebouncedCallback} from "use-debounce"; import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; -import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; +import {DataTypeInputValueComponent} from "@edition/datatype/components/inputs/DataTypeInputValueComponent"; export type DataTypeBooleanInputComponentProps = DataTypeInputComponentProps @@ -34,31 +31,23 @@ export const DataTypeBooleanInputComponent: React.FC <> {title} {description} - - } rightType={"action"}> - {initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( - - ) : initialValue?.__typename === "ReferenceValue" ? ( - - ) : ( -
- - - True - - - False - - -
- )} -
+ + + + True + + + False + + + , [formValidation, initialValue]) } \ No newline at end of file From 808c074bfbf14154e8335bc0e1696f221f982140 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:10:37 +0200 Subject: [PATCH 77/88] feat: update DataTypeInputComponent to support new value types in onChange handler --- .../src/datatype/components/inputs/DataTypeInputComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 1d3ad419..56f956d0 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -9,7 +9,7 @@ import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWr export interface DataTypeInputComponentProps extends Omit, "wrapperComponent" | "onChange"> { schema: NodeSchema clearable?: boolean - onChange?: (value: NodeParameterValue | NodeFunction | undefined) => void + onChange?: (value: ReferenceValue | LiteralValue | NodeFunction | undefined) => void suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[] onClear?: (event: React.MouseEvent) => void } From f3124cc7673bc424a9700b329d310d8055c01b4d Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:10:52 +0200 Subject: [PATCH 78/88] feat: add DataTypeInputValueComponent for enhanced value handling and input controls --- .../inputs/DataTypeInputValueComponent.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/packages/ce/src/datatype/components/inputs/DataTypeInputValueComponent.tsx diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputValueComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputValueComponent.tsx new file mode 100644 index 00000000..aee7618f --- /dev/null +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputValueComponent.tsx @@ -0,0 +1,32 @@ +import React from "react"; +import {InputWrapper} from "@code0-tech/pictor/dist/components/form/InputWrapper"; +import {DataTypeInputComponentProps} from "@edition/datatype/components/inputs/DataTypeInputComponent"; +import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; +import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; +import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; + +export interface DataTypeInputValueComponentProps extends Omit { + children?: React.ReactNode + inside?: boolean +} + +export const DataTypeInputValueComponent: React.FC = (props) => { + + const {children, inside = false, initialValue, suggestions, onChange, formValidation} = props + + return inside || initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" || initialValue?.__typename === "ReferenceValue" ? + + } rightType={"action"}> +
+ { + initialValue?.__typename === "NodeFunction" || initialValue?.__typename === "NodeFunctionIdWrapper" ? ( + + ) : initialValue?.__typename === "ReferenceValue" ? ( + + ) : inside ? children : null + } +
+
: children + +} \ No newline at end of file From 57ead972bd25a8c982203641c965689b96ba8d9a Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:11:10 +0200 Subject: [PATCH 79/88] feat: integrate DataTypeInputValueComponent into DataTypeTextInputComponent for improved value handling --- .../inputs/text/DataTypeTextInputComponent.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 6aedb21a..609849be 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -1,13 +1,12 @@ import React from "react"; import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; import {EditorInput, hashToColor, InputDescription, InputLabel} from "@code0-tech/pictor"; -import {NodeBadgeComponent} from "@edition/datatype/components/badges/NodeBadgeComponent"; -import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; import {StreamLanguage} from "@codemirror/language"; import {tags} from "@lezer/highlight"; import {useDebouncedCallback} from "use-debounce"; import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; +import {DataTypeInputValueComponent} from "@edition/datatype/components/inputs/DataTypeInputValueComponent"; export type DataTypeTextInputComponentProps = DataTypeInputComponentProps @@ -30,11 +29,8 @@ export const DataTypeTextInputComponent: React.FC <> {title} {description} - {defaultValue?.__typename === "NodeFunction" || defaultValue?.__typename === "NodeFunctionIdWrapper" ? ( - - ) : defaultValue?.__typename === "ReferenceValue" ? ( - - ) : ( + } rightType={"action"}/> - )} + , [formValidation, defaultValue]) } From 857d6f8dad9e367144d532a35f6bcd4785c4c90a Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:20:17 +0200 Subject: [PATCH 80/88] feat: add DataTypeNumberInputComponent to DataTypeInputComponent for number value handling --- .../datatype/components/inputs/DataTypeInputComponent.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx index 56f956d0..e37dd634 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputComponent.tsx @@ -5,6 +5,7 @@ import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@c import {DataTypeBooleanInputComponent} from "@edition/datatype/components/inputs/boolean/DataTypeBooleanInputComponent"; import {DataTypeSelectInputComponent} from "@edition/datatype/components/inputs/select/DataTypeSelectInputComponent"; import {InputWrapperProps} from "@code0-tech/pictor/dist/components/form/InputWrapper"; +import {DataTypeNumberInputComponent} from "@edition/datatype/components/inputs/number/DataTypeNumberInputComponent"; export interface DataTypeInputComponentProps extends Omit, "wrapperComponent" | "onChange"> { schema: NodeSchema @@ -32,6 +33,11 @@ export const DataTypeInputComponent: React.FC = (pr schema={schema} suggestions={suggestions} {...rest}/> + case "number": + return default: return Date: Thu, 7 May 2026 15:20:22 +0200 Subject: [PATCH 81/88] feat: add DataTypeNumberInputComponent for handling number inputs with validation --- .../number/DataTypeNumberInputComponent.tsx | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/packages/ce/src/datatype/components/inputs/number/DataTypeNumberInputComponent.tsx diff --git a/src/packages/ce/src/datatype/components/inputs/number/DataTypeNumberInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/number/DataTypeNumberInputComponent.tsx new file mode 100644 index 00000000..fb4bc01e --- /dev/null +++ b/src/packages/ce/src/datatype/components/inputs/number/DataTypeNumberInputComponent.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import {DataTypeInputComponentProps} from "../DataTypeInputComponent"; +import {EditorInput, hashToColor, InputDescription, InputLabel} from "@code0-tech/pictor"; +import {StreamLanguage} from "@codemirror/language"; +import {tags} from "@lezer/highlight"; +import {useDebouncedCallback} from "use-debounce"; +import {LiteralValue, NodeFunction, NodeParameterValue, ReferenceValue} from "@code0-tech/sagittarius-graphql-types"; +import {DataTypeInputControlsComponent} from "@edition/datatype/components/inputs/DataTypeInputControlsComponent"; +import {DataTypeInputValueComponent} from "@edition/datatype/components/inputs/DataTypeInputValueComponent"; + +export type DataTypeNumberInputComponentProps = DataTypeInputComponentProps + +export const DataTypeNumberInputComponent: React.FC = (props) => { + + const {formValidation, title, initialValue, description, suggestions, onChange} = props + + const defaultValue: NodeParameterValue | NodeFunction | undefined = React.useMemo(() => initialValue ?? undefined, [initialValue]) + const onChangeDebounced = useDebouncedCallback((value: string | LiteralValue | NodeFunction | ReferenceValue | undefined) => { + + if (typeof value === "string") { + console.log(value) + formValidation?.setValue?.(value ? {__typename: "LiteralValue", value: !Number.isNaN(Number(value)) ? Number(value) : value} : undefined) + onChange?.(value ? {__typename: "LiteralValue", value: !Number.isNaN(Number(value)) ? Number(value) : value} : undefined) + } else { + formValidation?.setValue?.(value) + onChange?.(value) + } + }, 200) + + return React.useMemo(() => <> + {title} + {description} + + + } + rightType={"action"}/> + + , [formValidation, defaultValue]) +} From 449c1f1b495d9866192d4e92a3a8667736ab914a Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:20:26 +0200 Subject: [PATCH 82/88] feat: convert defaultValue to string in DataTypeTextInputComponent for consistent input handling --- .../components/inputs/text/DataTypeTextInputComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx index 609849be..882fd997 100644 --- a/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/text/DataTypeTextInputComponent.tsx @@ -31,7 +31,7 @@ export const DataTypeTextInputComponent: React.FC{description} - Date: Thu, 7 May 2026 15:28:11 +0200 Subject: [PATCH 83/88] feat: update node measurement logic in FlowBuilderComponent for accurate layout handling --- .../builder/FlowBuilderComponent.tsx | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx index e222f995..db2b3339 100644 --- a/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx +++ b/src/packages/ce/src/flow/components/builder/FlowBuilderComponent.tsx @@ -680,18 +680,19 @@ const InternalFlowBuilder: React.FC = (props) => { }, [revalidateHandles]) React.useEffect(() => { - const layouted = getCachedLayoutElements(initialNodes, new Set(initialNodes.map(n => n.id))) - setNodes(prevState => { - return initialNodes.map((n, i) => { - if (prevState[i]) { - return { - ...prevState[i], - data: initialNodes[i].data - } + const localNodes = initialNodes.map(value => { + const nodeEls = !value.measured ? document.querySelectorAll("[data-id='" + value.id + "']") : []; + return { + ...value, + measured: { + width: value.measured?.width ?? (nodeEls[0] as any)?.clientWidth ?? 0, + height: value.measured?.height ?? (nodeEls[0] as any)?.clientHeight ?? 0, } - return n - }) + } as unknown as Node }) + + const layouted = getCachedLayoutElements(localNodes, new Set(localNodes.map(n => n.id))) + setNodes(layouted.nodes as Node[]) setEdges(initialEdges as Edge[]) revalidateHandles((layouted.nodes as Node[]).map(n => n.id)) From 1b9cd1988fd3cd745dc4e4517604c11b3d61a83a Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 15:35:38 +0200 Subject: [PATCH 84/88] feat: enhance suggestion handling in DataTypeInputControlsComponent with filtering and tooltips --- .../inputs/DataTypeInputControlsComponent.tsx | 98 ++++++++++++------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/DataTypeInputControlsComponent.tsx b/src/packages/ce/src/datatype/components/inputs/DataTypeInputControlsComponent.tsx index 7df61079..68937243 100644 --- a/src/packages/ce/src/datatype/components/inputs/DataTypeInputControlsComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/DataTypeInputControlsComponent.tsx @@ -2,7 +2,21 @@ import {LiteralValue, NodeFunction, ReferenceValue} from "@code0-tech/sagittariu import React from "react"; import {IconVariable, IconX} from "@tabler/icons-react"; import {ReferenceBadgeComponent} from "@edition/datatype/components/badges/ReferenceBadgeComponent"; -import {ButtonGroup, Menu, MenuTrigger, Button, MenuPortal, MenuContent, MenuItem, Flex} from "@code0-tech/pictor" +import { + Button, + ButtonGroup, + Flex, + Menu, + MenuContent, + MenuItem, + MenuPortal, + MenuTrigger, + Text, + Tooltip, + TooltipContent, + TooltipPortal, + TooltipTrigger +} from "@code0-tech/pictor" export interface DataTypeInputControlsComponentProps { suggestions?: (NodeFunction | ReferenceValue | LiteralValue)[] @@ -13,46 +27,56 @@ export const DataTypeInputControlsComponent: React.FC 0 ? ( - - - - - - - - {suggestions?.map((suggest, index) => { - if (suggest.__typename === "LiteralValue") { - return onSelect?.(suggest)}> - - {(suggest)?.value.toString()} - - - } + const filteredSuggestions = React.useMemo(() => { + if (!suggestions) return [] + return suggestions.filter(suggest => suggest.__typename === "LiteralValue" || suggest.__typename === "ReferenceValue") + }, [suggestions]) - if (suggest.__typename === "ReferenceValue") { - return onSelect?.(suggest)}> - - - } - })} - - - - - - ) : ( - + + + + + {filteredSuggestions.length <= 0 ? + No suggestion available + : + Suggestions for this parameter + } + + + + + + {filteredSuggestions?.map((suggest, index) => { + if (suggest.__typename === "LiteralValue") { + return onSelect?.(suggest)}> + + {(suggest)?.value.toString()} + + + } + + if (suggest.__typename === "ReferenceValue") { + return onSelect?.(suggest)}> + + + } + })} + + +
+ - ) + } \ No newline at end of file From a6dcc14e31ec6e887212babd990ad1ef314d94b9 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 16:12:00 +0200 Subject: [PATCH 85/88] feat: update @code0-tech/pictor dependency to version 0.7.2 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fed461d..85419a4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@apollo/client": "^4.0.9", - "@code0-tech/pictor": "^0.7.1", + "@code0-tech/pictor": "^0.7.2", "@code0-tech/triangulum": "^0.14.3", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", @@ -335,9 +335,9 @@ } }, "node_modules/@code0-tech/pictor": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@code0-tech/pictor/-/pictor-0.7.1.tgz", - "integrity": "sha512-+ikLjqVZjAdFjHnkH8KV38KLHJpVzWLQqQiBJkSCcTscd/Zt8KenS0bAabV/HPO9Vd1XV2ATJOpRuHghVVFHTg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@code0-tech/pictor/-/pictor-0.7.2.tgz", + "integrity": "sha512-M5YNs5IMUpMLfGpPERoDzFt2vdcNYRsWpkPWP8XH+A3zRVRk00ee7t+/JJICJyvSg/sabPLI4EITXNxRtNhi0Q==", "peerDependencies": { "@codemirror/autocomplete": "^6.20.0", "@codemirror/lang-json": "^6.0.2", diff --git a/package.json b/package.json index 1fd9b4a5..40a1d405 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ }, "dependencies": { "@apollo/client": "^4.0.9", - "@code0-tech/pictor": "^0.7.1", + "@code0-tech/pictor": "^0.7.2", "@code0-tech/triangulum": "^0.14.3", "@codemirror/lang-javascript": "^6.2.5", "@codemirror/lint": "^6.9.5", From 1ad603e7578cf0072c5a96b2ff456bde683cdf40 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 16:25:31 +0200 Subject: [PATCH 86/88] feat: update DataTypeTypeEditorInputProps to extend EditorProps for improved type handling --- .../components/inputs/datatype/DataTypeTypeEditorInput.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeEditorInput.tsx b/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeEditorInput.tsx index 84718324..8324b125 100644 --- a/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeEditorInput.tsx +++ b/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeEditorInput.tsx @@ -1,12 +1,12 @@ import React, {useCallback, useMemo} from "react"; import {tags as t} from "@lezer/highlight"; import {Badge, hashToColor, useService, useStore} from "@code0-tech/pictor"; -import {Editor, EditorInputProps, EditorTokenHighlights} from "@code0-tech/pictor/dist/components/editor/Editor"; +import {Editor, EditorProps, EditorTokenHighlights} from "@code0-tech/pictor/dist/components/editor/Editor"; import {StreamLanguage} from "@codemirror/language"; import {CompletionContext, CompletionResult} from "@codemirror/autocomplete"; import {DatatypeService} from "@edition/datatype/services/Datatype.service"; -export interface DataTypeTypeEditorInputProps extends EditorInputProps { +export interface DataTypeTypeEditorInputProps extends EditorProps { value: string | null isTechnicalType?: boolean } From 94d7190c250d82cdcd3dd33d2afc44d5fe0a927e Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 16:33:19 +0200 Subject: [PATCH 87/88] feat: add optional chaining to formValidation.setValue calls for safer value handling --- .../components/inputs/datatype/DataTypeTypeInputComponent.tsx | 2 +- .../components/inputs/json/DataTypeJSONInputComponent.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeInputComponent.tsx index 61cd999e..fa873099 100644 --- a/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/datatype/DataTypeTypeInputComponent.tsx @@ -53,7 +53,7 @@ export const DataTypeTypeInputComponent: React.FC { - formValidation?.setValue(type) + formValidation?.setValue?.(type) const timeout = setTimeout(() => { // @ts-ignore onChange?.() diff --git a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx index d99534e4..17e49239 100644 --- a/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx +++ b/src/packages/ce/src/datatype/components/inputs/json/DataTypeJSONInputComponent.tsx @@ -68,7 +68,7 @@ export const DataTypeJSONInputComponent: React.FC setEditDialogOpen(open)} onObjectChange={v => { - formValidation?.setValue(v) + formValidation?.setValue?.(v) setValue(v ?? null) // @ts-ignore onChange?.() @@ -84,7 +84,7 @@ export const DataTypeJSONInputComponent: React.FC { - formValidation?.setValue(suggestion.value) + formValidation?.setValue?.(suggestion.value) setValue(suggestion.value) // @ts-ignore onChange?.() From f3c6833ad66edcc500a99c7ddebdacc53a057428 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Thu, 7 May 2026 16:46:12 +0200 Subject: [PATCH 88/88] feat: add optional chaining to formValidation.setValue calls for safer value handling --- .../src/function/hooks/FunctionValueSuggestions.worker.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/packages/ce/src/function/hooks/FunctionValueSuggestions.worker.ts diff --git a/src/packages/ce/src/function/hooks/FunctionValueSuggestions.worker.ts b/src/packages/ce/src/function/hooks/FunctionValueSuggestions.worker.ts deleted file mode 100644 index 38a1cb58..00000000 --- a/src/packages/ce/src/function/hooks/FunctionValueSuggestions.worker.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {getValueSuggestions} from "@code0-tech/triangulum"; -import {DataType} from "@code0-tech/sagittarius-graphql-types"; - -addEventListener("message", (event: MessageEvent<{ type?: string, dataTypes: DataType[] }>) => { - const suggestions = getValueSuggestions(event.data.type, event.data.dataTypes) - postMessage(suggestions); -}); -