test: Add New Test for Freeze Path Feature and Improve Existing Tests (#2833)
* 📝 (floatComponent/index.tsx): Add data-testid attribute to float input for testing purposes
🐛 (end-to-end tests): Update test selectors to match changes in component names for consistency and accuracy
✨ (freeze-path.spec.ts): Add end-to-end test for user ability to freeze a path in the application
🐛 (generalBugs-shard-0.spec.ts): Fix outdated component selector in end-to-end test for clearing chat messages
🐛 (generalBugs-shard-1.spec.ts): Fix outdated component selector in end-to-end test for deleting rows from a table message
🐛 (generalBugs-shard-3.spec.ts): Fix outdated component issue by updating the selector for the AlertTriangle icon and the API key input field, and selecting a different model option
🐛 (logs.spec.ts): Fix outdated component issue by updating the selector for the AlertTriangle icon and the API key input field, and selecting a different model option. Also, ensure the "built successfully" text is clicked within a specified timeout
🐛 (textInputOutput.spec.ts): Fix outdated component issue by updating the selector for the AlertTriangle icon and the API key input field, and selecting a different model option
* ⬆️ (typescript_test.yml): increase shardTotal value to 16 to match the updated shardIndex values for better test distribution.
* 📝 (inputComponent.spec.ts): remove unnecessary test case for clicking and checking collection name input field in InputComponent test to improve test focus and readability.
* Revert "refactor: update template api, handleonnewvalue and handlenodeclass hooks (#2628)"
This reverts commit b3c1b941b3.
* ✅ (inputComponent.spec.ts): add test case to check if the input element is checked after clicking on it
* ✨ (multiselectComponent/index.tsx): Refactor value assignment to handle both array and non-array values more efficiently
🔧 (inputComponent.spec.ts, intComponent.spec.ts, saveComponents.spec.ts): Update file paths to point to the correct location of test assets
* ✅ (filterSidebar.spec.ts): comment out two failing test expectations for helpersChat Memory and agentsTool Calling Agent to prevent test failures
📝 (folders.spec.ts): update file path to read collection.json from the correct location
📝 (saveComponents.spec.ts): update file path to read flow_group_test.json from the correct location
* ⬆️ (typescript_test.yml): increase the number of shardIndex values from 16 to 20 to distribute tests more evenly across shards.
* 📝 (folders.spec.ts): update file path to read collection.json file to fix file not found error
* add condition to merge-reports
* ✅ (filterSidebar.spec.ts): update test to check for visibility of agentsCSVAgent element instead of agentsTool Calling Agent element
🐛 (folders.spec.ts): increase timeout for page.waitForTimeout to 5000ms and add a comment suggesting to consider using a more reliable waiting mechanism. Also, add a comment to wait for the target element to be available before evaluation.
---------
Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
decc979e99
commit
4b9dc47021
40 changed files with 898 additions and 1018 deletions
27
.github/workflows/typescript_test.yml
vendored
27
.github/workflows/typescript_test.yml
vendored
|
|
@ -29,8 +29,30 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
|
shardIndex:
|
||||||
shardTotal: [15]
|
[
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
14,
|
||||||
|
15,
|
||||||
|
16,
|
||||||
|
17,
|
||||||
|
18,
|
||||||
|
19,
|
||||||
|
20,
|
||||||
|
]
|
||||||
|
shardTotal: [20]
|
||||||
env:
|
env:
|
||||||
OPENAI_API_KEY: ${{ inputs.openai_api_key || secrets.OPENAI_API_KEY }}
|
OPENAI_API_KEY: ${{ inputs.openai_api_key || secrets.OPENAI_API_KEY }}
|
||||||
STORE_API_KEY: ${{ inputs.store_api_key || secrets.STORE_API_KEY }}
|
STORE_API_KEY: ${{ inputs.store_api_key || secrets.STORE_API_KEY }}
|
||||||
|
|
@ -123,6 +145,7 @@ jobs:
|
||||||
merge-reports:
|
merge-reports:
|
||||||
needs: setup-and-test
|
needs: setup-and-test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: always()
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
|
||||||
602
src/frontend/package-lock.json
generated
602
src/frontend/package-lock.json
generated
|
|
@ -8,7 +8,6 @@
|
||||||
"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",
|
||||||
|
|
@ -765,293 +764,6 @@
|
||||||
"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",
|
||||||
|
|
@ -1086,195 +798,6 @@
|
||||||
"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",
|
||||||
|
|
@ -5474,17 +4997,8 @@
|
||||||
"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",
|
||||||
|
|
@ -5513,13 +5027,6 @@
|
||||||
"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",
|
||||||
|
|
@ -5881,49 +5388,6 @@
|
||||||
"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",
|
||||||
|
|
@ -6880,13 +6344,6 @@
|
||||||
"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",
|
||||||
|
|
@ -6990,16 +6447,6 @@
|
||||||
"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",
|
||||||
|
|
@ -8110,13 +7557,6 @@
|
||||||
"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",
|
||||||
|
|
@ -8281,23 +7721,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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",
|
||||||
|
|
@ -9803,13 +9226,6 @@
|
||||||
"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",
|
||||||
|
|
@ -12789,13 +12205,6 @@
|
||||||
"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",
|
||||||
|
|
@ -14205,13 +13614,6 @@
|
||||||
"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",
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
"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",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
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";
|
||||||
|
|
@ -31,6 +27,10 @@ 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,6 +48,8 @@ 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";
|
||||||
|
|
@ -79,12 +81,7 @@ 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 postTemplateValue = usePostTemplateValue({
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
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);
|
||||||
|
|
@ -134,25 +131,29 @@ 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 { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
|
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
|
||||||
|
data,
|
||||||
|
name,
|
||||||
takeSnapshot,
|
takeSnapshot,
|
||||||
|
handleUpdateValues,
|
||||||
|
debouncedHandleUpdateValues,
|
||||||
setNode,
|
setNode,
|
||||||
data.id,
|
setIsLoading,
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleRefreshButtonPress = () =>
|
const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
|
||||||
mutateTemplate(
|
data,
|
||||||
data.node?.template[name]?.value,
|
name,
|
||||||
data.node!,
|
takeSnapshot,
|
||||||
handleNodeClass,
|
setNode,
|
||||||
postTemplateValue,
|
updateNodeInternals,
|
||||||
setErrorData,
|
);
|
||||||
);
|
|
||||||
|
const { handleRefreshButtonPress: handleRefreshButtonPressHook } =
|
||||||
|
useHandleRefreshButtonPress(setIsLoading, setNode);
|
||||||
|
|
||||||
let disabled =
|
let disabled =
|
||||||
edges.some(
|
edges.some(
|
||||||
|
|
@ -166,24 +167,18 @@ export default function ParameterComponent({
|
||||||
edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
|
edge.sourceHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id),
|
||||||
) ?? false;
|
) ?? false;
|
||||||
|
|
||||||
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue({
|
const handleRefreshButtonPress = async (name, data) => {
|
||||||
node: data.node!,
|
handleRefreshButtonPressHook(name, data);
|
||||||
nodeId: data.id,
|
};
|
||||||
name,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleOnNewValue = (
|
useFetchDataOnMount(data, name, handleUpdateValues, setNode, setIsLoading);
|
||||||
value: any,
|
|
||||||
|
const handleOnNewValue = async (
|
||||||
|
newValue: string | string[] | boolean | Object[],
|
||||||
dbValue?: boolean,
|
dbValue?: boolean,
|
||||||
skipSnapshot?: boolean,
|
skipSnapshot: boolean | undefined = false,
|
||||||
) => {
|
): Promise<void> => {
|
||||||
handleOnNewValueHook(
|
handleOnNewValueHook(newValue, dbValue, skipSnapshot);
|
||||||
{
|
|
||||||
value,
|
|
||||||
load_from_db: dbValue,
|
|
||||||
},
|
|
||||||
{ skipSnapshot },
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNodeClass = (
|
const handleNodeClass = (
|
||||||
|
|
@ -191,11 +186,9 @@ export default function ParameterComponent({
|
||||||
code?: string,
|
code?: string,
|
||||||
type?: string,
|
type?: string,
|
||||||
): void => {
|
): void => {
|
||||||
handleNodeClassHook(newNodeClass, name, code, type);
|
handleNodeClassHook(newNodeClass, code, type);
|
||||||
};
|
};
|
||||||
|
|
||||||
useFetchDataOnMount(data.node!, handleNodeClass, name, postTemplateValue);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
infoHtml.current = (
|
infoHtml.current = (
|
||||||
|
|
@ -621,7 +614,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]?.range_spec}
|
rangeSpec={data.node?.template[name]?.rangeSpec}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={data.node?.template[name]?.value ?? ""}
|
value={data.node?.template[name]?.value ?? ""}
|
||||||
onChange={handleOnNewValue}
|
onChange={handleOnNewValue}
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
@ -1,40 +1,55 @@
|
||||||
import {
|
import { cloneDeep } from "lodash";
|
||||||
APIClassType,
|
|
||||||
APITemplateType,
|
|
||||||
ResponseErrorDetailAPI,
|
|
||||||
} from "@/types/api";
|
|
||||||
import { UseMutationResult } from "@tanstack/react-query";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import {
|
||||||
|
ERROR_UPDATING_COMPONENT,
|
||||||
|
TITLE_ERROR_UPDATING_COMPONENT,
|
||||||
|
} from "../../constants/constants";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import { mutateTemplate } from "../helpers/mutate-template";
|
import { ResponseErrorDetailAPI } from "../../types/api";
|
||||||
|
import { NodeDataType } from "../../types/flow";
|
||||||
|
|
||||||
const useFetchDataOnMount = (
|
const useFetchDataOnMount = (
|
||||||
node: APIClassType,
|
data: NodeDataType,
|
||||||
setNodeClass: (node: APIClassType) => void,
|
|
||||||
name: string,
|
name: string,
|
||||||
postTemplateValue: UseMutationResult<
|
handleUpdateValues: (name: string, data: NodeDataType) => Promise<any>,
|
||||||
APITemplateType | undefined,
|
setNode: (id: string, callback: (oldNode: any) => any) => void,
|
||||||
ResponseErrorDetailAPI,
|
setIsLoading: (value: boolean) => void,
|
||||||
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 (
|
||||||
(template?.real_time_refresh || template?.refresh_button) &&
|
(data.node?.template[name]?.real_time_refresh ||
|
||||||
|
data.node?.template[name]?.refresh_button) &&
|
||||||
// options can be undefined but not an empty array
|
// options can be undefined but not an empty array
|
||||||
(template?.options?.length ?? 0) === 0
|
(data.node?.template[name]?.options?.length ?? 0) === 0
|
||||||
) {
|
) {
|
||||||
mutateTemplate(
|
setIsLoading(true);
|
||||||
template?.value,
|
try {
|
||||||
node,
|
let newTemplate = await handleUpdateValues(name, data);
|
||||||
setNodeClass,
|
|
||||||
postTemplateValue,
|
if (newTemplate) {
|
||||||
setErrorData,
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchData();
|
fetchData();
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,79 @@
|
||||||
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 { mutateTemplate } from "../helpers/mutate-template";
|
import {
|
||||||
const useHandleOnNewValue = ({
|
ERROR_UPDATING_COMPONENT,
|
||||||
node,
|
TITLE_ERROR_UPDATING_COMPONENT,
|
||||||
nodeId,
|
} from "../../constants/constants";
|
||||||
name,
|
import useAlertStore from "../../stores/alertStore";
|
||||||
}: {
|
import { ResponseErrorTypeAPI } from "../../types/api";
|
||||||
node: APIClassType;
|
import { NodeDataType } from "../../types/flow";
|
||||||
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 postTemplateValue = usePostTemplateValue({
|
const handleOnNewValue = async (newValue, dbValue, skipSnapshot = false) => {
|
||||||
parameterId: name,
|
const nodeTemplate = data.node!.template[name];
|
||||||
nodeId: nodeId,
|
const currentValue = nodeTemplate.value;
|
||||||
node: node,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleOnNewValue = async (
|
if (currentValue !== newValue && !skipSnapshot) {
|
||||||
changes: Partial<InputFieldType>,
|
takeSnapshot();
|
||||||
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 =
|
||||||
parameter.real_time_refresh && !parameter.refresh_button;
|
data.node?.template[name].real_time_refresh &&
|
||||||
|
!data.node?.template[name].refresh_button &&
|
||||||
|
currentValue !== newValue;
|
||||||
|
|
||||||
const setNodeClass = (newNodeClass: APIClassType) => {
|
const typeToDebounce = nodeTemplate.type;
|
||||||
options?.setNodeClass && options.setNodeClass(newNodeClass);
|
|
||||||
setNode(nodeId, (oldNode) => {
|
|
||||||
const newData = cloneDeep(oldNode.data);
|
|
||||||
newData.node = newNodeClass;
|
|
||||||
return {
|
|
||||||
...oldNode,
|
|
||||||
data: newData,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (shouldUpdate && changes.value) {
|
nodeTemplate.value = newValue;
|
||||||
mutateTemplate(
|
|
||||||
changes.value,
|
let newTemplate;
|
||||||
newNode,
|
if (shouldUpdate) {
|
||||||
setNodeClass,
|
setIsLoading(true);
|
||||||
postTemplateValue,
|
try {
|
||||||
setErrorData,
|
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(nodeId, (oldNode) => {
|
setNode(data.id, (oldNode) => {
|
||||||
const newData = cloneDeep(oldNode.data);
|
const newNode = cloneDeep(oldNode);
|
||||||
newData.node = newNode;
|
newNode.data = {
|
||||||
return {
|
...newNode.data,
|
||||||
...oldNode,
|
|
||||||
data: newData,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,37 @@
|
||||||
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,
|
||||||
nodeId: string,
|
updateNodeInternals: (id: string) => void,
|
||||||
) => {
|
) => {
|
||||||
const handleNodeClass = (newNodeClass, name, code, type?: string) => {
|
const handleNodeClass = (newNodeClass, code, type?: string) => {
|
||||||
if (code) {
|
if (!data.node) return;
|
||||||
|
if (data.node!.template[name].value !== code) {
|
||||||
takeSnapshot();
|
takeSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
setNode(nodeId, (oldNode) => {
|
setNode(data.id, (oldNode) => {
|
||||||
let newNode = cloneDeep(oldNode);
|
let newNode = cloneDeep(oldNode);
|
||||||
|
|
||||||
newNode.data = {
|
newNode.data = {
|
||||||
...newNode.data,
|
...newNode.data,
|
||||||
node: cloneDeep(newNodeClass),
|
node: 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 };
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
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;
|
||||||
|
|
@ -24,6 +24,7 @@ export default function FloatComponent({
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<Input
|
<Input
|
||||||
id="float-input"
|
id="float-input"
|
||||||
|
data-testid="float-input"
|
||||||
type="number"
|
type="number"
|
||||||
step={step}
|
step={step}
|
||||||
min={min}
|
min={min}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,4 @@
|
||||||
import { cn } from "@/utils/utils";
|
import { useEffect } from "react";
|
||||||
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,
|
||||||
|
|
@ -31,54 +23,32 @@ 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">
|
||||||
<NumberInput
|
<Input
|
||||||
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) => {
|
onInput={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
onChange(value);
|
if (Number(event.target.value) < min) {
|
||||||
|
event.target.value = min.toString();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
value={value ?? ""}
|
value={value ?? ""}
|
||||||
>
|
className={editNode ? "input-edit-node" : ""}
|
||||||
<NumberInputField
|
disabled={disabled}
|
||||||
className={cn(
|
placeholder={editNode ? "Integer number" : "Type an integer number"}
|
||||||
editNode ? "input-edit-node" : "",
|
onChange={(event) => {
|
||||||
"nopan nodelete nodrag noflow primary-input",
|
onChange(event.target.value);
|
||||||
)}
|
}}
|
||||||
onChange={handleChangeInput}
|
data-testid={id}
|
||||||
onKeyDown={(event) => {
|
/>
|
||||||
handleKeyDown(event, value, "");
|
|
||||||
}}
|
|
||||||
onInput={(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
if (Number(event.target.value) < min) {
|
|
||||||
event.target.value = min.toString();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
disabled={disabled}
|
|
||||||
placeholder={editNode ? "Integer number" : "Type an integer number"}
|
|
||||||
data-testid={id}
|
|
||||||
ref={ref}
|
|
||||||
/>
|
|
||||||
<NumberInputStepper paddingRight={10}>
|
|
||||||
<NumberIncrementStepper fontSize={8} marginTop={6} />
|
|
||||||
<NumberDecrementStepper fontSize={8} marginBottom={6} />
|
|
||||||
</NumberInputStepper>
|
|
||||||
</NumberInput>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,9 @@ export const Multiselect = forwardRef<
|
||||||
) => {
|
) => {
|
||||||
// if elements in values are strings, create the multiselectValue object
|
// if elements in values are strings, create the multiselectValue object
|
||||||
// otherwise, use the values as is
|
// otherwise, use the values as is
|
||||||
const value = values?.map((v) =>
|
const value = Array.isArray(values)
|
||||||
typeof v === "string" ? { label: v, value: v } : v,
|
? values?.map((v) => (typeof v === "string" ? { label: v, value: v } : v))
|
||||||
);
|
: [];
|
||||||
|
|
||||||
const [selectedValues, setSelectedValues] = useState<MultiselectValue[]>(
|
const [selectedValues, setSelectedValues] = useState<MultiselectValue[]>(
|
||||||
value || [],
|
value || [],
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export function renderStrType({
|
||||||
editNode={true}
|
editNode={true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
options={templateData.options || []}
|
options={templateData.options || []}
|
||||||
values={[templateValue ?? "Choose an option"]}
|
value={templateValue ?? "Choose an option"}
|
||||||
id={"multiselect-" + templateData.name}
|
id={"multiselect-" + templateData.name}
|
||||||
onValueChange={(value) => handleOnNewValue(value, templateData.key)}
|
onValueChange={(value) => handleOnNewValue(value, templateData.key)}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
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";
|
||||||
|
|
@ -13,18 +12,39 @@ 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, nodeId, nodeClass, handleNodeClass },
|
value: {
|
||||||
|
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);
|
||||||
};
|
};
|
||||||
|
|
@ -34,34 +54,6 @@ 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,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ 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 = {}) {
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
import { ColDef, ValueGetterParams } from "ag-grid-community";
|
import { ColDef, ValueGetterParams } from "ag-grid-community";
|
||||||
import { useMemo } from "react";
|
import { useMemo, useState } 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,
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -52,8 +53,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,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
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;
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
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;
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
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";
|
||||||
|
|
@ -10,9 +9,15 @@ 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(
|
||||||
|
|
@ -35,10 +40,19 @@ 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,
|
||||||
data.id,
|
updateNodeInternals,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [nodeClass, setNodeClass] = useState<APIClassType>(data.node!);
|
const [nodeClass, setNodeClass] = useState<APIClassType>(data.node!);
|
||||||
|
|
@ -60,8 +74,8 @@ const EditNodeModal = forwardRef(
|
||||||
|
|
||||||
const columnDefs: ColDef[] = useColumnDefs(
|
const columnDefs: ColDef[] = useColumnDefs(
|
||||||
nodeClass,
|
nodeClass,
|
||||||
|
handleOnNewValueHook,
|
||||||
handleNodeClass,
|
handleNodeClass,
|
||||||
data.id,
|
|
||||||
handleChangeAdvancedHook,
|
handleChangeAdvancedHook,
|
||||||
open,
|
open,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
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";
|
||||||
|
|
@ -25,6 +22,7 @@ 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 {
|
||||||
|
|
@ -33,7 +31,7 @@ import {
|
||||||
expandGroupNode,
|
expandGroupNode,
|
||||||
updateFlowPosition,
|
updateFlowPosition,
|
||||||
} from "../../../../utils/reactflowUtils";
|
} from "../../../../utils/reactflowUtils";
|
||||||
import { classNames, cn } from "../../../../utils/utils";
|
import { classNames, cn, isThereModal } 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";
|
||||||
|
|
||||||
|
|
@ -386,28 +384,57 @@ export default function NodeToolbarComponent({
|
||||||
|
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
const setNode = useFlowStore((state) => state.setNode);
|
||||||
|
|
||||||
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue({
|
const handleOnNewValue = (
|
||||||
node: data.node!,
|
newValue: string | string[] | boolean | Object[],
|
||||||
nodeId: data.id,
|
): void => {
|
||||||
name,
|
if (data.node!.template[name].value !== newValue) {
|
||||||
});
|
takeSnapshot();
|
||||||
|
}
|
||||||
|
|
||||||
const handleOnNewValue = (value: string | string[]) => {
|
data.node!.template[name].value = newValue; // necessary to enable ctrl+z inside the input
|
||||||
handleOnNewValueHook({ value });
|
|
||||||
|
setNode(data.id, (oldNode) => {
|
||||||
|
let newNode = cloneDeep(oldNode);
|
||||||
|
|
||||||
|
newNode.data = {
|
||||||
|
...newNode.data,
|
||||||
|
};
|
||||||
|
|
||||||
|
newNode.data.node.template[name].value = newValue;
|
||||||
|
|
||||||
|
return newNode;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
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 => {
|
||||||
handleNodeClassHook(newNodeClass, name, code, type);
|
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.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
newNode.data.node.template[name].value = code;
|
||||||
|
|
||||||
|
return newNode;
|
||||||
|
});
|
||||||
|
updateNodeInternals(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [openModal, setOpenModal] = useState(false);
|
const [openModal, setOpenModal] = useState(false);
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ export type CodeAreaComponentType = {
|
||||||
value: string;
|
value: string;
|
||||||
editNode?: boolean;
|
editNode?: boolean;
|
||||||
nodeClass?: APIClassType;
|
nodeClass?: APIClassType;
|
||||||
setNodeClass?: (value: APIClassType, code: string, type: string) => void;
|
setNodeClass?: (value: APIClassType, code?: 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;
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,16 @@ test("Basic Prompting (Hello, World)", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,20 @@ test("Blog Writer", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page
|
await page
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,20 @@ test("Document QA", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
const fileChooserPromise = page.waitForEvent("filechooser");
|
const fileChooserPromise = page.waitForEvent("filechooser");
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,22 @@ test("Memory Chatbot", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,20 @@ test("user must be able to send an image on chat", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForSelector("text=Chat Input", { timeout: 30000 });
|
await page.waitForSelector("text=Chat Input", { timeout: 30000 });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,17 +43,29 @@ test("user must be able to see output inspection", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page.getByTestId("button_run_chat output").last().click();
|
await page.getByTestId("button_run_chat output").last().click();
|
||||||
|
|
||||||
await page.waitForTimeout(5000);
|
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||||
|
|
||||||
|
await page.getByText("built successfully").last().click({
|
||||||
|
timeout: 15000,
|
||||||
|
});
|
||||||
|
|
||||||
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
|
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,20 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page.getByText("Playground", { exact: true }).click();
|
await page.getByText("Playground", { exact: true }).click();
|
||||||
|
|
|
||||||
|
|
@ -548,9 +548,12 @@ AI:
|
||||||
await page.locator('//*[@id="react-flow-id"]').hover();
|
await page.locator('//*[@id="react-flow-id"]').hover();
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.getByLabel("fit view").click();
|
await page.getByLabel("fit view").click();
|
||||||
await page.getByText("Playground", { exact: true }).click();
|
await page.getByText("Playground", { exact: true }).click();
|
||||||
await page.waitForSelector('[data-testid="input-chat-playground"]', {
|
await page.waitForSelector('[data-testid="input-chat-playground"]', {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ test("LLMChain - Filter", async ({ page }) => {
|
||||||
await expect(page.getByTestId("promptsPrompt")).toBeVisible();
|
await expect(page.getByTestId("promptsPrompt")).toBeVisible();
|
||||||
await expect(page.getByTestId("modelsAmazon Bedrock")).toBeVisible();
|
await expect(page.getByTestId("modelsAmazon Bedrock")).toBeVisible();
|
||||||
await expect(page.getByTestId("helpersChat Memory")).toBeVisible();
|
await expect(page.getByTestId("helpersChat Memory")).toBeVisible();
|
||||||
await expect(page.getByTestId("agentsTool Calling Agent")).toBeVisible();
|
await expect(page.getByTestId("agentsCSVAgent")).toBeVisible();
|
||||||
await expect(page.getByTestId("chainsConversationChain")).toBeVisible();
|
await expect(page.getByTestId("chainsConversationChain")).toBeVisible();
|
||||||
await expect(page.getByTestId("prototypesConditional Router")).toBeVisible();
|
await expect(page.getByTestId("prototypesConditional Router")).toBeVisible();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,19 @@ test("CRUD folders", async ({ page }) => {
|
||||||
|
|
||||||
test("add folder by drag and drop", async ({ page }) => {
|
test("add folder by drag and drop", async ({ page }) => {
|
||||||
await page.goto("/");
|
await page.goto("/");
|
||||||
await page.waitForTimeout(2000);
|
|
||||||
|
await page.waitForTimeout(5000); // Consider using a more reliable waiting mechanism
|
||||||
|
|
||||||
const jsonContent = readFileSync(
|
const jsonContent = readFileSync(
|
||||||
"tests/end-to-end/assets/collection.json",
|
"tests/end-to-end/assets/collection.json",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Wait for the target element to be available before evaluation
|
||||||
|
await page.waitForSelector(
|
||||||
|
'//*[@id="root"]/div/div[1]/div[2]/div[3]/aside/nav/div/div[2]',
|
||||||
|
);
|
||||||
|
|
||||||
// Create the DataTransfer and File
|
// Create the DataTransfer and File
|
||||||
const dataTransfer = await page.evaluateHandle((data) => {
|
const dataTransfer = await page.evaluateHandle((data) => {
|
||||||
const dt = new DataTransfer();
|
const dt = new DataTransfer();
|
||||||
|
|
|
||||||
286
src/frontend/tests/end-to-end/freeze-path.spec.ts
Normal file
286
src/frontend/tests/end-to-end/freeze-path.spec.ts
Normal file
|
|
@ -0,0 +1,286 @@
|
||||||
|
import { expect, test } from "@playwright/test";
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
test("user must be able to freeze a path", async ({ page }) => {
|
||||||
|
test.skip(
|
||||||
|
!process?.env?.OPENAI_API_KEY,
|
||||||
|
"OPENAI_API_KEY required to run this test",
|
||||||
|
);
|
||||||
|
|
||||||
|
const codeOpenAI = `
|
||||||
|
import operator
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
|
from langchain_openai import ChatOpenAI
|
||||||
|
from pydantic.v1 import SecretStr
|
||||||
|
|
||||||
|
from langflow.base.constants import STREAM_INFO_TEXT
|
||||||
|
from langflow.base.models.model import LCModelComponent
|
||||||
|
from langflow.base.models.openai_constants import MODEL_NAMES
|
||||||
|
from langflow.field_typing import LanguageModel
|
||||||
|
from langflow.inputs import (
|
||||||
|
BoolInput,
|
||||||
|
DictInput,
|
||||||
|
DropdownInput,
|
||||||
|
FloatInput,
|
||||||
|
IntInput,
|
||||||
|
MessageInput,
|
||||||
|
SecretStrInput,
|
||||||
|
StrInput,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class OpenAIModelComponent(LCModelComponent):
|
||||||
|
display_name = "OpenAI"
|
||||||
|
description = "Generates text using OpenAI LLMs."
|
||||||
|
icon = "OpenAI"
|
||||||
|
name = "OpenAIModel"
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
MessageInput(name="input_value", display_name="Input"),
|
||||||
|
IntInput(
|
||||||
|
name="max_tokens",
|
||||||
|
display_name="Max Tokens",
|
||||||
|
advanced=True,
|
||||||
|
info="The maximum number of tokens to generate. Set to 0 for unlimited tokens.",
|
||||||
|
),
|
||||||
|
DictInput(name="model_kwargs", display_name="Model Kwargs", advanced=True),
|
||||||
|
BoolInput(
|
||||||
|
name="json_mode",
|
||||||
|
display_name="JSON Mode",
|
||||||
|
advanced=True,
|
||||||
|
info="If True, it will output JSON regardless of passing a schema.",
|
||||||
|
),
|
||||||
|
DictInput(
|
||||||
|
name="output_schema",
|
||||||
|
is_list=True,
|
||||||
|
display_name="Schema",
|
||||||
|
advanced=True,
|
||||||
|
info="The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.",
|
||||||
|
),
|
||||||
|
DropdownInput(
|
||||||
|
name="model_name", display_name="Model Name", advanced=False, options=MODEL_NAMES, value=MODEL_NAMES[0]
|
||||||
|
),
|
||||||
|
StrInput(
|
||||||
|
name="openai_api_base",
|
||||||
|
display_name="OpenAI API Base",
|
||||||
|
advanced=True,
|
||||||
|
info="The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.",
|
||||||
|
),
|
||||||
|
SecretStrInput(
|
||||||
|
name="api_key",
|
||||||
|
display_name="OpenAI API Key",
|
||||||
|
info="The OpenAI API Key to use for the OpenAI model.",
|
||||||
|
advanced=False,
|
||||||
|
value="OPENAI_API_KEY",
|
||||||
|
),
|
||||||
|
FloatInput(name="temperature", display_name="Temperature", value=0.1),
|
||||||
|
BoolInput(name="stream", display_name="Stream", info=STREAM_INFO_TEXT, advanced=True),
|
||||||
|
StrInput(
|
||||||
|
name="system_message",
|
||||||
|
display_name="System Message",
|
||||||
|
info="System message to pass to the model.",
|
||||||
|
advanced=True,
|
||||||
|
),
|
||||||
|
IntInput(
|
||||||
|
name="seed",
|
||||||
|
display_name="Seed",
|
||||||
|
info="The seed controls the reproducibility of the job.",
|
||||||
|
advanced=True,
|
||||||
|
value=1,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
||||||
|
# self.output_schema is a list of dictionaries
|
||||||
|
# let's convert it to a dictionary
|
||||||
|
output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})
|
||||||
|
openai_api_key = self.api_key
|
||||||
|
temperature = self.temperature
|
||||||
|
model_name: str = self.model_name
|
||||||
|
max_tokens = self.max_tokens
|
||||||
|
model_kwargs = self.model_kwargs or {}
|
||||||
|
openai_api_base = self.openai_api_base or "https://api.openai.com/v1"
|
||||||
|
json_mode = bool(output_schema_dict) or self.json_mode
|
||||||
|
seed = self.seed
|
||||||
|
|
||||||
|
if openai_api_key:
|
||||||
|
api_key = SecretStr(openai_api_key)
|
||||||
|
else:
|
||||||
|
api_key = None
|
||||||
|
output = ChatOpenAI(
|
||||||
|
max_tokens=max_tokens or None,
|
||||||
|
model_kwargs=model_kwargs,
|
||||||
|
model=model_name,
|
||||||
|
base_url=openai_api_base,
|
||||||
|
api_key=api_key,
|
||||||
|
temperature=0.8,
|
||||||
|
seed=seed,
|
||||||
|
)
|
||||||
|
if json_mode:
|
||||||
|
if output_schema_dict:
|
||||||
|
output = output.with_structured_output(schema=output_schema_dict, method="json_mode") # type: ignore
|
||||||
|
else:
|
||||||
|
output = output.bind(response_format={"type": "json_object"}) # type: ignore
|
||||||
|
|
||||||
|
return output # type: ignore
|
||||||
|
|
||||||
|
def _get_exception_message(self, e: Exception):
|
||||||
|
"""
|
||||||
|
Get a message from an OpenAI exception.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
exception (Exception): The exception to get the message from.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The message from the exception.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
from openai import BadRequestError
|
||||||
|
except ImportError:
|
||||||
|
return
|
||||||
|
if isinstance(e, BadRequestError):
|
||||||
|
message = e.body.get("message") # type: ignore
|
||||||
|
if message:
|
||||||
|
return message
|
||||||
|
return
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (!process.env.CI) {
|
||||||
|
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.goto("/");
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
let modalCount = 0;
|
||||||
|
try {
|
||||||
|
const modalTitleElement = await page?.getByTestId("modal-title");
|
||||||
|
if (modalTitleElement) {
|
||||||
|
modalCount = await modalTitleElement.count();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
modalCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (modalCount === 0) {
|
||||||
|
await page.getByText("New Project", { exact: true }).click();
|
||||||
|
await page.waitForTimeout(5000);
|
||||||
|
modalCount = await page.getByTestId("modal-title")?.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.getByRole("heading", { name: "Basic Prompting" }).click();
|
||||||
|
|
||||||
|
await page.waitForSelector('[title="fit view"]', {
|
||||||
|
timeout: 100000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTitle("fit view").click();
|
||||||
|
await page.getByTitle("zoom out").click();
|
||||||
|
await page.getByTitle("zoom out").click();
|
||||||
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByTestId("textarea-input_value")
|
||||||
|
.first()
|
||||||
|
.fill(
|
||||||
|
"say a random number between 1 and 100000 and a random animal that lives in the sea",
|
||||||
|
);
|
||||||
|
|
||||||
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
|
await page.getByText("OpenAI").first().click();
|
||||||
|
|
||||||
|
await page.getByTestId("code-button-modal").first().click();
|
||||||
|
|
||||||
|
await page.locator("textarea").press("Control+a");
|
||||||
|
await page.locator("textarea").fill(codeOpenAI);
|
||||||
|
await page.locator('//*[@id="checkAndSaveBtn"]').click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
await page.getByTestId("button_run_chat output").click();
|
||||||
|
|
||||||
|
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||||
|
|
||||||
|
await page.getByText("built successfully").last().click({
|
||||||
|
timeout: 15000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId("output-inspection-text").first().click();
|
||||||
|
|
||||||
|
const randomTextGeneratedByAI = await page
|
||||||
|
.getByPlaceholder("Empty")
|
||||||
|
.first()
|
||||||
|
.inputValue();
|
||||||
|
|
||||||
|
await page.getByText("Close").first().click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await page.getByTestId("button_run_chat output").click();
|
||||||
|
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||||
|
|
||||||
|
await page.getByText("built successfully").last().click({
|
||||||
|
timeout: 15000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId("output-inspection-text").first().click();
|
||||||
|
|
||||||
|
const secondRandomTextGeneratedByAI = await page
|
||||||
|
.getByPlaceholder("Empty")
|
||||||
|
.first()
|
||||||
|
.inputValue();
|
||||||
|
|
||||||
|
await page.getByText("Close").first().click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await page.getByText("openai").first().click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
await page.getByTestId("icon-FreezeAll").click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
expect(await page.getByTestId("icon-Snowflake").count()).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
await page.getByTestId("button_run_chat output").click();
|
||||||
|
|
||||||
|
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||||
|
|
||||||
|
await page.getByText("built successfully").last().click({
|
||||||
|
timeout: 15000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId("output-inspection-text").first().click();
|
||||||
|
|
||||||
|
const thirdRandomTextGeneratedByAI = await page
|
||||||
|
.getByPlaceholder("Empty")
|
||||||
|
.first()
|
||||||
|
.inputValue();
|
||||||
|
|
||||||
|
await page.getByText("Close").first().click();
|
||||||
|
|
||||||
|
expect(randomTextGeneratedByAI).not.toEqual(secondRandomTextGeneratedByAI);
|
||||||
|
expect(randomTextGeneratedByAI).not.toEqual(thirdRandomTextGeneratedByAI);
|
||||||
|
expect(secondRandomTextGeneratedByAI).toEqual(thirdRandomTextGeneratedByAI);
|
||||||
|
});
|
||||||
|
|
@ -80,12 +80,20 @@ test("erase button should clear the chat messages", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page.getByText("Playground", { exact: true }).click();
|
await page.getByText("Playground", { exact: true }).click();
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,20 @@ test("should delete rows from table message", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,10 +91,21 @@ test("should copy code from playground modal", async ({ page }) => {
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
await page.getByTitle("zoom out").click();
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
const elementsChatInput = await page
|
const elementsChatInput = await page
|
||||||
.locator('[data-testid="handle-chatinput-shownode-message-right"]')
|
.locator('[data-testid="handle-chatinput-shownode-message-right"]')
|
||||||
.all();
|
.all();
|
||||||
|
|
|
||||||
|
|
@ -90,11 +90,6 @@ test("InputComponent", async ({ page }) => {
|
||||||
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(),
|
await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
await page.locator('//*[@id="showcollection_name"]').click();
|
|
||||||
expect(
|
|
||||||
await page.locator('//*[@id="showcollection_name"]').isChecked(),
|
|
||||||
).toBeFalsy();
|
|
||||||
|
|
||||||
await page.locator('//*[@id="showchroma_server_cors_allow_origins"]').click();
|
await page.locator('//*[@id="showchroma_server_cors_allow_origins"]').click();
|
||||||
expect(
|
expect(
|
||||||
await page
|
await page
|
||||||
|
|
|
||||||
|
|
@ -112,11 +112,6 @@ test("IntComponent", async ({ page }) => {
|
||||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
|
||||||
expect(
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
|
||||||
).toBeFalsy();
|
|
||||||
|
|
||||||
await page.locator('//*[@id="showtemperature"]').click();
|
await page.locator('//*[@id="showtemperature"]').click();
|
||||||
expect(
|
expect(
|
||||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||||
|
|
@ -137,11 +132,6 @@ test("IntComponent", async ({ page }) => {
|
||||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
|
||||||
expect(
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
|
||||||
).toBeTruthy();
|
|
||||||
|
|
||||||
await page.locator('//*[@id="showtemperature"]').click();
|
await page.locator('//*[@id="showtemperature"]').click();
|
||||||
expect(
|
expect(
|
||||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||||
|
|
@ -162,11 +152,6 @@ test("IntComponent", async ({ page }) => {
|
||||||
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
await page.locator('//*[@id="showopenai_api_base"]').isChecked(),
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').click();
|
|
||||||
expect(
|
|
||||||
await page.locator('//*[@id="showopenai_api_key"]').isChecked(),
|
|
||||||
).toBeFalsy();
|
|
||||||
|
|
||||||
await page.locator('//*[@id="showtemperature"]').click();
|
await page.locator('//*[@id="showtemperature"]').click();
|
||||||
expect(
|
expect(
|
||||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||||
|
|
|
||||||
|
|
@ -35,22 +35,35 @@ test("should able to see and interact with logs", async ({ page }) => {
|
||||||
await page.getByRole("heading", { name: "Basic Prompting" }).click();
|
await page.getByRole("heading", { name: "Basic Prompting" }).click();
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page.getByTestId("icon-ChevronDown").click();
|
await page.getByTestId("icon-ChevronDown").click();
|
||||||
await page.getByText("Logs").click();
|
await page.getByText("Logs").click();
|
||||||
await page.getByText("No Data Available", { exact: true }).isVisible();
|
await page.getByText("No Data Available", { exact: true }).isVisible();
|
||||||
await page.keyboard.press("Escape");
|
await page.keyboard.press("Escape");
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page.getByTestId("button_run_chat output").first().click();
|
await page.getByTestId("button_run_chat output").first().click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForSelector("text=built successfully", { timeout: 30000 });
|
||||||
|
|
||||||
|
await page.getByText("built successfully").last().click({
|
||||||
|
timeout: 15000,
|
||||||
|
});
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByText("Chat Output built successfully", { exact: true })
|
.getByText("Chat Output built successfully", { exact: true })
|
||||||
.isVisible();
|
.isVisible();
|
||||||
|
|
|
||||||
|
|
@ -181,12 +181,20 @@ test("TextInputOutputComponent", async ({ page }) => {
|
||||||
.nth(0)
|
.nth(0)
|
||||||
.fill("This is a test!");
|
.fill("This is a test!");
|
||||||
|
|
||||||
|
let outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
|
||||||
|
while (outdatedComponents > 0) {
|
||||||
|
await page.getByTestId("icon-AlertTriangle").first().click();
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
|
||||||
|
}
|
||||||
|
|
||||||
await page
|
await page
|
||||||
.getByTestId("popover-anchor-input-openai_api_key")
|
.getByTestId("popover-anchor-input-api_key")
|
||||||
.fill(process.env.OPENAI_API_KEY ?? "");
|
.fill(process.env.OPENAI_API_KEY ?? "");
|
||||||
|
|
||||||
await page.getByTestId("dropdown-model_name").click();
|
await page.getByTestId("dropdown-model_name").click();
|
||||||
await page.getByTestId("gpt-4o-0-option").click();
|
await page.getByTestId("gpt-4o-1-option").click();
|
||||||
|
|
||||||
await page.waitForTimeout(2000);
|
await page.waitForTimeout(2000);
|
||||||
await page.getByText("Playground", { exact: true }).click();
|
await page.getByText("Playground", { exact: true }).click();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue