refactor: update template api, handleonnewvalue and handlenodeclass hooks (#2628)

* Added Custom Component URL

* Added Post Template Value mutation

* Changed HandleOnNewValue hook to ParameterValue mutation

* refactored some states

* Added NumberInput component to replace input type=number. Added logic to maintain cursor at the same place when editing

* Refactored post-template-value to remove all logic

* Removed hooks from custom hook and removed mutation definition from parametercomponent

* Added mutate-template helper to call debounced mutation

* Changed handle new value to use the created function and update as requested.

* Removed pDebounce from imports

* Refactored FetchDataOnMount to only call mutateTemplate

* Refactored ParameterComponent to use the new MutateTemplate and the loading from the mutation

* removed handle refresh button

* Changed handleOnNewValue to change the value of any parameter of a template field

* Changed hooks to receive node instead of data, added HandleOnNewValue hook on tableNodeCellRender

* added SetNodeClass to update internal table state of EditNodeModal

* Removed other handle new value and node class, updated every component to use the same one

* Updated parameter component to use the same nodeclass hook

* FIxed hook to only assign value if code is present

* Fixed type attribution on useHandleNodeClass
This commit is contained in:
Lucas Oliveira 2024-07-19 13:12:19 -03:00 • committed by GitHub
commit b3c1b941b3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 965 additions and 436 deletions

View file

@ -8,6 +8,7 @@
"name": "langflow", "name": "langflow",
"version": "0.1.2", "version": "0.1.2",
"dependencies": { "dependencies": {
"@chakra-ui/number-input": "^2.1.2",
"@headlessui/react": "^2.0.4", "@headlessui/react": "^2.0.4",
"@hookform/resolvers": "^3.6.0", "@hookform/resolvers": "^3.6.0",
"@million/lint": "^1.0.0-rc.26", "@million/lint": "^1.0.0-rc.26",
@ -764,6 +765,293 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@chakra-ui/anatomy": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz",
"integrity": "sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg==",
"license": "MIT",
"peer": true
},
"node_modules/@chakra-ui/color-mode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz",
"integrity": "sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/react-use-safe-layout-effect": "2.1.0"
},
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/counter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.1.0.tgz",
"integrity": "sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw==",
"license": "MIT",
"dependencies": {
"@chakra-ui/number-utils": "2.0.7",
"@chakra-ui/react-use-callback-ref": "2.1.0",
"@chakra-ui/shared-utils": "2.0.5"
},
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/form-control": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.2.0.tgz",
"integrity": "sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw==",
"license": "MIT",
"dependencies": {
"@chakra-ui/icon": "3.2.0",
"@chakra-ui/react-context": "2.1.0",
"@chakra-ui/react-types": "2.0.7",
"@chakra-ui/react-use-merge-refs": "2.1.0",
"@chakra-ui/shared-utils": "2.0.5"
},
"peerDependencies": {
"@chakra-ui/system": ">=2.0.0",
"react": ">=18"
}
},
"node_modules/@chakra-ui/icon": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.2.0.tgz",
"integrity": "sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ==",
"license": "MIT",
"dependencies": {
"@chakra-ui/shared-utils": "2.0.5"
},
"peerDependencies": {
"@chakra-ui/system": ">=2.0.0",
"react": ">=18"
}
},
"node_modules/@chakra-ui/number-input": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.1.2.tgz",
"integrity": "sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA==",
"license": "MIT",
"dependencies": {
"@chakra-ui/counter": "2.1.0",
"@chakra-ui/form-control": "2.2.0",
"@chakra-ui/icon": "3.2.0",
"@chakra-ui/react-context": "2.1.0",
"@chakra-ui/react-types": "2.0.7",
"@chakra-ui/react-use-callback-ref": "2.1.0",
"@chakra-ui/react-use-event-listener": "2.1.0",
"@chakra-ui/react-use-interval": "2.1.0",
"@chakra-ui/react-use-merge-refs": "2.1.0",
"@chakra-ui/react-use-safe-layout-effect": "2.1.0",
"@chakra-ui/react-use-update-effect": "2.1.0",
"@chakra-ui/shared-utils": "2.0.5"
},
"peerDependencies": {
"@chakra-ui/system": ">=2.0.0",
"react": ">=18"
}
},
"node_modules/@chakra-ui/number-utils": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz",
"integrity": "sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg==",
"license": "MIT"
},
"node_modules/@chakra-ui/object-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz",
"integrity": "sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ==",
"license": "MIT",
"peer": true
},
"node_modules/@chakra-ui/react-context": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.1.0.tgz",
"integrity": "sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.7.tgz",
"integrity": "sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-callback-ref": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz",
"integrity": "sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-event-listener": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz",
"integrity": "sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q==",
"license": "MIT",
"dependencies": {
"@chakra-ui/react-use-callback-ref": "2.1.0"
},
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-interval": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz",
"integrity": "sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw==",
"license": "MIT",
"dependencies": {
"@chakra-ui/react-use-callback-ref": "2.1.0"
},
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-merge-refs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz",
"integrity": "sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-safe-layout-effect": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz",
"integrity": "sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-use-update-effect": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz",
"integrity": "sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA==",
"license": "MIT",
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/react-utils": {
"version": "2.0.12",
"resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz",
"integrity": "sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/utils": "2.0.15"
},
"peerDependencies": {
"react": ">=18"
}
},
"node_modules/@chakra-ui/shared-utils": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz",
"integrity": "sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q==",
"license": "MIT"
},
"node_modules/@chakra-ui/styled-system": {
"version": "2.9.2",
"resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz",
"integrity": "sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/shared-utils": "2.0.5",
"csstype": "^3.1.2",
"lodash.mergewith": "4.6.2"
}
},
"node_modules/@chakra-ui/system": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.6.2.tgz",
"integrity": "sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/color-mode": "2.2.0",
"@chakra-ui/object-utils": "2.1.0",
"@chakra-ui/react-utils": "2.0.12",
"@chakra-ui/styled-system": "2.9.2",
"@chakra-ui/theme-utils": "2.0.21",
"@chakra-ui/utils": "2.0.15",
"react-fast-compare": "3.2.2"
},
"peerDependencies": {
"@emotion/react": "^11.0.0",
"@emotion/styled": "^11.0.0",
"react": ">=18"
}
},
"node_modules/@chakra-ui/theme": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-3.3.1.tgz",
"integrity": "sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/anatomy": "2.2.2",
"@chakra-ui/shared-utils": "2.0.5",
"@chakra-ui/theme-tools": "2.1.2"
},
"peerDependencies": {
"@chakra-ui/styled-system": ">=2.8.0"
}
},
"node_modules/@chakra-ui/theme-tools": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz",
"integrity": "sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/anatomy": "2.2.2",
"@chakra-ui/shared-utils": "2.0.5",
"color2k": "^2.0.2"
},
"peerDependencies": {
"@chakra-ui/styled-system": ">=2.0.0"
}
},
"node_modules/@chakra-ui/theme-utils": {
"version": "2.0.21",
"resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz",
"integrity": "sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@chakra-ui/shared-utils": "2.0.5",
"@chakra-ui/styled-system": "2.9.2",
"@chakra-ui/theme": "3.3.1",
"lodash.mergewith": "4.6.2"
}
},
"node_modules/@chakra-ui/utils": {
"version": "2.0.15",
"resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.15.tgz",
"integrity": "sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash.mergewith": "4.6.7",
"css-box-model": "1.2.1",
"framesync": "6.1.2",
"lodash.mergewith": "4.6.2"
}
},
"node_modules/@clack/core": { "node_modules/@clack/core": {
"version": "0.3.4", "version": "0.3.4",
"resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz",
@ -798,6 +1086,195 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/@emotion/babel-plugin": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/serialize": "^1.1.2",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
"find-root": "^1.1.0",
"source-map": "^0.5.7",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@emotion/cache": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
"integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/memoize": "^0.8.1",
"@emotion/sheet": "^1.2.2",
"@emotion/utils": "^1.2.1",
"@emotion/weak-memoize": "^0.3.1",
"stylis": "4.2.0"
}
},
"node_modules/@emotion/hash": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/is-prop-valid": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
"integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/memoize": "^0.8.1"
}
},
"node_modules/@emotion/memoize": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/react": {
"version": "11.11.4",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
"integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/cache": "^11.11.0",
"@emotion/serialize": "^1.1.3",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@emotion/utils": "^1.2.1",
"@emotion/weak-memoize": "^0.3.1",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@emotion/serialize": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz",
"integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/hash": "^0.9.1",
"@emotion/memoize": "^0.8.1",
"@emotion/unitless": "^0.8.1",
"@emotion/utils": "^1.2.1",
"csstype": "^3.0.2"
}
},
"node_modules/@emotion/sheet": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/styled": {
"version": "11.11.5",
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.5.tgz",
"integrity": "sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/is-prop-valid": "^1.2.2",
"@emotion/serialize": "^1.1.4",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
"@emotion/utils": "^1.2.1"
},
"peerDependencies": {
"@emotion/react": "^11.0.0-rc.0",
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@emotion/unitless": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@emotion/utils": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==",
"license": "MIT",
"peer": true
},
"node_modules/@emotion/weak-memoize": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==",
"license": "MIT",
"peer": true
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5", "version": "0.21.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
@ -4997,8 +5474,17 @@
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.17.5", "version": "4.17.5",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz",
"integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==", "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw=="
"dev": true },
"node_modules/@types/lodash.mergewith": {
"version": "4.6.7",
"resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz",
"integrity": "sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash": "*"
}
}, },
"node_modules/@types/mathjax": { "node_modules/@types/mathjax": {
"version": "0.0.37", "version": "0.0.37",
@ -5027,6 +5513,13 @@
"undici-types": "~5.26.4" "undici-types": "~5.26.4"
} }
}, },
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
"license": "MIT",
"peer": true
},
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.12", "version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
@ -5388,6 +5881,49 @@
"proxy-from-env": "^1.1.0" "proxy-from-env": "^1.1.0"
} }
}, },
"node_modules/babel-plugin-macros": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
"resolve": "^1.19.0"
},
"engines": {
"node": ">=10",
"npm": ">=6"
}
},
"node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
"parse-json": "^5.0.0",
"path-type": "^4.0.0",
"yaml": "^1.10.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/babel-plugin-macros/node_modules/yaml": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/babel-plugin-syntax-hermes-parser": { "node_modules/babel-plugin-syntax-hermes-parser": {
"version": "0.21.1", "version": "0.21.1",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.21.1.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.21.1.tgz",
@ -6344,6 +6880,13 @@
"color-support": "bin.js" "color-support": "bin.js"
} }
}, },
"node_modules/color2k": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.3.tgz",
"integrity": "sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==",
"license": "MIT",
"peer": true
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -6447,6 +6990,16 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-box-model": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
"license": "MIT",
"peer": true,
"dependencies": {
"tiny-invariant": "^1.0.6"
}
},
"node_modules/css.escape": { "node_modules/css.escape": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
@ -7557,6 +8110,13 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
"license": "MIT",
"peer": true
},
"node_modules/find-up": { "node_modules/find-up": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
@ -7721,6 +8281,23 @@
} }
} }
}, },
"node_modules/framesync": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz",
"integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==",
"license": "MIT",
"peer": true,
"dependencies": {
"tslib": "2.4.0"
}
},
"node_modules/framesync/node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"license": "0BSD",
"peer": true
},
"node_modules/fs-extra": { "node_modules/fs-extra": {
"version": "11.2.0", "version": "11.2.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
@ -9226,6 +9803,13 @@
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true "dev": true
}, },
"node_modules/lodash.mergewith": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"license": "MIT",
"peer": true
},
"node_modules/lodash.template": { "node_modules/lodash.template": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
@ -12205,6 +12789,13 @@
"react": ">=16.13.1" "react": ">=16.13.1"
} }
}, },
"node_modules/react-fast-compare": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
"license": "MIT",
"peer": true
},
"node_modules/react-hook-form": { "node_modules/react-hook-form": {
"version": "7.52.0", "version": "7.52.0",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.0.tgz", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.0.tgz",
@ -13614,6 +14205,13 @@
"inline-style-parser": "0.1.1" "inline-style-parser": "0.1.1"
} }
}, },
"node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
"license": "MIT",
"peer": true
},
"node_modules/sucrase": { "node_modules/sucrase": {
"version": "3.35.0", "version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",

View file

@ -3,6 +3,7 @@
"version": "0.1.2", "version": "0.1.2",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@chakra-ui/number-input": "^2.1.2",
"@headlessui/react": "^2.0.4", "@headlessui/react": "^2.0.4",
"@hookform/resolvers": "^3.6.0", "@hookform/resolvers": "^3.6.0",
"@million/lint": "^1.0.0-rc.26", "@million/lint": "^1.0.0-rc.26",

View file

@ -1,3 +1,7 @@
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import useAlertStore from "@/stores/alertStore";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { ReactNode, useEffect, useRef, useState } from "react"; import { ReactNode, useEffect, useRef, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook"; import { useHotkeys } from "react-hotkeys-hook";
@ -27,10 +31,6 @@ import { useShortcutsStore } from "../../../../stores/shortcuts";
import { useTypesStore } from "../../../../stores/typesStore"; import { useTypesStore } from "../../../../stores/typesStore";
import { APIClassType } from "../../../../types/api"; import { APIClassType } from "../../../../types/api";
import { ParameterComponentType } from "../../../../types/components"; import { ParameterComponentType } from "../../../../types/components";
import {
debouncedHandleUpdateValues,
handleUpdateValues,
} from "../../../../utils/parameterUtils";
import { import {
convertObjToArray, convertObjToArray,
convertValuesToNumbers, convertValuesToNumbers,
@ -48,8 +48,6 @@ import {
} from "../../../../utils/utils"; } from "../../../../utils/utils";
import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount"; import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount";
import useHandleOnNewValue from "../../../hooks/use-handle-new-value"; import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
import useHandleNodeClass from "../../../hooks/use-handle-node-class";
import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons";
import OutputComponent from "../OutputComponent"; import OutputComponent from "../OutputComponent";
import HandleRenderComponent from "../handleRenderComponent"; import HandleRenderComponent from "../handleRenderComponent";
import OutputModal from "../outputModal"; import OutputModal from "../outputModal";
@ -81,7 +79,12 @@ export default function ParameterComponent({
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
const myData = useTypesStore((state) => state.data); const myData = useTypesStore((state) => state.data);
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const [isLoading, setIsLoading] = useState(false); const postTemplateValue = usePostTemplateValue({
node: data.node!,
nodeId: data.id,
parameterId: name,
});
const isLoading = postTemplateValue.isPending;
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const setFilterEdge = useFlowStore((state) => state.setFilterEdge);
@ -131,29 +134,25 @@ export default function ParameterComponent({
} }
} }
const setErrorData = useAlertStore((state) => state.setErrorData);
const output = useShortcutsStore((state) => state.output); const output = useShortcutsStore((state) => state.output);
useHotkeys(output, handleOutputWShortcut, { preventDefault }); useHotkeys(output, handleOutputWShortcut, { preventDefault });
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
data,
name,
takeSnapshot,
handleUpdateValues,
debouncedHandleUpdateValues,
setNode,
setIsLoading,
);
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass( const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
data,
name,
takeSnapshot, takeSnapshot,
setNode, setNode,
updateNodeInternals, data.id,
); );
const { handleRefreshButtonPress: handleRefreshButtonPressHook } = const handleRefreshButtonPress = () =>
useHandleRefreshButtonPress(setIsLoading, setNode); mutateTemplate(
data.node?.template[name]?.value,
data.node!,
handleNodeClass,
postTemplateValue,
setErrorData,
);
let disabled = let disabled =
edges.some( edges.some(
@ -167,18 +166,24 @@ export default function ParameterComponent({
edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id), edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
) ?? false; ) ?? false;
const handleRefreshButtonPress = async (name, data) => { const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue({
handleRefreshButtonPressHook(name, data); node: data.node!,
}; nodeId: data.id,
name,
});
useFetchDataOnMount(data, name, handleUpdateValues, setNode, setIsLoading); const handleOnNewValue = (
value: any,
const handleOnNewValue = async (
newValue: string | string[] | boolean | Object[],
dbValue?: boolean, dbValue?: boolean,
skipSnapshot: boolean | undefined = false, skipSnapshot?: boolean,
): Promise<void> => { ) => {
handleOnNewValueHook(newValue, dbValue, skipSnapshot); handleOnNewValueHook(
{
value,
load_from_db: dbValue,
},
{ skipSnapshot },
);
}; };
const handleNodeClass = ( const handleNodeClass = (
@ -186,9 +191,11 @@ export default function ParameterComponent({
code?: string, code?: string,
type?: string, type?: string,
): void => { ): void => {
handleNodeClassHook(newNodeClass, code, type); handleNodeClassHook(newNodeClass, name, code, type);
}; };
useFetchDataOnMount(data.node!, handleNodeClass, name, postTemplateValue);
useEffect(() => { useEffect(() => {
// @ts-ignore // @ts-ignore
infoHtml.current = ( infoHtml.current = (
@ -614,7 +621,7 @@ export default function ParameterComponent({
<Case condition={left === true && type === "int"}> <Case condition={left === true && type === "int"}>
<div className="mt-2 w-full"> <div className="mt-2 w-full">
<IntComponent <IntComponent
rangeSpec={data.node?.template[name]?.rangeSpec} rangeSpec={data.node?.template[name]?.range_spec}
disabled={disabled} disabled={disabled}
value={data.node?.template[name]?.value ?? ""} value={data.node?.template[name]?.value ?? ""}
onChange={handleOnNewValue} onChange={handleOnNewValue}

View file

@ -0,0 +1,44 @@
import {
ERROR_UPDATING_COMPONENT,
SAVE_DEBOUNCE_TIME,
TITLE_ERROR_UPDATING_COMPONENT,
} from "@/constants/constants";
import {
APIClassType,
APITemplateType,
ResponseErrorDetailAPI,
} from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { cloneDeep, debounce } from "lodash";
export const mutateTemplate = debounce(
async (
newValue,
node: APIClassType,
setNodeClass,
postTemplateValue: UseMutationResult<
APITemplateType | undefined,
ResponseErrorDetailAPI,
any
>,
setErrorData,
) => {
try {
const newNode = cloneDeep(node);
const newTemplate = await postTemplateValue.mutateAsync({
value: newValue,
});
if (newTemplate) {
newNode.template = newTemplate;
}
setNodeClass(newNode);
} catch (e) {
const error = e as ResponseErrorDetailAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [error.response?.data?.detail || ERROR_UPDATING_COMPONENT],
});
}
},
SAVE_DEBOUNCE_TIME,
);

View file

@ -1,55 +1,40 @@
import { cloneDeep } from "lodash";
import { useEffect } from "react";
import { import {
ERROR_UPDATING_COMPONENT, APIClassType,
TITLE_ERROR_UPDATING_COMPONENT, APITemplateType,
} from "../../constants/constants"; ResponseErrorDetailAPI,
} from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { useEffect } from "react";
import useAlertStore from "../../stores/alertStore"; import useAlertStore from "../../stores/alertStore";
import { ResponseErrorDetailAPI } from "../../types/api"; import { mutateTemplate } from "../helpers/mutate-template";
import { NodeDataType } from "../../types/flow";
const useFetchDataOnMount = ( const useFetchDataOnMount = (
data: NodeDataType, node: APIClassType,
setNodeClass: (node: APIClassType) => void,
name: string, name: string,
handleUpdateValues: (name: string, data: NodeDataType) => Promise<any>, postTemplateValue: UseMutationResult<
setNode: (id: string, callback: (oldNode: any) => any) => void, APITemplateType | undefined,
setIsLoading: (value: boolean) => void, ResponseErrorDetailAPI,
any
>,
) => { ) => {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
useEffect(() => { useEffect(() => {
async function fetchData() { async function fetchData() {
const template = node.template[name];
if ( if (
(data.node?.template[name]?.real_time_refresh || (template?.real_time_refresh || template?.refresh_button) &&
data.node?.template[name]?.refresh_button) &&
// options can be undefined but not an empty array // options can be undefined but not an empty array
(data.node?.template[name]?.options?.length ?? 0) === 0 (template?.options?.length ?? 0) === 0
) { ) {
setIsLoading(true); mutateTemplate(
try { template?.value,
let newTemplate = await handleUpdateValues(name, data); node,
setNodeClass,
if (newTemplate) { postTemplateValue,
setNode(data.id, (oldNode) => { setErrorData,
let newNode = cloneDeep(oldNode); );
newNode.data = {
...newNode.data,
};
newNode.data.node.template = newTemplate;
return newNode;
});
}
} catch (error) {
let responseError = error as ResponseErrorDetailAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [
responseError?.response?.data?.detail ?? ERROR_UPDATING_COMPONENT,
],
});
}
setIsLoading(false);
} }
} }
fetchData(); fetchData();

View file

@ -1,79 +1,91 @@
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
import useAlertStore from "@/stores/alertStore";
import useFlowStore from "@/stores/flowStore";
import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { APIClassType, InputFieldType } from "@/types/api";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { import { mutateTemplate } from "../helpers/mutate-template";
ERROR_UPDATING_COMPONENT, const useHandleOnNewValue = ({
TITLE_ERROR_UPDATING_COMPONENT, node,
} from "../../constants/constants"; nodeId,
import useAlertStore from "../../stores/alertStore"; name,
import { ResponseErrorTypeAPI } from "../../types/api"; }: {
import { NodeDataType } from "../../types/flow"; node: APIClassType;
nodeId: string;
name: string;
}) => {
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const setNode = useFlowStore((state) => state.setNode);
const useHandleOnNewValue = (
data: NodeDataType,
name: string,
takeSnapshot: () => void,
handleUpdateValues: (name: string, data: NodeDataType) => Promise<any>,
debouncedHandleUpdateValues: any,
setNode: (id: string, callback: (oldNode: any) => any) => void,
setIsLoading: (value: boolean) => void,
) => {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const handleOnNewValue = async (newValue, dbValue, skipSnapshot = false) => { const postTemplateValue = usePostTemplateValue({
const nodeTemplate = data.node!.template[name]; parameterId: name,
const currentValue = nodeTemplate.value; nodeId: nodeId,
node: node,
});
if (currentValue !== newValue && !skipSnapshot) { const handleOnNewValue = async (
takeSnapshot(); changes: Partial<InputFieldType>,
options?: {
skipSnapshot?: boolean;
setNodeClass?: (node: APIClassType) => void;
},
) => {
const newNode = cloneDeep(node);
const template = newNode.template;
if (!template) {
setErrorData({ title: "Template not found in the component" });
return;
} }
const parameter = template[name];
if (!parameter) {
setErrorData({ title: "Parameter not found in the template" });
return;
}
if (!options?.skipSnapshot) takeSnapshot();
Object.entries(changes).forEach(([key, value]) => {
parameter[key] = value;
});
const shouldUpdate = const shouldUpdate =
data.node?.template[name].real_time_refresh && parameter.real_time_refresh && !parameter.refresh_button;
!data.node?.template[name].refresh_button &&
currentValue !== newValue;
const typeToDebounce = nodeTemplate.type; const setNodeClass = (newNodeClass: APIClassType) => {
options?.setNodeClass && options.setNodeClass(newNodeClass);
nodeTemplate.value = newValue; setNode(nodeId, (oldNode) => {
const newData = cloneDeep(oldNode.data);
let newTemplate; newData.node = newNodeClass;
if (shouldUpdate) { return {
setIsLoading(true); ...oldNode,
try { data: newData,
if (["int"].includes(typeToDebounce)) { };
newTemplate = await handleUpdateValues(name, data);
} else {
newTemplate = await debouncedHandleUpdateValues(name, data);
}
} catch (error) {
let responseError = error as ResponseErrorTypeAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [
responseError?.response?.data?.detail.error ??
ERROR_UPDATING_COMPONENT,
],
}); });
}
setIsLoading(false);
}
setNode(data.id, (oldNode) => {
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
}; };
if (dbValue !== undefined) { if (shouldUpdate && changes.value) {
newNode.data.node.template[name].load_from_db = dbValue; mutateTemplate(
changes.value,
newNode,
setNodeClass,
postTemplateValue,
setErrorData,
);
} }
if (data.node?.template[name].real_time_refresh && newTemplate) { setNode(nodeId, (oldNode) => {
newNode.data.node.template = newTemplate; const newData = cloneDeep(oldNode.data);
} else { newData.node = newNode;
newNode.data.node.template[name].value = newValue; return {
} ...oldNode,
data: newData,
return newNode; };
}); });
}; };

View file

@ -1,37 +1,31 @@
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { NodeDataType } from "../../types/flow";
const useHandleNodeClass = ( const useHandleNodeClass = (
data: NodeDataType,
name: string,
takeSnapshot: () => void, takeSnapshot: () => void,
setNode: (id: string, callback: (oldNode: any) => any) => void, setNode: (id: string, callback: (oldNode: any) => any) => void,
updateNodeInternals: (id: string) => void, nodeId: string,
) => { ) => {
const handleNodeClass = (newNodeClass, code, type?: string) => { const handleNodeClass = (newNodeClass, name, code, type?: string) => {
if (!data.node) return; if (code) {
if (data.node!.template[name].value !== code) {
takeSnapshot(); takeSnapshot();
} }
setNode(data.id, (oldNode) => { setNode(nodeId, (oldNode) => {
let newNode = cloneDeep(oldNode); let newNode = cloneDeep(oldNode);
newNode.data = { newNode.data = {
...newNode.data, ...newNode.data,
node: newNodeClass, node: cloneDeep(newNodeClass),
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
}; };
if (type) { if (type) {
newNode.data.type = type; newNode.data.type = type;
} }
if (code) {
newNode.data.node.template[name].value = code; newNode.data.node.template[name].value = code;
}
return newNode; return newNode;
}); });
updateNodeInternals(data.id);
}; };
return { handleNodeClass }; return { handleNodeClass };

View file

@ -1,47 +0,0 @@
import { cloneDeep } from "lodash";
import {
ERROR_UPDATING_COMPONENT,
TITLE_ERROR_UPDATING_COMPONENT,
} from "../../constants/constants";
import useAlertStore from "../../stores/alertStore";
import { ResponseErrorDetailAPI } from "../../types/api";
import { handleUpdateValues } from "../../utils/parameterUtils";
const useHandleRefreshButtonPress = (
setIsLoading: (value: boolean) => void,
setNode: (id: string, callback: (oldNode: any) => any) => void,
) => {
const setErrorData = useAlertStore((state) => state.setErrorData);
const handleRefreshButtonPress = async (name, data) => {
setIsLoading(true);
try {
let newTemplate = await handleUpdateValues(name, data);
if (newTemplate) {
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
};
newNode.data.node.template = newTemplate;
return newNode;
});
}
} catch (error) {
let responseError = error as ResponseErrorDetailAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [
responseError?.response?.data?.detail ?? ERROR_UPDATING_COMPONENT,
],
});
}
setIsLoading(false);
};
return { handleRefreshButtonPress };
};
export default useHandleRefreshButtonPress;

View file

@ -1,4 +1,12 @@
import { useEffect } from "react"; import { cn } from "@/utils/utils";
import {
NumberDecrementStepper,
NumberIncrementStepper,
NumberInput,
NumberInputField,
NumberInputStepper,
} from "@chakra-ui/number-input";
import { useEffect, useRef, useState } from "react";
import { IntComponentType } from "../../types/components"; import { IntComponentType } from "../../types/components";
import { import {
handleKeyDown, handleKeyDown,
@ -23,32 +31,54 @@ export default function IntComponent({
} }
}, [disabled, onChange]); }, [disabled, onChange]);
const [cursor, setCursor] = useState<number | null>(null);
const ref = useRef<HTMLInputElement>(null);
useEffect(() => {
ref.current?.setSelectionRange(cursor, cursor);
}, [ref, cursor, value]);
const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
setCursor(e.target.selectionStart);
onChange(e.target.value);
};
return ( return (
<div className="w-full"> <div className="w-full">
<Input <NumberInput
id={id} id={id}
onKeyDown={(event) => {
handleOnlyIntegerInput(event);
handleKeyDown(event, value, "");
}}
type="number"
step={rangeSpec?.step ?? 1} step={rangeSpec?.step ?? 1}
min={rangeSpec?.min ?? min} min={rangeSpec?.min ?? min}
max={rangeSpec?.max ?? undefined} max={rangeSpec?.max ?? undefined}
onChange={(value) => {
onChange(value);
}}
value={value ?? ""}
>
<NumberInputField
className={cn(
editNode ? "input-edit-node" : "",
"nopan nodelete nodrag noflow primary-input",
)}
onChange={handleChangeInput}
onKeyDown={(event) => {
handleKeyDown(event, value, "");
}}
onInput={(event: React.ChangeEvent<HTMLInputElement>) => { onInput={(event: React.ChangeEvent<HTMLInputElement>) => {
if (Number(event.target.value) < min) { if (Number(event.target.value) < min) {
event.target.value = min.toString(); event.target.value = min.toString();
} }
}} }}
value={value ?? ""}
className={editNode ? "input-edit-node" : ""}
disabled={disabled} disabled={disabled}
placeholder={editNode ? "Integer number" : "Type an integer number"} placeholder={editNode ? "Integer number" : "Type an integer number"}
onChange={(event) => {
onChange(event.target.value);
}}
data-testid={id} data-testid={id}
ref={ref}
/> />
<NumberInputStepper paddingRight={10}>
<NumberIncrementStepper fontSize={8} marginTop={6} />
<NumberDecrementStepper fontSize={8} marginBottom={6} />
</NumberInputStepper>
</NumberInput>
</div> </div>
); );
} }

View file

@ -51,7 +51,7 @@ export function renderStrType({
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
options={templateData.options || []} options={templateData.options || []}
value={templateValue ?? "Choose an option"} values={[templateValue ?? "Choose an option"]}
id={"multiselect-" + templateData.name} id={"multiselect-" + templateData.name}
onValueChange={(value) => handleOnNewValue(value, templateData.key)} onValueChange={(value) => handleOnNewValue(value, templateData.key)}
/> />

View file

@ -1,3 +1,4 @@
import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value";
import { CustomCellRendererProps } from "ag-grid-react"; import { CustomCellRendererProps } from "ag-grid-react";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { useState } from "react"; import { useState } from "react";
@ -12,39 +13,18 @@ import {
import { classNames } from "../../../../utils/utils"; import { classNames } from "../../../../utils/utils";
import CodeAreaComponent from "../../../codeAreaComponent"; import CodeAreaComponent from "../../../codeAreaComponent";
import DictComponent from "../../../dictComponent"; import DictComponent from "../../../dictComponent";
import Dropdown from "../../../dropdownComponent";
import FloatComponent from "../../../floatComponent"; import FloatComponent from "../../../floatComponent";
import InputFileComponent from "../../../inputFileComponent"; import InputFileComponent from "../../../inputFileComponent";
import InputGlobalComponent from "../../../inputGlobalComponent";
import InputListComponent from "../../../inputListComponent";
import IntComponent from "../../../intComponent"; import IntComponent from "../../../intComponent";
import KeypairListComponent from "../../../keypairListComponent"; import KeypairListComponent from "../../../keypairListComponent";
import PromptAreaComponent from "../../../promptComponent"; import PromptAreaComponent from "../../../promptComponent";
import TextAreaComponent from "../../../textAreaComponent";
import ToggleShadComponent from "../../../toggleShadComponent"; import ToggleShadComponent from "../../../toggleShadComponent";
import { renderStrType } from "./cellTypeStr"; import { renderStrType } from "./cellTypeStr";
export default function TableNodeCellRender({ export default function TableNodeCellRender({
node: { data }, node: { data },
value: { value: { value, nodeId, nodeClass, handleNodeClass },
value,
nodeClass,
handleOnNewValue: handleOnNewValueNode,
handleNodeClass,
},
}: CustomCellRendererProps) { }: CustomCellRendererProps) {
const handleOnNewValue = (newValue: any, name: string, dbValue?: boolean) => {
handleOnNewValueNode(newValue, name, dbValue);
setTemplateData((old) => {
let newData = cloneDeep(old);
newData.value = newValue;
if (dbValue !== undefined) {
newData.load_from_db = newValue;
}
return newData;
});
setTemplateValue(newValue);
};
const setNodeClass = (value: APIClassType, code?: string, type?: string) => { const setNodeClass = (value: APIClassType, code?: string, type?: string) => {
handleNodeClass(value, templateData.key, code, type); handleNodeClass(value, templateData.key, code, type);
}; };
@ -54,6 +34,34 @@ export default function TableNodeCellRender({
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue({
node: nodeClass,
nodeId: nodeId,
name: data.key,
});
const handleOnNewValue = (
value: any,
dbValue?: boolean,
skipSnapshot?: boolean,
) => {
handleOnNewValueHook(
{
value,
load_from_db: dbValue,
},
{ skipSnapshot, setNodeClass },
);
setTemplateData((old) => {
let newData = cloneDeep(old);
newData.value = value;
if (dbValue !== undefined) {
newData.load_from_db = value;
}
return newData;
});
setTemplateValue(value);
};
const id = { const id = {
inputTypes: templateData.input_types, inputTypes: templateData.input_types,
type: templateData.type, type: templateData.type,

View file

@ -13,6 +13,7 @@ export const URLs = {
AUTOLOGIN: "auto_login", AUTOLOGIN: "auto_login",
REFRESH: "refresh", REFRESH: "refresh",
BUILD: `build`, BUILD: `build`,
CUSTOM_COMPONENT: `custom_component`,
} as const; } as const;
export function getURL(key: keyof typeof URLs, params: any = {}) { export function getURL(key: keyof typeof URLs, params: any = {}) {

View file

@ -0,0 +1,61 @@
import {
APIClassType,
APITemplateType,
ResponseErrorDetailAPI,
useMutationFunctionType,
} from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface IPostTemplateValue {
value: any;
}
interface IPostTemplateValueParams {
node: APIClassType;
nodeId: string;
parameterId: string;
}
export const usePostTemplateValue: useMutationFunctionType<
IPostTemplateValueParams,
IPostTemplateValue,
APITemplateType | undefined,
ResponseErrorDetailAPI
> = ({ parameterId, nodeId, node }, options?) => {
const { mutate } = UseRequestProcessor();
const postTemplateValueFn = async (
payload: IPostTemplateValue,
): Promise<APITemplateType | undefined> => {
const template = node.template;
if (!template) return;
const response = await api.post<APIClassType>(
getURL("CUSTOM_COMPONENT", { update: "update" }),
{
code: template.code.value,
template: template,
field: parameterId,
field_value: payload.value,
},
);
return response.data.template;
};
const mutation: UseMutationResult<
APITemplateType | undefined,
ResponseErrorDetailAPI,
IPostTemplateValue
> = mutate(
["usePostTemplateValue", { parameterId, nodeId }],
postTemplateValueFn,
options,
);
return mutation;
};

View file

@ -1,19 +1,18 @@
import { ColDef, ValueGetterParams } from "ag-grid-community"; import { ColDef, ValueGetterParams } from "ag-grid-community";
import { useMemo, useState } from "react"; import { useMemo } from "react";
import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender"; import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender";
import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender"; import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender";
import { APIClassType } from "../../../types/api"; import { APIClassType } from "../../../types/api";
import { NodeDataType } from "../../../types/flow";
const useColumnDefs = ( const useColumnDefs = (
nodeClass: APIClassType, nodeClass: APIClassType,
handleOnNewValue: (newValue: any, name: string, setDb?: boolean) => void,
handleNodeClass: ( handleNodeClass: (
newNodeClass: APIClassType, newNodeClass: APIClassType,
name: string, name: string,
code: string, code: string,
type?: string, type?: string,
) => void, ) => void,
nodeId: string,
changeAdvanced: (n: string) => void, changeAdvanced: (n: string) => void,
open: boolean, open: boolean,
) => { ) => {
@ -53,8 +52,8 @@ const useColumnDefs = (
valueGetter: (params: ValueGetterParams) => { valueGetter: (params: ValueGetterParams) => {
return { return {
value: params.data.value, value: params.data.value,
nodeId: nodeId,
nodeClass: nodeClass, nodeClass: nodeClass,
handleOnNewValue: handleOnNewValue,
handleNodeClass: handleNodeClass, handleNodeClass: handleNodeClass,
}; };
}, },

View file

@ -1,84 +0,0 @@
import { cloneDeep } from "lodash";
import {
ERROR_UPDATING_COMPONENT,
TITLE_ERROR_UPDATING_COMPONENT,
} from "../../../constants/constants";
import useAlertStore from "../../../stores/alertStore";
import { ResponseErrorTypeAPI } from "../../../types/api";
import { NodeDataType } from "../../../types/flow";
const useHandleOnNewValue = (
data: NodeDataType,
takeSnapshot: () => void,
handleUpdateValues: (name: string, data: NodeDataType) => Promise<any>,
debouncedHandleUpdateValues: any,
setNode: (id: string, callback: (oldNode: any) => any) => void,
) => {
const setErrorData = useAlertStore((state) => state.setErrorData);
const handleOnNewValue = async (
newValue,
name,
dbValue,
skipSnapshot = false,
) => {
const nodeTemplate = data.node!.template[name];
const currentValue = nodeTemplate.value;
if (currentValue !== newValue && !skipSnapshot) {
takeSnapshot();
}
const shouldUpdate =
data.node?.template[name].real_time_refresh &&
!data.node?.template[name].refresh_button &&
currentValue !== newValue;
const typeToDebounce = nodeTemplate.type;
nodeTemplate.value = newValue;
let newTemplate;
if (shouldUpdate) {
try {
if (["int"].includes(typeToDebounce)) {
newTemplate = await handleUpdateValues(name, data);
} else {
newTemplate = await debouncedHandleUpdateValues(name, data);
}
} catch (error) {
let responseError = error as ResponseErrorTypeAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [
responseError?.response?.data?.detail.error ??
ERROR_UPDATING_COMPONENT,
],
});
}
}
setNode(data.id, (oldNode) => {
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
};
if (dbValue !== undefined) {
newNode.data.node.template[name].load_from_db = dbValue;
}
if (data.node?.template[name].real_time_refresh && newTemplate) {
newNode.data.node.template = newTemplate;
} else {
newNode.data.node.template[name].value = newValue;
}
return newNode;
});
};
return { handleOnNewValue };
};
export default useHandleOnNewValue;

View file

@ -1,39 +0,0 @@
import { cloneDeep } from "lodash";
import { NodeDataType } from "../../../types/flow";
const useHandleNodeClass = (
data: NodeDataType,
takeSnapshot: () => void,
setNode: (id: string, callback: (oldNode: any) => any) => void,
updateNodeInternals: (id: string) => void,
) => {
const handleNodeClass = (newNodeClass, name, code, type?: string) => {
if (!data.node) return;
if (data.node!.template[name].value !== code) {
takeSnapshot();
}
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: newNodeClass,
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
};
if (type) {
newNode.data.node.template[name].type = type;
}
newNode.data.node.template[name].value = code;
return newNode;
});
updateNodeInternals(data.id);
};
return { handleNodeClass };
};
export default useHandleNodeClass;

View file

@ -1,6 +1,7 @@
import { ColDef } from "ag-grid-community"; import { ColDef } from "ag-grid-community";
import { forwardRef, useState } from "react"; import { forwardRef, useState } from "react";
import { useUpdateNodeInternals } from "reactflow"; import { useUpdateNodeInternals } from "reactflow";
import useHandleNodeClass from "../../CustomNodes/hooks/use-handle-node-class";
import TableComponent from "../../components/tableComponent"; import TableComponent from "../../components/tableComponent";
import { Badge } from "../../components/ui/badge"; import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
@ -9,15 +10,9 @@ import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { APIClassType } from "../../types/api"; import { APIClassType } from "../../types/api";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import {
debouncedHandleUpdateValues,
handleUpdateValues,
} from "../../utils/parameterUtils";
import BaseModal from "../baseModal"; import BaseModal from "../baseModal";
import useColumnDefs from "./hooks/use-column-defs"; import useColumnDefs from "./hooks/use-column-defs";
import useHandleChangeAdvanced from "./hooks/use-handle-change-advanced"; import useHandleChangeAdvanced from "./hooks/use-handle-change-advanced";
import useHandleOnNewValue from "./hooks/use-handle-new-value";
import useHandleNodeClass from "./hooks/use-handle-node-class";
import useRowData from "./hooks/use-row-data"; import useRowData from "./hooks/use-row-data";
const EditNodeModal = forwardRef( const EditNodeModal = forwardRef(
@ -40,19 +35,10 @@ const EditNodeModal = forwardRef(
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const updateNodeInternals = useUpdateNodeInternals(); const updateNodeInternals = useUpdateNodeInternals();
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
data,
takeSnapshot,
handleUpdateValues,
debouncedHandleUpdateValues,
setNode,
);
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass( const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
data,
takeSnapshot, takeSnapshot,
setNode, setNode,
updateNodeInternals, data.id,
); );
const [nodeClass, setNodeClass] = useState<APIClassType>(data.node!); const [nodeClass, setNodeClass] = useState<APIClassType>(data.node!);
@ -74,8 +60,8 @@ const EditNodeModal = forwardRef(
const columnDefs: ColDef[] = useColumnDefs( const columnDefs: ColDef[] = useColumnDefs(
nodeClass, nodeClass,
handleOnNewValueHook,
handleNodeClass, handleNodeClass,
data.id,
handleChangeAdvancedHook, handleChangeAdvancedHook,
open, open,
); );

View file

@ -1,4 +1,7 @@
import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value";
import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class";
import { usePostRetrieveVertexOrder } from "@/controllers/API/queries/vertex"; import { usePostRetrieveVertexOrder } from "@/controllers/API/queries/vertex";
import { APIClassType } from "@/types/api";
import _, { cloneDeep } from "lodash"; import _, { cloneDeep } from "lodash";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook"; import { useHotkeys } from "react-hotkeys-hook";
@ -22,7 +25,6 @@ import useFlowStore from "../../../../stores/flowStore";
import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore";
import { useShortcutsStore } from "../../../../stores/shortcuts"; import { useShortcutsStore } from "../../../../stores/shortcuts";
import { useStoreStore } from "../../../../stores/storeStore"; import { useStoreStore } from "../../../../stores/storeStore";
import { APIClassType } from "../../../../types/api";
import { nodeToolbarPropsType } from "../../../../types/components"; import { nodeToolbarPropsType } from "../../../../types/components";
import { FlowType } from "../../../../types/flow"; import { FlowType } from "../../../../types/flow";
import { import {
@ -31,7 +33,7 @@ import {
expandGroupNode, expandGroupNode,
updateFlowPosition, updateFlowPosition,
} from "../../../../utils/reactflowUtils"; } from "../../../../utils/reactflowUtils";
import { classNames, cn, isThereModal } from "../../../../utils/utils"; import { classNames, cn } from "../../../../utils/utils";
import isWrappedWithClass from "../PageComponent/utils/is-wrapped-with-class"; import isWrappedWithClass from "../PageComponent/utils/is-wrapped-with-class";
import ToolbarSelectItem from "./toolbarSelectItem"; import ToolbarSelectItem from "./toolbarSelectItem";
@ -384,57 +386,28 @@ export default function NodeToolbarComponent({
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
const handleOnNewValue = ( const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue({
newValue: string | string[] | boolean | Object[], node: data.node!,
): void => { nodeId: data.id,
if (data.node!.template[name].value !== newValue) { name,
takeSnapshot();
}
data.node!.template[name].value = newValue; // necessary to enable ctrl+z inside the input
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
};
newNode.data.node.template[name].value = newValue;
return newNode;
}); });
const handleOnNewValue = (value: string | string[]) => {
handleOnNewValueHook({ value });
}; };
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
takeSnapshot,
setNode,
data.id,
);
const handleNodeClass = ( const handleNodeClass = (
newNodeClass: APIClassType, newNodeClass: APIClassType,
code?: string, code: string,
type?: string, type: string,
): void => { ) => {
if (!data.node) return; handleNodeClassHook(newNodeClass, name, code, type);
if (data.node!.template[name].value !== code) {
takeSnapshot();
}
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: newNodeClass,
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
};
if (type) {
newNode.data.type = type;
}
newNode.data.node.template[name].value = code;
return newNode;
});
updateNodeInternals(data.id);
}; };
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);

View file

@ -171,7 +171,7 @@ export type CodeAreaComponentType = {
value: string; value: string;
editNode?: boolean; editNode?: boolean;
nodeClass?: APIClassType; nodeClass?: APIClassType;
setNodeClass?: (value: APIClassType, code?: string) => void; setNodeClass?: (value: APIClassType, code: string, type: string) => void;
dynamic?: boolean; dynamic?: boolean;
id?: string; id?: string;
readonly?: boolean; readonly?: boolean;
@ -612,8 +612,8 @@ export type codeAreaModalPropsType = {
nodeClass: APIClassType | undefined; nodeClass: APIClassType | undefined;
setNodeClass: ( setNodeClass: (
Class: APIClassType, Class: APIClassType,
code?: string, code: string,
type?: string, type: string,
) => void | undefined; ) => void | undefined;
children: ReactNode; children: ReactNode;
dynamic?: boolean; dynamic?: boolean;