From 3859a7e09baccf54ea06f55994b022c09e593c63 Mon Sep 17 00:00:00 2001 From: akhilmhdh Date: Fri, 3 Feb 2023 22:16:31 +0530 Subject: [PATCH 1/6] feat(ui): added new react-query hooks for settings page --- frontend/package-lock.json | 273 ++++++++++++------ frontend/package.json | 5 +- frontend/src/hooks/api/index.tsx | 6 +- frontend/src/hooks/api/keys/index.tsx | 1 + frontend/src/hooks/api/keys/queries.tsx | 24 ++ frontend/src/hooks/api/keys/types.ts | 22 ++ frontend/src/hooks/api/serviceTokens/index.ts | 1 + .../src/hooks/api/serviceTokens/queries.tsx | 60 ++++ frontend/src/hooks/api/serviceTokens/types.ts | 28 ++ .../src/hooks/api/subscriptions/index.tsx | 1 + .../src/hooks/api/subscriptions/queries.tsx | 30 ++ frontend/src/hooks/api/subscriptions/types.ts | 25 ++ frontend/src/hooks/api/types.ts | 13 + frontend/src/hooks/api/workspace/index.tsx | 8 + frontend/src/hooks/api/workspace/queries.tsx | 94 ++++++ frontend/src/hooks/api/workspace/types.ts | 29 ++ frontend/src/hooks/usePopUp.tsx | 6 +- 17 files changed, 529 insertions(+), 97 deletions(-) create mode 100644 frontend/src/hooks/api/keys/index.tsx create mode 100644 frontend/src/hooks/api/keys/queries.tsx create mode 100644 frontend/src/hooks/api/keys/types.ts create mode 100644 frontend/src/hooks/api/serviceTokens/index.ts create mode 100644 frontend/src/hooks/api/serviceTokens/queries.tsx create mode 100644 frontend/src/hooks/api/serviceTokens/types.ts create mode 100644 frontend/src/hooks/api/subscriptions/index.tsx create mode 100644 frontend/src/hooks/api/subscriptions/queries.tsx create mode 100644 frontend/src/hooks/api/subscriptions/types.ts create mode 100644 frontend/src/hooks/api/types.ts create mode 100644 frontend/src/hooks/api/workspace/index.tsx create mode 100644 frontend/src/hooks/api/workspace/queries.tsx create mode 100644 frontend/src/hooks/api/workspace/types.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f5bb934fe8..283c69b532 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "@fortawesome/free-solid-svg-icons": "^6.1.2", "@fortawesome/react-fontawesome": "^0.1.19", "@headlessui/react": "^1.6.6", + "@hookform/resolvers": "^2.9.10", "@radix-ui/react-accordion": "^1.1.0", "@radix-ui/react-alert-dialog": "^1.0.2", "@radix-ui/react-checkbox": "^1.0.1", @@ -51,6 +52,7 @@ "react-code-input": "^3.10.1", "react-dom": "^17.0.2", "react-grid-layout": "^1.3.4", + "react-hook-form": "^7.43.0", "react-i18next": "^12.1.1", "react-mailchimp-subscribe": "^2.1.3", "react-markdown": "^8.0.3", @@ -64,7 +66,8 @@ "tweetnacl-util": "^0.15.1", "uuid": "^8.3.2", "uuidv4": "^6.2.13", - "yaml": "^2.2.0" + "yaml": "^2.2.0", + "yup": "^0.32.11" }, "devDependencies": { "@storybook/addon-essentials": "^7.0.0-beta.30", @@ -108,7 +111,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -121,7 +123,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "dependencies": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -157,7 +158,6 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -166,7 +166,6 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -196,7 +195,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -212,14 +210,12 @@ "node_modules/@babel/core/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -265,7 +261,6 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", - "dev": true, "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", @@ -284,7 +279,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "dependencies": { "yallist": "^3.0.2" } @@ -293,7 +287,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -301,8 +294,7 @@ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.20.12", @@ -461,7 +453,6 @@ "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", @@ -535,7 +526,6 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, "dependencies": { "@babel/types": "^7.20.2" }, @@ -586,7 +576,6 @@ "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -610,7 +599,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "dev": true, "dependencies": { "@babel/template": "^7.18.10", "@babel/traverse": "^7.20.5", @@ -2897,6 +2885,14 @@ "react-dom": "^16 || ^17 || ^18" } }, + "node_modules/@hookform/resolvers": { + "version": "2.9.10", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.9.10.tgz", + "integrity": "sha512-JIL1DgJIlH9yuxcNGtyhsWX/PgNltz+5Gr6+8SX9fhXc/hPbEIk6wPI82nhgvp3uUb6ZfAM5mqg/x7KR7NAb+A==", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -7005,8 +7001,7 @@ "node_modules/@types/lodash": { "version": "4.14.191", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", - "dev": true + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" }, "node_modules/@types/mdast": { "version": "3.0.10", @@ -8997,7 +8992,6 @@ "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -10680,8 +10674,7 @@ "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -10977,7 +10970,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -12818,7 +12810,6 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -14991,7 +14982,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -15210,6 +15200,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.castarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", @@ -16183,6 +16178,11 @@ "object-assign": "^4.1.0" } }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -16464,8 +16464,7 @@ "node_modules/node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -17625,6 +17624,11 @@ "react-is": "^16.13.1" } }, + "node_modules/property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, "node_modules/property-information": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", @@ -18142,6 +18146,21 @@ "react-dom": ">= 16.3.0" } }, + "node_modules/react-hook-form": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.43.0.tgz", + "integrity": "sha512-/rVEz7T0gLdSFwPqutJ1kn2e0sQNyb9ci/hmwEYr2YG0KF/LSuRLvNrf9QWJM+gj88CjDpDW5Bh/1AD7B2+z9Q==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-i18next": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz", @@ -21168,6 +21187,11 @@ "node": ">=0.6" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -21404,7 +21428,7 @@ "version": "4.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21730,7 +21754,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -22480,6 +22503,23 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } } }, "dependencies": { @@ -22487,7 +22527,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.1.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -22497,7 +22536,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, "requires": { "@jridgewell/set-array": "^1.0.0", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -22525,14 +22563,12 @@ "@babel/compat-data": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", - "dev": true + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" }, "@babel/core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -22555,7 +22591,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -22563,14 +22598,12 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" } } }, @@ -22606,7 +22639,6 @@ "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", - "dev": true, "requires": { "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", @@ -22619,7 +22651,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, "requires": { "yallist": "^3.0.2" } @@ -22627,14 +22658,12 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, @@ -22753,7 +22782,6 @@ "version": "7.20.11", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", @@ -22809,7 +22837,6 @@ "version": "7.20.2", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, "requires": { "@babel/types": "^7.20.2" } @@ -22844,8 +22871,7 @@ "@babel/helper-validator-option": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" }, "@babel/helper-wrap-function": { "version": "7.20.5", @@ -22863,7 +22889,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "dev": true, "requires": { "@babel/template": "^7.18.10", "@babel/traverse": "^7.20.5", @@ -24061,7 +24086,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", - "dev": true + "dev": true, + "requires": {} }, "@emotion/utils": { "version": "1.2.0", @@ -24366,7 +24392,14 @@ "@headlessui/react": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.6.6.tgz", - "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==" + "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==", + "requires": {} + }, + "@hookform/resolvers": { + "version": "2.9.10", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-2.9.10.tgz", + "integrity": "sha512-JIL1DgJIlH9yuxcNGtyhsWX/PgNltz+5Gr6+8SX9fhXc/hPbEIk6wPI82nhgvp3uUb6ZfAM5mqg/x7KR7NAb+A==", + "requires": {} }, "@humanwhocodes/config-array": { "version": "0.11.8", @@ -27340,8 +27373,7 @@ "@types/lodash": { "version": "4.14.191", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", - "dev": true + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" }, "@types/mdast": { "version": "3.0.10", @@ -28016,7 +28048,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-node": { "version": "1.8.2", @@ -28150,7 +28183,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-align": { "version": "3.0.1", @@ -28444,7 +28478,8 @@ "axios-auth-refresh": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.3.tgz", - "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg==" + "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg==", + "requires": {} }, "axobject-query": { "version": "3.1.1", @@ -28459,7 +28494,8 @@ "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==", - "dev": true + "dev": true, + "requires": {} }, "babel-loader": { "version": "9.1.2", @@ -28838,7 +28874,6 @@ "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, "requires": { "caniuse-lite": "^1.0.30001400", "electron-to-chromium": "^1.4.251", @@ -29668,7 +29703,8 @@ "cva": { "version": "npm:class-variance-authority@0.4.0", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.4.0.tgz", - "integrity": "sha512-74enNN8O9ZNieycac/y8FxqgyzZhZbxmCitAtAeUrLPlxjSd5zA7LfpprmxEcOmQBnaGs5hYhiSGnJ0mqrtBLQ==" + "integrity": "sha512-74enNN8O9ZNieycac/y8FxqgyzZhZbxmCitAtAeUrLPlxjSd5zA7LfpprmxEcOmQBnaGs5hYhiSGnJ0mqrtBLQ==", + "requires": {} }, "damerau-levenshtein": { "version": "1.0.8", @@ -30121,8 +30157,7 @@ "electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "emoji-regex": { "version": "9.2.2", @@ -30368,8 +30403,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -30632,7 +30666,8 @@ "version": "8.6.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", - "dev": true + "dev": true, + "requires": {} }, "eslint-import-resolver-node": { "version": "0.3.7", @@ -30890,13 +30925,15 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-simple-import-sort": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz", "integrity": "sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-storybook": { "version": "0.6.10", @@ -31760,8 +31797,7 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" }, "get-caller-file": { "version": "2.0.5", @@ -32325,7 +32361,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ieee754": { "version": "1.2.1", @@ -33339,8 +33376,7 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonfile": { "version": "6.1.0", @@ -33508,6 +33544,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash.castarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", @@ -33638,7 +33679,8 @@ "version": "7.1.8", "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.8.tgz", "integrity": "sha512-rRSa1aFmFnpDRFAhv5vIkWM4nPaoB9vnzIjuIKa1wGupfn2hdCNeaQHKpu4/muoc8n8J7yowjTP2oncA4/Rbgg==", - "dev": true + "dev": true, + "requires": {} }, "md5.js": { "version": "1.3.5", @@ -34155,6 +34197,11 @@ "object-assign": "^4.1.0" } }, + "nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -34344,8 +34391,7 @@ "node-releases": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", - "dev": true + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, "normalize-package-data": { "version": "2.5.0", @@ -34935,7 +34981,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -35044,7 +35091,8 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.2.tgz", "integrity": "sha512-5RjUbWRe305pUpc48MosoIp6uxZvZxrM6GyOgsbGLTce+ehePKNm7ziW2dLG2air9aXbGuXlHVSQQw4Lbosq3w==", - "dev": true + "dev": true, + "requires": {} }, "pretty-error": { "version": "4.0.0", @@ -35132,6 +35180,11 @@ "react-is": "^16.13.1" } }, + "property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" + }, "property-information": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.1.1.tgz", @@ -35437,7 +35490,8 @@ "version": "5.6.1", "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", - "dev": true + "dev": true, + "requires": {} }, "react-docgen": { "version": "5.4.3", @@ -35469,7 +35523,8 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz", "integrity": "sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==", - "dev": true + "dev": true, + "requires": {} }, "react-dom": { "version": "17.0.2", @@ -35521,6 +35576,12 @@ "react-resizable": "^3.0.4" } }, + "react-hook-form": { + "version": "7.43.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.43.0.tgz", + "integrity": "sha512-/rVEz7T0gLdSFwPqutJ1kn2e0sQNyb9ci/hmwEYr2YG0KF/LSuRLvNrf9QWJM+gj88CjDpDW5Bh/1AD7B2+z9Q==", + "requires": {} + }, "react-i18next": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-12.1.1.tgz", @@ -35534,7 +35595,8 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.1.tgz", "integrity": "sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==", - "dev": true + "dev": true, + "requires": {} }, "react-is": { "version": "16.13.1", @@ -35649,7 +35711,8 @@ "react-table": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", - "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==" + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", + "requires": {} }, "read-cache": { "version": "1.0.0", @@ -35805,7 +35868,8 @@ "redux-thunk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", - "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==" + "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==", + "requires": {} }, "regenerate": { "version": "1.4.2", @@ -37258,7 +37322,8 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "dev": true + "dev": true, + "requires": {} }, "style-to-object": { "version": "0.3.0", @@ -37288,7 +37353,8 @@ "styled-jsx": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", - "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==" + "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", + "requires": {} }, "stylis": { "version": "4.0.13", @@ -37750,6 +37816,11 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" + }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -37928,7 +37999,7 @@ "version": "4.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", - "dev": true + "devOptional": true }, "uc.micro": { "version": "1.0.6", @@ -38164,7 +38235,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -38202,12 +38272,14 @@ "use-isomorphic-layout-effect": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==" + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} }, "use-memo-one": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", - "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==" + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "requires": {} }, "use-sidecar": { "version": "1.1.2", @@ -38221,7 +38293,8 @@ "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} }, "util": { "version": "0.12.5", @@ -38412,7 +38485,8 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true + "dev": true, + "requires": {} }, "eslint-scope": { "version": "5.1.1", @@ -38638,7 +38712,8 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "dev": true + "dev": true, + "requires": {} }, "xtend": { "version": "4.0.2", @@ -38698,6 +38773,20 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "requires": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + } } } } diff --git a/frontend/package.json b/frontend/package.json index f97edd68f2..322e60f311 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,6 +21,7 @@ "@fortawesome/free-solid-svg-icons": "^6.1.2", "@fortawesome/react-fontawesome": "^0.1.19", "@headlessui/react": "^1.6.6", + "@hookform/resolvers": "^2.9.10", "@radix-ui/react-accordion": "^1.1.0", "@radix-ui/react-alert-dialog": "^1.0.2", "@radix-ui/react-checkbox": "^1.0.1", @@ -58,6 +59,7 @@ "react-code-input": "^3.10.1", "react-dom": "^17.0.2", "react-grid-layout": "^1.3.4", + "react-hook-form": "^7.43.0", "react-i18next": "^12.1.1", "react-mailchimp-subscribe": "^2.1.3", "react-markdown": "^8.0.3", @@ -71,7 +73,8 @@ "tweetnacl-util": "^0.15.1", "uuid": "^8.3.2", "uuidv4": "^6.2.13", - "yaml": "^2.2.0" + "yaml": "^2.2.0", + "yup": "^0.32.11" }, "devDependencies": { "@storybook/addon-essentials": "^7.0.0-beta.30", diff --git a/frontend/src/hooks/api/index.tsx b/frontend/src/hooks/api/index.tsx index 9df70dcf04..424fb514a7 100644 --- a/frontend/src/hooks/api/index.tsx +++ b/frontend/src/hooks/api/index.tsx @@ -1 +1,5 @@ -export { useGetAuthToken } from './auth'; +export * from './auth'; +export * from './keys'; +export * from './serviceTokens'; +export * from './subscriptions'; +export * from './workspace'; diff --git a/frontend/src/hooks/api/keys/index.tsx b/frontend/src/hooks/api/keys/index.tsx new file mode 100644 index 0000000000..23ffdf8d1e --- /dev/null +++ b/frontend/src/hooks/api/keys/index.tsx @@ -0,0 +1 @@ +export { useGetUserWsKey } from './queries'; diff --git a/frontend/src/hooks/api/keys/queries.tsx b/frontend/src/hooks/api/keys/queries.tsx new file mode 100644 index 0000000000..d37c73f13e --- /dev/null +++ b/frontend/src/hooks/api/keys/queries.tsx @@ -0,0 +1,24 @@ +import { useQuery } from '@tanstack/react-query'; + +import { apiRequest } from '@app/config/request'; + +import { UserWsKeyPair } from './types'; + +const encKeyKeys = { + getUserWorkspaceKey: (workspaceID: string) => ['worksapce-key-pair', { workspaceID }] as const +}; + +const fetchUserWsKey = async (workspaceID: string) => { + const { data } = await apiRequest.get<{ latestKey: UserWsKeyPair }>( + `/api/v1/key/${workspaceID}/latest` + ); + + return data.latestKey; +}; + +export const useGetUserWsKey = (workspaceID: string) => + useQuery({ + queryKey: encKeyKeys.getUserWorkspaceKey(workspaceID), + queryFn: () => fetchUserWsKey(workspaceID), + enabled: Boolean(workspaceID) + }); diff --git a/frontend/src/hooks/api/keys/types.ts b/frontend/src/hooks/api/keys/types.ts new file mode 100644 index 0000000000..bad61b5dd4 --- /dev/null +++ b/frontend/src/hooks/api/keys/types.ts @@ -0,0 +1,22 @@ +export type UserWsKeyPair = { + _id: string; + encryptedKey: string; + nonce: string; + sender: Sender; + receiver: string; + workspace: string; + createdAt: string; + updatedAt: string; + __v: number; +}; + +export type Sender = { + _id: string; + email: string; + createdAt: string; + updatedAt: string; + __v: number; + firstName: string; + lastName: string; + publicKey: string; +}; diff --git a/frontend/src/hooks/api/serviceTokens/index.ts b/frontend/src/hooks/api/serviceTokens/index.ts new file mode 100644 index 0000000000..548ad313ab --- /dev/null +++ b/frontend/src/hooks/api/serviceTokens/index.ts @@ -0,0 +1 @@ +export { useCreateServiceToken, useDeleteServiceToken, useGetUserWsServiceTokens } from './queries'; diff --git a/frontend/src/hooks/api/serviceTokens/queries.tsx b/frontend/src/hooks/api/serviceTokens/queries.tsx new file mode 100644 index 0000000000..70e0736d36 --- /dev/null +++ b/frontend/src/hooks/api/serviceTokens/queries.tsx @@ -0,0 +1,60 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; + +import { apiRequest } from '@app/config/request'; + +import { + CreateServiceTokenDTO, + CreateServiceTokenRes, + DeleteServiceTokenRes, + ServiceToken +} from './types'; + +const serviceTokenKeys = { + getAllWorkspaceServiceToken: (workspaceID: string) => [{ workspaceID }, 'service-tokens'] as const +}; + +const fetchWorkspaceServiceTokens = async (workspaceID: string) => { + const { data } = await apiRequest.get<{ serviceTokenData: ServiceToken[] }>( + `/api/v2/workspace/${workspaceID}/service-token-data` + ); + + return data.serviceTokenData; +}; + +type UseGetWorkspaceServiceTokensProps = { workspaceID: string }; + +export const useGetUserWsServiceTokens = ({ workspaceID }: UseGetWorkspaceServiceTokensProps) => + useQuery({ + queryKey: serviceTokenKeys.getAllWorkspaceServiceToken(workspaceID), + queryFn: () => fetchWorkspaceServiceTokens(workspaceID), + enabled: Boolean(workspaceID) + }); + +// mutation +export const useCreateServiceToken = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (body) => { + const { data } = await apiRequest.post('/api/v2/service-token/', body); + return data; + }, + onSuccess: ({ serviceTokenData: { workspace } }) => { + queryClient.invalidateQueries(serviceTokenKeys.getAllWorkspaceServiceToken(workspace)); + } + }); +}; + +export const useDeleteServiceToken = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (serviceTokenId) => { + const { data } = await apiRequest.delete(`/api/v2/service-token/${serviceTokenId}`); + return data; + }, + onSuccess: ({ serviceTokenData: { workspace } }) => { + queryClient.invalidateQueries(serviceTokenKeys.getAllWorkspaceServiceToken(workspace)); + } + }); +}; diff --git a/frontend/src/hooks/api/serviceTokens/types.ts b/frontend/src/hooks/api/serviceTokens/types.ts new file mode 100644 index 0000000000..a1eb73743d --- /dev/null +++ b/frontend/src/hooks/api/serviceTokens/types.ts @@ -0,0 +1,28 @@ +export type ServiceToken = { + _id: string; + name: string; + workspace: string; + environment: string; + user: string; + expiresAt: string; + createdAt: string; + updatedAt: string; + __v: number; +}; + +export type CreateServiceTokenDTO = { + name: string; + workspaceId: string; + environment: string; + expiresIn: number; + encryptedKey: string; + iv: string; + tag: string; +}; + +export type CreateServiceTokenRes = { + serviceToken: string; + serviceTokenData: ServiceToken; +}; + +export type DeleteServiceTokenRes = { serviceTokenData: ServiceToken }; diff --git a/frontend/src/hooks/api/subscriptions/index.tsx b/frontend/src/hooks/api/subscriptions/index.tsx new file mode 100644 index 0000000000..4bb98e85a4 --- /dev/null +++ b/frontend/src/hooks/api/subscriptions/index.tsx @@ -0,0 +1 @@ +export { useGetOrgSubscription } from './queries'; diff --git a/frontend/src/hooks/api/subscriptions/queries.tsx b/frontend/src/hooks/api/subscriptions/queries.tsx new file mode 100644 index 0000000000..4a65912efa --- /dev/null +++ b/frontend/src/hooks/api/subscriptions/queries.tsx @@ -0,0 +1,30 @@ +import { useQuery } from '@tanstack/react-query'; + +import { apiRequest } from '@app/config/request'; + +import { GetSubscriptionPlan } from './types'; + +// import { Workspace } from './types'; + +const subscriptionKeys = { + getOrgSubsription: (orgID: string) => ['subscription', { orgID }] as const +}; + +const fetchOrgSubscription = async (orgID: string) => { + const { data } = await apiRequest.get<{ subscriptions: GetSubscriptionPlan }>( + `/api/v1/organization/${orgID}/subscriptions` + ); + + return data.subscriptions; +}; + +type UseGetOrgSubscriptionProps = { + orgID: string; +}; + +export const useGetOrgSubscription = ({ orgID }: UseGetOrgSubscriptionProps) => + useQuery({ + queryKey: subscriptionKeys.getOrgSubsription(orgID), + queryFn: () => fetchOrgSubscription(orgID), + enabled: Boolean(orgID) + }); diff --git a/frontend/src/hooks/api/subscriptions/types.ts b/frontend/src/hooks/api/subscriptions/types.ts new file mode 100644 index 0000000000..f9dfcbf0b5 --- /dev/null +++ b/frontend/src/hooks/api/subscriptions/types.ts @@ -0,0 +1,25 @@ +export type GetSubscriptionPlan = { + data: { plan: SubscriptionPlan }[]; +}; + +export type SubscriptionPlan = { + id: string; + object: string; + active: boolean; + aggregate_usage: unknown; + amount: 1400; + amount_decimal: 1400; + billing_scheme: string; + created: 1674833546; + currency: string; + interval: string; + interval_count: 1; + livemode: false; + metadata: {}; + nickname: null; + product: string; + tiers_mode: unknown; + transform_usage: unknown; + trial_period_days: unknown; + usage_type: string; +}; diff --git a/frontend/src/hooks/api/types.ts b/frontend/src/hooks/api/types.ts new file mode 100644 index 0000000000..cc7498b723 --- /dev/null +++ b/frontend/src/hooks/api/types.ts @@ -0,0 +1,13 @@ +export type { GetAuthTokenAPI } from './auth/types'; +export type { UserWsKeyPair } from './keys/types'; +export type { CreateServiceTokenDTO, ServiceToken } from './serviceTokens/types'; +export type { GetSubscriptionPlan, SubscriptionPlan } from './subscriptions/types'; +export type { + CreateEnvironmentDTO, + DeleteEnvironmentDTO, + DeleteWorkspaceDTO, + RenameWorkspaceDTO, + UpdateEnvironmentDTO, + Workspace, + WorkspaceEnv +} from './workspace/types'; diff --git a/frontend/src/hooks/api/workspace/index.tsx b/frontend/src/hooks/api/workspace/index.tsx new file mode 100644 index 0000000000..5de95ab059 --- /dev/null +++ b/frontend/src/hooks/api/workspace/index.tsx @@ -0,0 +1,8 @@ +export { + useCreateWsEnvironment, + useDeleteWorkspace, + useDeleteWsEnvironment, + useGetUserWorkspaces, + useRenameWorkspace, + useUpdateWsEnvironment +} from './queries'; diff --git a/frontend/src/hooks/api/workspace/queries.tsx b/frontend/src/hooks/api/workspace/queries.tsx new file mode 100644 index 0000000000..b0566a43d8 --- /dev/null +++ b/frontend/src/hooks/api/workspace/queries.tsx @@ -0,0 +1,94 @@ +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; + +import { apiRequest } from '@app/config/request'; + +import { + CreateEnvironmentDTO, + DeleteEnvironmentDTO, + DeleteWorkspaceDTO, + RenameWorkspaceDTO, + UpdateEnvironmentDTO, + Workspace +} from './types'; + +const workspaceKeys = { + getAllUserWorkspace: ['workspaces'] as const +}; + +const fetchUserWorkspaces = async () => { + const { data } = await apiRequest.get<{ workspaces: Workspace[] }>('/api/v1/workspace'); + + return data.workspaces; +}; + +export const useGetUserWorkspaces = () => + useQuery(workspaceKeys.getAllUserWorkspace, fetchUserWorkspaces); + +// mutation +export const useRenameWorkspace = () => { + const queryClient = useQueryClient(); + + return useMutation<{}, {}, RenameWorkspaceDTO>({ + mutationFn: ({ workspaceID, newWorkspaceName }) => + apiRequest.post(`/api/v1/workspace/${workspaceID}/name`, { name: newWorkspaceName }), + onSuccess: () => { + queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace); + } + }); +}; + +export const useDeleteWorkspace = () => { + const queryClient = useQueryClient(); + + return useMutation<{}, {}, DeleteWorkspaceDTO>({ + mutationFn: ({ workspaceID }) => apiRequest.delete(`/api/v1/workspace/${workspaceID}`), + onSuccess: () => { + queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace); + } + }); +}; + +export const useCreateWsEnvironment = () => { + const queryClient = useQueryClient(); + + return useMutation<{}, {}, CreateEnvironmentDTO>({ + mutationFn: ({ workspaceID, environmentName, environmentSlug }) => + apiRequest.post(`/api/v2/workspace/${workspaceID}/environments`, { + environmentName, + environmentSlug + }), + onSuccess: () => { + queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace); + } + }); +}; + +export const useUpdateWsEnvironment = () => { + const queryClient = useQueryClient(); + + return useMutation<{}, {}, UpdateEnvironmentDTO>({ + mutationFn: ({ workspaceID, environmentName, environmentSlug, oldEnvironmentSlug }) => + apiRequest.put(`/api/v2/workspace/${workspaceID}/environments`, { + environmentName, + environmentSlug, + oldEnvironmentSlug + }), + onSuccess: () => { + queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace); + } + }); +}; + +export const useDeleteWsEnvironment = () => { + const queryClient = useQueryClient(); + + return useMutation<{}, {}, DeleteEnvironmentDTO>({ + mutationFn: ({ workspaceID, environmentSlug }) => + apiRequest.delete(`/api/v2/workspace/${workspaceID}/environments`, { + data: { environmentSlug } + }), + onSuccess: () => { + queryClient.invalidateQueries(workspaceKeys.getAllUserWorkspace); + } + }); +}; diff --git a/frontend/src/hooks/api/workspace/types.ts b/frontend/src/hooks/api/workspace/types.ts new file mode 100644 index 0000000000..cc47094775 --- /dev/null +++ b/frontend/src/hooks/api/workspace/types.ts @@ -0,0 +1,29 @@ +export type Workspace = { + __v: number; + _id: string; + name: string; + organization: string; + environments: WorkspaceEnv[]; +}; + +export type WorkspaceEnv = { name: string; slug: string }; + +// mutation dto +export type RenameWorkspaceDTO = { workspaceID: string; newWorkspaceName: string }; + +export type DeleteWorkspaceDTO = { workspaceID: string }; + +export type CreateEnvironmentDTO = { + workspaceID: string; + environmentSlug: string; + environmentName: string; +}; + +export type UpdateEnvironmentDTO = { + workspaceID: string; + oldEnvironmentSlug: string; + environmentSlug: string; + environmentName: string; +}; + +export type DeleteEnvironmentDTO = { workspaceID: string; environmentSlug: string }; diff --git a/frontend/src/hooks/usePopUp.tsx b/frontend/src/hooks/usePopUp.tsx index b0c4163beb..52839142d8 100644 --- a/frontend/src/hooks/usePopUp.tsx +++ b/frontend/src/hooks/usePopUp.tsx @@ -21,7 +21,7 @@ interface UsePopUpReturn | UsePopUpProps[]> { popUp: UsePopUpState; handlePopUpOpen: (popUpName: keyof UsePopUpState, data?: unknown) => void; handlePopUpClose: (popUpName: keyof UsePopUpState) => void; - handlePopUpToggle: (popUpName: keyof UsePopUpState) => void; + handlePopUpToggle: (popUpName: keyof UsePopUpState, state?: boolean) => void; } /** @@ -50,10 +50,10 @@ export const usePopUp = | UsePopUpProps[]>( setPopUp((oldState) => ({ ...oldState, [popUpName]: { isOpen: false } })); }, []); - const handlePopUpToggle = useCallback((popUpName: keyof UsePopUpState) => { + const handlePopUpToggle = useCallback((popUpName: keyof UsePopUpState, state?: boolean) => { setPopUp((oldState) => ({ ...oldState, - [popUpName]: { isOpen: !oldState[popUpName].isOpen } + [popUpName]: { isOpen: typeof state === 'undefined' ? !oldState[popUpName].isOpen : state } })); }, []); From 48cd84ce77cde98165a856a19cb0c3cd22ae2951 Mon Sep 17 00:00:00 2001 From: akhilmhdh Date: Fri, 3 Feb 2023 22:17:54 +0530 Subject: [PATCH 2/6] feat(ui): fine tuning components library with exiting app design --- frontend/src/components/v2/Button/Button.tsx | 19 ++-- frontend/src/components/v2/Card/Card.tsx | 4 +- .../DeleteActionModal/DeleteActionModal.tsx | 89 +++++++++++++++++++ .../components/v2/DeleteActionModal/index.tsx | 1 + .../components/v2/FormControl/FormControl.tsx | 10 ++- .../components/v2/IconButton/IconButton.tsx | 2 +- frontend/src/components/v2/Input/Input.tsx | 5 +- frontend/src/components/v2/Modal/Modal.tsx | 16 ++-- frontend/src/components/v2/Modal/index.tsx | 4 +- frontend/src/components/v2/Select/Select.tsx | 22 ++--- frontend/src/components/v2/Table/Table.tsx | 28 +++--- .../v2/UpgradePlanModal/UpgradePlanModal.tsx | 36 ++++++++ .../components/v2/UpgradePlanModal/index.tsx | 1 + frontend/src/components/v2/index.tsx | 2 + 14 files changed, 192 insertions(+), 47 deletions(-) create mode 100644 frontend/src/components/v2/DeleteActionModal/DeleteActionModal.tsx create mode 100644 frontend/src/components/v2/DeleteActionModal/index.tsx create mode 100644 frontend/src/components/v2/UpgradePlanModal/UpgradePlanModal.tsx create mode 100644 frontend/src/components/v2/UpgradePlanModal/index.tsx diff --git a/frontend/src/components/v2/Button/Button.tsx b/frontend/src/components/v2/Button/Button.tsx index 21548d0e3d..27f34838da 100644 --- a/frontend/src/components/v2/Button/Button.tsx +++ b/frontend/src/components/v2/Button/Button.tsx @@ -18,7 +18,8 @@ const buttonVariants = cva( 'font-inter font-medium', 'cursor-pointer', 'inline-flex items-center justify-center', - 'relative' + 'relative', + 'whitespace-nowrap' ], { variants: { @@ -33,7 +34,7 @@ const buttonVariants = cva( plain: '' }, isDisabled: { - true: 'bg-opacity-70 cursor-not-allowed', + true: 'bg-opacity-40 cursor-not-allowed', false: '' }, isFullWidth: { @@ -45,9 +46,9 @@ const buttonVariants = cva( false: '' }, size: { - xs: ['text-xs', 'py-1', 'px-2'], - sm: ['text-sm', 'py-2', 'px-4'], - md: ['text-md', 'py-2', 'px-6'], + xs: ['text-xs', 'py-1', 'px-1'], + sm: ['text-sm', 'py-2', 'px-2'], + md: ['text-md', 'py-2', 'px-4'], lg: ['text-lg', 'py-2', 'px-8'] } }, @@ -75,7 +76,7 @@ const buttonVariants = cva( { colorSchema: 'secondary', variant: 'plain', - className: 'text-mineshaft' + className: 'text-mineshaft-300' }, { colorSchema: 'danger', @@ -101,7 +102,7 @@ export const Button = forwardRef( children, isDisabled = false, className = '', - size = 'md', + size = 'sm', variant = 'solid', isFullWidth, isRounded = true, @@ -144,7 +145,7 @@ export const Button = forwardRef( )} ( {children} ( -
{children}
+
{children}
); export type CardProps = { @@ -47,7 +47,7 @@ export const Card = forwardRef(
void; + onChange?: (isOpen: boolean) => void; + deleteKey: string; + title: string; + onDeleteApproved: () => Promise; +}; + +export const DeleteActionModal = ({ + isOpen, + onClose, + onChange, + deleteKey, + onDeleteApproved, + title +}: Props): JSX.Element => { + const [inputData, setInputData] = useState(''); + const [isLoading, setIsLoading] = useToggle(); + + useEffect(() => { + setInputData(''); + }, [isOpen]); + + const onDelete = async () => { + setIsLoading.on(); + try { + await onDeleteApproved(); + } catch { + setIsLoading.off(); + } finally { + setIsLoading.off(); + } + }; + + return ( + { + setInputData(''); + if (onChange) onChange(isOpenState); + }} + > + + + +
+ } + onClose={onClose} + > +
+ + Type {deleteKey} to delete the resource + + } + className="mb-4" + > + setInputData(e.target.value)} /> + +
+ + + ); +}; diff --git a/frontend/src/components/v2/DeleteActionModal/index.tsx b/frontend/src/components/v2/DeleteActionModal/index.tsx new file mode 100644 index 0000000000..b69763984a --- /dev/null +++ b/frontend/src/components/v2/DeleteActionModal/index.tsx @@ -0,0 +1 @@ +export { DeleteActionModal } from './DeleteActionModal'; diff --git a/frontend/src/components/v2/FormControl/FormControl.tsx b/frontend/src/components/v2/FormControl/FormControl.tsx index 14e58d5bed..5a545acecf 100644 --- a/frontend/src/components/v2/FormControl/FormControl.tsx +++ b/frontend/src/components/v2/FormControl/FormControl.tsx @@ -11,7 +11,7 @@ export type FormLabelProps = { }; export const FormLabel = ({ id, label, isRequired }: FormLabelProps) => ( - + {label} {isRequired && *} @@ -25,7 +25,7 @@ export type FormHelperTextProps = { export const FormHelperText = ({ isError, text }: FormHelperTextProps) => (
@@ -46,6 +46,7 @@ export type FormControlProps = { helperText?: ReactNode; errorText?: ReactNode; children: JSX.Element; + className?: string; }; export const FormControl = ({ @@ -55,10 +56,11 @@ export const FormControl = ({ helperText, errorText, id, - isError + isError, + className }: FormControlProps): JSX.Element => { return ( -
+
{typeof label === 'string' ? ( ) : ( diff --git a/frontend/src/components/v2/IconButton/IconButton.tsx b/frontend/src/components/v2/IconButton/IconButton.tsx index b1a1f4813d..eb49196177 100644 --- a/frontend/src/components/v2/IconButton/IconButton.tsx +++ b/frontend/src/components/v2/IconButton/IconButton.tsx @@ -14,7 +14,7 @@ const iconButtonVariants = cva( [ 'button', 'transition-all', - 'font-inter font-medium', + 'font-inter font-medium user-select-none', 'cursor-pointer', 'inline-flex items-center justify-center', 'relative' diff --git a/frontend/src/components/v2/Input/Input.tsx b/frontend/src/components/v2/Input/Input.tsx index 4f502e31db..8c3685dacd 100644 --- a/frontend/src/components/v2/Input/Input.tsx +++ b/frontend/src/components/v2/Input/Input.tsx @@ -8,6 +8,7 @@ type Props = { isRequired?: boolean; leftIcon?: ReactNode; rightIcon?: ReactNode; + isDisabled?: boolean; }; const inputVariants = cva( @@ -46,7 +47,7 @@ const inputParentContainerVariants = cva('inline-flex font-inter items-center bo }, isError: { true: 'border-red', - false: 'border-mineshaft-400' + false: 'border-mineshaft-500' }, isFullWidth: { true: 'w-full', @@ -70,6 +71,7 @@ export const Input = forwardRef( className, isRounded = true, isFullWidth = true, + isDisabled, isError = false, isRequired, leftIcon, @@ -87,6 +89,7 @@ export const Input = forwardRef( {...props} required={isRequired} ref={ref} + disabled={isDisabled} className={twMerge( leftIcon ? 'pl-9' : 'pl-4', rightIcon ? 'pr-9' : 'pr-4', diff --git a/frontend/src/components/v2/Modal/Modal.tsx b/frontend/src/components/v2/Modal/Modal.tsx index c7d42541dc..eea12fbc51 100644 --- a/frontend/src/components/v2/Modal/Modal.tsx +++ b/frontend/src/components/v2/Modal/Modal.tsx @@ -11,31 +11,32 @@ export type ModalContentProps = DialogPrimitive.DialogContentProps & { title?: ReactNode; subTitle?: string; footerContent?: ReactNode; + onClose?: () => void; }; export const ModalContent = forwardRef( - ({ children, title, subTitle, className, footerContent, ...props }, forwardedRef) => ( + ({ children, title, subTitle, className, footerContent, onClose, ...props }, forwardedRef) => ( {title && {title}} {children} {footerContent && {footerContent}} - + @@ -55,3 +56,6 @@ export const Modal = ({ isOpen, ...props }: ModalProps) => ( export const ModalTrigger = DialogPrimitive.Trigger; export type ModalTriggerProps = DialogPrimitive.DialogTriggerProps; + +export const ModalClose = DialogPrimitive.Close; +export type ModalCloseProps = DialogPrimitive.DialogCloseProps; diff --git a/frontend/src/components/v2/Modal/index.tsx b/frontend/src/components/v2/Modal/index.tsx index c97a564fba..7517b3ec1b 100644 --- a/frontend/src/components/v2/Modal/index.tsx +++ b/frontend/src/components/v2/Modal/index.tsx @@ -1,2 +1,2 @@ -export type { ModalContentProps, ModalProps, ModalTriggerProps } from './Modal'; -export { Modal, ModalContent, ModalTrigger } from './Modal'; +export type { ModalCloseProps, ModalContentProps, ModalProps, ModalTriggerProps } from './Modal'; +export { Modal, ModalClose, ModalContent, ModalTrigger } from './Modal'; diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx index c093b8b70d..e76e902605 100644 --- a/frontend/src/components/v2/Select/Select.tsx +++ b/frontend/src/components/v2/Select/Select.tsx @@ -22,21 +22,23 @@ export const Select = forwardRef( - {!props.disabled && - - } + {!props.disabled && ( + + + + )} @@ -75,11 +77,11 @@ export const SelectItem = forwardRef( (
( @@ -47,7 +47,7 @@ export type THeadProps = { }; export const THead = ({ children, className }: THeadProps): JSX.Element => ( - + {children} ); @@ -56,15 +56,17 @@ export const THead = ({ children, className }: THeadProps): JSX.Element => ( export type TrProps = { children: ReactNode; className?: string; -}; +} & HTMLAttributes; -export const Tr = ({ children, className }: TrProps): JSX.Element => ( - {children} +export const Tr = ({ children, className, ...props }: TrProps): JSX.Element => ( + + {children} + ); // table head columns export type ThProps = { - children: ReactNode; + children?: ReactNode; className?: string; }; @@ -84,10 +86,12 @@ export const TBody = ({ children, className }: TBodyProps): JSX.Element => ( // table body columns export type TdProps = { - children: ReactNode; + children?: ReactNode; className?: string; -}; +} & TdHTMLAttributes; -export const Td = ({ children, className }: TdProps): JSX.Element => ( - +export const Td = ({ children, className, ...props }: TdProps): JSX.Element => ( + ); diff --git a/frontend/src/components/v2/UpgradePlanModal/UpgradePlanModal.tsx b/frontend/src/components/v2/UpgradePlanModal/UpgradePlanModal.tsx new file mode 100644 index 0000000000..e991ca3a87 --- /dev/null +++ b/frontend/src/components/v2/UpgradePlanModal/UpgradePlanModal.tsx @@ -0,0 +1,36 @@ +import Link from 'next/link'; + +import { Button } from '../Button'; +import { Modal, ModalClose, ModalContent } from '../Modal'; + +type Props = { + isOpen?: boolean; + onOpenChange?: (isOpen: boolean) => void; + text: string; +}; + +export const UpgradePlanModal = ({ text, isOpen, onOpenChange }: Props): JSX.Element => ( + + + + , + + + + ]} + > +

{text}

+

+ Upgrade and get access to this, as well as to other powerful enhancements. +

+
+
+); diff --git a/frontend/src/components/v2/UpgradePlanModal/index.tsx b/frontend/src/components/v2/UpgradePlanModal/index.tsx new file mode 100644 index 0000000000..e4649c2dfd --- /dev/null +++ b/frontend/src/components/v2/UpgradePlanModal/index.tsx @@ -0,0 +1 @@ +export { UpgradePlanModal } from './UpgradePlanModal'; diff --git a/frontend/src/components/v2/index.tsx b/frontend/src/components/v2/index.tsx index 4371140473..0f89a3a2b7 100644 --- a/frontend/src/components/v2/index.tsx +++ b/frontend/src/components/v2/index.tsx @@ -1,6 +1,7 @@ export * from './Button'; export * from './Card'; export * from './Checkbox'; +export * from './DeleteActionModal'; export * from './Dropdown'; export * from './FormControl'; export * from './IconButton'; @@ -12,3 +13,4 @@ export * from './Spinner'; export * from './Switch'; export * from './Table'; export * from './TextArea'; +export * from './UpgradePlanModal'; From a4f78437278a593a92513283742b7ac461f3b9b2 Mon Sep 17 00:00:00 2001 From: akhilmhdh Date: Fri, 3 Feb 2023 22:18:30 +0530 Subject: [PATCH 3/6] feat(ui): global workspace and subscription context --- .../SubscriptionContext.tsx | 47 +++++++++++++++++ .../src/context/SubscriptionContext/index.tsx | 1 + .../WorkspaceContext/WorkspaceContext.tsx | 52 +++++++++++++++++++ .../src/context/WorkspaceContext/index.tsx | 1 + frontend/src/context/index.tsx | 2 + 5 files changed, 103 insertions(+) create mode 100644 frontend/src/context/SubscriptionContext/SubscriptionContext.tsx create mode 100644 frontend/src/context/SubscriptionContext/index.tsx create mode 100644 frontend/src/context/WorkspaceContext/WorkspaceContext.tsx create mode 100644 frontend/src/context/WorkspaceContext/index.tsx create mode 100644 frontend/src/context/index.tsx diff --git a/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx b/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx new file mode 100644 index 0000000000..ae99102243 --- /dev/null +++ b/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx @@ -0,0 +1,47 @@ +import { createContext, ReactNode, useContext, useMemo } from 'react'; + +import { useGetOrgSubscription } from '@app/hooks/api'; +import { GetSubscriptionPlan } from '@app/hooks/api/types'; + +import { useWorkspace } from '../WorkspaceContext'; +// import { Subscription } from '@app/hooks/api/workspace/types'; + +type TSubscriptionContext = { + subscription?: GetSubscriptionPlan; + subscriptionPlan: string; + isLoading: boolean; +}; + +const SubscriptionContext = createContext(null); + +type Props = { + children: ReactNode; +}; + +export const SubscriptionProvider = ({ children }: Props): JSX.Element => { + const { currentWorkspace } = useWorkspace(); + const { data, isLoading } = useGetOrgSubscription({ + orgID: currentWorkspace?.organization || '' + }); + + // memorize the workspace details for the context + const value = useMemo( + () => ({ + subscription: data, + subscriptionPlan: data?.data?.[0]?.plan?.product || '', + isLoading + }), + [data, isLoading] + ); + + return {children}; +}; + +export const useSubscription = () => { + const ctx = useContext(SubscriptionContext); + if (!ctx) { + throw new Error('useSubscription has to be used within '); + } + + return ctx; +}; diff --git a/frontend/src/context/SubscriptionContext/index.tsx b/frontend/src/context/SubscriptionContext/index.tsx new file mode 100644 index 0000000000..9a2b07b15a --- /dev/null +++ b/frontend/src/context/SubscriptionContext/index.tsx @@ -0,0 +1 @@ +export { SubscriptionProvider, useSubscription } from './SubscriptionContext'; diff --git a/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx b/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx new file mode 100644 index 0000000000..ea82fbbe7b --- /dev/null +++ b/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx @@ -0,0 +1,52 @@ +import { createContext, ReactNode, useContext, useEffect, useMemo } from 'react'; +import { useRouter } from 'next/router'; + +import { useGetUserWorkspaces } from '@app/hooks/api'; +import { Workspace } from '@app/hooks/api/workspace/types'; + +type TWorkspaceContext = { + workspaces: Workspace[]; + currentWorkspace?: Workspace; + isLoading: boolean; +}; + +const WorkspaceContext = createContext(null); + +type Props = { + children: ReactNode; +}; + +export const WorkspaceProvider = ({ children }: Props): JSX.Element => { + const { data: ws, isLoading } = useGetUserWorkspaces(); + const router = useRouter(); + const workspaceId = router.query.id; + + // memorize the workspace details for the context + const value = useMemo(() => { + return { + workspaces: ws || [], + currentWorkspace: (ws || []).find(({ _id: id }) => id === workspaceId), + isLoading + }; + }, [ws, workspaceId, isLoading]); + + useEffect(() => { + // not loading and current workspace is empty + // ws empty means user has no access to the ws + // push to the first workspace + if (!isLoading && !value?.currentWorkspace?._id) { + router.push(`/dashboard/${value.workspaces?.[0]?._id}`); + } + }, [value?.currentWorkspace?._id, isLoading, value.workspaces?.[0]?._id, router.pathname]); + + return {children}; +}; + +export const useWorkspace = () => { + const ctx = useContext(WorkspaceContext); + if (!ctx) { + throw new Error('useWorkspace has to be used within '); + } + + return ctx; +}; diff --git a/frontend/src/context/WorkspaceContext/index.tsx b/frontend/src/context/WorkspaceContext/index.tsx new file mode 100644 index 0000000000..3496038c3b --- /dev/null +++ b/frontend/src/context/WorkspaceContext/index.tsx @@ -0,0 +1 @@ +export { useWorkspace, WorkspaceProvider } from './WorkspaceContext'; diff --git a/frontend/src/context/index.tsx b/frontend/src/context/index.tsx new file mode 100644 index 0000000000..1bf59f9ac4 --- /dev/null +++ b/frontend/src/context/index.tsx @@ -0,0 +1,2 @@ +export { SubscriptionProvider, useSubscription } from './SubscriptionContext'; +export { useWorkspace, WorkspaceProvider } from './WorkspaceContext'; From ed148a542d6671dc2f172e90d265777328e765cb Mon Sep 17 00:00:00 2001 From: akhilmhdh Date: Fri, 3 Feb 2023 22:19:03 +0530 Subject: [PATCH 4/6] feat(ui): implemented the new project settings page --- frontend/public/locales/en/section-token.json | 2 +- frontend/src/components/basic/Layout.tsx | 57 ++- .../basic/table/EnvironmentsTable.tsx | 57 ++- frontend/src/components/dashboard/SideBar.tsx | 4 +- .../components/navigation/NavBarDashboard.tsx | 2 +- .../src/components/navigation/NavHeader.tsx | 23 +- frontend/src/const.ts | 28 +- frontend/src/pages/_app.tsx | 16 +- frontend/src/pages/activity/[id].tsx | 2 +- frontend/src/pages/dashboard/[id].tsx | 4 +- frontend/src/pages/settings/project/[id].tsx | 328 +----------------- .../ProjectSettingsPage.tsx | 287 +++++++++++++++ .../CopyProjectIDSection.tsx | 66 ++++ .../components/CopyProjectIDSection/index.tsx | 1 + .../EnvironmentSection/EnvironmentSection.tsx | 239 +++++++++++++ .../components/EnvironmentSection/index.tsx | 1 + .../ProjectNameChangeSection.tsx | 71 ++++ .../ProjectNameChangeSection/index.tsx | 1 + .../ServiceTokenSection.tsx | 307 ++++++++++++++++ .../components/ServiceTokenSection/index.tsx | 1 + .../ProjectSettingsPage/components/index.tsx | 6 + .../Settings/ProjectSettingsPage/index.tsx | 1 + 22 files changed, 1099 insertions(+), 405 deletions(-) create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/ProjectSettingsPage.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/CopyProjectIDSection/CopyProjectIDSection.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/CopyProjectIDSection/index.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/EnvironmentSection/EnvironmentSection.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/EnvironmentSection/index.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/ProjectNameChangeSection/ProjectNameChangeSection.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/ProjectNameChangeSection/index.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenSection/ServiceTokenSection.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/ServiceTokenSection/index.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/components/index.tsx create mode 100644 frontend/src/views/Settings/ProjectSettingsPage/index.tsx diff --git a/frontend/public/locales/en/section-token.json b/frontend/public/locales/en/section-token.json index d12bd202c1..ce468b1af8 100644 --- a/frontend/public/locales/en/section-token.json +++ b/frontend/public/locales/en/section-token.json @@ -4,7 +4,7 @@ "add-new": "Add New Token", "add-dialog": { "title": "Add a service token for {{target}}", - "description": "Specify the name, environment, and expiry period. When a token is generated, you will only be able to see it once before it disappears. Make sure to save it somewhere.", + "description": "When a token is generated, you will only be able to see it once before it disappears. Make sure to save it somewhere.", "name": "Service Token Name", "add": "Add Service Token", "copy-service-token": "Copy your service token", diff --git a/frontend/src/components/basic/Layout.tsx b/frontend/src/components/basic/Layout.tsx index a3d6092a1a..ba4cf73b2e 100644 --- a/frontend/src/components/basic/Layout.tsx +++ b/frontend/src/components/basic/Layout.tsx @@ -187,10 +187,10 @@ const Layout = ({ children }: LayoutProps) => { }); const userWorkspaces = orgUserProjects; if ( - userWorkspaces.length === 0 && - router.asPath !== '/noprojects' && - !router.asPath.includes('home') && - !router.asPath.includes('settings') || + (userWorkspaces.length === 0 && + router.asPath !== '/noprojects' && + !router.asPath.includes('home') && + !router.asPath.includes('settings')) || router.asPath === '/dashboard/undefined' ) { router.push('/noprojects'); @@ -246,16 +246,15 @@ const Layout = ({ children }: LayoutProps) => { return ( <> -
-
{children} + {children} +