From d0baa8cdd2c75bdf7730e7afc1ed8b87d01c6cd5 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Wed, 13 Nov 2024 20:18:12 +0000 Subject: [PATCH 01/71] feat: initial commit for idp org sync settings --- site/components.json | 3 +- site/package.json | 5 + site/pnpm-lock.yaml | 2593 +++++++++++------ site/src/api/api.ts | 21 + site/src/api/queries/idpsync.ts | 23 + site/src/components/ui/badge.tsx | 36 + site/src/components/ui/button.tsx | 4 +- site/src/components/ui/command.tsx | 151 + site/src/components/ui/dialog.tsx | 120 + site/src/components/ui/label.tsx | 24 + site/src/components/ui/multiple-selector.tsx | 637 ++++ site/src/components/ui/switch.tsx | 27 + site/src/contexts/auth/permissions.tsx | 7 + site/src/index.css | 24 +- site/src/modules/management/SidebarView.tsx | 5 + .../IdpOrgSyncPage/IdpOrgSyncPage.tsx | 96 + .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 287 ++ .../IdpOrgSyncPage/IdpPillList.tsx | 106 + site/src/router.tsx | 4 + site/src/testHelpers/entities.ts | 2 + site/tailwind.config.js | 19 +- site/tsconfig.json | 5 +- site/vite.config.mts | 1 + 23 files changed, 3354 insertions(+), 846 deletions(-) create mode 100644 site/src/api/queries/idpsync.ts create mode 100644 site/src/components/ui/badge.tsx create mode 100644 site/src/components/ui/command.tsx create mode 100644 site/src/components/ui/dialog.tsx create mode 100644 site/src/components/ui/label.tsx create mode 100644 site/src/components/ui/multiple-selector.tsx create mode 100644 site/src/components/ui/switch.tsx create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpPillList.tsx diff --git a/site/components.json b/site/components.json index 8f7ae7d9d6da5..f3db7d2f5b9eb 100644 --- a/site/components.json +++ b/site/components.json @@ -16,5 +16,6 @@ "ui": "/components/ui", "lib": "/lib", "hooks": "/hooks" - } + }, + "iconLibrary": "lucide" } diff --git a/site/package.json b/site/package.json index 109e7814beb46..5731c026c9d28 100644 --- a/site/package.json +++ b/site/package.json @@ -50,7 +50,11 @@ "@mui/system": "5.16.7", "@mui/utils": "5.16.6", "@mui/x-tree-view": "7.18.0", + "@radix-ui/react-dialog": "1.1.2", + "@radix-ui/react-label": "2.1.0", + "@radix-ui/react-slider": "1.2.1", "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-switch": "1.1.1", "@tanstack/react-query-devtools": "4.35.3", "@xterm/addon-canvas": "0.7.0", "@xterm/addon-fit": "0.10.0", @@ -67,6 +71,7 @@ "chroma-js": "2.4.2", "class-variance-authority": "0.7.0", "clsx": "2.1.1", + "cmdk": "1.0.0", "color-convert": "2.0.1", "cron-parser": "4.9.0", "cronstrue": "2.50.0", diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml index fbd144a3acbd2..368b3e737279c 100644 --- a/site/pnpm-lock.yaml +++ b/site/pnpm-lock.yaml @@ -63,9 +63,21 @@ importers: '@mui/x-tree-view': specifier: 7.18.0 version: 7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': + specifier: 1.1.2 + version: 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-label': + specifier: 2.1.0 + version: 2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slider': + specifier: 1.2.1 + version: 1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-slot': specifier: 1.1.0 version: 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-switch': + specifier: 1.1.1 + version: 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@tanstack/react-query-devtools': specifier: 4.35.3 version: 4.35.3(@tanstack/react-query@4.35.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -114,6 +126,9 @@ importers: clsx: specifier: 2.1.1 version: 2.1.1 + cmdk: + specifier: 1.0.0 + version: 1.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) color-convert: specifier: 2.0.1 version: 2.0.1 @@ -1523,638 +1538,1035 @@ packages: '@protobufjs/utf8@1.1.0': resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - '@radix-ui/react-compose-refs@1.1.0': - resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + '@radix-ui/number@1.1.0': + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + + '@radix-ui/primitive@1.0.1': + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-collection@1.1.0': + resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} peerDependencies: '@types/react': '*' + '@types/react-dom': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true + '@types/react-dom': + optional: true - '@radix-ui/react-slot@1.1.0': - resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + '@radix-ui/react-compose-refs@1.0.1': + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} peerDependencies: '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react: ^16.8 || ^17.0 || ^18.0 peerDependenciesMeta: '@types/react': optional: true - '@remix-run/router@1.19.2': - resolution: {integrity: sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==} - engines: {node: '>=14.0.0'} - - '@rollup/pluginutils@5.0.5': - resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': optional: true - '@rollup/rollup-android-arm-eabi@4.24.3': - resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.24.3': - resolution: {integrity: sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.24.3': - resolution: {integrity: sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.24.3': - resolution: {integrity: sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-freebsd-arm64@4.24.3': - resolution: {integrity: sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.24.3': - resolution: {integrity: sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==} - cpu: [x64] - os: [freebsd] - - '@rollup/rollup-linux-arm-gnueabihf@4.24.3': - resolution: {integrity: sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.24.3': - resolution: {integrity: sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.24.3': - resolution: {integrity: sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.24.3': - resolution: {integrity: sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': - resolution: {integrity: sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.24.3': - resolution: {integrity: sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.24.3': - resolution: {integrity: sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.24.3': - resolution: {integrity: sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.24.3': - resolution: {integrity: sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.24.3': - resolution: {integrity: sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.24.3': - resolution: {integrity: sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.24.3': - resolution: {integrity: sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==} - cpu: [x64] - os: [win32] - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@sinonjs/commons@3.0.0': - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} - - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - - '@storybook/addon-actions@8.4.6': - resolution: {integrity: sha512-vbplwjMj7UXbdzoFhQkqFHLQAPJX8OVGTM9Q+yjuWDHViaKKUlgRWp0jclT7aIDNJQU2a6wJbTimHgJeF16Vhg==} + '@radix-ui/react-context@1.0.1': + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-backgrounds@8.4.6': - resolution: {integrity: sha512-RSjJ3iElxlQXebZrz1s5LeoLpAXr9LAGifX7w0abMzN5sg6QSwNeUHko2eT3V57M3k1Fa/5Eelso/QBQifFEog==} + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-controls@8.4.6': - resolution: {integrity: sha512-70pEGWh0C2g8s0DYsISElOzsMbQS6p/K9iU5EqfotDF+hvEqstjsV/bTbR5f3OK4vR/7Gxamk7j8RVd14Nql6A==} + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-docs@8.4.6': - resolution: {integrity: sha512-olxz61W7PW/EsXrKhLrYbI3rn9GMBhY3KIOF/6tumbRkh0Siu/qe4EAImaV9NNwiC1R7+De/1OIVMY6o0EIZVw==} + '@radix-ui/react-dialog@1.0.5': + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/addon-essentials@8.4.6': - resolution: {integrity: sha512-TbFqyvWFUKw8LBpVcZuGQydzVB/3kSuHxDHi+Wj3Qas3cxBl7+w4/HjwomT2D2Tni1dZ1uPDOsAtNLmwp1POsg==} + '@radix-ui/react-dialog@1.1.2': + resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/addon-highlight@8.4.6': - resolution: {integrity: sha512-m8wedbqDMbwkP99dNHkHAiAUkx5E7FEEEyLPX1zfkhZWOGtTkavXHH235SGp50zD75LQ6eC/BvgegrzxSQa9Wg==} + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-interactions@8.4.6': - resolution: {integrity: sha512-sR2oUSYIGUoAdrHT+fM1zgykhad98bsJ11c79r7HfBMXEPWc1yRcjIMmz8Xz06FMROMfebqduYDf60V++/I0Jw==} + '@radix-ui/react-dismissable-layer@1.0.5': + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/addon-links@8.4.6': - resolution: {integrity: sha512-1KoG9ytEWWwdF/dheu1O0dayQTMsHw++Qk8afqw7bwW1Cxz5LuAJH5ZscFWMiE5f4Xq1NgaJdeAUaIavyoOcdg==} + '@radix-ui/react-dismissable-layer@1.1.1': + resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - react: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@storybook/addon-mdx-gfm@8.4.6': - resolution: {integrity: sha512-wagsSBUN6pwcSZSWxp/aOhE16ZKI8ZW4XeRT6QivySmkJaLcbva+HNvQOijdXIM28W8PprKjqtyVa8nu4YQxsw==} + '@radix-ui/react-focus-guards@1.0.1': + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-measure@8.4.6': - resolution: {integrity: sha512-N2IRpr39g5KpexCAS1vIHJT+phc9Yilwm3PULds2rQ66VMTbkxobXJDdt0NS05g5n9/eDniroNQwdCeLg4tkpw==} + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-outline@8.4.6': - resolution: {integrity: sha512-EhcWx8OpK85HxQulLWzpWUHEwQpDYuAiKzsFj9ivAbfeljkIWNTG04mierfaH1xX016uL9RtLJL/zwBS5ChnFg==} + '@radix-ui/react-focus-scope@1.0.4': + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/addon-themes@8.4.6': - resolution: {integrity: sha512-0Eyh7jxxQ8hc7KIO2bJF8BKY1CRJ9zPo2DKoRiUKDoSGSP8qdlj4V/ks892GcUffdhTjoFAJCRzG7Ff+TnVKrA==} + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/addon-toolbars@8.4.6': - resolution: {integrity: sha512-+Xao/uGa8FnYsyUiREUkYXWNysm3Aba8tL/Bwd+HufHtdiKJGa9lrXaC7VLCqBUaEjwqM3aaPwqEWIROsthmPQ==} + '@radix-ui/react-id@1.0.1': + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/addon-viewport@8.4.6': - resolution: {integrity: sha512-BuQll5YzOCpMS7p5Rsw9wcmi8hTnEKyg6+qAbkZNfiZ2JhXCa1GFUqX725fF1whpYVQULtkQxU8r+vahoRn7Yg==} + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/blocks@8.4.6': - resolution: {integrity: sha512-Gzbx8hM7ZQIHlQELcFIMbY1v+r1Po4mlinq0QVPtKS4lBcW4eZIsesbxOaL+uFNrxb583TLFzXo0DbRPzS46sg==} + '@radix-ui/react-label@2.1.0': + resolution: {integrity: sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - react: + '@types/react': optional: true - react-dom: + '@types/react-dom': optional: true - '@storybook/builder-vite@8.4.6': - resolution: {integrity: sha512-PyJsaEPyuRFFEplpNUi+nbuJd7d1DC2dAZjpsaHTXyqg5iPIbkIgsbCJLUDeIXnUDqM/utjmMpN0sQKJuhIc6w==} + '@radix-ui/react-portal@1.0.4': + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: - storybook: ^8.4.6 - vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/channels@8.1.11': - resolution: {integrity: sha512-fu5FTqo6duOqtJFa6gFzKbiSLJoia+8Tibn3xFfB6BeifWrH81hc+AZq0lTmHo5qax2G5t8ZN8JooHjMw6k2RA==} + '@radix-ui/react-portal@1.1.2': + resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/client-logger@8.1.11': - resolution: {integrity: sha512-DVMh2usz3yYmlqCLCiCKy5fT8/UR9aTh+gSqwyNFkGZrIM4otC5A8eMXajXifzotQLT5SaOEnM3WzHwmpvMIEA==} + '@radix-ui/react-presence@1.0.1': + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/components@8.4.6': - resolution: {integrity: sha512-9tKSJJCyFT5RZMRGyozTBJkr9C9Yfk1nuOE9XbDEE1Z+3/IypKR9+iwc5mfNBStDNY+rxtYWNLKBb5GPR2yhzA==} + '@radix-ui/react-presence@1.1.1': + resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==} peerDependencies: - storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/core-events@8.1.11': - resolution: {integrity: sha512-vXaNe2KEW9BGlLrg0lzmf5cJ0xt+suPjWmEODH5JqBbrdZ67X6ApA2nb6WcxDQhykesWCuFN5gp1l+JuDOBi7A==} + '@radix-ui/react-primitive@1.0.3': + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/core@8.4.6': - resolution: {integrity: sha512-WeojVtHy0/t50tzw/15S+DLzKsj8BN9yWdo3vJMvm+nflLFvfq1XvD9WGOWeaFp8E/o3AP+4HprXG0r42KEJtA==} + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} peerDependencies: - prettier: ^2 || ^3 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - prettier: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@storybook/csf-plugin@8.4.6': - resolution: {integrity: sha512-JDIT0czC4yMgKGNf39KTZr3zm5MusAZdn6LBrTfvWb7CrTCR4iVHa4lp2yb7EJk41vHsBec0QUYDDuiFH/vV0g==} + '@radix-ui/react-slider@1.2.1': + resolution: {integrity: sha512-bEzQoDW0XP+h/oGbutF5VMWJPAl/UU8IJjr7h02SOHDIIIxq+cep8nItVNoBV+OMmahCdqdF38FTpmXoqQUGvw==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/csf@0.1.11': - resolution: {integrity: sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==} + '@radix-ui/react-slot@1.0.2': + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/global@5.0.0': - resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/icons@1.2.12': - resolution: {integrity: sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==} - engines: {node: '>=14.0.0'} + '@radix-ui/react-switch@1.1.1': + resolution: {integrity: sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - '@storybook/instrumenter@8.4.6': - resolution: {integrity: sha512-snXjlgbp065A6KoK9zkjBYEIMCSlN5JefPKzt1FC0rbcbtahhD+iPpqISKhDSczwgOku/JVhVUDp/vU7AIf4mg==} + '@radix-ui/react-use-callback-ref@1.0.1': + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/manager-api@8.4.6': - resolution: {integrity: sha512-TsXlQ5m5rTl2KNT9icPFyy822AqXrx1QplZBt/L7cFn7SpqQKDeSta21FH7MG0piAvzOweXebVSqKngJ6cCWWQ==} + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} peerDependencies: - storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/preview-api@8.4.6': - resolution: {integrity: sha512-LbD+lR1FGvWaJBXteVx5xdgs1x1D7tyidBg2CsW2ex+cP0iJ176JgjPfutZxlWOfQnhfRYNnJ3WKoCIfxFOTKA==} + '@radix-ui/react-use-controllable-state@1.0.1': + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} peerDependencies: - storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/react-dom-shim@8.4.6': - resolution: {integrity: sha512-f7RM8GO++fqMxbjNdEzeGS1P821jXuwRnAraejk5hyjB5SqetauFxMwoFYEYfJXPaLX2qIubnIJ78hdJ/IBaEA==} + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/react-vite@8.4.6': - resolution: {integrity: sha512-bVoYj3uJRz0SknK2qN3vBVSoEXsvyARQLuHjP9eX0lWBd9XSxZinmVbexPdD0OeJYcJIdmbli2/Gw7/hu5CjFA==} - engines: {node: '>=18.0.0'} + '@radix-ui/react-use-escape-keydown@1.0.3': + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.4.6 - vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/react@8.4.6': - resolution: {integrity: sha512-QAT23beoYNLhFGAXPimtuMErvpcI7eZbZ4AlLqW1fhiTZrRYw06cjC1bs9H3tODMcHH9LS5p3Wz9b29jtV2XGw==} - engines: {node: '>=18.0.0'} + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} peerDependencies: - '@storybook/test': 8.4.6 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.4.6 - typescript: '>= 4.2.x' + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - '@storybook/test': + '@types/react': optional: true - typescript: + + '@radix-ui/react-use-layout-effect@1.0.1': + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': optional: true - '@storybook/test@8.4.6': - resolution: {integrity: sha512-MeU1g65YgU66M2NtmEIL9gVeHk+en0k9Hp0wfxEO7NT/WLfaOD5RXLRDJVhbAlrH/6tLeWKIPNh/D26y27vO/g==} + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} peerDependencies: - storybook: ^8.4.6 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@storybook/theming@8.4.6': - resolution: {integrity: sha512-q7vDPN/mgj7cXIVQ9R1/V75hrzNgKkm2G0LjMo57//9/djQ+7LxvBsR1iScbFIRSEqppvMiBFzkts+2uXidySA==} + '@radix-ui/react-use-previous@1.1.0': + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} peerDependencies: - storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@swc/core-darwin-arm64@1.3.38': - resolution: {integrity: sha512-4ZTJJ/cR0EsXW5UxFCifZoGfzQ07a8s4ayt1nLvLQ5QoB1GTAf9zsACpvWG8e7cmCR0L76R5xt8uJuyr+noIXA==} - engines: {node: '>=10'} + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@remix-run/router@1.19.2': + resolution: {integrity: sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==} + engines: {node: '>=14.0.0'} + + '@rollup/pluginutils@5.0.5': + resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.24.3': + resolution: {integrity: sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.24.3': + resolution: {integrity: sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.24.3': + resolution: {integrity: sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.3.38': - resolution: {integrity: sha512-Kim727rNo4Dl8kk0CR8aJQe4zFFtsT1TZGlNrNMUgN1WC3CRX7dLZ6ZJi/VVcTG1cbHp5Fp3mUzwHsMxEh87Mg==} - engines: {node: '>=10'} + '@rollup/rollup-darwin-x64@4.24.3': + resolution: {integrity: sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.3.38': - resolution: {integrity: sha512-yaRdnPNU2enlJDRcIMvYVSyodY+Amhf5QuXdUbAj6rkDD6wUs/s9C6yPYrFDmoTltrG+nBv72mUZj+R46wVfSw==} - engines: {node: '>=10'} + '@rollup/rollup-freebsd-arm64@4.24.3': + resolution: {integrity: sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.24.3': + resolution: {integrity: sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.24.3': + resolution: {integrity: sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.3.38': - resolution: {integrity: sha512-iNY1HqKo/wBSu3QOGBUlZaLdBP/EHcwNjBAqIzpb8J64q2jEN02RizqVW0mDxyXktJ3lxr3g7VW9uqklMeXbjQ==} - engines: {node: '>=10'} + '@rollup/rollup-linux-arm-musleabihf@4.24.3': + resolution: {integrity: sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.24.3': + resolution: {integrity: sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.3.38': - resolution: {integrity: sha512-LJCFgLZoPRkPCPmux+Q5ctgXRp6AsWhvWuY61bh5bIPBDlaG9pZk94DeHyvtiwT0syhTtXb2LieBOx6NqN3zeA==} - engines: {node: '>=10'} + '@rollup/rollup-linux-arm64-musl@4.24.3': + resolution: {integrity: sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.3.38': - resolution: {integrity: sha512-hRQGRIWHmv2PvKQM/mMV45mVXckM2+xLB8TYLLgUG66mmtyGTUJPyxjnJkbI86WNGqo18k+lAuMG2mn6QmzYwQ==} - engines: {node: '>=10'} - cpu: [x64] + '@rollup/rollup-linux-powerpc64le-gnu@4.24.3': + resolution: {integrity: sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==} + cpu: [ppc64] os: [linux] - '@swc/core-linux-x64-musl@1.3.38': - resolution: {integrity: sha512-PTYSqtsIfPHLKDDNbueI5e0sc130vyHRiFOeeC6qqzA2FAiVvIxuvXHLr0soPvKAR1WyhtYmFB9QarcctemL2w==} - engines: {node: '>=10'} - cpu: [x64] + '@rollup/rollup-linux-riscv64-gnu@4.24.3': + resolution: {integrity: sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==} + cpu: [riscv64] os: [linux] - '@swc/core-win32-arm64-msvc@1.3.38': - resolution: {integrity: sha512-9lHfs5TPNs+QdkyZFhZledSmzBEbqml/J1rqPSb9Fy8zB6QlspixE6OLZ3nTlUOdoGWkcTTdrOn77Sd7YGf1AA==} - engines: {node: '>=10'} + '@rollup/rollup-linux-s390x-gnu@4.24.3': + resolution: {integrity: sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.24.3': + resolution: {integrity: sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.24.3': + resolution: {integrity: sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.24.3': + resolution: {integrity: sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.3.38': - resolution: {integrity: sha512-SbL6pfA2lqvDKnwTHwOfKWvfHAdcbAwJS4dBkFidr7BiPTgI5Uk8wAPcRb8mBECpmIa9yFo+N0cAFRvMnf+cNw==} - engines: {node: '>=10'} + '@rollup/rollup-win32-ia32-msvc@4.24.3': + resolution: {integrity: sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.3.38': - resolution: {integrity: sha512-UFveLrL6eGvViOD8OVqUQa6QoQwdqwRvLtL5elF304OT8eCPZa8BhuXnWk25X8UcOyns8gFcb8Fhp3oaLi/Rlw==} - engines: {node: '>=10'} + '@rollup/rollup-win32-x64-msvc@4.24.3': + resolution: {integrity: sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==} cpu: [x64] os: [win32] - '@swc/core@1.3.38': - resolution: {integrity: sha512-AiEVehRFws//AiiLx9DPDp1WDXt+yAoGD1kMYewhoF6QLdTz8AtYu6i8j/yAxk26L8xnegy0CDwcNnub9qenyQ==} - engines: {node: '>=10'} + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@sinonjs/commons@3.0.0': + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} - '@swc/jest@0.2.37': - resolution: {integrity: sha512-CR2BHhmXKGxTiFr21DYPRHQunLkX3mNIFGFkxBGji6r9uyIR5zftTOVYj1e0sFNMV2H7mf/+vpaglqaryBtqfQ==} - engines: {npm: '>= 7.0.0'} + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@storybook/addon-actions@8.4.6': + resolution: {integrity: sha512-vbplwjMj7UXbdzoFhQkqFHLQAPJX8OVGTM9Q+yjuWDHViaKKUlgRWp0jclT7aIDNJQU2a6wJbTimHgJeF16Vhg==} peerDependencies: - '@swc/core': '*' + storybook: ^8.4.6 - '@tanstack/match-sorter-utils@8.8.4': - resolution: {integrity: sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==} - engines: {node: '>=12'} + '@storybook/addon-backgrounds@8.4.6': + resolution: {integrity: sha512-RSjJ3iElxlQXebZrz1s5LeoLpAXr9LAGifX7w0abMzN5sg6QSwNeUHko2eT3V57M3k1Fa/5Eelso/QBQifFEog==} + peerDependencies: + storybook: ^8.4.6 - '@tanstack/query-core@4.35.3': - resolution: {integrity: sha512-PS+WEjd9wzKTyNjjQymvcOe1yg8f3wYc6mD+vb6CKyZAKvu4sIJwryfqfBULITKCla7P9C4l5e9RXePHvZOZeQ==} + '@storybook/addon-controls@8.4.6': + resolution: {integrity: sha512-70pEGWh0C2g8s0DYsISElOzsMbQS6p/K9iU5EqfotDF+hvEqstjsV/bTbR5f3OK4vR/7Gxamk7j8RVd14Nql6A==} + peerDependencies: + storybook: ^8.4.6 - '@tanstack/react-query-devtools@4.35.3': - resolution: {integrity: sha512-UvLT7qPzCuCZ3NfjwsOqDUVN84JvSOuW6ukrjZmSqgjPqVxD6ra/HUp1CEOatQY2TRvKCp8y1lTVu+trXM30fg==} + '@storybook/addon-docs@8.4.6': + resolution: {integrity: sha512-olxz61W7PW/EsXrKhLrYbI3rn9GMBhY3KIOF/6tumbRkh0Siu/qe4EAImaV9NNwiC1R7+De/1OIVMY6o0EIZVw==} peerDependencies: - '@tanstack/react-query': ^4.35.3 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + storybook: ^8.4.6 - '@tanstack/react-query@4.35.3': - resolution: {integrity: sha512-UgTPioip/rGG3EQilXfA2j4BJkhEQsR+KAbF+KIuvQ7j4MkgnTCJF01SfRpIRNtQTlEfz/+IL7+jP8WA8bFbsw==} + '@storybook/addon-essentials@8.4.6': + resolution: {integrity: sha512-TbFqyvWFUKw8LBpVcZuGQydzVB/3kSuHxDHi+Wj3Qas3cxBl7+w4/HjwomT2D2Tni1dZ1uPDOsAtNLmwp1POsg==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true + storybook: ^8.4.6 - '@testing-library/dom@10.4.0': - resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} - engines: {node: '>=18'} + '@storybook/addon-highlight@8.4.6': + resolution: {integrity: sha512-m8wedbqDMbwkP99dNHkHAiAUkx5E7FEEEyLPX1zfkhZWOGtTkavXHH235SGp50zD75LQ6eC/BvgegrzxSQa9Wg==} + peerDependencies: + storybook: ^8.4.6 - '@testing-library/dom@9.3.3': - resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} - engines: {node: '>=14'} + '@storybook/addon-interactions@8.4.6': + resolution: {integrity: sha512-sR2oUSYIGUoAdrHT+fM1zgykhad98bsJ11c79r7HfBMXEPWc1yRcjIMmz8Xz06FMROMfebqduYDf60V++/I0Jw==} + peerDependencies: + storybook: ^8.4.6 - '@testing-library/jest-dom@6.4.6': - resolution: {integrity: sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@storybook/addon-links@8.4.6': + resolution: {integrity: sha512-1KoG9ytEWWwdF/dheu1O0dayQTMsHw++Qk8afqw7bwW1Cxz5LuAJH5ZscFWMiE5f4Xq1NgaJdeAUaIavyoOcdg==} peerDependencies: - '@jest/globals': '>= 28' - '@types/bun': latest - '@types/jest': '>= 28' - jest: '>= 28' - vitest: '>= 0.32' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.6 peerDependenciesMeta: - '@jest/globals': - optional: true - '@types/bun': - optional: true - '@types/jest': - optional: true - jest: - optional: true - vitest: + react: optional: true - '@testing-library/jest-dom@6.5.0': - resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - - '@testing-library/react-hooks@8.0.1': - resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} - engines: {node: '>=12'} + '@storybook/addon-mdx-gfm@8.4.6': + resolution: {integrity: sha512-wagsSBUN6pwcSZSWxp/aOhE16ZKI8ZW4XeRT6QivySmkJaLcbva+HNvQOijdXIM28W8PprKjqtyVa8nu4YQxsw==} peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 - react: ^16.9.0 || ^17.0.0 - react-dom: ^16.9.0 || ^17.0.0 - react-test-renderer: ^16.9.0 || ^17.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - react-dom: - optional: true - react-test-renderer: - optional: true + storybook: ^8.4.6 - '@testing-library/react@14.3.1': - resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} - engines: {node: '>=14'} + '@storybook/addon-measure@8.4.6': + resolution: {integrity: sha512-N2IRpr39g5KpexCAS1vIHJT+phc9Yilwm3PULds2rQ66VMTbkxobXJDdt0NS05g5n9/eDniroNQwdCeLg4tkpw==} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + storybook: ^8.4.6 - '@testing-library/user-event@14.5.1': - resolution: {integrity: sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==} - engines: {node: '>=12', npm: '>=6'} + '@storybook/addon-outline@8.4.6': + resolution: {integrity: sha512-EhcWx8OpK85HxQulLWzpWUHEwQpDYuAiKzsFj9ivAbfeljkIWNTG04mierfaH1xX016uL9RtLJL/zwBS5ChnFg==} peerDependencies: - '@testing-library/dom': '>=7.21.4' + storybook: ^8.4.6 - '@testing-library/user-event@14.5.2': - resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} - engines: {node: '>=12', npm: '>=6'} + '@storybook/addon-themes@8.4.6': + resolution: {integrity: sha512-0Eyh7jxxQ8hc7KIO2bJF8BKY1CRJ9zPo2DKoRiUKDoSGSP8qdlj4V/ks892GcUffdhTjoFAJCRzG7Ff+TnVKrA==} peerDependencies: - '@testing-library/dom': '>=7.21.4' + storybook: ^8.4.6 - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} + '@storybook/addon-toolbars@8.4.6': + resolution: {integrity: sha512-+Xao/uGa8FnYsyUiREUkYXWNysm3Aba8tL/Bwd+HufHtdiKJGa9lrXaC7VLCqBUaEjwqM3aaPwqEWIROsthmPQ==} + peerDependencies: + storybook: ^8.4.6 - '@ts-morph/common@0.12.3': - resolution: {integrity: sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==} + '@storybook/addon-viewport@8.4.6': + resolution: {integrity: sha512-BuQll5YzOCpMS7p5Rsw9wcmi8hTnEKyg6+qAbkZNfiZ2JhXCa1GFUqX725fF1whpYVQULtkQxU8r+vahoRn7Yg==} + peerDependencies: + storybook: ^8.4.6 - '@tsconfig/node10@1.0.9': - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + '@storybook/blocks@8.4.6': + resolution: {integrity: sha512-Gzbx8hM7ZQIHlQELcFIMbY1v+r1Po4mlinq0QVPtKS4lBcW4eZIsesbxOaL+uFNrxb583TLFzXo0DbRPzS46sg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.6 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + '@storybook/builder-vite@8.4.6': + resolution: {integrity: sha512-PyJsaEPyuRFFEplpNUi+nbuJd7d1DC2dAZjpsaHTXyqg5iPIbkIgsbCJLUDeIXnUDqM/utjmMpN0sQKJuhIc6w==} + peerDependencies: + storybook: ^8.4.6 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + '@storybook/channels@8.1.11': + resolution: {integrity: sha512-fu5FTqo6duOqtJFa6gFzKbiSLJoia+8Tibn3xFfB6BeifWrH81hc+AZq0lTmHo5qax2G5t8ZN8JooHjMw6k2RA==} - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@storybook/client-logger@8.1.11': + resolution: {integrity: sha512-DVMh2usz3yYmlqCLCiCKy5fT8/UR9aTh+gSqwyNFkGZrIM4otC5A8eMXajXifzotQLT5SaOEnM3WzHwmpvMIEA==} - '@types/aria-query@5.0.3': - resolution: {integrity: sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA==} + '@storybook/components@8.4.6': + resolution: {integrity: sha512-9tKSJJCyFT5RZMRGyozTBJkr9C9Yfk1nuOE9XbDEE1Z+3/IypKR9+iwc5mfNBStDNY+rxtYWNLKBb5GPR2yhzA==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@storybook/core-events@8.1.11': + resolution: {integrity: sha512-vXaNe2KEW9BGlLrg0lzmf5cJ0xt+suPjWmEODH5JqBbrdZ67X6ApA2nb6WcxDQhykesWCuFN5gp1l+JuDOBi7A==} - '@types/babel__generator@7.6.8': - resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + '@storybook/core@8.4.6': + resolution: {integrity: sha512-WeojVtHy0/t50tzw/15S+DLzKsj8BN9yWdo3vJMvm+nflLFvfq1XvD9WGOWeaFp8E/o3AP+4HprXG0r42KEJtA==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@storybook/csf-plugin@8.4.6': + resolution: {integrity: sha512-JDIT0czC4yMgKGNf39KTZr3zm5MusAZdn6LBrTfvWb7CrTCR4iVHa4lp2yb7EJk41vHsBec0QUYDDuiFH/vV0g==} + peerDependencies: + storybook: ^8.4.6 - '@types/babel__traverse@7.20.6': - resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@storybook/csf@0.1.11': + resolution: {integrity: sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==} - '@types/body-parser@1.19.2': - resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} - '@types/chroma-js@2.4.0': - resolution: {integrity: sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw==} + '@storybook/icons@1.2.12': + resolution: {integrity: sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@types/color-convert@2.0.0': - resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} + '@storybook/instrumenter@8.4.6': + resolution: {integrity: sha512-snXjlgbp065A6KoK9zkjBYEIMCSlN5JefPKzt1FC0rbcbtahhD+iPpqISKhDSczwgOku/JVhVUDp/vU7AIf4mg==} + peerDependencies: + storybook: ^8.4.6 - '@types/color-name@1.1.1': - resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==} + '@storybook/manager-api@8.4.6': + resolution: {integrity: sha512-TsXlQ5m5rTl2KNT9icPFyy822AqXrx1QplZBt/L7cFn7SpqQKDeSta21FH7MG0piAvzOweXebVSqKngJ6cCWWQ==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@types/connect@3.4.35': - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + '@storybook/preview-api@8.4.6': + resolution: {integrity: sha512-LbD+lR1FGvWaJBXteVx5xdgs1x1D7tyidBg2CsW2ex+cP0iJ176JgjPfutZxlWOfQnhfRYNnJ3WKoCIfxFOTKA==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@storybook/react-dom-shim@8.4.6': + resolution: {integrity: sha512-f7RM8GO++fqMxbjNdEzeGS1P821jXuwRnAraejk5hyjB5SqetauFxMwoFYEYfJXPaLX2qIubnIJ78hdJ/IBaEA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.6 - '@types/debug@4.1.12': - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@storybook/react-vite@8.4.6': + resolution: {integrity: sha512-bVoYj3uJRz0SknK2qN3vBVSoEXsvyARQLuHjP9eX0lWBd9XSxZinmVbexPdD0OeJYcJIdmbli2/Gw7/hu5CjFA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.6 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 - '@types/doctrine@0.0.9': - resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + '@storybook/react@8.4.6': + resolution: {integrity: sha512-QAT23beoYNLhFGAXPimtuMErvpcI7eZbZ4AlLqW1fhiTZrRYw06cjC1bs9H3tODMcHH9LS5p3Wz9b29jtV2XGw==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.4.6 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.4.6 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@storybook/test@8.4.6': + resolution: {integrity: sha512-MeU1g65YgU66M2NtmEIL9gVeHk+en0k9Hp0wfxEO7NT/WLfaOD5RXLRDJVhbAlrH/6tLeWKIPNh/D26y27vO/g==} + peerDependencies: + storybook: ^8.4.6 - '@types/express-serve-static-core@4.17.35': - resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + '@storybook/theming@8.4.6': + resolution: {integrity: sha512-q7vDPN/mgj7cXIVQ9R1/V75hrzNgKkm2G0LjMo57//9/djQ+7LxvBsR1iScbFIRSEqppvMiBFzkts+2uXidySA==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - '@types/express@4.17.17': - resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + '@swc/core-darwin-arm64@1.3.38': + resolution: {integrity: sha512-4ZTJJ/cR0EsXW5UxFCifZoGfzQ07a8s4ayt1nLvLQ5QoB1GTAf9zsACpvWG8e7cmCR0L76R5xt8uJuyr+noIXA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] - '@types/file-saver@2.0.7': - resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + '@swc/core-darwin-x64@1.3.38': + resolution: {integrity: sha512-Kim727rNo4Dl8kk0CR8aJQe4zFFtsT1TZGlNrNMUgN1WC3CRX7dLZ6ZJi/VVcTG1cbHp5Fp3mUzwHsMxEh87Mg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@swc/core-linux-arm-gnueabihf@1.3.38': + resolution: {integrity: sha512-yaRdnPNU2enlJDRcIMvYVSyodY+Amhf5QuXdUbAj6rkDD6wUs/s9C6yPYrFDmoTltrG+nBv72mUZj+R46wVfSw==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] - '@types/hast@2.3.8': - resolution: {integrity: sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==} + '@swc/core-linux-arm64-gnu@1.3.38': + resolution: {integrity: sha512-iNY1HqKo/wBSu3QOGBUlZaLdBP/EHcwNjBAqIzpb8J64q2jEN02RizqVW0mDxyXktJ3lxr3g7VW9uqklMeXbjQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] - '@types/hast@3.0.3': - resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + '@swc/core-linux-arm64-musl@1.3.38': + resolution: {integrity: sha512-LJCFgLZoPRkPCPmux+Q5ctgXRp6AsWhvWuY61bh5bIPBDlaG9pZk94DeHyvtiwT0syhTtXb2LieBOx6NqN3zeA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] - '@types/hoist-non-react-statics@3.3.5': - resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + '@swc/core-linux-x64-gnu@1.3.38': + resolution: {integrity: sha512-hRQGRIWHmv2PvKQM/mMV45mVXckM2+xLB8TYLLgUG66mmtyGTUJPyxjnJkbI86WNGqo18k+lAuMG2mn6QmzYwQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] - '@types/http-errors@2.0.1': - resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==} + '@swc/core-linux-x64-musl@1.3.38': + resolution: {integrity: sha512-PTYSqtsIfPHLKDDNbueI5e0sc130vyHRiFOeeC6qqzA2FAiVvIxuvXHLr0soPvKAR1WyhtYmFB9QarcctemL2w==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] - '@types/istanbul-lib-coverage@2.0.5': - resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==} + '@swc/core-win32-arm64-msvc@1.3.38': + resolution: {integrity: sha512-9lHfs5TPNs+QdkyZFhZledSmzBEbqml/J1rqPSb9Fy8zB6QlspixE6OLZ3nTlUOdoGWkcTTdrOn77Sd7YGf1AA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + '@swc/core-win32-ia32-msvc@1.3.38': + resolution: {integrity: sha512-SbL6pfA2lqvDKnwTHwOfKWvfHAdcbAwJS4dBkFidr7BiPTgI5Uk8wAPcRb8mBECpmIa9yFo+N0cAFRvMnf+cNw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] - '@types/istanbul-lib-report@3.0.2': - resolution: {integrity: sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==} + '@swc/core-win32-x64-msvc@1.3.38': + resolution: {integrity: sha512-UFveLrL6eGvViOD8OVqUQa6QoQwdqwRvLtL5elF304OT8eCPZa8BhuXnWk25X8UcOyns8gFcb8Fhp3oaLi/Rlw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + '@swc/core@1.3.38': + resolution: {integrity: sha512-AiEVehRFws//AiiLx9DPDp1WDXt+yAoGD1kMYewhoF6QLdTz8AtYu6i8j/yAxk26L8xnegy0CDwcNnub9qenyQ==} + engines: {node: '>=10'} - '@types/istanbul-reports@3.0.3': - resolution: {integrity: sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@swc/jest@0.2.37': + resolution: {integrity: sha512-CR2BHhmXKGxTiFr21DYPRHQunLkX3mNIFGFkxBGji6r9uyIR5zftTOVYj1e0sFNMV2H7mf/+vpaglqaryBtqfQ==} + engines: {npm: '>= 7.0.0'} + peerDependencies: + '@swc/core': '*' - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@tanstack/match-sorter-utils@8.8.4': + resolution: {integrity: sha512-rKH8LjZiszWEvmi01NR72QWZ8m4xmXre0OOwlRGnjU01Eqz/QnN+cqpty2PJ0efHblq09+KilvyR7lsbzmXVEw==} + engines: {node: '>=12'} - '@types/jsdom@20.0.1': - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + '@tanstack/query-core@4.35.3': + resolution: {integrity: sha512-PS+WEjd9wzKTyNjjQymvcOe1yg8f3wYc6mD+vb6CKyZAKvu4sIJwryfqfBULITKCla7P9C4l5e9RXePHvZOZeQ==} - '@types/lodash@4.17.13': - resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + '@tanstack/react-query-devtools@4.35.3': + resolution: {integrity: sha512-UvLT7qPzCuCZ3NfjwsOqDUVN84JvSOuW6ukrjZmSqgjPqVxD6ra/HUp1CEOatQY2TRvKCp8y1lTVu+trXM30fg==} + peerDependencies: + '@tanstack/react-query': ^4.35.3 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@types/mdast@4.0.3': - resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + '@tanstack/react-query@4.35.3': + resolution: {integrity: sha512-UgTPioip/rGG3EQilXfA2j4BJkhEQsR+KAbF+KIuvQ7j4MkgnTCJF01SfRpIRNtQTlEfz/+IL7+jP8WA8bFbsw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true - '@types/mdx@2.0.9': - resolution: {integrity: sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg==} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} - '@types/mime@1.3.2': - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + '@testing-library/dom@9.3.3': + resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} + engines: {node: '>=14'} - '@types/mime@3.0.1': - resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + '@testing-library/jest-dom@6.4.6': + resolution: {integrity: sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + peerDependencies: + '@jest/globals': '>= 28' + '@types/bun': latest + '@types/jest': '>= 28' + jest: '>= 28' + vitest: '>= 0.32' + peerDependenciesMeta: + '@jest/globals': + optional: true + '@types/bun': + optional: true + '@types/jest': + optional: true + jest: + optional: true + vitest: + optional: true - '@types/ms@0.7.34': - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@testing-library/jest-dom@6.5.0': + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - '@types/mute-stream@0.0.4': - resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + '@testing-library/react-hooks@8.0.1': + resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} + engines: {node: '>=12'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 + react: ^16.9.0 || ^17.0.0 + react-dom: ^16.9.0 || ^17.0.0 + react-test-renderer: ^16.9.0 || ^17.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-dom: + optional: true + react-test-renderer: + optional: true - '@types/node@18.19.0': - resolution: {integrity: sha512-667KNhaD7U29mT5wf+TZUnrzPrlL2GNQ5N0BMjO2oNULhBxX0/FKCkm6JMu0Jh7Z+1LwUlR21ekd7KhIboNFNw==} + '@testing-library/react@14.3.1': + resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} + engines: {node: '>=14'} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 - '@types/node@20.17.6': - resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} + '@testing-library/user-event@14.5.1': + resolution: {integrity: sha512-UCcUKrUYGj7ClomOo2SpNVvx4/fkd/2BbIHDCle8A0ax+P3bU7yJwDBDrS6ZwdTMARWTGODX1hEsCcO+7beJjg==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' - '@types/parse-json@4.0.0': - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' - '@types/prop-types@15.7.12': - resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} - '@types/prop-types@15.7.13': - resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + '@ts-morph/common@0.12.3': + resolution: {integrity: sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==} - '@types/qs@6.9.7': - resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + '@tsconfig/node10@1.0.9': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/aria-query@5.0.3': + resolution: {integrity: sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/body-parser@1.19.2': + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + + '@types/chroma-js@2.4.0': + resolution: {integrity: sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw==} + + '@types/color-convert@2.0.0': + resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} + + '@types/color-name@1.1.1': + resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==} + + '@types/connect@3.4.35': + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/express-serve-static-core@4.17.35': + resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + + '@types/express@4.17.17': + resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + + '@types/file-saver@2.0.7': + resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/hast@2.3.8': + resolution: {integrity: sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ==} + + '@types/hast@3.0.3': + resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + + '@types/hoist-non-react-statics@3.3.5': + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + + '@types/http-errors@2.0.1': + resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==} + + '@types/istanbul-lib-coverage@2.0.5': + resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.2': + resolution: {integrity: sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.3': + resolution: {integrity: sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + + '@types/lodash@4.17.13': + resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + + '@types/mdast@4.0.3': + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + + '@types/mdx@2.0.9': + resolution: {integrity: sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg==} + + '@types/mime@1.3.2': + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + + '@types/mime@3.0.1': + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + + '@types/node@18.19.0': + resolution: {integrity: sha512-667KNhaD7U29mT5wf+TZUnrzPrlL2GNQ5N0BMjO2oNULhBxX0/FKCkm6JMu0Jh7Z+1LwUlR21ekd7KhIboNFNw==} + + '@types/node@20.17.6': + resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} + + '@types/parse-json@4.0.0': + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + + '@types/prop-types@15.7.12': + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + + '@types/qs@6.9.7': + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} '@types/range-parser@1.2.4': resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} @@ -2396,6 +2808,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -2670,6 +3086,12 @@ packages: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cmdk@1.0.0: + resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} @@ -2922,6 +3344,9 @@ packages: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -3072,6 +3497,7 @@ packages: eslint@8.52.0: resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -3279,6 +3705,10 @@ packages: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -4642,6 +5072,36 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.5: + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.6.0: + resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-router-dom@6.26.2: resolution: {integrity: sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==} engines: {node: '>=14.0.0'} @@ -4655,6 +5115,16 @@ packages: peerDependencies: react: '>=16.8' + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-syntax-highlighter@15.5.0: resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} peerDependencies: @@ -5310,6 +5780,26 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -6156,558 +6646,913 @@ snapshots: '@eslint/js@8.52.0': optional: true - '@fastly/performance-observer-polyfill@2.0.0': + '@fastly/performance-observer-polyfill@2.0.0': + dependencies: + tslib: 2.6.1 + + '@floating-ui/core@1.6.7': + dependencies: + '@floating-ui/utils': 0.2.7 + + '@floating-ui/dom@1.6.10': + dependencies: + '@floating-ui/core': 1.6.7 + '@floating-ui/utils': 0.2.7 + + '@floating-ui/react-dom@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.6.10 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.7': {} + + '@fontsource-variable/inter@5.0.15': {} + + '@fontsource/ibm-plex-mono@5.1.0': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + optional: true + + '@humanwhocodes/module-importer@1.0.1': + optional: true + + '@humanwhocodes/object-schema@2.0.3': + optional: true + + '@icons/material@0.2.4(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@inquirer/confirm@3.0.0': + dependencies: + '@inquirer/core': 7.0.0 + '@inquirer/type': 1.2.0 + + '@inquirer/core@7.0.0': + dependencies: + '@inquirer/type': 1.2.0 + '@types/mute-stream': 0.0.4 + '@types/node': 20.17.6 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + figures: 3.2.0 + mute-stream: 1.0.0 + run-async: 3.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + '@inquirer/type@1.2.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jedmao/location@3.0.0': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.17.6 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.17.6 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/create-cache-key-function@29.7.0': + dependencies: + '@jest/types': 29.6.3 + + '@jest/environment@29.6.2': + dependencies: + '@jest/fake-timers': 29.6.2 + '@jest/types': 29.6.1 + '@types/node': 20.17.6 + jest-mock: 29.6.2 + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.17.6 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.6.2': + dependencies: + '@jest/types': 29.6.1 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.17.6 + jest-message-util: 29.6.2 + jest-mock: 29.6.2 + jest-util: 29.6.2 + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.17.6 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.17.6 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.26.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.1': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.5 + '@types/istanbul-reports': 3.0.3 + '@types/node': 20.17.6 + '@types/yargs': 17.0.29 + chalk: 4.1.2 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.17.6 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.17.6))': + dependencies: + magic-string: 0.27.0 + react-docgen-typescript: 2.2.2(typescript@5.6.3) + vite: 5.4.10(@types/node@20.17.6) + optionalDependencies: + typescript: 5.6.3 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': dependencies: - tslib: 2.6.1 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 - '@floating-ui/core@1.6.7': + '@kurkle/color@0.3.2': {} + + '@leeoniya/ufuzzy@1.0.10': {} + + '@mdx-js/react@3.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@floating-ui/utils': 0.2.7 + '@types/mdx': 2.0.9 + '@types/react': 18.3.12 + react: 18.3.1 - '@floating-ui/dom@1.6.10': + '@monaco-editor/loader@1.4.0(monaco-editor@0.52.0)': dependencies: - '@floating-ui/core': 1.6.7 - '@floating-ui/utils': 0.2.7 + monaco-editor: 0.52.0 + state-local: 1.0.7 - '@floating-ui/react-dom@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.6.10 + '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.0) + monaco-editor: 0.52.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@floating-ui/utils@0.2.7': {} + '@mswjs/interceptors@0.29.1': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.2 + strict-event-emitter: 0.5.1 - '@fontsource-variable/inter@5.0.15': {} + '@mui/base@5.0.0-beta.40(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.6 + '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.15(@types/react@18.3.12) + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + '@popperjs/core': 2.11.8 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 - '@fontsource/ibm-plex-mono@5.1.0': {} + '@mui/core-downloads-tracker@5.16.7': {} - '@humanwhocodes/config-array@0.11.14': + '@mui/icons-material@5.16.7(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.7 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - optional: true + '@babel/runtime': 7.25.4 + '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@humanwhocodes/module-importer@1.0.1': - optional: true + '@mui/lab@5.0.0-alpha.173(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.4 + '@mui/base': 5.0.0-beta.40(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/types': 7.2.15(@types/react@18.3.12) + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 - '@humanwhocodes/object-schema@2.0.3': - optional: true + '@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.4 + '@mui/core-downloads-tracker': 5.16.7 + '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/types': 7.2.15(@types/react@18.3.12) + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + '@popperjs/core': 2.11.8 + '@types/react-transition-group': 4.4.11 + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 - '@icons/material@0.2.4(react@18.3.1)': + '@mui/private-theming@5.16.6(@types/react@18.3.12)(react@18.3.1)': dependencies: + '@babel/runtime': 7.25.6 + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + prop-types: 15.8.1 react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@inquirer/confirm@3.0.0': + '@mui/styled-engine@5.16.6(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1)': dependencies: - '@inquirer/core': 7.0.0 - '@inquirer/type': 1.2.0 + '@babel/runtime': 7.25.6 + '@emotion/cache': 11.13.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - '@inquirer/core@7.0.0': + '@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@inquirer/type': 1.2.0 - '@types/mute-stream': 0.0.4 - '@types/node': 20.17.6 - '@types/wrap-ansi': 3.0.0 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-spinners: 2.9.2 - cli-width: 4.1.0 - figures: 3.2.0 - mute-stream: 1.0.0 - run-async: 3.0.0 - signal-exit: 4.1.0 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 + '@babel/runtime': 7.25.4 + '@mui/private-theming': 5.16.6(@types/react@18.3.12)(react@18.3.1) + '@mui/styled-engine': 5.16.6(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.15(@types/react@18.3.12) + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 - '@inquirer/type@1.2.0': {} + '@mui/types@7.2.15(@types/react@18.3.12)': + optionalDependencies: + '@types/react': 18.3.12 - '@isaacs/cliui@8.0.2': + '@mui/utils@5.16.6(@types/react@18.3.12)(react@18.3.1)': dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 + '@babel/runtime': 7.25.4 + '@mui/types': 7.2.15(@types/react@18.3.12) + '@types/prop-types': 15.7.12 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@istanbuljs/load-nyc-config@1.1.0': + '@mui/x-internals@7.18.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - - '@istanbuljs/schema@0.1.3': {} + '@babel/runtime': 7.25.6 + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + transitivePeerDependencies: + - '@types/react' - '@jedmao/location@3.0.0': {} + '@mui/x-tree-view@7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.6 + '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + '@mui/x-internals': 7.18.0(@types/react@18.3.12)(react@18.3.1) + '@types/react-transition-group': 4.4.11 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + transitivePeerDependencies: + - '@types/react' - '@jest/console@29.7.0': + '@nodelib/fs.scandir@2.1.5': dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.17.6 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3))': + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.6 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.17.6)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.3.38)(@types/node@20.17.6)(typescript@5.6.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@octokit/openapi-types@19.0.2': {} - '@jest/create-cache-key-function@29.7.0': + '@octokit/types@12.3.0': dependencies: - '@jest/types': 29.6.3 + '@octokit/openapi-types': 19.0.2 - '@jest/environment@29.6.2': - dependencies: - '@jest/fake-timers': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.17.6 - jest-mock: 29.6.2 + '@open-draft/deferred-promise@2.2.0': {} - '@jest/environment@29.7.0': + '@open-draft/logger@0.3.0': dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.17.6 - jest-mock: 29.7.0 + is-node-process: 1.2.0 + outvariant: 1.4.2 - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 + '@open-draft/until@2.1.0': {} - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color + '@pkgjs/parseargs@0.11.0': + optional: true - '@jest/fake-timers@29.6.2': + '@playwright/test@1.47.2': dependencies: - '@jest/types': 29.6.1 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.17.6 - jest-message-util: 29.6.2 - jest-mock: 29.6.2 - jest-util: 29.6.2 + playwright: 1.47.2 - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.17.6 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 + '@popperjs/core@2.11.8': {} - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color + '@protobufjs/aspromise@1.1.2': {} - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.17.6 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color + '@protobufjs/base64@1.1.2': {} - '@jest/schemas@29.6.3': + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': dependencies: - '@sinclair/typebox': 0.27.8 + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 - '@jest/source-map@29.6.3': + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@radix-ui/number@1.1.0': {} + + '@radix-ui/primitive@1.0.1': dependencies: - '@jridgewell/trace-mapping': 0.3.25 - callsites: 3.1.0 - graceful-fs: 4.2.11 + '@babel/runtime': 7.25.6 - '@jest/test-result@29.7.0': + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@jest/test-sequencer@29.7.0': + '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 + '@babel/runtime': 7.25.6 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@jest/transform@29.7.0': + '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/core': 7.26.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.25 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.6 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@jest/types@29.6.1': + '@radix-ui/react-context@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.5 - '@types/istanbul-reports': 3.0.3 - '@types/node': 20.17.6 - '@types/yargs': 17.0.29 - chalk: 4.1.2 + '@babel/runtime': 7.25.6 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@jest/types@29.6.3': + '@radix-ui/react-context@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.6 - '@types/yargs': 17.0.33 - chalk: 4.1.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.6.3)(vite@5.4.10(@types/node@20.17.6))': + '@radix-ui/react-context@1.1.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - magic-string: 0.27.0 - react-docgen-typescript: 2.2.2(typescript@5.6.3) - vite: 5.4.10(@types/node@20.17.6) + react: 18.3.1 optionalDependencies: - typescript: 5.6.3 + '@types/react': 18.3.12 - '@jridgewell/gen-mapping@0.3.5': + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.12)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@jridgewell/resolve-uri@3.1.2': {} + '@radix-ui/react-dialog@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.6.0(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@jridgewell/set-array@1.2.1': {} + '@radix-ui/react-direction@1.1.0(@types/react@18.3.12)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@jridgewell/sourcemap-codec@1.5.0': {} + '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@jridgewell/trace-mapping@0.3.25': + '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@babel/runtime': 7.25.6 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@jridgewell/trace-mapping@0.3.9': + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@kurkle/color@0.3.2': {} + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@leeoniya/ufuzzy@1.0.10': {} + '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mdx-js/react@3.0.1(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-id@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@types/mdx': 2.0.9 + '@babel/runtime': 7.25.6 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: '@types/react': 18.3.12 - react: 18.3.1 - '@monaco-editor/loader@1.4.0(monaco-editor@0.52.0)': + '@radix-ui/react-id@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - monaco-editor: 0.52.0 - state-local: 1.0.7 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-label@2.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.0) - monaco-editor: 0.52.0 + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mswjs/interceptors@0.29.1': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.2 - strict-event-emitter: 0.5.1 - - '@mui/base@5.0.0-beta.40(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 - '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/types': 7.2.15(@types/react@18.3.12) - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - '@popperjs/core': 2.11.8 - clsx: 2.1.1 - prop-types: 15.8.1 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/core-downloads-tracker@5.16.7': {} - - '@mui/icons-material@5.16.7(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-portal@1.1.2(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/lab@5.0.0-alpha.173(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/base': 5.0.0-beta.40(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - '@mui/types': 7.2.15(@types/react@18.3.12) - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - clsx: 2.1.1 - prop-types: 15.8.1 + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-presence@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/core-downloads-tracker': 5.16.7 - '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - '@mui/types': 7.2.15(@types/react@18.3.12) - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.11 - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/private-theming@5.16.6(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - prop-types: 15.8.1 + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/styled-engine@5.16.6(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.6 - '@emotion/cache': 11.13.1 - csstype: 3.1.3 - prop-types: 15.8.1 + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-slider@1.2.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/private-theming': 5.16.6(@types/react@18.3.12)(react@18.3.1) - '@mui/styled-engine': 5.16.6(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(react@18.3.1) - '@mui/types': 7.2.15(@types/react@18.3.12) - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - clsx: 2.1.1 - csstype: 3.1.3 - prop-types: 15.8.1 + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/types@7.2.15(@types/react@18.3.12)': + '@radix-ui/react-slot@1.0.2(@types/react@18.3.12)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 optionalDependencies: '@types/react': 18.3.12 - '@mui/utils@5.16.6(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-slot@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.4 - '@mui/types': 7.2.15(@types/react@18.3.12) - '@types/prop-types': 15.7.12 - clsx: 2.1.1 - prop-types: 15.8.1 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 - react-is: 18.3.1 optionalDependencies: '@types/react': 18.3.12 - '@mui/x-internals@7.18.0(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-switch@1.1.1(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.25.6 - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 - transitivePeerDependencies: - - '@types/react' + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + '@types/react-dom': 18.3.1 - '@mui/x-tree-view@7.18.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@mui/material@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/material': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/system': 5.16.7(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - '@mui/utils': 5.16.6(@types/react@18.3.12)(react@18.3.1) - '@mui/x-internals': 7.18.0(@types/react@18.3.12)(react@18.3.1) - '@types/react-transition-group': 4.4.11 - clsx: 2.1.1 - prop-types: 15.8.1 react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) optionalDependencies: - '@emotion/react': 11.13.3(@types/react@18.3.12)(react@18.3.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.12)(react@18.3.1))(@types/react@18.3.12)(react@18.3.1) - transitivePeerDependencies: - - '@types/react' + '@types/react': 18.3.12 - '@nodelib/fs.scandir@2.1.5': + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@nodelib/fs.walk@1.2.8': + '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@octokit/openapi-types@19.0.2': {} + '@babel/runtime': 7.25.6 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@octokit/types@12.3.0': + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@octokit/openapi-types': 19.0.2 - - '@open-draft/deferred-promise@2.2.0': {} + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@open-draft/logger@0.3.0': + '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.12)(react@18.3.1)': dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.2 - - '@open-draft/until@2.1.0': {} - - '@pkgjs/parseargs@0.11.0': - optional: true + '@babel/runtime': 7.25.6 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@playwright/test@1.47.2': + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - playwright: 1.47.2 - - '@popperjs/core@2.11.8': {} - - '@protobufjs/aspromise@1.1.2': {} - - '@protobufjs/base64@1.1.2': {} - - '@protobufjs/codegen@2.0.4': {} - - '@protobufjs/eventemitter@1.1.0': {} + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.12)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@protobufjs/fetch@1.1.0': + '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/inquire': 1.1.0 - - '@protobufjs/float@1.0.2': {} - - '@protobufjs/inquire@1.1.0': {} - - '@protobufjs/path@1.1.2': {} - - '@protobufjs/pool@1.1.0': {} + '@babel/runtime': 7.25.6 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@protobufjs/utf8@1.1.0': {} + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.12)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.12 - '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: react: 18.3.1 optionalDependencies: '@types/react': 18.3.12 - '@radix-ui/react-slot@1.1.0(@types/react@18.3.12)(react@18.3.1)': + '@radix-ui/react-use-size@1.1.0(@types/react@18.3.12)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.12)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.12)(react@18.3.1) react: 18.3.1 optionalDependencies: '@types/react': 18.3.12 @@ -7598,6 +8443,10 @@ snapshots: argparse@2.0.1: optional: true + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.2 + aria-query@5.1.3: dependencies: deep-equal: 2.2.2 @@ -7908,6 +8757,16 @@ snapshots: clsx@2.1.1: {} + cmdk@1.0.0(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.1)(@types/react@18.3.12)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + co@4.6.0: {} code-block-writer@11.0.3: {} @@ -8129,6 +8988,8 @@ snapshots: detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -8592,6 +9453,8 @@ snapshots: has-symbols: 1.0.3 hasown: 2.0.0 + get-nonce@1.0.1: {} + get-package-type@0.1.0: {} get-stream@6.0.1: {} @@ -10348,6 +11211,36 @@ snapshots: react-refresh@0.14.2: {} + react-remove-scroll-bar@2.3.6(@types/react@18.3.12)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.1(@types/react@18.3.12)(react@18.3.1) + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.12 + + react-remove-scroll@2.5.5(@types/react@18.3.12)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.12)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.12)(react@18.3.1) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.3.12)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + + react-remove-scroll@2.6.0(@types/react@18.3.12)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.12)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.12)(react@18.3.1) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.3.12)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.12)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + react-router-dom@6.26.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.19.2 @@ -10360,6 +11253,15 @@ snapshots: '@remix-run/router': 1.19.2 react: 18.3.1 + react-style-singleton@2.2.1(@types/react@18.3.12)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.12 + react-syntax-highlighter@15.5.0(react@18.3.1): dependencies: '@babel/runtime': 7.22.6 @@ -11114,6 +12016,21 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 + use-callback-ref@1.3.2(@types/react@18.3.12)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.12 + + use-sidecar@1.1.2(@types/react@18.3.12)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.12 + use-sync-external-store@1.2.0(react@18.3.1): dependencies: react: 18.3.1 diff --git a/site/src/api/api.ts b/site/src/api/api.ts index cfba27408e9c6..b39ad1d038080 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -712,6 +712,27 @@ class ApiMethods { return response.data; }; + /** + * @param organization Can be the organization's ID or name + */ + getOrganizationIdpSyncSettings = + async (): Promise => { + const response = await this.axios.get( + "/api/v2/settings/idpsync/organization", + ); + return response.data; + }; + + patchOrganizationIdpSyncSettings = async ( + data: TypesGen.OrganizationSyncSettings, + ) => { + const response = await this.axios.patch( + "/api/v2/settings/idpsync/organization", + data, + ); + return response.data; + }; + /** * @param organization Can be the organization's ID or name */ diff --git a/site/src/api/queries/idpsync.ts b/site/src/api/queries/idpsync.ts new file mode 100644 index 0000000000000..1840f0a5251cb --- /dev/null +++ b/site/src/api/queries/idpsync.ts @@ -0,0 +1,23 @@ +import { API } from "api/api"; +import type { OrganizationSyncSettings } from "api/typesGenerated"; +import type { QueryClient } from "react-query"; + +export const getOrganizationIdpSyncSettingsKey = () => [ + "organizationIdpSyncSettings", +]; + +export const patchOrganizationSyncSettings = (queryClient: QueryClient) => { + return { + mutationFn: (request: OrganizationSyncSettings) => + API.patchOrganizationIdpSyncSettings(request), + onSuccess: async () => + await queryClient.invalidateQueries(getOrganizationIdpSyncSettingsKey()), + }; +}; + +export const organizationIdpSyncSettings = () => { + return { + queryKey: getOrganizationIdpSyncSettingsKey(), + queryFn: () => API.getOrganizationIdpSyncSettings(), + }; +}; diff --git a/site/src/components/ui/badge.tsx b/site/src/components/ui/badge.tsx new file mode 100644 index 0000000000000..9d31ce5bf74b3 --- /dev/null +++ b/site/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import { type VariantProps, cva } from "class-variance-authority"; +import type * as React from "react"; + +import { cn } from "utils/cn"; + +const badgeVariants = cva( + "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-surface-secondary text-content-secondary shadow hover:bg-surface-tertiary", + secondary: + "border-transparent bg-surface-secondary text-content-secondary hover:bg-surface-tertiary", + destructive: + "border-transparent bg-surface-error text-content-danger shadow hover:bg-surface-error/80", + outline: "text-content-primary", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ); +} + +export { Badge, badgeVariants }; diff --git a/site/src/components/ui/button.tsx b/site/src/components/ui/button.tsx index d3a708d48a82a..1ad4608e7559f 100644 --- a/site/src/components/ui/button.tsx +++ b/site/src/components/ui/button.tsx @@ -10,7 +10,7 @@ const buttonVariants = cva( variants: { variant: { default: - "bg-surface-invert-primary text-content-invert hover:bg-surface-invert-secondary", + "bg-surface-invert-primary text-content-invert hover:bg-surface-invert-secondary border-none", outline: "border border-border-default text-content-primary bg-transparent hover:bg-surface-secondary", subtle: @@ -19,7 +19,7 @@ const buttonVariants = cva( "border border-border-error text-content-primary bg-surface-error hover:bg-transparent", }, size: { - default: "h-10 px-3 py-2", + default: "h-9 px-3 py-2", sm: "h-8 px-2 text-xs", }, }, diff --git a/site/src/components/ui/command.tsx b/site/src/components/ui/command.tsx new file mode 100644 index 0000000000000..113d49605d993 --- /dev/null +++ b/site/src/components/ui/command.tsx @@ -0,0 +1,151 @@ +import type { DialogProps } from "@radix-ui/react-dialog"; +import { Command as CommandPrimitive } from "cmdk"; +import { Search } from "lucide-react"; +import * as React from "react"; + +import { Dialog, DialogContent } from "components/ui/dialog"; +import { cn } from "utils/cn"; + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +Command.displayName = CommandPrimitive.displayName; + +const CommandDialog = ({ children, ...props }: DialogProps) => { + return ( + + + + {children} + + + + ); +}; + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + +
+)); + +CommandInput.displayName = CommandPrimitive.Input.displayName; + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandList.displayName = CommandPrimitive.List.displayName; + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)); + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandGroup.displayName = CommandPrimitive.Group.displayName; + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); + +CommandItem.displayName = CommandPrimitive.Item.displayName; + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ); +}; +CommandShortcut.displayName = "CommandShortcut"; + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +}; diff --git a/site/src/components/ui/dialog.tsx b/site/src/components/ui/dialog.tsx new file mode 100644 index 0000000000000..775e11d74aaf6 --- /dev/null +++ b/site/src/components/ui/dialog.tsx @@ -0,0 +1,120 @@ +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { X } from "lucide-react"; +import * as React from "react"; + +import { cn } from "utils/cn"; + +const Dialog = DialogPrimitive.Root; + +const DialogTrigger = DialogPrimitive.Trigger; + +const DialogPortal = DialogPrimitive.Portal; + +const DialogClose = DialogPrimitive.Close; + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); +DialogContent.displayName = DialogPrimitive.Content.displayName; + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogHeader.displayName = "DialogHeader"; + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+); +DialogFooter.displayName = "DialogFooter"; + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogTitle.displayName = DialogPrimitive.Title.displayName; + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +DialogDescription.displayName = DialogPrimitive.Description.displayName; + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogTrigger, + DialogClose, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +}; diff --git a/site/src/components/ui/label.tsx b/site/src/components/ui/label.tsx new file mode 100644 index 0000000000000..5fb36e06ebde2 --- /dev/null +++ b/site/src/components/ui/label.tsx @@ -0,0 +1,24 @@ +import * as LabelPrimitive from "@radix-ui/react-label"; +import { type VariantProps, cva } from "class-variance-authority"; +import * as React from "react"; + +import { cn } from "utils/cn"; + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", +); + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)); +Label.displayName = LabelPrimitive.Root.displayName; + +export { Label }; diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx new file mode 100644 index 0000000000000..62aef003f5fe8 --- /dev/null +++ b/site/src/components/ui/multiple-selector.tsx @@ -0,0 +1,637 @@ +"use client"; + +import { Command as CommandPrimitive, useCommandState } from "cmdk"; +import { X } from "lucide-react"; +import * as React from "react"; +import { forwardRef, useEffect } from "react"; + +import { Badge } from "components/ui/badge"; +import { + Command, + CommandGroup, + CommandItem, + CommandList, +} from "components/ui/command"; +import { cn } from "utils/cn"; + +export interface Option { + value: string; + label: string; + disable?: boolean; + /** fixed option that can't be removed. */ + fixed?: boolean; + /** Group the options by providing key. */ + [key: string]: string | boolean | undefined; +} +interface GroupOption { + [key: string]: Option[]; +} + +interface MultipleSelectorProps { + value?: Option[]; + defaultOptions?: Option[]; + /** manually controlled options */ + options?: Option[]; + placeholder?: string; + /** Loading component. */ + loadingIndicator?: React.ReactNode; + /** Empty component. */ + emptyIndicator?: React.ReactNode; + /** Debounce time for async search. Only work with `onSearch`. */ + delay?: number; + /** + * Only work with `onSearch` prop. Trigger search when `onFocus`. + * For example, when user click on the input, it will trigger the search to get initial options. + **/ + triggerSearchOnFocus?: boolean; + /** async search */ + onSearch?: (value: string) => Promise; + /** + * sync search. This search will not showing loadingIndicator. + * The rest props are the same as async search. + * i.e.: creatable, groupBy, delay. + **/ + onSearchSync?: (value: string) => Option[]; + onChange?: (options: Option[]) => void; + /** Limit the maximum number of selected options. */ + maxSelected?: number; + /** When the number of selected options exceeds the limit, the onMaxSelected will be called. */ + onMaxSelected?: (maxLimit: number) => void; + /** Hide the placeholder when there are options selected. */ + hidePlaceholderWhenSelected?: boolean; + disabled?: boolean; + /** Group the options base on provided key. */ + groupBy?: string; + className?: string; + badgeClassName?: string; + /** + * First item selected is a default behavior by cmdk. That is why the default is true. + * This is a workaround solution by add a dummy item. + * + * @reference: https://github.com/pacocoursey/cmdk/issues/171 + */ + selectFirstItem?: boolean; + /** Allow user to create option when there is no option matched. */ + creatable?: boolean; + /** Props of `Command` */ + commandProps?: React.ComponentPropsWithoutRef; + /** Props of `CommandInput` */ + inputProps?: Omit< + React.ComponentPropsWithoutRef, + "value" | "placeholder" | "disabled" + >; + /** hide the clear all button. */ + hideClearAllButton?: boolean; +} + +export interface MultipleSelectorRef { + selectedValue: Option[]; + input: HTMLInputElement; + focus: () => void; + reset: () => void; +} + +export function useDebounce(value: T, delay?: number): T { + const [debouncedValue, setDebouncedValue] = React.useState(value); + + useEffect(() => { + const timer = setTimeout(() => setDebouncedValue(value), delay || 500); + + return () => { + clearTimeout(timer); + }; + }, [value, delay]); + + return debouncedValue; +} + +function transToGroupOption(options: Option[], groupBy?: string) { + if (options.length === 0) { + return {}; + } + if (!groupBy) { + return { + "": options, + }; + } + + const groupOption: GroupOption = {}; + for (const option of options) { + const key = (option[groupBy] as string) || ""; + if (!groupOption[key]) { + groupOption[key] = []; + } + groupOption[key].push(option); + } + return groupOption; +} + +function removePickedOption(groupOption: GroupOption, picked: Option[]) { + const cloneOption = JSON.parse(JSON.stringify(groupOption)) as GroupOption; + + for (const [key, value] of Object.entries(cloneOption)) { + cloneOption[key] = value.filter( + (val) => !picked.find((p) => p.value === val.value), + ); + } + return cloneOption; +} + +function isOptionsExist(groupOption: GroupOption, targetOption: Option[]) { + for (const [, value] of Object.entries(groupOption)) { + if ( + value.some((option) => targetOption.find((p) => p.value === option.value)) + ) { + return true; + } + } + return false; +} + +/** + * The `CommandEmpty` of shadcn/ui will cause the cmdk empty not rendering correctly. + * So we create one and copy the `Empty` implementation from `cmdk`. + * + * @reference: https://github.com/hsuanyi-chou/shadcn-ui-expansions/issues/34#issuecomment-1949561607 + **/ +const CommandEmpty = forwardRef< + HTMLDivElement, + React.ComponentProps +>(({ className, ...props }, forwardedRef) => { + const render = useCommandState((state) => state.filtered.count === 0); + + if (!render) return null; + + return ( +
+ ); +}); + +CommandEmpty.displayName = "CommandEmpty"; + +const MultipleSelector = React.forwardRef< + MultipleSelectorRef, + MultipleSelectorProps +>( + ( + { + value, + onChange, + placeholder, + defaultOptions: arrayDefaultOptions = [], + options: arrayOptions, + delay, + onSearch, + onSearchSync, + loadingIndicator, + emptyIndicator, + maxSelected = Number.MAX_SAFE_INTEGER, + onMaxSelected, + hidePlaceholderWhenSelected, + disabled, + groupBy, + className, + badgeClassName, + selectFirstItem = true, + creatable = false, + triggerSearchOnFocus = false, + commandProps, + inputProps, + hideClearAllButton = false, + }: MultipleSelectorProps, + ref: React.Ref, + ) => { + const inputRef = React.useRef(null); + const [open, setOpen] = React.useState(false); + const [onScrollbar, setOnScrollbar] = React.useState(false); + const [isLoading, setIsLoading] = React.useState(false); + const dropdownRef = React.useRef(null); // Added this + + const [selected, setSelected] = React.useState(value || []); + const [options, setOptions] = React.useState( + transToGroupOption(arrayDefaultOptions, groupBy), + ); + const [inputValue, setInputValue] = React.useState(""); + const debouncedSearchTerm = useDebounce(inputValue, delay || 500); + + React.useImperativeHandle( + ref, + () => ({ + selectedValue: [...selected], + input: inputRef.current as HTMLInputElement, + focus: () => inputRef?.current?.focus(), + reset: () => setSelected([]), + }), + [selected], + ); + + const handleClickOutside = (event: MouseEvent | TouchEvent) => { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target as Node) && + inputRef.current && + !inputRef.current.contains(event.target as Node) + ) { + setOpen(false); + inputRef.current.blur(); + } + }; + + const handleUnselect = React.useCallback( + (option: Option) => { + const newOptions = selected.filter((s) => s.value !== option.value); + setSelected(newOptions); + onChange?.(newOptions); + }, + [onChange, selected], + ); + + const handleKeyDown = React.useCallback( + (e: React.KeyboardEvent) => { + const input = inputRef.current; + if (input) { + if (e.key === "Delete" || e.key === "Backspace") { + if (input.value === "" && selected.length > 0) { + const lastSelectOption = selected[selected.length - 1]; + // If last item is fixed, we should not remove it. + if (!lastSelectOption.fixed) { + handleUnselect(selected[selected.length - 1]); + } + } + } + // This is not a default behavior of the field + if (e.key === "Escape") { + input.blur(); + } + } + }, + [handleUnselect, selected], + ); + + useEffect(() => { + if (open) { + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("touchend", handleClickOutside); + } else { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("touchend", handleClickOutside); + } + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("touchend", handleClickOutside); + }; + }, [open]); + + useEffect(() => { + if (value) { + setSelected(value); + } + }, [value]); + + useEffect(() => { + /** If `onSearch` is provided, do not trigger options updated. */ + if (!arrayOptions || onSearch) { + return; + } + const newOption = transToGroupOption(arrayOptions || [], groupBy); + if (JSON.stringify(newOption) !== JSON.stringify(options)) { + setOptions(newOption); + } + }, [arrayDefaultOptions, arrayOptions, groupBy, onSearch, options]); + + useEffect(() => { + /** sync search */ + + const doSearchSync = () => { + const res = onSearchSync?.(debouncedSearchTerm); + setOptions(transToGroupOption(res || [], groupBy)); + }; + + const exec = async () => { + if (!onSearchSync || !open) return; + + if (triggerSearchOnFocus) { + doSearchSync(); + } + + if (debouncedSearchTerm) { + doSearchSync(); + } + }; + + void exec(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]); + + useEffect(() => { + /** async search */ + + const doSearch = async () => { + setIsLoading(true); + const res = await onSearch?.(debouncedSearchTerm); + setOptions(transToGroupOption(res || [], groupBy)); + setIsLoading(false); + }; + + const exec = async () => { + if (!onSearch || !open) return; + + if (triggerSearchOnFocus) { + await doSearch(); + } + + if (debouncedSearchTerm) { + await doSearch(); + } + }; + + void exec(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [debouncedSearchTerm, groupBy, open, triggerSearchOnFocus]); + + const CreatableItem = () => { + if (!creatable) return undefined; + if ( + isOptionsExist(options, [{ value: inputValue, label: inputValue }]) || + selected.find((s) => s.value === inputValue) + ) { + return undefined; + } + + const Item = ( + { + e.preventDefault(); + e.stopPropagation(); + }} + onSelect={(value: string) => { + if (selected.length >= maxSelected) { + onMaxSelected?.(selected.length); + return; + } + setInputValue(""); + const newOptions = [...selected, { value, label: value }]; + setSelected(newOptions); + onChange?.(newOptions); + }} + > + {`Create "${inputValue}"`} + + ); + + // For normal creatable + if (!onSearch && inputValue.length > 0) { + return Item; + } + + // For async search creatable. avoid showing creatable item before loading at first. + if (onSearch && debouncedSearchTerm.length > 0 && !isLoading) { + return Item; + } + + return undefined; + }; + + const EmptyItem = React.useCallback(() => { + if (!emptyIndicator) return undefined; + + // For async search that showing emptyIndicator + if (onSearch && !creatable && Object.keys(options).length === 0) { + return ( + + {emptyIndicator} + + ); + } + + return {emptyIndicator}; + }, [creatable, emptyIndicator, onSearch, options]); + + const selectables = React.useMemo( + () => removePickedOption(options, selected), + [options, selected], + ); + + /** Avoid Creatable Selector freezing or lagging when paste a long string. */ + const commandFilter = React.useCallback(() => { + if (commandProps?.filter) { + return commandProps.filter; + } + + if (creatable) { + return (value: string, search: string) => { + return value.toLowerCase().includes(search.toLowerCase()) ? 1 : -1; + }; + } + // Using default filter in `cmdk`. We don't have to provide it. + return undefined; + }, [creatable, commandProps?.filter]); + + return ( + { + handleKeyDown(e); + commandProps?.onKeyDown?.(e); + }} + className={cn( + "h-auto overflow-visible bg-transparent", + commandProps?.className, + )} + shouldFilter={ + commandProps?.shouldFilter !== undefined + ? commandProps.shouldFilter + : !onSearch + } // When onSearch is provided, we don't want to filter the options. You can still override it. + filter={commandFilter()} + > +
{ + if (disabled) return; + inputRef?.current?.focus(); + }} + > +
+ {selected.map((option) => { + return ( + + {option.label} + + + ); + })} + {/* Avoid having the "Search" Icon */} + { + setInputValue(value); + inputProps?.onValueChange?.(value); + }} + onBlur={(event) => { + if (!onScrollbar) { + setOpen(false); + } + inputProps?.onBlur?.(event); + }} + onFocus={(event) => { + setOpen(true); + triggerSearchOnFocus && onSearch?.(debouncedSearchTerm); + inputProps?.onFocus?.(event); + }} + placeholder={ + hidePlaceholderWhenSelected && selected.length !== 0 + ? "" + : placeholder + } + className={cn( + "flex-1 border-none outline-none bg-transparent placeholder:text-content-secondary", + { + "w-full": hidePlaceholderWhenSelected, + "px-3 py-2.5": selected.length === 0, + "ml-1": selected.length !== 0, + }, + inputProps?.className, + )} + /> + +
+
+
+ {open && ( + { + setOnScrollbar(false); + }} + onMouseEnter={() => { + setOnScrollbar(true); + }} + onMouseUp={() => { + inputRef?.current?.focus(); + }} + > + {isLoading ? ( + <>{loadingIndicator} + ) : ( + <> + {EmptyItem()} + {CreatableItem()} + {!selectFirstItem && ( + + )} + {Object.entries(selectables).map(([key, dropdowns]) => ( + + {/* biome-ignore lint/complexity/noUselessFragments: */} + <> + {dropdowns.map((option) => { + return ( + { + e.preventDefault(); + e.stopPropagation(); + }} + onSelect={() => { + if (selected.length >= maxSelected) { + onMaxSelected?.(selected.length); + return; + } + setInputValue(""); + const newOptions = [...selected, option]; + setSelected(newOptions); + onChange?.(newOptions); + }} + className={cn( + "cursor-pointer", + option.disable && + "cursor-default text-muted-foreground", + )} + > + {option.label} + + ); + })} + + + ))} + + )} + + )} +
+
+ ); + }, +); + +MultipleSelector.displayName = "MultipleSelector"; +export default MultipleSelector; diff --git a/site/src/components/ui/switch.tsx b/site/src/components/ui/switch.tsx new file mode 100644 index 0000000000000..226cb38dc3573 --- /dev/null +++ b/site/src/components/ui/switch.tsx @@ -0,0 +1,27 @@ +import * as SwitchPrimitives from "@radix-ui/react-switch"; +import * as React from "react"; + +import { cn } from "utils/cn"; + +const Switch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +Switch.displayName = SwitchPrimitives.Root.displayName; + +export { Switch }; diff --git a/site/src/contexts/auth/permissions.tsx b/site/src/contexts/auth/permissions.tsx index d2de7864874f0..b44d85e963fe4 100644 --- a/site/src/contexts/auth/permissions.tsx +++ b/site/src/contexts/auth/permissions.tsx @@ -21,6 +21,7 @@ export const checks = { createGroup: "createGroup", viewAllLicenses: "viewAllLicenses", viewNotificationTemplate: "viewNotificationTemplate", + viewOrganizationIDPSyncSettings: "viewOrganizationIDPSyncSettings", } as const satisfies Record; // Type expression seems a little redundant (`keyof typeof checks` has the same @@ -152,6 +153,12 @@ export const permissionsToCheck = { }, action: "read", }, + [checks.viewOrganizationIDPSyncSettings]: { + object: { + resource_type: "idpsync_settings", + }, + action: "read", + }, } as const satisfies Record; export type Permissions = Record; diff --git a/site/src/index.css b/site/src/index.css index aeca658d11995..8991ec4828e63 100644 --- a/site/src/index.css +++ b/site/src/index.css @@ -14,6 +14,7 @@ --surface-primary: 0, 0%, 98%; --surface-secondary: 240, 4%, 96%; --surface-tertiary: 240, 4%, 89%; + --surface-quaternary: 240, 5%, 84%; --surface-invert-primary: 240, 3%, 15%; --surface-invert-secondary: 240, 4%, 25%; --surface-error: 0, 100%, 14%; @@ -25,7 +26,13 @@ --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; - --background: 0, 0%, 98%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 10% 3.9%; } .dark { --content-primary: 0, 0%, 98%; @@ -38,6 +45,7 @@ --surface-primary: 240, 5%, 4%; --surface-secondary: 240, 5%, 9%; --surface-tertiary: 240, 3%, 15%; + --surface-quaternary: 240, 5%, 26%; --surface-invert-primary: 240, 4%, 89%; --surface-invert-secondary: 240, 4%, 66%; --surface-error: 0, 100%, 14%; @@ -48,6 +56,18 @@ --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; --chart-5: 340 75% 55%; - --background: 240, 5%, 4%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + } +} + +@layer base { + * { + @apply border-border; } } diff --git a/site/src/modules/management/SidebarView.tsx b/site/src/modules/management/SidebarView.tsx index eabcac8f30ccc..d63dcca388b8e 100644 --- a/site/src/modules/management/SidebarView.tsx +++ b/site/src/modules/management/SidebarView.tsx @@ -155,6 +155,11 @@ const DeploymentSettingsNavigation: FC = ({ )} + {permissions.viewOrganizationIDPSyncSettings && ( + + IdP Organization Sync + + )} {!isPremium && ( Premium )} diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx new file mode 100644 index 0000000000000..ba7e3c7567257 --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx @@ -0,0 +1,96 @@ +import LaunchOutlined from "@mui/icons-material/LaunchOutlined"; +import Button from "@mui/material/Button"; +import { getErrorMessage } from "api/errors"; +import { + organizationIdpSyncSettings, + patchOrganizationSyncSettings, +} from "api/queries/idpsync"; +import type { OrganizationSyncSettings } from "api/typesGenerated"; +import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; +import { EmptyState } from "components/EmptyState/EmptyState"; +import { displayError } from "components/GlobalSnackbar/utils"; +import { Paywall } from "components/Paywall/Paywall"; +import { SettingsHeader } from "components/SettingsHeader/SettingsHeader"; +import { Stack } from "components/Stack/Stack"; +import { useDashboard } from "modules/dashboard/useDashboard"; +import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; +import type { FC } from "react"; +import { Helmet } from "react-helmet-async"; +import { useMutation, useQuery, useQueryClient } from "react-query"; +import { docs } from "utils/docs"; +import { pageTitle } from "utils/page"; +import IdpOrgSyncPageView from "./IdpOrgSyncPageView"; + +export const IdpOrgSyncPage: FC = () => { + const queryClient = useQueryClient(); + // IdP sync does not have its own entitlement and is based on templace_rbac + const { template_rbac: isIdpSyncEnabled } = useFeatureVisibility(); + const { organizations } = useDashboard(); + const organizationIdpSyncSettingsQuery = useQuery( + organizationIdpSyncSettings(), + ); + const patchOrganizationSyncSettingsMutation = useMutation( + patchOrganizationSyncSettings(queryClient), + ); + + const error = organizationIdpSyncSettingsQuery.error; + + return ( + <> + + {pageTitle("Organization IdP Sync")} + + + + + + + + + + + + { + try { + // await patchOrganizationSyncSettingsMutation.mutateAsync(data); + console.log("submit form", data); + } catch (error) { + displayError( + getErrorMessage( + error, + "Failed to organization IdP sync settings", + ), + ); + } + }} + error={error || patchOrganizationSyncSettingsMutation.error} + // isLoading={patchOrganizationSyncSettingsMutation.isLoading} + /> + + + + ); +}; + +export default IdpOrgSyncPage; diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx new file mode 100644 index 0000000000000..94be08f5ef33b --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -0,0 +1,287 @@ +import type { Interpolation, Theme } from "@emotion/react"; +import Skeleton from "@mui/material/Skeleton"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TableRow from "@mui/material/TableRow"; +import TextField from "@mui/material/TextField"; +import type { + Organization, + OrganizationSyncSettings, +} from "api/typesGenerated"; +import { ErrorAlert } from "components/Alert/ErrorAlert"; +import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; +import { EmptyState } from "components/EmptyState/EmptyState"; +import { Loader } from "components/Loader/Loader"; +import { Stack } from "components/Stack/Stack"; +import { StatusIndicator } from "components/StatusIndicator/StatusIndicator"; +import { + TableLoaderSkeleton, + TableRowSkeleton, +} from "components/TableLoader/TableLoader"; +import { Button } from "components/ui/button"; +import { Label } from "components/ui/label"; +import MultipleSelector, { type Option } from "components/ui/multiple-selector"; +import { Switch } from "components/ui/switch"; +// import { Input } from "components/ui/input"; +import { useFormik } from "formik"; +import { Plus, SquareArrowOutUpRight } from "lucide-react"; +import type React from "react"; +import { useState } from "react"; +import type { FC } from "react"; +import { MONOSPACE_FONT_FAMILY } from "theme/constants"; +import { docs } from "utils/docs"; +import { getFormHelpers, onChangeTrimmed } from "utils/formUtils"; +// import { ExportPolicyButton } from "./ExportPolicyButton"; +import { IdpPillList } from "./IdpPillList"; + +interface IdpSyncPageViewProps { + organizationSyncSettings: OrganizationSyncSettings | undefined; + organizations: readonly Organization[]; + onSubmit: (data: OrganizationSyncSettings) => void; + error?: unknown; +} + +export const IdpSyncPageView: FC = ({ + organizationSyncSettings, + organizations, + onSubmit, + error, +}) => { + const form = useFormik({ + initialValues: { + field: organizationSyncSettings?.field || "", + organization_assign_default: + organizationSyncSettings?.organization_assign_default || true, + mapping: organizationSyncSettings?.mapping || {}, + }, + // validationSchema, + onSubmit, + }); + const getFieldHelpers = getFormHelpers(form, error); + const [coderOrgs, setCoderOrgs] = useState([]); + const [isChecked, setIsChecked] = useState( + form.initialValues.organization_assign_default, + ); + const organizationMappingCount = organizationSyncSettings?.mapping + ? Object.entries(organizationSyncSettings.mapping).length + : 0; + + if (error) { + return ; + } + + if (!organizationSyncSettings) { + return ; + } + + const OPTIONS: Option[] = organizations.map((org) => ({ + label: org.name, + value: org.id, + })); + + return ( + <> + +
+ + + { + setIsChecked(checked); + await form.setFieldValue( + "organization_assign_default", + checked, + ); + }} + /> + + + + {/* */} + + +
+ + + no results found. +

+ } + /> + +
+ + + + {organizationSyncSettings?.mapping && + Object.entries(organizationSyncSettings.mapping) + .sort() + .map(([idpOrg, organizations]) => ( + + ))} + + + +
+
+ + ); +}; + +interface IdpMappingTableProps { + isEmpty: boolean; + children: React.ReactNode; +} + +const IdpMappingTable: FC = ({ isEmpty, children }) => { + const isLoading = false; + + return ( + + + + + IdP organization + Coder organization + + + + + + + + + + + + + + + How to setup IdP organization sync + + + } + /> + + + + + {children} + + +
+
+ ); +}; + +interface OrganizationRowProps { + idpOrg: string; + coderOrgs: readonly string[]; +} + +const OrganizationRow: FC = ({ idpOrg, coderOrgs }) => { + return ( + + {idpOrg} + + + + + ); +}; + +const TableLoader = () => { + return ( + + + + + + + + + + + + + + ); +}; + +const styles = { + fieldText: { + fontFamily: MONOSPACE_FONT_FAMILY, + whiteSpace: "nowrap", + paddingBottom: ".02rem", + }, + fieldLabel: (theme) => ({ + color: theme.palette.text.secondary, + }), + tableInfo: () => ({ + marginBottom: 16, + }), +} satisfies Record>; + +export default IdpSyncPageView; diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpPillList.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpPillList.tsx new file mode 100644 index 0000000000000..4f489747f0bba --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpPillList.tsx @@ -0,0 +1,106 @@ +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; +import Stack from "@mui/material/Stack"; +import { Pill } from "components/Pill/Pill"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "components/Popover/Popover"; +import type { FC } from "react"; + +interface PillListProps { + roles: readonly string[]; +} + +// used to check if the role is a UUID +const UUID = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + +export const IdpPillList: FC = ({ roles }) => { + return ( + + {roles.length > 0 ? ( + + {roles[0]} + + ) : ( +

None

+ )} + + {roles.length > 1 && } +
+ ); +}; + +interface OverflowPillProps { + roles: string[]; +} + +const OverflowPill: FC = ({ roles }) => { + const theme = useTheme(); + + return ( + + + + +{roles.length} more + + + + + {roles.map((role) => ( + + {role} + + ))} + + + ); +}; + +const styles = { + pill: (theme) => ({ + backgroundColor: theme.experimental.pillDefault.background, + borderColor: theme.experimental.pillDefault.outline, + color: theme.experimental.pillDefault.text, + width: "fit-content", + }), + errorPill: (theme) => ({ + backgroundColor: theme.roles.error.background, + borderColor: theme.roles.error.outline, + color: theme.roles.error.text, + width: "fit-content", + }), +} satisfies Record>; diff --git a/site/src/router.tsx b/site/src/router.tsx index 1b23b55245e8f..0c9ffb38e411b 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -301,6 +301,9 @@ const RequestOTPPage = lazy( const ChangePasswordPage = lazy( () => import("./pages/ResetPasswordPage/ChangePasswordPage"), ); +const IdpOrgSyncPage = lazy( + () => import("./pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage"), +); const RoutesWithSuspense = () => { return ( @@ -453,6 +456,7 @@ export const router = createBrowserRouter( path="notifications" element={} /> + } /> } /> diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 1593790e9792d..178f042af13dc 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2774,6 +2774,7 @@ export const MockPermissions: Permissions = { createGroup: true, viewAllLicenses: true, viewNotificationTemplate: true, + viewOrganizationIDPSyncSettings: true, }; export const MockNoPermissions: Permissions = { @@ -2797,6 +2798,7 @@ export const MockNoPermissions: Permissions = { createGroup: false, viewAllLicenses: false, viewNotificationTemplate: false, + viewOrganizationIDPSyncSettings: false, }; export const MockDeploymentConfig: DeploymentConfig = { diff --git a/site/tailwind.config.js b/site/tailwind.config.js index e375cec1c59ac..185e836995b97 100644 --- a/site/tailwind.config.js +++ b/site/tailwind.config.js @@ -32,6 +32,7 @@ module.exports = { primary: "hsl(var(--surface-primary))", secondary: "hsl(var(--surface-secondary))", tertiary: "hsl(var(--surface-tertiary))", + quaternary: "hsl(var(--surface-quaternary))", invert: { primary: "hsl(var(--surface-invert-primary))", secondary: "hsl(var(--surface-invert-secondary))", @@ -42,8 +43,22 @@ module.exports = { DEFAULT: "hsl(var(--border-default))", error: "hsl(var(--border-error))", }, - background: { - DEFAULT: "hsl(var(--background))", + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + chart: { + 1: "hsl(var(--chart-1))", + 2: "hsl(var(--chart-2))", + 3: "hsl(var(--chart-3))", + 4: "hsl(var(--chart-4))", + 5: "hsl(var(--chart-5))", }, }, }, diff --git a/site/tsconfig.json b/site/tsconfig.json index 7e969d18c42dd..68b987d79af10 100644 --- a/site/tsconfig.json +++ b/site/tsconfig.json @@ -16,7 +16,10 @@ "skipLibCheck": true, "strict": true, "target": "es2020", - "baseUrl": "src/" + "baseUrl": "src/", + "paths": { + "@/*": ["./*"] + } }, "include": ["**/*.ts", "**/*.tsx"], "exclude": ["node_modules/", "_jest"], diff --git a/site/vite.config.mts b/site/vite.config.mts index d58e7538581ba..9d13db8645aab 100644 --- a/site/vite.config.mts +++ b/site/vite.config.mts @@ -92,6 +92,7 @@ export default defineConfig({ testHelpers: path.resolve(__dirname, "./src/testHelpers"), theme: path.resolve(__dirname, "./src/theme"), utils: path.resolve(__dirname, "./src/utils"), + "@": path.resolve(__dirname, "./src"), }, }, }); From 6463076a6f0f7822e16e995d774fe7c1bcee9acd Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Fri, 15 Nov 2024 20:33:38 +0000 Subject: [PATCH 02/71] feat: add export policy button --- .../IdpOrgSyncPage/ExportPolicyButton.tsx | 49 +++++++++++ .../IdpOrgSyncPage/IdpOrgSyncPage.tsx | 2 +- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 85 +++++++++++++++---- 3 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx new file mode 100644 index 0000000000000..337a1846903d4 --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx @@ -0,0 +1,49 @@ +import DownloadOutlined from "@mui/icons-material/DownloadOutlined"; +import Button from "@mui/material/Button"; +import type { OrganizationSyncSettings } from "api/typesGenerated"; +import { displayError } from "components/GlobalSnackbar/utils"; +import { saveAs } from "file-saver"; +import { type FC, useMemo, useState } from "react"; + +interface ExportPolicyButtonProps { + syncSettings: OrganizationSyncSettings | undefined; + download?: (file: Blob, filename: string) => void; +} + +export const ExportPolicyButton: FC = ({ + syncSettings, + download = saveAs, +}) => { + const [isDownloading, setIsDownloading] = useState(false); + + const policyJSON = useMemo(() => { + return syncSettings?.field && syncSettings.mapping + ? JSON.stringify(syncSettings, null, 2) + : null; + }, [syncSettings]); + console.log({ syncSettings }); + return ( + + ); +}; diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx index ba7e3c7567257..4adecf463ba2f 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx @@ -34,7 +34,7 @@ export const IdpOrgSyncPage: FC = () => { ); const error = organizationIdpSyncSettingsQuery.error; - + console.log({ organizationIdpSyncSettingsQuery }); return ( <> diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 94be08f5ef33b..2af16ceeb209d 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -16,7 +16,6 @@ import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Loader } from "components/Loader/Loader"; import { Stack } from "components/Stack/Stack"; -import { StatusIndicator } from "components/StatusIndicator/StatusIndicator"; import { TableLoaderSkeleton, TableRowSkeleton, @@ -34,7 +33,7 @@ import type { FC } from "react"; import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { docs } from "utils/docs"; import { getFormHelpers, onChangeTrimmed } from "utils/formUtils"; -// import { ExportPolicyButton } from "./ExportPolicyButton"; +import { ExportPolicyButton } from "./ExportPolicyButton"; import { IdpPillList } from "./IdpPillList"; interface IdpSyncPageViewProps { @@ -62,11 +61,33 @@ export const IdpSyncPageView: FC = ({ }); const getFieldHelpers = getFormHelpers(form, error); const [coderOrgs, setCoderOrgs] = useState([]); - const [isChecked, setIsChecked] = useState( - form.initialValues.organization_assign_default, - ); - const organizationMappingCount = organizationSyncSettings?.mapping - ? Object.entries(organizationSyncSettings.mapping).length + const [idpOrgName, setIdpOrgName] = useState(""); + const [syncSettings, setSyncSettings] = useState< + OrganizationSyncSettings | undefined + >(organizationSyncSettings); + console.log({ organizationSyncSettings }); + // const newMapping: Record = + // organizationSyncSettings?.mapping !== undefined + // ? Object.entries(organizationSyncSettings.mapping).reduce( + // (acc, [key, value]) => { + // acc[key] = value as string[]; + // return acc; + // }, + // {} as Record, + // ) + // : {}; + // console.log({ newMapping }); + // const [mapping, setMapping] = useState>( + // organizationSyncSettings?.mapping || {}, + // ); + // const [isChecked, setIsChecked] = useState( + // form.initialValues.organization_assign_default, + // ); + // const organizationMappingCount = organizationSyncSettings?.mapping + // ? Object.entries(organizationSyncSettings.mapping).length + // : 0; + const organizationMappingCount = syncSettings?.mapping + ? Object.entries(syncSettings.mapping).length : 0; if (error) { @@ -82,6 +103,13 @@ export const IdpSyncPageView: FC = ({ value: org.id, })); + const getOrgNames = (orgIds: readonly string[]) => { + return orgIds.map( + (orgId) => + organizations.find((org) => org.id === orgId)?.display_name || orgId, + ); + }; + return ( <> @@ -89,16 +117,26 @@ export const IdpSyncPageView: FC = ({ ) => { + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + field: event.target.value, + }); + }} /> { - setIsChecked(checked); + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + organization_assign_default: checked, + }); await form.setFieldValue( "organization_assign_default", checked, @@ -115,15 +153,16 @@ export const IdpSyncPageView: FC = ({ justifyContent="space-between" css={styles.tableInfo} > - {/* */} +
) => { + setIdpOrgName(event.target.value); + }} autoFocus fullWidth label="Idp organization name" @@ -144,8 +183,18 @@ export const IdpSyncPageView: FC = ({ /> - - - - - - - { - try { - // await patchOrganizationSyncSettingsMutation.mutateAsync(data); - console.log("submit form", data); - } catch (error) { - displayError( - getErrorMessage( - error, - "Failed to organization IdP sync settings", - ), - ); - } - }} - error={error || patchOrganizationSyncSettingsMutation.error} - // isLoading={patchOrganizationSyncSettingsMutation.isLoading} - /> - - +
+
+
+

Organization IdP Sync

+

+ Automatically assign users to an organization based on their IdP + claims. + + View docs + + +

+
+ +
+ + + + + + { + try { + await patchOrganizationSyncSettingsMutation.mutateAsync(data); + } catch (error) { + displayError( + getErrorMessage( + error, + "Failed to organization IdP sync settings", + ), + ); + } + }} + error={error || patchOrganizationSyncSettingsMutation.error} + /> + + +
); }; diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 2af16ceeb209d..3e762a598782f 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -6,7 +6,6 @@ import TableCell from "@mui/material/TableCell"; import TableContainer from "@mui/material/TableContainer"; import TableHead from "@mui/material/TableHead"; import TableRow from "@mui/material/TableRow"; -import TextField from "@mui/material/TextField"; import type { Organization, OrganizationSyncSettings, @@ -21,10 +20,10 @@ import { TableRowSkeleton, } from "components/TableLoader/TableLoader"; import { Button } from "components/ui/button"; +import { Input } from "components/ui/input"; import { Label } from "components/ui/label"; import MultipleSelector, { type Option } from "components/ui/multiple-selector"; import { Switch } from "components/ui/switch"; -// import { Input } from "components/ui/input"; import { useFormik } from "formik"; import { Plus, SquareArrowOutUpRight } from "lucide-react"; import type React from "react"; @@ -32,7 +31,6 @@ import { useState } from "react"; import type { FC } from "react"; import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { docs } from "utils/docs"; -import { getFormHelpers, onChangeTrimmed } from "utils/formUtils"; import { ExportPolicyButton } from "./ExportPolicyButton"; import { IdpPillList } from "./IdpPillList"; @@ -59,33 +57,16 @@ export const IdpSyncPageView: FC = ({ // validationSchema, onSubmit, }); - const getFieldHelpers = getFormHelpers(form, error); const [coderOrgs, setCoderOrgs] = useState([]); const [idpOrgName, setIdpOrgName] = useState(""); - const [syncSettings, setSyncSettings] = useState< - OrganizationSyncSettings | undefined - >(organizationSyncSettings); - console.log({ organizationSyncSettings }); - // const newMapping: Record = - // organizationSyncSettings?.mapping !== undefined - // ? Object.entries(organizationSyncSettings.mapping).reduce( - // (acc, [key, value]) => { - // acc[key] = value as string[]; - // return acc; - // }, - // {} as Record, - // ) - // : {}; - // console.log({ newMapping }); - // const [mapping, setMapping] = useState>( - // organizationSyncSettings?.mapping || {}, - // ); - // const [isChecked, setIsChecked] = useState( - // form.initialValues.organization_assign_default, - // ); - // const organizationMappingCount = organizationSyncSettings?.mapping - // ? Object.entries(organizationSyncSettings.mapping).length - // : 0; + const [syncSettings, setSyncSettings] = useState( + organizationSyncSettings || { + field: "", + organization_assign_default: true, + mapping: {}, + }, + ); + const organizationMappingCount = syncSettings?.mapping ? Object.entries(syncSettings.mapping).length : 0; @@ -109,90 +90,105 @@ export const IdpSyncPageView: FC = ({ organizations.find((org) => org.id === orgId)?.display_name || orgId, ); }; - return ( <>
- - ) => { - setSyncSettings({ - ...(syncSettings as OrganizationSyncSettings), - field: event.target.value, - }); - }} - /> - { - setSyncSettings({ - ...(syncSettings as OrganizationSyncSettings), - organization_assign_default: checked, - }); - await form.setFieldValue( - "organization_assign_default", - checked, - ); - }} - /> - - - +
+ +
+ , + ) => { + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + field: event.target.value, + }); + await form.setFieldValue("field", event.target.value); + }} + /> +
+ { + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + organization_assign_default: checked, + }); + await form.setFieldValue( + "organization_assign_default", + checked, + ); + }} + /> + +
+
+
+
+ {/* - +
*/}
- ) => { - setIdpOrgName(event.target.value); - }} - autoFocus - fullWidth - label="Idp organization name" - className="min-w-72 w-72" - /> - - no results found. -

- } - /> +
+ + ) => { + setIdpOrgName(event.target.value); + }} + /> +
+
+ + + no results found. +

+ } + /> +
From f6e286c84209a1a621b97ab6d41538069ee9d58e Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sun, 17 Nov 2024 20:02:16 +0000 Subject: [PATCH 05/71] feat: add delete button for org mapping --- site/src/components/ui/button.tsx | 2 +- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 50 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/site/src/components/ui/button.tsx b/site/src/components/ui/button.tsx index 1ad4608e7559f..d3bd60b7a3e26 100644 --- a/site/src/components/ui/button.tsx +++ b/site/src/components/ui/button.tsx @@ -5,7 +5,7 @@ import * as React from "react"; import { cn } from "utils/cn"; const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid", + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid cursor-pointer", { variants: { variant: { diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 3e762a598782f..d7991a925413b 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -25,13 +25,12 @@ import { Label } from "components/ui/label"; import MultipleSelector, { type Option } from "components/ui/multiple-selector"; import { Switch } from "components/ui/switch"; import { useFormik } from "formik"; -import { Plus, SquareArrowOutUpRight } from "lucide-react"; +import { Plus, SquareArrowOutUpRight, Trash } from "lucide-react"; import type React from "react"; import { useState } from "react"; import type { FC } from "react"; import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { docs } from "utils/docs"; -import { ExportPolicyButton } from "./ExportPolicyButton"; import { IdpPillList } from "./IdpPillList"; interface IdpSyncPageViewProps { @@ -90,6 +89,21 @@ export const IdpSyncPageView: FC = ({ organizations.find((org) => org.id === orgId)?.display_name || orgId, ); }; + + const handleDelete = async (idpOrg: string) => { + const newMapping = Object.fromEntries( + Object.entries(syncSettings?.mapping || {}).filter( + ([key]) => key !== idpOrg, + ), + ); + const newSyncSettings = { + ...(syncSettings as OrganizationSyncSettings), + mapping: newMapping, + }; + setSyncSettings(newSyncSettings); + await form.setFieldValue("mapping", newSyncSettings.mapping); + }; + return ( <> @@ -134,17 +148,11 @@ export const IdpSyncPageView: FC = ({
+

+ If empty, organization sync is deactivated +

- {/* - - */} -
-
-
- - ) => { - setIdpOrgName(event.target.value); + +
+
+
+ + ) => { + setIdpOrgName(event.target.value); + }} + /> +
+
+ + + no results found. +

+ } + /> +
+
-
- - - no results found. -

- } - /> -
- -
- - {syncSettings?.mapping && Object.entries(syncSettings.mapping) @@ -222,6 +223,7 @@ export const IdpSyncPageView: FC = ({ - +
From ad1aa84ca885bb610f4aaa5942fb33d737c580f6 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sun, 17 Nov 2024 20:47:39 +0000 Subject: [PATCH 07/71] feat: update export policy button to shadcn --- .../IdpOrgSyncPage/ExportPolicyButton.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx index 2c3c7c74ed210..ab5bb1979859c 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx @@ -1,5 +1,5 @@ -import DownloadOutlined from "@mui/icons-material/DownloadOutlined"; -import Button from "@mui/material/Button"; +import { Download } from "lucide-react"; +import { Button } from "components/ui/button"; import type { OrganizationSyncSettings } from "api/typesGenerated"; import { displayError } from "components/GlobalSnackbar/utils"; import { saveAs } from "file-saver"; @@ -17,14 +17,14 @@ export const ExportPolicyButton: FC = ({ const [isDownloading, setIsDownloading] = useState(false); const policyJSON = useMemo(() => { - return syncSettings?.field && syncSettings.mapping + return syncSettings?.field && Object.keys(syncSettings.mapping).length > 0 ? JSON.stringify(syncSettings, null, 2) : null; }, [syncSettings]); return ( ); From b01588dafaeb25492a6f7965a3a8f860f5bfd28a Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sun, 17 Nov 2024 23:28:37 +0000 Subject: [PATCH 08/71] fix: fix format --- .../IdpOrgSyncPage/ExportPolicyButton.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx index ab5bb1979859c..437661d5f6da5 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx @@ -1,8 +1,8 @@ -import { Download } from "lucide-react"; -import { Button } from "components/ui/button"; import type { OrganizationSyncSettings } from "api/typesGenerated"; import { displayError } from "components/GlobalSnackbar/utils"; +import { Button } from "components/ui/button"; import { saveAs } from "file-saver"; +import { Download } from "lucide-react"; import { type FC, useMemo, useState } from "react"; interface ExportPolicyButtonProps { From 6203d048e59b7e0afc071d0e3d6a2e04b83b920a Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Wed, 20 Nov 2024 21:41:29 +0000 Subject: [PATCH 09/71] feat: display success/error toast on form submission --- .../IdpOrgSyncPage/IdpOrgSyncPage.tsx | 4 +- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 222 +++++++++--------- 2 files changed, 117 insertions(+), 109 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx index 8d27a648d2ebd..20789eb4e69fa 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx @@ -6,6 +6,7 @@ import { import type { OrganizationSyncSettings } from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { displayError } from "components/GlobalSnackbar/utils"; +import { displaySuccess } from "components/GlobalSnackbar/utils"; import { Loader } from "components/Loader/Loader"; import { Paywall } from "components/Paywall/Paywall"; import { SquareArrowOutUpRight } from "lucide-react"; @@ -77,11 +78,12 @@ export const IdpOrgSyncPage: FC = () => { onSubmit={async (data: OrganizationSyncSettings) => { try { await patchOrganizationSyncSettingsMutation.mutateAsync(data); + displaySuccess("Organization sync settings updated."); } catch (error) { displayError( getErrorMessage( error, - "Failed to organization IdP sync settings", + "Failed to update organization IdP sync settings", ), ); } diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 1e7ab5097d310..8bee281b5a2bb 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -55,6 +55,7 @@ export const IdpSyncPageView: FC = ({ }, // validationSchema, onSubmit, + enableReinitialize: true, }); const [coderOrgs, setCoderOrgs] = useState([]); const [idpOrgName, setIdpOrgName] = useState(""); @@ -108,130 +109,135 @@ export const IdpSyncPageView: FC = ({ <>
-
-
- -
- , - ) => { - setSyncSettings({ - ...(syncSettings as OrganizationSyncSettings), - field: event.target.value, - }); - await form.setFieldValue("field", event.target.value); - }} - /> -
- { +
+
+
+ +
+ , + ) => { setSyncSettings({ ...(syncSettings as OrganizationSyncSettings), - organization_assign_default: checked, + field: event.target.value, }); - await form.setFieldValue( - "organization_assign_default", - checked, - ); + await form.setFieldValue("field", event.target.value); }} /> - +
+ { + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + organization_assign_default: checked, + }); + await form.setFieldValue( + "organization_assign_default", + checked, + ); + }} + /> + +
+

+ If empty, organization sync is deactivated +

-

- If empty, organization sync is deactivated -

-
-
-
-
- - ) => { - setIdpOrgName(event.target.value); +
+
+
+ + ) => { + setIdpOrgName(event.target.value); + }} + /> +
+
+ + + no results found. +

+ } + /> +
+
-
- - - no results found. -

- } - /> + > + + Add IdP organization +
+ + {syncSettings?.mapping && + Object.entries(syncSettings.mapping) + .sort() + .map(([idpOrg, organizations]) => ( + + ))} +
- - {syncSettings?.mapping && - Object.entries(syncSettings.mapping) - .sort() - .map(([idpOrg, organizations]) => ( - - ))} - - -
+ From bc37998a5442ae00258bca2971bc2ea3ee2e5f77 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Wed, 20 Nov 2024 22:19:08 +0000 Subject: [PATCH 10/71] feat: create story for export policy button --- .../ExportPolicyButton.stories.tsx | 41 +++++++++++++++++++ .../ExportPolicyButton.stories.tsx | 2 +- .../IdpSyncPage/IdpSyncPageView.stories.tsx | 2 +- site/src/testHelpers/entities.ts | 12 ++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.stories.tsx diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.stories.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.stories.tsx new file mode 100644 index 0000000000000..a4206c3b04a1e --- /dev/null +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.stories.tsx @@ -0,0 +1,41 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { expect, fn, userEvent, waitFor, within } from "@storybook/test"; +import { MockOrganizationSyncSettings } from "testHelpers/entities"; +import { ExportPolicyButton } from "./ExportPolicyButton"; + +const meta: Meta = { + title: "pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton", + component: ExportPolicyButton, + args: { + syncSettings: MockOrganizationSyncSettings, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const ClickExportPolicy: Story = { + args: { + syncSettings: MockOrganizationSyncSettings, + download: fn(), + }, + play: async ({ canvasElement, args }) => { + const canvas = within(canvasElement); + await userEvent.click( + canvas.getByRole("button", { name: "Export Policy" }), + ); + await waitFor(() => + expect(args.download).toHaveBeenCalledWith( + expect.anything(), + "organizations_policy.json", + ), + ); + const blob: Blob = (args.download as jest.Mock).mock.lastCall[0]; + await expect(blob.type).toEqual("application/json"); + await expect(await blob.text()).toEqual( + JSON.stringify(MockOrganizationSyncSettings, null, 2), + ); + }, +}; diff --git a/site/src/pages/ManagementSettingsPage/IdpSyncPage/ExportPolicyButton.stories.tsx b/site/src/pages/ManagementSettingsPage/IdpSyncPage/ExportPolicyButton.stories.tsx index da2f5140d3d73..af9a6b2fa4073 100644 --- a/site/src/pages/ManagementSettingsPage/IdpSyncPage/ExportPolicyButton.stories.tsx +++ b/site/src/pages/ManagementSettingsPage/IdpSyncPage/ExportPolicyButton.stories.tsx @@ -8,7 +8,7 @@ import { import { ExportPolicyButton } from "./ExportPolicyButton"; const meta: Meta = { - title: "modules/resources/ExportPolicyButton", + title: "pages/IdpSyncPage/ExportPolicyButton", component: ExportPolicyButton, args: { syncSettings: MockGroupSyncSettings, diff --git a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx index 239d97ba0a1ad..d2ff522fbbfd9 100644 --- a/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx +++ b/site/src/pages/ManagementSettingsPage/IdpSyncPage/IdpSyncPageView.stories.tsx @@ -12,7 +12,7 @@ import { import { IdpSyncPageView } from "./IdpSyncPageView"; const meta: Meta = { - title: "pages/OrganizationIdpSyncPage", + title: "pages/IdpSyncPage", component: IdpSyncPageView, }; diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 178f042af13dc..51efdb6c60645 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -2674,6 +2674,18 @@ export const MockRoleSyncSettings: TypesGen.RoleSyncSettings = { }, }; +export const MockOrganizationSyncSettings: TypesGen.OrganizationSyncSettings = { + field: "organization-test", + mapping: { + "idp-org-1": [ + "fbd2116a-8961-4954-87ae-e4575bd29ce0", + "13de3eb4-9b4f-49e7-b0f8-0c3728a0d2e2", + ], + "idp-org-2": ["fbd2116a-8961-4954-87ae-e4575bd29ce0"], + }, + organization_assign_default: true, +}; + export const MockGroup: TypesGen.Group = { id: "fbd2116a-8961-4954-87ae-e4575bd29ce0", name: "Front-End", From 2c2246d3a8f5604e1db6d632b88d18199991aa2c Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Thu, 21 Nov 2024 05:15:17 +0000 Subject: [PATCH 11/71] feat: update pill list component --- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 18 +-- .../IdpOrgSyncPage/IdpPillList.tsx | 106 ------------------ .../IdpOrgSyncPage/PillList.tsx | 98 ++++++++++++++++ 3 files changed, 100 insertions(+), 122 deletions(-) delete mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpPillList.tsx create mode 100644 site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/PillList.tsx diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 8bee281b5a2bb..52206c79587f3 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -31,7 +31,7 @@ import { useState } from "react"; import type { FC } from "react"; import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { docs } from "utils/docs"; -import { IdpPillList } from "./IdpPillList"; +import { PillList } from "./PillList"; interface IdpSyncPageViewProps { organizationSyncSettings: OrganizationSyncSettings | undefined; @@ -313,7 +313,7 @@ const OrganizationRow: FC = ({ {idpOrg} - + +
From 6e871302fea6a2f9b8c02f100d9491a1b6342b33 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sat, 23 Nov 2024 22:29:23 +0000 Subject: [PATCH 13/71] chore: update conventions for shadcn components --- site/src/components/ui/badge.tsx | 11 +++--- site/src/components/ui/button.tsx | 31 ++++++++-------- site/src/components/ui/command.tsx | 35 +++++++----------- site/src/components/ui/dialog.tsx | 37 +++++++------------- site/src/components/ui/input.tsx | 33 +++++++++-------- site/src/components/ui/label.tsx | 6 ++-- site/src/components/ui/multiple-selector.tsx | 2 +- 7 files changed, 64 insertions(+), 91 deletions(-) diff --git a/site/src/components/ui/badge.tsx b/site/src/components/ui/badge.tsx index 368dcfafb9650..f33c4f369fbd8 100644 --- a/site/src/components/ui/badge.tsx +++ b/site/src/components/ui/badge.tsx @@ -1,9 +1,9 @@ import { type VariantProps, cva } from "class-variance-authority"; -import type * as React from "react"; +import type { FC } from "react"; import { cn } from "utils/cn"; -const badgeVariants = cva( +export const badgeVariants = cva( "inline-flex items-center rounded-md border px-2.5 py-1 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", { variants: { @@ -27,10 +27,9 @@ export interface BadgeProps extends React.HTMLAttributes, VariantProps {} -function Badge({ className, variant, ...props }: BadgeProps) { +export const Badge: FC = ({ className, variant, ...props }) => { return (
); -} - -export { Badge, badgeVariants }; +}; +Badge.displayName = "Badge"; diff --git a/site/src/components/ui/button.tsx b/site/src/components/ui/button.tsx index a7bd2a3d405e6..c1249768811fa 100644 --- a/site/src/components/ui/button.tsx +++ b/site/src/components/ui/button.tsx @@ -1,10 +1,10 @@ import { Slot } from "@radix-ui/react-slot"; import { type VariantProps, cva } from "class-variance-authority"; -import * as React from "react"; +import { type FC, forwardRef } from "react"; import { cn } from "utils/cn"; -const buttonVariants = cva( +export const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:text-content-disabled [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid cursor-pointer", { variants: { @@ -36,18 +36,17 @@ export interface ButtonProps asChild?: boolean; } -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button"; - return ( - - ); - }, -); +export const Button: FC = forwardRef< + HTMLButtonElement, + ButtonProps +>(({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); +}); Button.displayName = "Button"; - -export { Button, buttonVariants }; diff --git a/site/src/components/ui/command.tsx b/site/src/components/ui/command.tsx index 113d49605d993..602c1860a0a4f 100644 --- a/site/src/components/ui/command.tsx +++ b/site/src/components/ui/command.tsx @@ -1,12 +1,12 @@ import type { DialogProps } from "@radix-ui/react-dialog"; import { Command as CommandPrimitive } from "cmdk"; import { Search } from "lucide-react"; -import * as React from "react"; +import { type FC, forwardRef } from "react"; import { Dialog, DialogContent } from "components/ui/dialog"; import { cn } from "utils/cn"; -const Command = React.forwardRef< +export const Command = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -21,7 +21,10 @@ const Command = React.forwardRef< )); Command.displayName = CommandPrimitive.displayName; -const CommandDialog = ({ children, ...props }: DialogProps) => { +export const CommandDialog: FC = ({ + children, + ...props +}: DialogProps) => { return ( @@ -33,7 +36,7 @@ const CommandDialog = ({ children, ...props }: DialogProps) => { ); }; -const CommandInput = React.forwardRef< +export const CommandInput = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -52,7 +55,7 @@ const CommandInput = React.forwardRef< CommandInput.displayName = CommandPrimitive.Input.displayName; -const CommandList = React.forwardRef< +export const CommandList = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -65,7 +68,7 @@ const CommandList = React.forwardRef< CommandList.displayName = CommandPrimitive.List.displayName; -const CommandEmpty = React.forwardRef< +export const CommandEmpty = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => ( @@ -78,7 +81,7 @@ const CommandEmpty = React.forwardRef< CommandEmpty.displayName = CommandPrimitive.Empty.displayName; -const CommandGroup = React.forwardRef< +export const CommandGroup = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -94,7 +97,7 @@ const CommandGroup = React.forwardRef< CommandGroup.displayName = CommandPrimitive.Group.displayName; -const CommandSeparator = React.forwardRef< +export const CommandSeparator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -106,7 +109,7 @@ const CommandSeparator = React.forwardRef< )); CommandSeparator.displayName = CommandPrimitive.Separator.displayName; -const CommandItem = React.forwardRef< +export const CommandItem = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -122,7 +125,7 @@ const CommandItem = React.forwardRef< CommandItem.displayName = CommandPrimitive.Item.displayName; -const CommandShortcut = ({ +export const CommandShortcut = ({ className, ...props }: React.HTMLAttributes) => { @@ -137,15 +140,3 @@ const CommandShortcut = ({ ); }; CommandShortcut.displayName = "CommandShortcut"; - -export { - Command, - CommandDialog, - CommandInput, - CommandList, - CommandEmpty, - CommandGroup, - CommandItem, - CommandShortcut, - CommandSeparator, -}; diff --git a/site/src/components/ui/dialog.tsx b/site/src/components/ui/dialog.tsx index 775e11d74aaf6..ba3ed6120a82f 100644 --- a/site/src/components/ui/dialog.tsx +++ b/site/src/components/ui/dialog.tsx @@ -1,25 +1,25 @@ import * as DialogPrimitive from "@radix-ui/react-dialog"; import { X } from "lucide-react"; -import * as React from "react"; +import { forwardRef } from "react"; import { cn } from "utils/cn"; -const Dialog = DialogPrimitive.Root; +export const Dialog = DialogPrimitive.Root; -const DialogTrigger = DialogPrimitive.Trigger; +export const DialogTrigger = DialogPrimitive.Trigger; -const DialogPortal = DialogPrimitive.Portal; +export const DialogPortal = DialogPrimitive.Portal; -const DialogClose = DialogPrimitive.Close; +export const DialogClose = DialogPrimitive.Close; -const DialogOverlay = React.forwardRef< +export const DialogOverlay = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( , React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( @@ -51,7 +51,7 @@ const DialogContent = React.forwardRef< )); DialogContent.displayName = DialogPrimitive.Content.displayName; -const DialogHeader = ({ +export const DialogHeader = ({ className, ...props }: React.HTMLAttributes) => ( @@ -65,7 +65,7 @@ const DialogHeader = ({ ); DialogHeader.displayName = "DialogHeader"; -const DialogFooter = ({ +export const DialogFooter = ({ className, ...props }: React.HTMLAttributes) => ( @@ -79,7 +79,7 @@ const DialogFooter = ({ ); DialogFooter.displayName = "DialogFooter"; -const DialogTitle = React.forwardRef< +export const DialogTitle = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -94,7 +94,7 @@ const DialogTitle = React.forwardRef< )); DialogTitle.displayName = DialogPrimitive.Title.displayName; -const DialogDescription = React.forwardRef< +export const DialogDescription = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( @@ -105,16 +105,3 @@ const DialogDescription = React.forwardRef< /> )); DialogDescription.displayName = DialogPrimitive.Description.displayName; - -export { - Dialog, - DialogPortal, - DialogOverlay, - DialogTrigger, - DialogClose, - DialogContent, - DialogHeader, - DialogFooter, - DialogTitle, - DialogDescription, -}; diff --git a/site/src/components/ui/input.tsx b/site/src/components/ui/input.tsx index bfe696870dc41..c770644d1d808 100644 --- a/site/src/components/ui/input.tsx +++ b/site/src/components/ui/input.tsx @@ -2,21 +2,20 @@ import * as React from "react"; import { cn } from "utils/cn"; -const Input = React.forwardRef>( - ({ className, type, ...props }, ref) => { - return ( - - ); - }, -); +export const Input = React.forwardRef< + HTMLInputElement, + React.ComponentProps<"input"> +>(({ className, type, ...props }, ref) => { + return ( + + ); +}); Input.displayName = "Input"; - -export { Input }; diff --git a/site/src/components/ui/label.tsx b/site/src/components/ui/label.tsx index 5fb36e06ebde2..16bac98b090ed 100644 --- a/site/src/components/ui/label.tsx +++ b/site/src/components/ui/label.tsx @@ -1,6 +1,6 @@ import * as LabelPrimitive from "@radix-ui/react-label"; import { type VariantProps, cva } from "class-variance-authority"; -import * as React from "react"; +import { forwardRef } from "react"; import { cn } from "utils/cn"; @@ -8,7 +8,7 @@ const labelVariants = cva( "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70", ); -const Label = React.forwardRef< +export const Label = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef & VariantProps @@ -20,5 +20,3 @@ const Label = React.forwardRef< /> )); Label.displayName = LabelPrimitive.Root.displayName; - -export { Label }; diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index ca3f224042a59..34abae9744b28 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -1,7 +1,7 @@ "use client"; import { Command as CommandPrimitive, useCommandState } from "cmdk"; -import { X, ChevronDown } from "lucide-react"; +import { ChevronDown, X } from "lucide-react"; import * as React from "react"; import { forwardRef, useEffect } from "react"; From a1b6e79a4f0f1ab2b852eba47b8cb04e75b780d0 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Sun, 24 Nov 2024 22:35:34 +0000 Subject: [PATCH 14/71] feat: use semantic list html for overflow pills --- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 7 ++-- .../{PillList.tsx => OrganizationPills.tsx} | 35 +++++++++++-------- 2 files changed, 23 insertions(+), 19 deletions(-) rename site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/{PillList.tsx => OrganizationPills.tsx} (71%) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 52206c79587f3..cc74ae1ac903c 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -29,9 +29,8 @@ import { Plus, SquareArrowOutUpRight, Trash } from "lucide-react"; import type React from "react"; import { useState } from "react"; import type { FC } from "react"; -import { MONOSPACE_FONT_FAMILY } from "theme/constants"; import { docs } from "utils/docs"; -import { PillList } from "./PillList"; +import { OrganizationPills } from "./OrganizationPills"; interface IdpSyncPageViewProps { organizationSyncSettings: OrganizationSyncSettings | undefined; @@ -281,7 +280,7 @@ const IdpMappingTable: FC = ({ isEmpty, children }) => { className="no-underline" > - How to setup IdP organization sync + How to set up IdP organization sync } @@ -313,7 +312,7 @@ const OrganizationRow: FC = ({ {idpOrg} - + + /> +
+
+ + ({ + label: org.display_name, + value: org.id, + }))} + hidePlaceholderWhenSelected + placeholder="Select organization" + emptyIndicator={ +

+ All organizations selected +

+ } + />
- - {syncSettings?.mapping && - Object.entries(syncSettings.mapping) - .sort() - .map(([idpOrg, organizations]) => ( - - ))} -
- - - - + + {syncSettings?.mapping && + Object.entries(syncSettings.mapping) + .sort() + .map(([idpOrg, organizations]) => ( + + ))} + + +
+ + + ); }; From c282765b915cd8a945748ef5b14fdd0c30fb9642 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Mon, 25 Nov 2024 13:40:23 +0000 Subject: [PATCH 19/71] fix: styling for x and chevron buttons --- site/src/components/ui/multiple-selector.tsx | 177 +++++++++--------- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 4 +- 2 files changed, 93 insertions(+), 88 deletions(-) diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index d559d5fbe2e17..6a9e6143d0a21 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -476,96 +476,101 @@ const MultipleSelector = React.forwardRef< inputRef?.current?.focus(); }} > -
- {selected.map((option) => { - return ( - - {option.label} - - - ); - })} - {/* Avoid having the "Search" Icon */} - { - setInputValue(value); - inputProps?.onValueChange?.(value); - }} - onBlur={(event) => { - if (!onScrollbar) { - setOpen(false); + {option.label} + + + ); + })} + {/* Avoid having the "Search" Icon */} + { + setInputValue(value); + inputProps?.onValueChange?.(value); + }} + onBlur={(event) => { + if (!onScrollbar) { + setOpen(false); + } + inputProps?.onBlur?.(event); + }} + onFocus={(event) => { + setOpen(true); + triggerSearchOnFocus && onSearch?.(debouncedSearchTerm); + inputProps?.onFocus?.(event); + }} + placeholder={ + hidePlaceholderWhenSelected && selected.length !== 0 + ? "" + : placeholder } - inputProps?.onBlur?.(event); - }} - onFocus={(event) => { - setOpen(true); - triggerSearchOnFocus && onSearch?.(debouncedSearchTerm); - inputProps?.onFocus?.(event); - }} - placeholder={ - hidePlaceholderWhenSelected && selected.length !== 0 - ? "" - : placeholder - } - className={cn( - "flex-1 border-none outline-none bg-transparent placeholder:text-content-secondary", - { - "w-full": hidePlaceholderWhenSelected, - "px-3 py-2.5": selected.length === 0, - "ml-1": selected.length !== 0, - }, - inputProps?.className, - )} - /> - - + className={cn( + "flex-1 border-none outline-none bg-transparent placeholder:text-content-secondary", + { + "w-full": hidePlaceholderWhenSelected, + "px-3 py-2.5": selected.length === 0, + "ml-1": selected.length !== 0, + }, + inputProps?.className, + )} + /> +
+
+ + +
diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index bcd18e29e82ff..fa74f8a4a904d 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -169,7 +169,7 @@ export const IdpSyncPageView: FC = ({ Coder organization ({ @@ -179,7 +179,7 @@ export const IdpSyncPageView: FC = ({ hidePlaceholderWhenSelected placeholder="Select organization" emptyIndicator={ -

+

All organizations selected

} From 40155bc63489e6a55e137f4088bf353427d59a65 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Mon, 25 Nov 2024 16:49:58 +0000 Subject: [PATCH 20/71] chore: extract fixed filter options to a variable --- site/src/components/ui/multiple-selector.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index 6a9e6143d0a21..f5e16b995f491 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -442,6 +442,8 @@ const MultipleSelector = React.forwardRef< return undefined; }, [creatable, commandProps?.filter]); + const fixedOptions = selected.filter((s) => s.fixed); + return ( { - setSelected(selected.filter((s) => s.fixed)); - onChange?.(selected.filter((s) => s.fixed)); + setSelected(fixedOptions); + onChange?.(fixedOptions); }} className={cn( "bg-transparent mt-1 border-none cursor-pointer text-content-secondary hover:text-content-primary", (hideClearAllButton || disabled || selected.length < 1 || - selected.filter((s) => s.fixed).length === - selected.length) && + fixedOptions.length === selected.length) && "hidden", )} > From a1298200b6f15e2837c07cc4047092ef063d2b73 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Mon, 25 Nov 2024 21:21:51 +0000 Subject: [PATCH 21/71] fix: update focus styles --- site/src/components/ui/button.tsx | 2 +- site/src/components/ui/input.tsx | 2 +- site/src/components/ui/switch.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/site/src/components/ui/button.tsx b/site/src/components/ui/button.tsx index c1249768811fa..3d4f93756430e 100644 --- a/site/src/components/ui/button.tsx +++ b/site/src/components/ui/button.tsx @@ -5,7 +5,7 @@ import { type FC, forwardRef } from "react"; import { cn } from "utils/cn"; export const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:text-content-disabled [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid cursor-pointer", + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-content-link disabled:pointer-events-none disabled:text-content-disabled [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 font-semibold border-solid cursor-pointer", { variants: { variant: { diff --git a/site/src/components/ui/input.tsx b/site/src/components/ui/input.tsx index c770644d1d808..f4207410af267 100644 --- a/site/src/components/ui/input.tsx +++ b/site/src/components/ui/input.tsx @@ -10,7 +10,7 @@ export const Input = React.forwardRef< (({ className, ...props }, ref) => ( Date: Mon, 25 Nov 2024 21:40:10 +0000 Subject: [PATCH 22/71] fix: multi-select placement fix --- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index fa74f8a4a904d..d415b7bafebaa 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -150,7 +150,7 @@ export const IdpSyncPageView: FC = ({
-
+
- +
+
 
+ +
{syncSettings?.mapping && From e54e5ca4c44e72d646dea9948752a93b3909895b Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Mon, 25 Nov 2024 21:58:50 +0000 Subject: [PATCH 23/71] fix: improve export policy button logic --- .../IdpOrgSyncPage/ExportPolicyButton.tsx | 15 ++++++--------- .../IdpSyncPage/ExportPolicyButton.tsx | 15 ++++++--------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx index 437661d5f6da5..7af6766af49f3 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/ExportPolicyButton.tsx @@ -3,7 +3,7 @@ import { displayError } from "components/GlobalSnackbar/utils"; import { Button } from "components/ui/button"; import { saveAs } from "file-saver"; import { Download } from "lucide-react"; -import { type FC, useMemo, useState } from "react"; +import { type FC, useState } from "react"; interface ExportPolicyButtonProps { syncSettings: OrganizationSyncSettings | undefined; @@ -16,21 +16,18 @@ export const ExportPolicyButton: FC = ({ }) => { const [isDownloading, setIsDownloading] = useState(false); - const policyJSON = useMemo(() => { - return syncSettings?.field && Object.keys(syncSettings.mapping).length > 0 - ? JSON.stringify(syncSettings, null, 2) - : null; - }, [syncSettings]); + const canCreatePolicyJson = + syncSettings?.field && Object.keys(syncSettings?.mapping).length > 0; return (
- {syncSettings?.mapping && + {syncSettings.mapping && Object.entries(syncSettings.mapping) .sort() .map(([idpOrg, organizations]) => ( diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/OrganizationPills.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/OrganizationPills.tsx index a7d0ee2d3abb8..3a8f8ee929e80 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/OrganizationPills.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/OrganizationPills.tsx @@ -19,30 +19,32 @@ const UUID = export const OrganizationPills: FC = ({ organizations, }) => { + const orgs = organizations.map((org) => { + return { name: org, isUUID: UUID.test(org) }; + }); + return (
- {organizations.length > 0 ? ( + {orgs.length > 0 ? ( - {organizations[0]} + {orgs[0].name} ) : (

None

)} - {organizations.length > 1 && ( - - )} + {orgs.length > 1 && }
); }; interface OverflowPillProps { - organizations: string[]; + organizations: { name: string; isUUID: boolean }[]; } const OverflowPillList: FC = ({ organizations }) => { @@ -85,14 +87,14 @@ const OverflowPillList: FC = ({ organizations }) => { >
    {organizations.map((organization) => ( -
  • +
  • - {organization} + {organization.name}
  • ))} From a13d9b242c044a5a172d552755d245eb1df0fc31 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Mon, 25 Nov 2024 23:54:50 +0000 Subject: [PATCH 26/71] fix: update error handling --- .../IdpOrgSyncPage/IdpOrgSyncPage.tsx | 13 ++++++++++++- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 10 +++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx index e261dcfaae918..b94314dc789f3 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPage.tsx @@ -12,7 +12,7 @@ import { Paywall } from "components/Paywall/Paywall"; import { SquareArrowOutUpRight } from "lucide-react"; import { useDashboard } from "modules/dashboard/useDashboard"; import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; -import type { FC } from "react"; +import { type FC, useEffect } from "react"; import { Helmet } from "react-helmet-async"; import { useMutation, useQuery, useQueryClient } from "react-query"; import { docs } from "utils/docs"; @@ -35,6 +35,17 @@ export const IdpOrgSyncPage: FC = () => { patchOrganizationSyncSettings(queryClient), ); + useEffect(() => { + if (patchOrganizationSyncSettingsMutation.error) { + displayError( + getErrorMessage( + patchOrganizationSyncSettingsMutation.error, + "Error updating organization idp sync settings.", + ), + ); + } + }, [patchOrganizationSyncSettingsMutation.error]); + if (isLoading) { return ; } diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index 1bcb5e3131d2c..a09989bfbbeb2 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -14,7 +14,6 @@ import { ErrorAlert } from "components/Alert/ErrorAlert"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Loader } from "components/Loader/Loader"; -import { Stack } from "components/Stack/Stack"; import { TableLoaderSkeleton, TableRowSkeleton, @@ -70,10 +69,6 @@ export const IdpSyncPageView: FC = ({ ? Object.entries(syncSettings.mapping).length : 0; - if (error) { - return ; - } - if (!organizationSyncSettings) { return ; } @@ -100,7 +95,8 @@ export const IdpSyncPageView: FC = ({ }; return ( - +
    + {Boolean(error) && }
    @@ -238,7 +234,7 @@ export const IdpSyncPageView: FC = ({
    - +
    ); }; From 1b8efd1eab50d5204a18b98ed7c9322af1d0d2d8 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 00:00:01 +0000 Subject: [PATCH 27/71] chore: add source comment --- site/src/components/ui/multiple-selector.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index acf839e341b33..3d655dd8b85ee 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -1,3 +1,5 @@ +// This component is based on multiple-selector from +// https://shadcnui-expansions.typeart.cc/docs/multiple-selector import { Command as CommandPrimitive, useCommandState } from "cmdk"; import { ChevronDown, X } from "lucide-react"; import * as React from "react"; From 137c25c759862890c7644b1a0ae644714f4e1ea9 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 00:10:44 +0000 Subject: [PATCH 28/71] chore: remove debounce --- site/src/components/ui/multiple-selector.tsx | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index 3d655dd8b85ee..9d391748b3f7b 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -4,6 +4,7 @@ import { Command as CommandPrimitive, useCommandState } from "cmdk"; import { ChevronDown, X } from "lucide-react"; import * as React from "react"; import { forwardRef, useEffect } from "react"; +import { useDebouncedValue } from "hooks/debounce"; import { Badge } from "components/ui/badge"; import { @@ -91,20 +92,6 @@ export interface MultipleSelectorRef { reset: () => void; } -export function useDebounce(value: T, delay?: number): T { - const [debouncedValue, setDebouncedValue] = React.useState(value); - - useEffect(() => { - const timer = setTimeout(() => setDebouncedValue(value), delay || 500); - - return () => { - clearTimeout(timer); - }; - }, [value, delay]); - - return debouncedValue; -} - function transToGroupOption(options: Option[], groupBy?: string) { if (options.length === 0) { return {}; @@ -218,7 +205,7 @@ const MultipleSelector = React.forwardRef< transToGroupOption(arrayDefaultOptions, groupBy), ); const [inputValue, setInputValue] = React.useState(""); - const debouncedSearchTerm = useDebounce(inputValue, delay || 500); + const debouncedSearchTerm = useDebouncedValue(inputValue, delay || 500); React.useImperativeHandle( ref, From 46a46466027d1dfe79fa9d2faefd8d59548ab1e3 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 00:17:11 +0000 Subject: [PATCH 29/71] fix: format --- site/src/components/ui/multiple-selector.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index 9d391748b3f7b..c41f0c43c4a1a 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -1,10 +1,10 @@ // This component is based on multiple-selector from // https://shadcnui-expansions.typeart.cc/docs/multiple-selector import { Command as CommandPrimitive, useCommandState } from "cmdk"; +import { useDebouncedValue } from "hooks/debounce"; import { ChevronDown, X } from "lucide-react"; import * as React from "react"; import { forwardRef, useEffect } from "react"; -import { useDebouncedValue } from "hooks/debounce"; import { Badge } from "components/ui/badge"; import { @@ -69,7 +69,7 @@ interface MultipleSelectorProps { * First item selected is a default behavior by cmdk. That is why the default is true. * This is a workaround solution by add a dummy item. * - * @reference: https://github.com/pacocoursey/cmdk/issues/171 + * @see {@link https://github.com/pacocoursey/cmdk/issues/171} */ selectFirstItem?: boolean; /** Allow user to create option when there is no option matched. */ From 85a455c6057b9df399726d8738eff6a3fc667590 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 16:53:57 +0000 Subject: [PATCH 30/71] feat: update form save logic --- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index a09989bfbbeb2..db0dd7c56537d 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -92,6 +92,7 @@ export const IdpSyncPageView: FC = ({ }; setSyncSettings(newSyncSettings); await form.setFieldValue("mapping", newSyncSettings.mapping); + form.handleSubmit(); }; return ( @@ -105,20 +106,31 @@ export const IdpSyncPageView: FC = ({ Organization sync field
    - , - ) => { - setSyncSettings({ - ...(syncSettings as OrganizationSyncSettings), - field: event.target.value, - }); - await form.setFieldValue("field", event.target.value); - }} - /> +
    + , + ) => { + setSyncSettings({ + ...(syncSettings as OrganizationSyncSettings), + field: event.target.value, + }); + await form.setFieldValue("field", event.target.value); + }} + /> + +
    = ({ "organization_assign_default", checked, ); + form.handleSubmit(); }} />
    From a9e06f15935ef1a35e0931c6c01f0fad49630b02 Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 17:13:51 +0000 Subject: [PATCH 31/71] fix: remove popover and muted colors from shadcn --- site/src/components/ui/command.tsx | 6 +++--- site/src/components/ui/dialog.tsx | 4 ++-- site/src/components/ui/multiple-selector.tsx | 8 ++++---- site/src/index.css | 8 -------- site/tailwind.config.js | 8 -------- 5 files changed, 9 insertions(+), 25 deletions(-) diff --git a/site/src/components/ui/command.tsx b/site/src/components/ui/command.tsx index 602c1860a0a4f..9b5431a17b354 100644 --- a/site/src/components/ui/command.tsx +++ b/site/src/components/ui/command.tsx @@ -13,7 +13,7 @@ export const Command = forwardRef< = ({ return ( - + {children} @@ -132,7 +132,7 @@ export const CommandShortcut = ({ return ( {children} - + Close @@ -100,7 +100,7 @@ export const DialogDescription = forwardRef< >(({ className, ...props }, ref) => ( )); diff --git a/site/src/components/ui/multiple-selector.tsx b/site/src/components/ui/multiple-selector.tsx index c41f0c43c4a1a..27409d0e98072 100644 --- a/site/src/components/ui/multiple-selector.tsx +++ b/site/src/components/ui/multiple-selector.tsx @@ -474,8 +474,8 @@ const MultipleSelector = React.forwardRef< {open && ( { setOnScrollbar(false); }} @@ -618,7 +618,7 @@ const MultipleSelector = React.forwardRef< className={cn( "cursor-pointer", option.disable && - "cursor-default text-muted-foreground", + "cursor-default text-content-disabled", )} > {option.label} diff --git a/site/src/index.css b/site/src/index.css index 19d02bcc28332..1353b200745c0 100644 --- a/site/src/index.css +++ b/site/src/index.css @@ -28,10 +28,6 @@ --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; - --popover: 0 0% 100%; - --popover-foreground: 240 10% 3.9%; - --muted: 240 4.8% 95.9%; - --muted-foreground: 240 3.8% 46.1%; --border: 240 5.9% 90%; --input: 240 5.9% 90%; --ring: 240 10% 3.9%; @@ -60,10 +56,6 @@ --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; --chart-5: 340 75% 55%; - --popover: 240 10% 3.9%; - --popover-foreground: 0 0% 98%; - --muted: 240 3.7% 15.9%; - --muted-foreground: 240 5% 64.9%; --border: 240 3.7% 15.9%; --input: 240 3.7% 15.9%; --ring: 240 4.9% 83.9%; diff --git a/site/tailwind.config.js b/site/tailwind.config.js index 185e836995b97..f0dc8f7a97b4f 100644 --- a/site/tailwind.config.js +++ b/site/tailwind.config.js @@ -43,14 +43,6 @@ module.exports = { DEFAULT: "hsl(var(--border-default))", error: "hsl(var(--border-error))", }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, input: "hsl(var(--input))", ring: "hsl(var(--ring))", chart: { From d921b088485b052b261d6ace90021e934ff1916b Mon Sep 17 00:00:00 2001 From: Jaayden Halko Date: Tue, 26 Nov 2024 19:25:58 +0000 Subject: [PATCH 32/71] chore: cleanup --- .../IdpOrgSyncPage/IdpOrgSyncPageView.tsx | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx index db0dd7c56537d..0acdfefbbacee 100644 --- a/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/IdpOrgSyncPage/IdpOrgSyncPageView.tsx @@ -87,7 +87,7 @@ export const IdpSyncPageView: FC = ({ ), ); const newSyncSettings = { - ...(syncSettings as OrganizationSyncSettings), + ...syncSettings, mapping: newMapping, }; setSyncSettings(newSyncSettings); @@ -95,6 +95,10 @@ export const IdpSyncPageView: FC = ({ form.handleSubmit(); }; + const SYNC_FIELD_ID = "sync-field"; + const ORGANIZATION_ASSIGN_DEFAULT_ID = "organization-assign-default"; + const IDP_ORGANIZATION_NAME_ID = "idp-organization-name"; + return (
    {Boolean(error) && } @@ -102,19 +106,17 @@ export const IdpSyncPageView: FC = ({
    -