From ff1bca1816c8ce678846393c27a0c8a53a987cd0 Mon Sep 17 00:00:00 2001 From: Ady Beraud <102751374+ady-beraud@users.noreply.github.com> Date: Tue, 11 Jun 2024 10:45:17 +0300 Subject: [PATCH] Docs modifications (#5804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes #5504 - Fixes #5503 - Return 404 when the page does not exist - Modified the footer in order to align it properly - Removed "noticed something to change" in each table of content - Fixed the URLs of the edit module - Added the edit module to Developers - Fixed header style on the REST API page. - Edited the README to point to Developers - Fixed selected state when clicking on sidebar elements --------- Co-authored-by: Félix Malfait --- .github/workflows/ci-docs.yaml | 42 - README.md | 6 +- packages/twenty-docs/.gitignore | 22 - packages/twenty-docs/README.md | 5 - packages/twenty-docs/babel.config.js | 3 - .../docs/contributor/_category_.json | 4 - .../docs/contributor/bug-and-requests.mdx | 15 - .../docs/contributor/frontend/_category_.json | 5 - .../contributor/frontend/best-practices.mdx | 330 ---- .../frontend/folder-architecture.mdx | 113 -- .../docs/contributor/frontend/frontend.mdx | 86 - .../docs/contributor/frontend/hotkeys.mdx | 179 -- .../docs/contributor/frontend/style-guide.mdx | 291 ---- .../contributor/frontend/work-with-figma.mdx | 65 - .../docs/contributor/server/_category_.json | 5 - .../contributor/server/best-practices.mdx | 25 - .../contributor/server/custom-objects.mdx | 41 - .../docs/contributor/server/feature-flags.mdx | 52 - .../server/folder-architecture.mdx | 132 -- .../docs/contributor/server/queue.mdx | 47 - .../docs/contributor/server/server.mdx | 87 - .../docs/contributor/server/zapier.mdx | 75 - packages/twenty-docs/docs/index.mdx | 26 - .../twenty-docs/docs/start/_category_.json | 4 - packages/twenty-docs/docs/start/cloud.mdx | 23 - .../twenty-docs/docs/start/local-setup.mdx | 226 --- .../docs/start/self-hosting/_category_.json | 5 - .../start/self-hosting/cloud-providers.mdx | 437 ----- .../start/self-hosting/docker-compose.mdx | 58 - .../docs/start/self-hosting/self-hosting.mdx | 220 --- .../docs/start/self-hosting/upgrade-guide.mdx | 8 - .../docs/ui-components/_category_.json | 4 - .../ui-components/display/_category_.json | 9 - .../ui-components/display/app-tooltip.mdx | 139 -- .../docs/ui-components/display/checkmark.mdx | 95 -- .../docs/ui-components/display/chip.mdx | 252 --- .../docs/ui-components/display/icons.mdx | 134 -- .../docs/ui-components/display/soon-pill.mdx | 49 - .../docs/ui-components/display/tag.mdx | 68 - .../ui-components/feedback/_category_.json | 9 - .../ui-components/feedback/progress-bar.mdx | 143 -- .../docs/ui-components/input/_category_.json | 9 - .../docs/ui-components/input/block-editor.mdx | 46 - .../docs/ui-components/input/button.mdx | 795 --------- .../docs/ui-components/input/checkbox.mdx | 93 - .../docs/ui-components/input/color-scheme.mdx | 113 -- .../docs/ui-components/input/icon-picker.mdx | 92 - .../docs/ui-components/input/image-input.mdx | 92 - .../docs/ui-components/input/radio.mdx | 164 -- .../docs/ui-components/input/select.mdx | 85 - .../docs/ui-components/input/text.mdx | 322 ---- .../docs/ui-components/input/toggle.mdx | 71 - .../ui-components/navigation/_category_.json | 9 - .../ui-components/navigation/bread-crumb.mdx | 53 - .../docs/ui-components/navigation/link.mdx | 237 --- .../ui-components/navigation/menu-item.mdx | 768 --------- .../navigation/navigation-bar.mdx | 53 - .../ui-components/navigation/step-bar.mdx | 47 - .../docs/ui-components/ui-components.mdx | 8 - packages/twenty-docs/docusaurus.config.js | 145 -- packages/twenty-docs/package.json | 37 - packages/twenty-docs/sidebars.js | 110 -- .../src/components/graphql-playground.tsx | 111 -- .../twenty-docs/src/components/playground.tsx | 76 - .../twenty-docs/src/components/token-form.css | 146 -- .../twenty-docs/src/components/token-form.tsx | 200 --- packages/twenty-docs/src/css/custom.css | 350 ---- .../twenty-docs/src/pages/graphql/core.tsx | 9 - .../src/pages/graphql/metadata.tsx | 9 - .../twenty-docs/src/pages/rest-api/core.tsx | 55 - .../src/pages/rest-api/metadata.tsx | 55 - .../twenty-docs/src/theme/DocCard/index.js | 97 -- .../src/theme/DocCard/styles.module.css | 35 - .../theme/DocSidebarItem/Category/index.js | 103 -- .../src/theme/DocSidebarItem/Link/index.js | 62 - .../src/theme/DocSidebarItem/index.js | 65 - .../src/theme/Icon/DarkMode/index.js | 10 - .../twenty-docs/src/theme/Icon/Home/index.js | 5 - .../src/theme/Icon/LightMode/index.js | 10 - .../src/theme/Navbar/Search/index.js | 5 - .../src/theme/NavbarItem/ComponentTypes.js | 24 - .../src/theme/NavbarItem/GithubLink.tsx | 21 - .../src/theme/OptionTable/index.js | 29 - .../src/theme/OptionTable/style.module.css | 87 - packages/twenty-docs/src/theme/icons.js | 79 - packages/twenty-docs/src/ui/SandpackEditor.js | 109 -- .../src/ui/display/animatedCheckmarkCode.js | 12 - .../src/ui/display/appTooltipCode.js | 22 - .../src/ui/display/checkmarkCode.js | 5 - .../twenty-docs/src/ui/display/chipCode.js | 17 - .../src/ui/display/entityChipCode.js | 18 - .../src/ui/display/iconAddressBookCode.js | 5 - .../display/overflowingTextWithTooltipCode.js | 8 - .../src/ui/display/soonPillCode.js | 5 - .../src/ui/display/tablerIconExampleCode.js | 5 - .../twenty-docs/src/ui/display/tagCode.js | 12 - .../ui/feedback/circularProgressBarCode.js | 5 - .../src/ui/feedback/progressBarCode.js | 14 - .../src/ui/generated/dark-noise-JHVNKF2E.jpg | Bin 26053 -> 0 bytes .../twenty-docs/src/ui/generated/index.cjs | 1509 ----------------- .../twenty-docs/src/ui/generated/index.d.cts | 968 ----------- .../src/ui/generated/light-noise-JRI6I6YG.png | Bin 9657 -> 0 bytes .../src/ui/input/blockEditorCode.js | 8 - .../src/ui/input/button/buttonCode.js | 20 - .../src/ui/input/button/buttonGroupCode.js | 51 - .../src/ui/input/button/floatingButtonCode.js | 18 - .../input/button/floatingButtonGroupCode.js | 31 - .../ui/input/button/floatingIconButtonCode.js | 19 - .../button/floatingIconButtonGroupCode.js | 24 - .../src/ui/input/button/lightButtonCode.js | 14 - .../ui/input/button/lightIconButtonCode.js | 19 - .../src/ui/input/button/mainButtonCode.js | 14 - .../ui/input/button/roundedIconButtonCode.js | 10 - .../input/color-scheme/colorSchemeCardCode.js | 10 - .../color-scheme/colorSchemePickerCode.js | 8 - .../input/components/autosizeTextInputCode.js | 18 - .../src/ui/input/components/checkboxCode.js | 15 - .../entityTitleDoubleTextInputCode.js | 31 - .../src/ui/input/components/iconPickerCode.js | 23 - .../src/ui/input/components/imageInputCode.js | 5 - .../src/ui/input/components/radioCode.js | 25 - .../src/ui/input/components/radioGroupCode.js | 20 - .../src/ui/input/components/selectCode.js | 27 - .../src/ui/input/components/textAreaCode.js | 13 - .../src/ui/input/components/textInputCode.js | 27 - .../src/ui/input/components/toggleCode.js | 12 - .../src/ui/navigation/breadcrumbCode.js | 17 - .../src/ui/navigation/link/contactLinkCode.js | 21 - .../src/ui/navigation/link/rawLinkCode.js | 16 - .../src/ui/navigation/link/roundedLinkCode.js | 16 - .../src/ui/navigation/link/socialLinkCode.js | 13 - .../ui/navigation/menu-item/menuItemCode.js | 26 - .../menu-item/menuItemCommandCode.js | 20 - .../menu-item/menuItemDraggableCode.js | 22 - .../menuItemMultiSelectAvatarCode.js | 20 - .../menu-item/menuItemMultiSelectCode.js | 18 - .../menu-item/menuItemNavigateCode.js | 17 - .../menu-item/menuItemSelectAvatarCode.js | 23 - .../menu-item/menuItemSelectCode.js | 20 - .../menu-item/menuItemSelectColorCode.js | 19 - .../menu-item/menuItemToggleCode.js | 20 - .../src/ui/navigation/navBarCode.js | 25 - .../src/ui/navigation/stepBarCode.js | 11 - packages/twenty-docs/src/ui/uiComponents.css | 9 - packages/twenty-docs/static/.nojekyll | 0 packages/twenty-docs/static/img/api-dark.png | Bin 417613 -> 0 bytes packages/twenty-docs/static/img/api-light.png | Bin 390357 -> 0 bytes .../static/img/architecture-dark.png | Bin 81847 -> 0 bytes .../static/img/architecture-light.png | Bin 71910 -> 0 bytes .../img/contributor/add-custom-objects.jpeg | Bin 35993 -> 0 bytes .../img/contributor/custom-object-schema.jpeg | Bin 32340 -> 0 bytes .../contributor/ide-dev-container-open.png | Bin 488001 -> 0 bytes .../static/img/contributor/ide-extensions.png | Bin 501729 -> 0 bytes .../img/contributor/ide-fresh-install.png | Bin 183048 -> 0 bytes .../img/contributor/ide-project-open.png | Bin 226952 -> 0 bytes .../contributor/ide-start-dev-container.png | Bin 241755 -> 0 bytes .../static/img/contributor/wsl-complete.png | Bin 239468 -> 0 bytes .../static/img/dark-doc-preview.png | Bin 384070 -> 0 bytes .../twenty-docs/static/img/dark-sign-in.png | Bin 267596 -> 0 bytes packages/twenty-docs/static/img/data-dark.png | Bin 473178 -> 0 bytes .../twenty-docs/static/img/data-light.png | Bin 443784 -> 0 bytes .../twenty-docs/static/img/discord-icon.svg | 1 - .../twenty-docs/static/img/emails-dark.png | Bin 394898 -> 0 bytes .../twenty-docs/static/img/emails-light.png | Bin 365283 -> 0 bytes .../twenty-docs/static/img/figma-icon.png | Bin 11101 -> 0 bytes .../twenty-docs/static/img/index-dark.png | Bin 432209 -> 0 bytes .../twenty-docs/static/img/index-light.png | Bin 401208 -> 0 bytes .../twenty-docs/static/img/kanban-dark.png | Bin 392973 -> 0 bytes .../twenty-docs/static/img/kanban-light.png | Bin 363962 -> 0 bytes .../twenty-docs/static/img/keyboard-dark.png | Bin 457903 -> 0 bytes .../twenty-docs/static/img/keyboard-light.png | Bin 430186 -> 0 bytes .../static/img/light-doc-preview.png | Bin 340943 -> 0 bytes .../twenty-docs/static/img/light-sign-in.png | Bin 253074 -> 0 bytes .../static/img/logo-square-dark-no-radius.svg | 1 - .../static/img/logo-square-dark.ico | Bin 4286 -> 0 bytes .../static/img/logo-square-dark.svg | 1 - .../static/img/logo-square-light.svg | 11 - .../twenty-docs/static/img/notes-dark.png | Bin 398306 -> 0 bytes .../twenty-docs/static/img/notes-light.png | Bin 369712 -> 0 bytes .../twenty-docs/static/img/preview-dark.png | Bin 263526 -> 0 bytes .../twenty-docs/static/img/preview-light.png | Bin 241059 -> 0 bytes .../twenty-docs/static/img/social-card.png | Bin 512926 -> 0 bytes .../twenty-docs/static/img/tasks-dark.png | Bin 369023 -> 0 bytes .../twenty-docs/static/img/tasks-light.png | Bin 346008 -> 0 bytes packages/twenty-docs/tsconfig.json | 8 - .../_components/contributors/AvatarGrid.tsx | 17 +- .../_components/contributors/ProfileCard.tsx | 3 +- .../src/app/_components/docs/ClientOnly.tsx | 13 + .../src/app/_components/docs/DocsContent.tsx | 45 +- .../src/app/_components/docs/DocsSideBar.tsx | 1 - .../_components/docs/DocsSidebarSection.tsx | 4 +- .../src/app/_components/docs/TableContent.tsx | 73 +- .../ui/layout/articles/ArticleContent.tsx | 8 +- .../ui/layout/articles/ArticleEditContent.tsx | 14 +- .../_components/ui/layout/header/styled.ts | 9 + .../src/app/developers/[slug]/page.tsx | 6 +- .../section/[folder]/[documentation]/page.tsx | 6 +- .../app/developers/section/[folder]/page.tsx | 7 + .../src/app/twenty-ui/[slug]/page.tsx | 4 + .../section/[folder]/[documentation]/page.tsx | 4 + .../app/twenty-ui/section/[folder]/page.tsx | 7 + .../src/app/user-guide/[slug]/page.tsx | 6 +- .../section/[folder]/[documentation]/page.tsx | 4 + .../app/user-guide/section/[folder]/page.tsx | 7 + .../best-practices-server.mdx | 4 +- .../backend-development/custom-objects.mdx | 2 + .../backend-development/feature-flags.mdx | 2 + .../folder-architecture-server.mdx | 4 +- .../developers/backend-development/queue.mdx | 1 + .../backend-development/server-commands.mdx | 4 +- .../developers/backend-development/zapier.mdx | 2 + .../content/developers/bug-and-requests.mdx | 2 + .../best-practices-front.mdx | 1 + .../folder-architecture-front.mdx | 2 + .../frontend-commands.mdx | 2 + .../frontend-development/hotkeys.mdx | 180 +- .../frontend-development/style-guide.mdx | 2 + .../frontend-development/work-with-figma.mdx | 4 +- .../src/content/developers/local-setup.mdx | 2 + .../self-hosting/cloud-providers.mdx | 7 +- .../self-hosting/docker-compose.mdx | 2 + .../self-hosting/self-hosting-var.mdx | 27 +- .../content/twenty-ui/display/app-tooltip.mdx | 2 + .../content/twenty-ui/display/checkmark.mdx | 4 +- .../src/content/twenty-ui/display/chip.mdx | 4 +- .../src/content/twenty-ui/display/icons.mdx | 4 +- .../content/twenty-ui/display/soon-pill.mdx | 1 + .../src/content/twenty-ui/display/tag.mdx | 2 + .../content/twenty-ui/input/block-editor.mdx | 2 + .../src/content/twenty-ui/input/buttons.mdx | 2 + .../src/content/twenty-ui/input/checkbox.mdx | 2 + .../content/twenty-ui/input/color-scheme.mdx | 2 + .../content/twenty-ui/input/icon-picker.mdx | 2 + .../content/twenty-ui/input/image-input.mdx | 2 + .../src/content/twenty-ui/input/radio.mdx | 2 + .../src/content/twenty-ui/input/select.mdx | 2 + .../src/content/twenty-ui/input/text.mdx | 2 + .../src/content/twenty-ui/input/toggle.mdx | 2 + .../twenty-ui/navigation/breadcrumb.mdx | 2 + .../content/twenty-ui/navigation/links.mdx | 2 + .../twenty-ui/navigation/menu-item.mdx | 2 + .../twenty-ui/navigation/navigation-bar.mdx | 4 +- .../content/twenty-ui/navigation/step-bar.mdx | 4 +- .../src/content/twenty-ui/progress-bar.mdx | 4 +- .../user-guide/functions/api-webhooks.mdx | 2 +- .../content/user-guide/functions/emails.mdx | 2 +- .../user-guide/functions/integrations.mdx | 2 +- .../content/user-guide/functions/notes.mdx | 2 +- .../content/user-guide/functions/tasks.mdx | 2 +- .../getting-started/create-workspace.mdx | 2 +- .../getting-started/what-is-twenty.mdx | 2 +- .../src/content/user-guide/objects/fields.mdx | 2 +- .../user-guide/objects/import-export-data.mdx | 2 +- .../user-guide/objects/kanban-views.mdx | 2 +- .../user-guide/objects/standard-objects.mdx | 6 +- .../user-guide/objects/table-views.mdx | 2 +- .../user-guide/objects/views-sort-filter.mdx | 2 +- .../src/content/user-guide/other/github.mdx | 2 +- .../src/content/user-guide/other/glossary.mdx | 2 +- .../src/content/user-guide/other/tips.mdx | 2 +- .../src/shared-utils/getCardPath.tsx | 2 +- 261 files changed, 459 insertions(+), 12184 deletions(-) delete mode 100644 .github/workflows/ci-docs.yaml delete mode 100644 packages/twenty-docs/.gitignore delete mode 100644 packages/twenty-docs/README.md delete mode 100644 packages/twenty-docs/babel.config.js delete mode 100644 packages/twenty-docs/docs/contributor/_category_.json delete mode 100644 packages/twenty-docs/docs/contributor/bug-and-requests.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/_category_.json delete mode 100644 packages/twenty-docs/docs/contributor/frontend/best-practices.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/folder-architecture.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/frontend.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/hotkeys.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/style-guide.mdx delete mode 100644 packages/twenty-docs/docs/contributor/frontend/work-with-figma.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/_category_.json delete mode 100644 packages/twenty-docs/docs/contributor/server/best-practices.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/custom-objects.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/feature-flags.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/folder-architecture.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/queue.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/server.mdx delete mode 100644 packages/twenty-docs/docs/contributor/server/zapier.mdx delete mode 100644 packages/twenty-docs/docs/index.mdx delete mode 100644 packages/twenty-docs/docs/start/_category_.json delete mode 100644 packages/twenty-docs/docs/start/cloud.mdx delete mode 100644 packages/twenty-docs/docs/start/local-setup.mdx delete mode 100644 packages/twenty-docs/docs/start/self-hosting/_category_.json delete mode 100644 packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx delete mode 100644 packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx delete mode 100644 packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx delete mode 100644 packages/twenty-docs/docs/start/self-hosting/upgrade-guide.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/_category_.json delete mode 100644 packages/twenty-docs/docs/ui-components/display/_category_.json delete mode 100644 packages/twenty-docs/docs/ui-components/display/app-tooltip.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/display/checkmark.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/display/chip.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/display/icons.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/display/soon-pill.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/display/tag.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/feedback/_category_.json delete mode 100644 packages/twenty-docs/docs/ui-components/feedback/progress-bar.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/_category_.json delete mode 100644 packages/twenty-docs/docs/ui-components/input/block-editor.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/button.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/checkbox.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/color-scheme.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/icon-picker.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/image-input.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/radio.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/select.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/text.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/input/toggle.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/_category_.json delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/bread-crumb.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/link.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/menu-item.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/navigation-bar.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/navigation/step-bar.mdx delete mode 100644 packages/twenty-docs/docs/ui-components/ui-components.mdx delete mode 100644 packages/twenty-docs/docusaurus.config.js delete mode 100644 packages/twenty-docs/package.json delete mode 100644 packages/twenty-docs/sidebars.js delete mode 100644 packages/twenty-docs/src/components/graphql-playground.tsx delete mode 100644 packages/twenty-docs/src/components/playground.tsx delete mode 100644 packages/twenty-docs/src/components/token-form.css delete mode 100644 packages/twenty-docs/src/components/token-form.tsx delete mode 100644 packages/twenty-docs/src/css/custom.css delete mode 100644 packages/twenty-docs/src/pages/graphql/core.tsx delete mode 100644 packages/twenty-docs/src/pages/graphql/metadata.tsx delete mode 100644 packages/twenty-docs/src/pages/rest-api/core.tsx delete mode 100644 packages/twenty-docs/src/pages/rest-api/metadata.tsx delete mode 100644 packages/twenty-docs/src/theme/DocCard/index.js delete mode 100644 packages/twenty-docs/src/theme/DocCard/styles.module.css delete mode 100644 packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js delete mode 100644 packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js delete mode 100644 packages/twenty-docs/src/theme/DocSidebarItem/index.js delete mode 100644 packages/twenty-docs/src/theme/Icon/DarkMode/index.js delete mode 100644 packages/twenty-docs/src/theme/Icon/Home/index.js delete mode 100644 packages/twenty-docs/src/theme/Icon/LightMode/index.js delete mode 100644 packages/twenty-docs/src/theme/Navbar/Search/index.js delete mode 100644 packages/twenty-docs/src/theme/NavbarItem/ComponentTypes.js delete mode 100644 packages/twenty-docs/src/theme/NavbarItem/GithubLink.tsx delete mode 100644 packages/twenty-docs/src/theme/OptionTable/index.js delete mode 100644 packages/twenty-docs/src/theme/OptionTable/style.module.css delete mode 100644 packages/twenty-docs/src/theme/icons.js delete mode 100644 packages/twenty-docs/src/ui/SandpackEditor.js delete mode 100644 packages/twenty-docs/src/ui/display/animatedCheckmarkCode.js delete mode 100644 packages/twenty-docs/src/ui/display/appTooltipCode.js delete mode 100644 packages/twenty-docs/src/ui/display/checkmarkCode.js delete mode 100644 packages/twenty-docs/src/ui/display/chipCode.js delete mode 100644 packages/twenty-docs/src/ui/display/entityChipCode.js delete mode 100644 packages/twenty-docs/src/ui/display/iconAddressBookCode.js delete mode 100644 packages/twenty-docs/src/ui/display/overflowingTextWithTooltipCode.js delete mode 100644 packages/twenty-docs/src/ui/display/soonPillCode.js delete mode 100644 packages/twenty-docs/src/ui/display/tablerIconExampleCode.js delete mode 100644 packages/twenty-docs/src/ui/display/tagCode.js delete mode 100644 packages/twenty-docs/src/ui/feedback/circularProgressBarCode.js delete mode 100644 packages/twenty-docs/src/ui/feedback/progressBarCode.js delete mode 100644 packages/twenty-docs/src/ui/generated/dark-noise-JHVNKF2E.jpg delete mode 100644 packages/twenty-docs/src/ui/generated/index.cjs delete mode 100644 packages/twenty-docs/src/ui/generated/index.d.cts delete mode 100644 packages/twenty-docs/src/ui/generated/light-noise-JRI6I6YG.png delete mode 100644 packages/twenty-docs/src/ui/input/blockEditorCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/buttonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/buttonGroupCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/floatingButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/floatingButtonGroupCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/floatingIconButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/floatingIconButtonGroupCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/lightButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/lightIconButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/mainButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/button/roundedIconButtonCode.js delete mode 100644 packages/twenty-docs/src/ui/input/color-scheme/colorSchemeCardCode.js delete mode 100644 packages/twenty-docs/src/ui/input/color-scheme/colorSchemePickerCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/autosizeTextInputCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/checkboxCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/entityTitleDoubleTextInputCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/iconPickerCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/imageInputCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/radioCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/radioGroupCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/selectCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/textAreaCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/textInputCode.js delete mode 100644 packages/twenty-docs/src/ui/input/components/toggleCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/breadcrumbCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/link/contactLinkCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/link/rawLinkCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/link/roundedLinkCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/link/socialLinkCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemCommandCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemDraggableCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemMultiSelectAvatarCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemMultiSelectCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemNavigateCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemSelectAvatarCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemSelectCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemSelectColorCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/menu-item/menuItemToggleCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/navBarCode.js delete mode 100644 packages/twenty-docs/src/ui/navigation/stepBarCode.js delete mode 100644 packages/twenty-docs/src/ui/uiComponents.css delete mode 100644 packages/twenty-docs/static/.nojekyll delete mode 100644 packages/twenty-docs/static/img/api-dark.png delete mode 100644 packages/twenty-docs/static/img/api-light.png delete mode 100644 packages/twenty-docs/static/img/architecture-dark.png delete mode 100644 packages/twenty-docs/static/img/architecture-light.png delete mode 100644 packages/twenty-docs/static/img/contributor/add-custom-objects.jpeg delete mode 100644 packages/twenty-docs/static/img/contributor/custom-object-schema.jpeg delete mode 100644 packages/twenty-docs/static/img/contributor/ide-dev-container-open.png delete mode 100644 packages/twenty-docs/static/img/contributor/ide-extensions.png delete mode 100644 packages/twenty-docs/static/img/contributor/ide-fresh-install.png delete mode 100644 packages/twenty-docs/static/img/contributor/ide-project-open.png delete mode 100644 packages/twenty-docs/static/img/contributor/ide-start-dev-container.png delete mode 100644 packages/twenty-docs/static/img/contributor/wsl-complete.png delete mode 100644 packages/twenty-docs/static/img/dark-doc-preview.png delete mode 100644 packages/twenty-docs/static/img/dark-sign-in.png delete mode 100644 packages/twenty-docs/static/img/data-dark.png delete mode 100644 packages/twenty-docs/static/img/data-light.png delete mode 100644 packages/twenty-docs/static/img/discord-icon.svg delete mode 100644 packages/twenty-docs/static/img/emails-dark.png delete mode 100644 packages/twenty-docs/static/img/emails-light.png delete mode 100644 packages/twenty-docs/static/img/figma-icon.png delete mode 100644 packages/twenty-docs/static/img/index-dark.png delete mode 100644 packages/twenty-docs/static/img/index-light.png delete mode 100644 packages/twenty-docs/static/img/kanban-dark.png delete mode 100644 packages/twenty-docs/static/img/kanban-light.png delete mode 100644 packages/twenty-docs/static/img/keyboard-dark.png delete mode 100644 packages/twenty-docs/static/img/keyboard-light.png delete mode 100644 packages/twenty-docs/static/img/light-doc-preview.png delete mode 100644 packages/twenty-docs/static/img/light-sign-in.png delete mode 100644 packages/twenty-docs/static/img/logo-square-dark-no-radius.svg delete mode 100644 packages/twenty-docs/static/img/logo-square-dark.ico delete mode 100644 packages/twenty-docs/static/img/logo-square-dark.svg delete mode 100644 packages/twenty-docs/static/img/logo-square-light.svg delete mode 100644 packages/twenty-docs/static/img/notes-dark.png delete mode 100644 packages/twenty-docs/static/img/notes-light.png delete mode 100644 packages/twenty-docs/static/img/preview-dark.png delete mode 100644 packages/twenty-docs/static/img/preview-light.png delete mode 100644 packages/twenty-docs/static/img/social-card.png delete mode 100644 packages/twenty-docs/static/img/tasks-dark.png delete mode 100644 packages/twenty-docs/static/img/tasks-light.png delete mode 100644 packages/twenty-docs/tsconfig.json create mode 100644 packages/twenty-website/src/app/_components/docs/ClientOnly.tsx diff --git a/.github/workflows/ci-docs.yaml b/.github/workflows/ci-docs.yaml deleted file mode 100644 index 730a98e30..000000000 --- a/.github/workflows/ci-docs.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: CI Docs -on: - push: - branches: - - main - paths: - - 'package.json' - - 'packages/twenty-docs/**' - - 'packages/twenty-ui/**' - pull_request: - paths: - - 'package.json' - - 'packages/twenty-docs/**' - - 'packages/twenty-ui/**' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - docs-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install dependencies - uses: ./.github/workflows/actions/yarn-install - - name: Docs / Build Documentation - run: npx nx build twenty-docs - vale: - name: runner / vale - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: errata-ai/vale-action@reviewdog - with: - files: ${{ steps.directories.outputs.LIST }} - fail_on_error: true - vale_flags: "--minAlertLevel=error" - reporter: github-pr-check - token: ${{ github.token }} - filter_mode: nofilter - env: - REVIEWDOG_GITHUB_API_TOKEN: ${{ github.token }} diff --git a/README.md b/README.md index 7619bf60a..ea28ac658 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@

The #1 Open-Source CRM

Tailored to your unique business needs

-

🌐 Website · 📚 Documentation · Discord · Figma

+

🌐 Website · 📚 Documentation · Discord · Figma


@@ -38,8 +38,8 @@ password: Applecar2025 ``` See also: -🚀 [Self-hosting](https://docs.twenty.com/start/self-hosting/) -🖥️ [Local Setup](https://docs.twenty.com/start/local-setup) +🚀 [Self-hosting](https://twenty.com/developers/section/self-hosting) +🖥️ [Local Setup](https://twenty.com/developers/local-setup) # Why Choose Twenty? We understand that the CRM landscape is vast. So why should you choose us? diff --git a/packages/twenty-docs/.gitignore b/packages/twenty-docs/.gitignore deleted file mode 100644 index bcf1e57c0..000000000 --- a/packages/twenty-docs/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# Dependencies -/node_modules - -# Production -/build - -# Generated files -.docusaurus -.cache-loader - -# Misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -package-lock.json \ No newline at end of file diff --git a/packages/twenty-docs/README.md b/packages/twenty-docs/README.md deleted file mode 100644 index a3d87f560..000000000 --- a/packages/twenty-docs/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Documentation - -The docs here are managed through [Docusaurus 2](https://docusaurus.io/). - -We recommend you go directly to the [statically generated website](https://docs.twenty.com) rather than read them here. \ No newline at end of file diff --git a/packages/twenty-docs/babel.config.js b/packages/twenty-docs/babel.config.js deleted file mode 100644 index e00595dae..000000000 --- a/packages/twenty-docs/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], -}; diff --git a/packages/twenty-docs/docs/contributor/_category_.json b/packages/twenty-docs/docs/contributor/_category_.json deleted file mode 100644 index e12f1ce53..000000000 --- a/packages/twenty-docs/docs/contributor/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Contributing", - "position": 3 -} diff --git a/packages/twenty-docs/docs/contributor/bug-and-requests.mdx b/packages/twenty-docs/docs/contributor/bug-and-requests.mdx deleted file mode 100644 index 63d022f4a..000000000 --- a/packages/twenty-docs/docs/contributor/bug-and-requests.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Bugs and Requests -sidebar_position: 3 -sidebar_custom_props: - icon: TbBug ---- - -## Reporting Bugs -To report a bug, please [create an issue on GitHub](https://github.com/twentyhq/twenty/issues/new). - -You can also ask for help on [Discord](https://discord.gg/cx5n4Jzs57). - -## Feature Requests - -If you're not sure it's a bug and you feel it's closer to a feature request, then you should probably [open a discussion instead](https://github.com/twentyhq/twenty/discussions/new). diff --git a/packages/twenty-docs/docs/contributor/frontend/_category_.json b/packages/twenty-docs/docs/contributor/frontend/_category_.json deleted file mode 100644 index 254ec2489..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "position": 3, - "collapsible": true, - "collapsed": true -} diff --git a/packages/twenty-docs/docs/contributor/frontend/best-practices.mdx b/packages/twenty-docs/docs/contributor/frontend/best-practices.mdx deleted file mode 100644 index a4b91b95b..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/best-practices.mdx +++ /dev/null @@ -1,330 +0,0 @@ ---- -title: Best Practices -sidebar_position: 3 -sidebar_custom_props: - icon: TbChecklist ---- - -This document outlines the best practices you should follow when working on the frontend. - -## State management - -React and Recoil handle state management in the codebase. - -### Use `useRecoilState` to store state - -It's good practice to create as many atoms as you need to store your state. - -:::tip - -It's better to use extra atoms than trying to be too concise with props drilling. - -::: - -```tsx -export const myAtomState = atom({ - key: 'myAtomState', - default: 'default value', -}); - -export const MyComponent = () => { - const [myAtom, setMyAtom] = useRecoilState(myAtomState); - - return ( -

- setMyAtom(e.target.value)} - /> -
- ); -} -``` - -### Do not use `useRef` to store state - -Avoid using `useRef` to store state. - -If you want to store state, you should use `useState` or `useRecoilState`. - -See [how to manage re-renders](#managing-re-renders) if you feel like you need `useRef` to prevent some re-renders from happening. - -## Managing re-renders - -Re-renders can be hard to manage in React. - -Here are some rules to follow to avoid unnecessary re-renders. - -Keep in mind that you can **always** avoid re-renders by understanding their cause. - -### Work at the root level - -Avoiding re-renders in new features is now made easy by eliminating them at the root level. - -The `PageChangeEffect` sidecar component contains just one `useEffect` that holds all the logic to execute on a page change. - -That way you know that there's just one place that can trigger a re-render. - -### Always think twice before adding `useEffect` in your codebase - -Re-renders are often caused by unnecessary `useEffect`. - -You should think whether you need `useEffect`, or if you can move the logic in a event handler function. - -You'll find it generally easy to move the logic in a `handleClick` or `handleChange` function. - -You can also find them in libraries like Apollo: `onCompleted`, `onError`, etc. - -### Use a sibling component to extract `useEffect` or data fetching logic - -If you feel like you need to add a `useEffect` in your root component, you should consider extracting it in a sidecar component. - -You can apply the same for data fetching logic, with Apollo hooks. - -```tsx -// ❌ Bad, will cause re-renders even if data is not changing, -// because useEffect needs to be re-evaluated -export const PageComponent = () => { - const [data, setData] = useRecoilState(dataState); - const [someDependency] = useRecoilState(someDependencyState); - - useEffect(() => { - if(someDependency !== data) { - setData(someDependency); - } - }, [someDependency]); - - return
{data}
; -}; - -export const App = () => ( - - - -); -``` - -```tsx -// ✅ Good, will not cause re-renders if data is not changing, -// because useEffect is re-evaluated in another sibling component -export const PageComponent = () => { - const [data, setData] = useRecoilState(dataState); - - return
{data}
; -}; - -export const PageData = () => { - const [data, setData] = useRecoilState(dataState); - const [someDependency] = useRecoilState(someDependencyState); - - useEffect(() => { - if(someDependency !== data) { - setData(someDependency); - } - }, [someDependency]); - - return <>; -}; - -export const App = () => ( - - - - -); -``` - -### Use recoil family states and recoil family selectors - -Recoil family states and selectors are a great way to avoid re-renders. - -They are useful when you need to store a list of items. - -### You shouldn't use `React.memo(MyComponent)` - -Avoid using `React.memo()` because it does not solve the cause of the re-render, but instead breaks the re-render chain, which can lead to unexpected behavior and make the code very hard to refactor. - -### Limit `useCallback` or `useMemo` usage - -They are often not necessary and will make the code harder to read and maintain for a gain of performance that is unnoticeable. - -## Console.logs - -`console.log` statements are invaluable during development, offering real-time insights into variable values and code flow. But, leaving them in production code can lead to several issues: - -1. **Performance**: Excessive logging can affect the runtime performance, specially on client-side applications. - -2. **Security**: Logging sensitive data can expose critical information to anyone who inspects the browser's console. - -3. **Cleanliness**: Filling up the console with logs can obscure important warnings or errors that developers or tools need to see. - -4. **Professionalism**: End users or clients checking the console and seeing a myriad of log statements might question the code's quality and polish. - -Make sure you remove all `console.logs` before pushing the code to production. - -## Naming - -### Variable Naming - -Variable names ought to precisely depict the purpose or function of the variable. - -#### The issue with generic names -Generic names in programming are not ideal because they lack specificity, leading to ambiguity and reduced code readability. Such names fail to convey the variable or function's purpose, making it challenging for developers to understand the code's intent without deeper investigation. This can result in increased debugging time, higher susceptibility to errors, and difficulties in maintenance and collaboration. Meanwhile, descriptive naming makes the code self-explanatory and easier to navigate, enhancing code quality and developer productivity. - -```tsx -// ❌ Bad, uses a generic name that doesn't communicate its -// purpose or content clearly -const [value, setValue] = useState(''); -``` - -```tsx -// ✅ Good, uses a descriptive name -const [email, setEmail] = useState(''); -``` - -#### Some words to avoid in variable names - - - dummy - -### Event handlers - -Event handler names should start with `handle`, while `on` is a prefix used to name events in components props. - -```tsx -// ❌ Bad -const onEmailChange = (val: string) => { - // ... -}; -``` - -```tsx -// ✅ Good -const handleEmailChange = (val: string) => { - // ... -}; -``` - -## Optional Props - -Avoid passing the default value for an optional prop. - -**EXAMPLE** - -Take the`EmailField` component defined below: - -```tsx -type EmailFieldProps = { - value: string; - disabled?: boolean; -}; - -const EmailField = ({ value, disabled = false }: EmailFieldProps) => ( - -); -``` - -**Usage** - -```tsx -// ❌ Bad, passing in the same value as the default value adds no value -const Form = () => ; -``` - -```tsx -// ✅ Good, assumes the default value -const Form = () => ; -``` - -## Component as props - -Try as much as possible to pass uninstantiated components as props, so children can decide on their own of what props they need to pass. - -The most common example for that is icon components: - -```tsx -const SomeParentComponent = () => ; - -// In MyComponent -const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => { - const theme = useTheme(); - - return ( -
- -
- ) -}; -``` - -For React to understand that the component is a component, you need to use PascalCase, to later instantiate it with `` - -## Prop Drilling: Keep It Minimal - -Prop drilling, in the React context, refers to the practice of passing state variables and their setters through many component layers, even if intermediary components don't use them. While sometimes necessary, excessive prop drilling can lead to: - -1. **Decreased Readability**: Tracing where a prop originates or where it's utilized can become convoluted in a deeply nested component structure. - -2. **Maintenance Challenges**: Changes in one component's prop structure might require adjustments in several components, even if they don't directly use the prop. - -3. **Reduced Component Reusability**: A component receiving a lot of props solely for passing them down becomes less general-purpose and harder to reuse in different contexts. - -If you feel that you are using excessive prop drilling, see [state management best practices](#state-management). - -## Imports - -When importing, opt for the designated aliases rather than specifying complete or relative paths. - -**The Aliases** - -```js -{ - alias: { - "~": path.resolve(__dirname, "src"), - "@": path.resolve(__dirname, "src/modules"), - "@testing": path.resolve(__dirname, "src/testing"), - }, -} -``` - -**Usage** -```tsx -// ❌ Bad, specifies the entire relative path -import { - CatalogDecorator -} from '../../../../../testing/decorators/CatalogDecorator'; -import { - ComponentDecorator -} from '../../../../../testing/decorators/ComponentDecorator'; -``` - -```tsx -// ✅ Good, utilises the designated aliases -import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; -import { ComponentDecorator } from 'twenty-ui';= -``` - -## Schema Validation - -[Zod](https://github.com/colinhacks/zod) is the schema validator for untyped objects: - -```js -const validationSchema = z - .object({ - exist: z.boolean(), - email: z - .string() - .email('Email must be a valid email'), - password: z - .string() - .regex(PASSWORD_REGEX, 'Password must contain at least 8 characters'), - }) - .required(); - -type Form = z.infer; -``` - - -## Breaking Changes - -Always perform thorough manual testing before proceeding to guarantee that modifications haven’t caused disruptions elsewhere, given that tests have not yet been extensively integrated. - diff --git a/packages/twenty-docs/docs/contributor/frontend/folder-architecture.mdx b/packages/twenty-docs/docs/contributor/frontend/folder-architecture.mdx deleted file mode 100644 index cdeab4bc7..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/folder-architecture.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Folder Architecture -sidebar_position: 5 -description: A detailed look into our folder architecture -sidebar_custom_props: - icon: TbFolder ---- - -In this guide, you will explore the details of the project directory structure and how it contributes to the organization and maintainability of Twenty. - -By following this folder architecture convention, it's easier to find the files related to specific features and ensure that the application is scalable and maintainable. - -``` -front -└───modules -│ └───module1 -│ │ └───submodule1 -│ └───module2 -│ └───ui -│ │ └───display -│ │ └───inputs -│ │ │ └───buttons -│ │ └───... -└───pages -└───... -``` - -## Pages - -Includes the top-level components defined by the application routes. They import more low-level components from the modules folder (more details below). - -## Modules - -Each module represents a feature or a group of feature, comprising its specific components, states, and operational logic. -They should all follow the structure below. You can nest modules within modules (referred to as submodules) and the same rules will apply. - -``` -module1 - └───components - │ └───component1 - │ └───component2 - └───constants - └───contexts - └───graphql - │ └───fragments - │ └───queries - │ └───mutations - └───hooks - │ └───internal - └───states - │ └───selectors - └───types - └───utils -``` - -### Contexts - -A context is a way to pass data through the component tree without having to pass props down manually at every level. - -See [React Context](https://react.dev/reference/react#context-hooks) for more details. - -### GraphQL - -Includes fragments, queries, and mutations. - -See [GraphQL](https://graphql.org/learn/) for more details. - -- Fragments - -A fragment is a reusable piece of a query, which you can use in different places. By using fragments, it's easier to avoid duplicating code. - -See [GraphQL Fragments](https://graphql.org/learn/queries/#fragments) for more details. - -- Queries - -See [GraphQL Queries](https://graphql.org/learn/queries/) for more details. - -- Mutations - -See [GraphQL Mutations](https://graphql.org/learn/queries/#mutations) for more details. - -### Hooks - -See [Hooks](https://react.dev/learn/reusing-logic-with-custom-hooks) for more details. - -### States - -Contains the state management logic. [RecoilJS](https://recoiljs.org) handles this. - -- Selectors: See [RecoilJS Selectors](https://recoiljs.org/docs/basic-tutorial/selectors) for more details. - -React's built-in state management still handles state within a component. - -### Utils - -Should just contain reusable pure functions. Otherwise, create custom hooks in the `hooks` folder. - - -## UI - -Contains all the reusable UI components used in the application. - -This folder can contain sub-folders, like `data`, `display`, `feedback`, and `input` for specific types of components. Each component should be self-contained and reusable, so that you can use it in different parts of the application. - -By separating the UI components from the other components in the `modules` folder, it's easier to maintain a consistent design and to make changes to the UI without affecting other parts (business logic) of the codebase. - -## Interface and dependencies - -You can import other module code from any module except for the `ui` folder. This will keep its code easy to test. - -### Internal - -Each part (hooks, states, ...) of a module can have an `internal` folder, which contains parts that are just used within the module. diff --git a/packages/twenty-docs/docs/contributor/frontend/frontend.mdx b/packages/twenty-docs/docs/contributor/frontend/frontend.mdx deleted file mode 100644 index 434bac164..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/frontend.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -id: frontend -title: Frontend Development -sidebar_position: 0 -sidebar_custom_props: - icon: TbTerminal2 ---- - -import DocCardList from '@theme/DocCardList'; - - - - -## Useful commands - -### Starting the app - -```bash - nx start twenty-front - ``` - -### Regenerate graphql schema based on API graphql schema - -```bash -nx graphql:generate twenty-front -``` - -### Lint - -```bash -nx lint twenty-front -``` - -### Test - -```bash -nx test twenty-front# run jest tests -nx storybook:dev twenty-front# run storybook -nx storybook:test twenty-front# run tests # (needs yarn storybook:dev to be running) -nx storybook:coverage twenty-front # (needs yarn storybook:dev to be running) -``` - -## Tech Stack - -The project has a clean and simple stack, with minimal boilerplate code. - -**App** - -- [React](https://react.dev/) -- [Apollo](https://www.apollographql.com/docs/) -- [GraphQL Codegen](https://the-guild.dev/graphql/codegen) -- [Recoil](https://recoiljs.org/docs/introduction/core-concepts) -- [TypeScript](https://www.typescriptlang.org/) - -**Testing** - -- [Jest](https://jestjs.io/) -- [Storybook](https://storybook.js.org/) - -**Tooling** - -- [Yarn](https://yarnpkg.com/) -- [Craco](https://craco.js.org/docs/) -- [ESLint](https://eslint.org/) - -## Architecture - -### Routing - -[React Router](https://reactrouter.com/) handles the routing. - -To avoid unnecessary [re-renders](/contributor/frontend/best-practices#managing-re-renders) all the routing logic is in a `useEffect` in `PageChangeEffect`. - -### State Management - -[Recoil](https://recoiljs.org/docs/introduction/core-concepts) handles state management. - -See [best practices](/contributor/frontend/best-practices#state-management) for more information on state management. - -## Testing - -[Jest](https://jestjs.io/) serves as the tool for unit testing while [Storybook](https://storybook.js.org/) is for component testing. - -Jest is mainly for testing utility functions, and not components themselves. - -Storybook is for testing the behavior of isolated components, as well as displaying the design system. diff --git a/packages/twenty-docs/docs/contributor/frontend/hotkeys.mdx b/packages/twenty-docs/docs/contributor/frontend/hotkeys.mdx deleted file mode 100644 index 15884bebf..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/hotkeys.mdx +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: Hotkeys -sidebar_position: 11 -sidebar_custom_props: - icon: TbKeyboard ---- - -## Introduction - -When you need to listen to a hotkey, you would normally use the `onKeyDown` event listener. - -In `twenty-front` however, you might have conflicts between same hotkeys that are used in different components, mounted at the same time. - -For example, if you have a page that listens for the Enter key, and a modal that listens for the Enter key, with a Select component inside that modal that listens for the Enter key, you might have a conflict when all are mounted at the same time. - -## The `useScopedHotkeys` hook - -To handle this problem, we have a custom hook that makes it possible to listen to hotkeys without any conflict. - -You place it in a component and it will listen to the hotkeys only when the component is mounted AND when the specified **hotkey scope** is active. - -## How to listen for hotkeys in practice ? - -There are two steps involved in setting up hotkey listening : -1. Set the [hotkey scope](#what-is-a-hotkey-scope-) that will listen to hotkeys -2. Use the `useScopedHotkeys` hook to listen to hotkeys - -Setting up hotkey scopes is required even in simple pages, because other UI elements like left menu or command menu might also listen to hotkeys. - -## Use cases for hotkeys - -In general, you'll have two use cases that require hotkeys : -1. In a page or a component mounted in a page -2. In a modal-type component that takes the focus due to a user action - -The second use case can happen recursively : a dropdown in a modal for example. - -### Listening to hotkeys in a page - -Example : - -```tsx -const PageListeningEnter = () => { - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); - - // 1. Set the hotkey scope in a useEffect - useEffect(() => { - setHotkeyScopeAndMemorizePreviousScope( - ExampleHotkeyScopes.ExampleEnterPage, - ); - - // Revert to the previous hotkey scope when the component is unmounted - return () => { - goBackToPreviousHotkeyScope(); - }; - }, [goBackToPreviousHotkeyScope, setHotkeyScopeAndMemorizePreviousScope]); - - // 2. Use the useScopedHotkeys hook - useScopedHotkeys( - Key.Enter, - () => { - // Some logic executed on this page when the user presses Enter - // ... - }, - ExampleHotkeyScopes.ExampleEnterPage, - ); - - return
My page that listens for Enter
; -}; -``` - -### Listening to hotkeys in a modal-type component - -For this example we'll use a modal component that listens for the Escape key to tell it's parent to close it. - -Here the user interaction is changing the scope. - -```tsx -const ExamplePageWithModal = () => { - const [showModal, setShowModal] = useState(false); - - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); - - const handleOpenModalClick = () => { - // 1. Set the hotkey scope when user opens the modal - setShowModal(true); - setHotkeyScopeAndMemorizePreviousScope( - ExampleHotkeyScopes.ExampleModal, - ); - }; - - const handleModalClose = () => { - // 1. Revert to the previous hotkey scope when the modal is closed - setShowModal(false); - goBackToPreviousHotkeyScope(); - }; - - return
-

My page with a modal

- - {showModal && } -
; -}; -``` - -Then in the modal component : - -```tsx -const MyDropdownComponent = ({ onClose }: { onClose: () => void }) => { - // 2. Use the useScopedHotkeys hook to listen for Escape. - // Note that escape is a common hotkey that could be used by many other components - // So it's important to use a hotkey scope to avoid conflicts - useScopedHotkeys( - Key.Escape, - () => { - onClose() - }, - ExampleHotkeyScopes.ExampleModal, - ); - - return
My modal component
; -}; -``` - -It's important to use this pattern when you're not sure that just using a useEffect with mount/unmount will be enough to avoid conflicts. - -Those conflicts can be hard to debug, and it might happen more often than not with useEffects. - -## What is a hotkey scope ? - -A hotkey scope is a string that represents a context in which the hotkeys are active. It is generally encoded as an enum. - -When you change the hotkey scope, the hotkeys that are listening to this scope will be enabled and the hotkeys that are listening to other scopes will be disabled. - -You can set only one scope at a time. - -As an example, the hotkey scopes for each page are defined in the `PageHotkeyScope` enum: - -```tsx -export enum PageHotkeyScope { - Settings = 'settings', - CreateWokspace = 'create-workspace', - SignInUp = 'sign-in-up', - CreateProfile = 'create-profile', - PlanRequired = 'plan-required', - ShowPage = 'show-page', - PersonShowPage = 'person-show-page', - CompanyShowPage = 'company-show-page', - CompaniesPage = 'companies-page', - PeoplePage = 'people-page', - OpportunitiesPage = 'opportunities-page', - ProfilePage = 'profile-page', - WorkspaceMemberPage = 'workspace-member-page', - TaskPage = 'task-page', -} -``` - -Internally, the currently selected scope is stored in a Recoil state that is shared across the application : - -```tsx -export const currentHotkeyScopeState = createState({ - key: 'currentHotkeyScopeState', - defaultValue: INITIAL_HOTKEYS_SCOPE, -}); -``` - -But this Recoil state should never be handled manually ! We'll see how to use it in the next section. - -## How is it working internally ? - -We made a thin wrapper on top of [react-hotkeys-hook](https://react-hotkeys-hook.vercel.app/docs/intro) that makes it more performant and avoids unnecessary re-renders. - -We also create a Recoil state to handle the hotkey scope state and make it available everywhere in the application. diff --git a/packages/twenty-docs/docs/contributor/frontend/style-guide.mdx b/packages/twenty-docs/docs/contributor/frontend/style-guide.mdx deleted file mode 100644 index b53dab55f..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/style-guide.mdx +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: Style Guide -sidebar_position: 4 -sidebar_custom_props: - icon: TbPencil ---- - -This document includes the rules to follow when writing code. - -The goal here is to have a consistent codebase, which is easy to read and easy to maintain. - -For this, it's better to be a bit more verbose than to be too concise. - -Always keep in mind that people read code more often than they write it, specially on an open source project, where anyone can contribute. - -There are a lot of rules that are not defined here, but that are automatically checked by linters. - -## React - -### Use functional components - -Always use TSX functional components. - -Do not use default `import` with `const`, because it's harder to read and harder to import with code completion. - -```tsx -// ❌ Bad, harder to read, harder to import with code completion -const MyComponent = () => { - return
Hello World
; -}; - -export default MyComponent; - -// ✅ Good, easy to read, easy to import with code completion -export function MyComponent() { - return
Hello World
; -}; -``` - -### Props - -Create the type of the props and call it `(ComponentName)Props` if there's no need to export it. - -Use props destructuring. - -```tsx -// ❌ Bad, no type -export const MyComponent = (props) =>
Hello {props.name}
; - -// ✅ Good, type -type MyComponentProps = { - name: string; -}; - -export const MyComponent = ({ name }: MyComponentProps) =>
Hello {name}
; -``` - -#### Refrain from using `React.FC` or `React.FunctionComponent` to define prop types - -```tsx -/* ❌ - Bad, defines the component type annotations with `FC` - * - With `React.FC`, the component implicitly accepts a `children` prop - * even if it's not defined in the prop type. This might not always be - * desirable, especially if the component doesn't intend to render - * children. - */ -const EmailField: React.FC<{ - value: string; -}> = ({ value }) => ; -``` - -```tsx -/* ✅ - Good, a separate type (OwnProps) is explicitly defined for the - * component's props - * - This method doesn't automatically include the children prop. If - * you want to include it, you have to specify it in OwnProps. - */ -type EmailFieldProps = { - value: string; -}; - -const EmailField = ({ value }: EmailFieldProps) => ( - -); -``` - -#### No Single Variable Prop Spreading in JSX Elements - -Avoid using single variable prop spreading in JSX elements, like `{...props}`. This practice often results in code that is less readable and harder to maintain because it's unclear which props the component is receiving. - -```tsx -/* ❌ - Bad, spreads a single variable prop into the underlying component - */ -const MyComponent = (props: OwnProps) => { - return ; -} -``` - -```tsx -/* ✅ - Good, Explicitly lists all props - * - Enhances readability and maintainability - */ -const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => { - return ; -}; -``` - -Rationale: -- At a glance, it's clearer which props the code passes down, making it easier to understand and maintain. -- It helps to prevent tight coupling between components via their props. -- Linting tools make it easier to identify misspelled or unused props when you list props explicitly. - -## JavaScript - -### Use nullish-coalescing operator `??` - -```tsx -// ❌ Bad, can return 'default' even if value is 0 or '' -const value = process.env.MY_VALUE || 'default'; - -// ✅ Good, will return 'default' only if value is null or undefined -const value = process.env.MY_VALUE ?? 'default'; -``` - -### Use optional chaining `?.` - -```tsx -// ❌ Bad -onClick && onClick(); - -// ✅ Good -onClick?.(); -``` - -## TypeScript - -### Use `type` instead of `interface` - -Always use `type` instead of `interface`, because they almost always overlap, and `type` is more flexible. - -```tsx -// ❌ Bad -interface MyInterface { - name: string; -} - -// ✅ Good -type MyType = { - name: string; -}; -``` - -### Use string literals instead of enums - -[String literals](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) are the go-to way to handle enum-like values in TypeScript. They are easier to extend with Pick and Omit, and offer a better developer experience, specially with code completion. - -You can see why TypeScript recommends avoiding enums [here](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#enums). - -```tsx -// ❌ Bad, utilizes an enum -enum Color { - Red = "red", - Green = "green", - Blue = "blue", -} - -let color = Color.Red; -``` - -```tsx -// ✅ Good, utilizes a string literal -let color: "red" | "green" | "blue" = "red"; -``` - -#### GraphQL and internal libraries - -You should use enums that GraphQL codegen generates. - -It's also better to use an enum when using an internal library, so the internal library doesn't have to expose a string literal type that is not related to the internal API. - -Example: - -```TSX -const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, -} = usePreviousHotkeyScope(); - -setHotkeyScopeAndMemorizePreviousScope( - RelationPickerHotkeyScope.RelationPicker, -); -``` - -## Styling - -### Use StyledComponents - -Style the components with [styled-components](https://emotion.sh/docs/styled). - -```tsx -// ❌ Bad -
Hello World
-``` - -```tsx -// ✅ Good -const StyledTitle = styled.div` - color: red; -`; -``` - -Prefix styled components with "Styled" to differentiate them from "real" components. - -```tsx -// ❌ Bad -const Title = styled.div` - color: red; -`; -``` - -```tsx -// ✅ Good -const StyledTitle = styled.div` - color: red; -`; -``` - -### Theming - -Utilizing the theme for the majority of component styling is the preferred approach. - -#### Units of measurement - -Avoid using `px` or `rem` values directly within the styled components. The necessary values are generally already defined in the theme, so it’s recommended to make use of the theme for these purposes. - -#### Colors - -Refrain from introducing new colors; instead, use the existing palette from the theme. Should there be a situation where the palette does not align, please leave a comment so that the team can rectify it. - - -```tsx -// ❌ Bad, directly specifies style values without utilizing the theme -const StyledButton = styled.button` - color: #333333; - font-size: 1rem; - font-weight: 400; - margin-left: 4px; - border-radius: 50px; -`; -``` - -```tsx -// ✅ Good, utilizes the theme -const StyledButton = styled.button` - color: ${({ theme }) => theme.font.color.primary}; - font-size: ${({ theme }) => theme.font.size.md}; - font-weight: ${({ theme }) => theme.font.weight.regular}; - margin-left: ${({ theme }) => theme.spacing(1)}; - border-radius: ${({ theme }) => theme.border.rounded}; -`; -``` -## Enforcing No-Type Imports - -Avoid type imports. To enforce this standard, an ESLint rule checks for and reports any type imports. This helps maintain consistency and readability in the TypeScript code. - -```tsx -// ❌ Bad -import { type Meta, type StoryObj } from '@storybook/react'; - -// ❌ Bad -import type { Meta, StoryObj } from '@storybook/react'; - -// ✅ Good -import { Meta, StoryObj } from '@storybook/react'; -``` - -### Why No-Type Imports - -- **Consistency**: By avoiding type imports and using a single approach for both type and value imports, the codebase remains consistent in its module import style. - -- **Readability**: No-type imports improve code readability by making it clear when you're importing values or types. This reduces ambiguity and makes it easier to understand the purpose of imported symbols. - -- **Maintainability**: It enhances codebase maintainability because developers can identify and locate type-only imports when reviewing or modifying code. - -### ESLint Rule - -An ESLint rule, `@typescript-eslint/consistent-type-imports`, enforces the no-type import standard. This rule will generate errors or warnings for any type import violations. - -Please note that this rule specifically addresses rare edge cases where unintentional type imports occur. TypeScript itself discourages this practice, as mentioned in the [TypeScript 3.8 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html). In most situations, you should not need to use type-only imports. - -To ensure your code complies with this rule, make sure to run ESLint as part of your development workflow. diff --git a/packages/twenty-docs/docs/contributor/frontend/work-with-figma.mdx b/packages/twenty-docs/docs/contributor/frontend/work-with-figma.mdx deleted file mode 100644 index e1cda50d3..000000000 --- a/packages/twenty-docs/docs/contributor/frontend/work-with-figma.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Work with Figma -description: Learn how you can collaborate with Twenty's Figma -sidebar_position: 2 -sidebar_custom_props: - icon: TbBrandFigma ---- - -Figma is a collaborative interface design tool that aids in bridging the communication barrier between designers and developers. -This guide explains how you can collaborate with Figma. - -## Access - -1. **Access the shared link:** You can access the project's Figma file [here](https://www.figma.com/file/xt8O9mFeLl46C5InWwoMrN/Twenty). -2. **Sign in:** If you're not already signed in, Figma will prompt you to do so. -Key features are only available to logged-in users, such as the developer mode and the ability to select a dedicated frame. - -:::caution Note - -You will not be able to collaborate effectively without an account. - -::: - - -## Figma structure - -On the left sidebar, you can access the different pages of Twenty's Figma. This is how they're organized: - -- **Components page:** This is the first page. The designer uses it to create and organize the reusable design elements used throughout the design file. For example, buttons, icons, symbols, or any other reusable components. It serves to maintain consistency across the design. -- **Main page:** The second page is the main page, which shows the complete user interface of the project. You can press ***Play*** to use the full app prototype. -- **Features pages:** The other pages are typically dedicated to features in progress. They contain the design of specific features or modules of the application or website. They are typically still in progress. - -## Useful Tips - -With read-only access, you can't edit the design but you can access all features that will be useful to convert the designs into code. - -### Use the Dev mode - -Figma's Dev Mode enhances developers' productivity by providing easy design navigation, effective asset management, efficient communication tools, toolbox integrations, quick code snippets, and key layer information, bridging the gap between design and development. You can learn more about Dev Mode [here](https://www.figma.com/dev-mode/). - -Switch to the "Developer" mode in the right part of the toolbar to see design specs, copy CSS, and access assets. - -### Use the Prototype - -Click on any element on the canvas and press the “Play” button at the top right edge of the interface to access the prototype view. Prototype mode allows you to interact with the design as if it were the final product. It demonstrates the flow between screens and how interface elements like buttons, links, or menus behave when interacted with. - -1. **Understanding transitions and animations:** In the Prototype mode, you can view any transitions or animations added by a designer between screens or UI elements, providing clear visual instructions to developers on the intended behavior and style. -2. **Implementation clarification:** A prototype can also help reduce ambiguities. Developers can interact with it to gain a better understanding of the functionality or appearance of particular elements. - -For more comprehensive details and guidance on learning the Figma platform, you can visit the official [Figma Documentation](https://help.figma.com/hc/en-us). - -### Measure distances - -Select an element, hold `Option` key (Mac) or `Alt` key (Windows), then hover over another element to see the distance between them. - -### Figma extension for VSCode (Recommended) - -[Figma for VS Code](https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension) -lets you navigate and inspect design files, collaborate with designers, track changes, and speed up implementation - all without leaving your text editor. -It's part of our recommended extensions. - -## Collaboration - -1. **Using Comments:** You are welcome to use the comment feature by clicking on the bubble icon in the left part of the toolbar. -2. **Cursor chat:** A nice feature of Figma is the Cursor chat. Just press `;` on Mac and `/` on Windows to send a message if you see someone else using Figma as the same time as you. \ No newline at end of file diff --git a/packages/twenty-docs/docs/contributor/server/_category_.json b/packages/twenty-docs/docs/contributor/server/_category_.json deleted file mode 100644 index cf5d22abc..000000000 --- a/packages/twenty-docs/docs/contributor/server/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "position": 4, - "collapsible": true, - "collapsed": true -} diff --git a/packages/twenty-docs/docs/contributor/server/best-practices.mdx b/packages/twenty-docs/docs/contributor/server/best-practices.mdx deleted file mode 100644 index b84a3ed19..000000000 --- a/packages/twenty-docs/docs/contributor/server/best-practices.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Best Practices -sidebar_position: 3 -sidebar_custom_props: - icon: TbChecklist ---- - -This document outlines the best practices you should follow when working on the backend. - -## Follow a modular approach - -The backend follows a modular approach, which is a fundamental principle when working with NestJS. Make sure you break down your code into reusable modules to maintain a clean and organized codebase. -Each module should encapsulate a particular feature or functionality and have a well-defined scope. This modular approach enables clear separation of concerns and removes unnecessary complexities. - -## Expose services to use in modules - -Always create services that have a clear and single responsibility, which enhances code readability and maintainability. Name the services descriptively and consistently. - -You should also expose services that you want to use in other modules. Exposing services to other modules is possible through NestJS's powerful dependency injection system, and promotes loose coupling between components. - -## Avoid using `any` type - -When you declare a variable as `any`, TypeScript's type checker doesn't perform any type checking, making it possible to assign any type of values to the variable. TypeScript uses type inference to determine the type of variable based on the value. By declaring it as `any`, TypeScript can no longer infer the type. This makes it hard to catch type-related errors during development, leading to runtime errors and makes the code less maintainable, less reliable, and harder to understand for others. - -This is why everything should have a type. So if you create a new object with a first name and last name, you should create an interface or type that contains a first name and last name that defines the shape of the object you are manipulating. \ No newline at end of file diff --git a/packages/twenty-docs/docs/contributor/server/custom-objects.mdx b/packages/twenty-docs/docs/contributor/server/custom-objects.mdx deleted file mode 100644 index a23732549..000000000 --- a/packages/twenty-docs/docs/contributor/server/custom-objects.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Custom Objects -sidebar_position: 4 -sidebar_custom_props: - icon: TbAugmentedReality ---- - -Objects are structures that allow you to store data (records, attributes, and values) specific to an organization. Twenty provides both standard and custom objects. - -Standard objects are in-built objects with a set of attributes available for all users. Examples of standard objects in Twenty include Company and Person. Standard objects have standard fields that are also available for all Twenty users, like Company.displayName. - -Custom objects are objects that you can create to store information that is unique to your organization. They are not built-in; members of your workspace can create and customize custom objects to hold information that standard objects aren't suitable for. - - -## High-level schema - -
- High level schema -
- -
- -## How it works - -Custom objects come from metadata tables that determine the shape, name, and type of the objects. All this information is present in the metadata schema database, consisting of tables: - -- **DataSource**: Details where the data is present. -- **Object**: Describes the object and links to a DataSource. -- **Field**: Outlines an Object's fields and connects to the Object. - -To add a custom object, the workspaceMember will query the /metadata API. This updates the metadata accordingly and computes a GraphQL schema based on the metadata, storing it in a GQL cache for later use. -
- Query the /metadata API to add custom objects -
- -
- -To fetch data, the process involves making queries through the /graphql endpoint and passing them through the Query Resolver. -
- Query the /graphql endpoint to fetch data -
diff --git a/packages/twenty-docs/docs/contributor/server/feature-flags.mdx b/packages/twenty-docs/docs/contributor/server/feature-flags.mdx deleted file mode 100644 index 9ccbf049b..000000000 --- a/packages/twenty-docs/docs/contributor/server/feature-flags.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Feature Flags -sidebar_position: 1 -sidebar_custom_props: - icon: TbFlag ---- - -Feature flags are used to hide experimental features. For twenty they are set on workspace level and not on a user level. - -## Adding a new feature flag - -In `FeatureFlagKey.ts` add the feature flag: - -```ts -type FeatureFlagKey = - | 'IS_FEATURENAME_ENABLED' - | ...; -``` - -Also add it to the enum in `feature-flag.entity.ts`: - -```ts -enum FeatureFlagKeys { - IsFeatureNameEnabled = 'IS_FEATURENAME_ENABLED', - ... -} -``` - - - -To apply a feature flag on a **backend** feature use: - -```ts -@Gate({ - featureFlag: 'IS_FEATURENAME_ENABLED', -}) -``` - -To apply a feature flag on a **frontend** feature use: - -```ts -const isFeatureNameEnabled = useIsFeatureEnabled('IS_FEATURENAME_ENABLED'); -``` - - -## Configure feature flags for the deployment - -Change the corresponding record in the Table `core.featureFlag`: - -| id | key | workspaceId | value | -|----------|--------------------------|---------------|--------| -| Random | `IS_FEATURENAME_ENABLED` | WorkspaceID | `true` | diff --git a/packages/twenty-docs/docs/contributor/server/folder-architecture.mdx b/packages/twenty-docs/docs/contributor/server/folder-architecture.mdx deleted file mode 100644 index 4a59213bc..000000000 --- a/packages/twenty-docs/docs/contributor/server/folder-architecture.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Folder Architecture -sidebar_position: 2 -description: A detailed look into our server folder architecture -sidebar_custom_props: - icon: TbFolder ---- - - -The backend directory structure is as follows: - -``` -server - └───ability - └───constants - └───core - └───database - └───decorators - └───filters - └───guards - └───health - └───integrations - └───metadata - └───workspace - └───utils -``` - -## Ability - -Defines permissions and includes handlers for each entity. - -## Decorators - -Defines custom decorators in NestJS for added functionality. - -See [custom decorators](https://docs.nestjs.com/custom-decorators) for more details. - -## Filters - -Includes exception filters to handle exceptions that might occur in GraphQL endpoints. - -## Guards - -See [guards](https://docs.nestjs.com/guards) for more details. - -## Health - -Includes a publicly available REST API (healthz) that returns a JSON to confirm whether the database is working as expected. - -## Metadata - -Defines custom objects and makes available a GraphQL API (graphql/metadata). - -## Workspace - -Generates and serves custom GraphQL schema based on the metadata. - -### Workspace Directory Structure - -``` -workspace - └───workspace-schema-builder - └───factories - └───graphql-types - └───database - └───interfaces - └───object-definitions - └───services - └───storage - └───utils - └───workspace-resolver-builder - └───factories - └───interfaces - └───workspace-query-builder - └───factories - └───interfaces - └───workspace-query-runner - └───interfaces - └───utils - └───workspace-datasource - └───workspace-manager - └───workspace-migration-runner - └───utils - └───workspace.module.ts - └───workspace.factory.spec.ts - └───workspace.factory.ts -``` - - -The root of the workspace directory includes the `workspace.factory.ts`, a file containing the `createGraphQLSchema` function. This function generates workspace-specific schema by using the metadata to tailor a schema for individual workspaces. By separating the schema and resolver construction, we use the `makeExecutableSchema` function, which combines these discrete elements. - -This strategy is not just about organization, but also helps with optimization, such as caching generated type definitions to enhance performance and scalability. - -### Workspace Schema builder - -Generates the GraphQL schema, and includes: - -#### Factories: - -Specialised constructors to generate GraphQL-related constructs. -- The type.factory translates field metadata into GraphQL types using `TypeMapperService`. -- The type-definition.factory creates GraphQL input or output objects derived from `objectMetadata`. - -#### GraphQL Types - -Includes enumerations, inputs, objects, and scalars, and serves as the building blocks for the schema construction. - -#### Interfaces and Object Definitions - -Contains the blueprints for GraphQL entities, and includes both predefined and custom types like `MONEY` or `URL`. - -#### Services - -Contains the service responsible for associating FieldMetadataType with its appropriate GraphQL scalar or query modifiers. - -#### Storage - -Includes the `TypeDefinitionsStorage` class that contains reusable type definitions, preventing duplication of GraphQL types. - -### Workspace Resolver Builder - -Creates resolver functions for querying and mutatating the GraphQL schema. - -Each factory in this directory is responsible for producing a distinct resolver type, such as the `FindManyResolverFactory`, designed for adaptable application across various tables. - -### Workspace Query Builder - -Includes factories that generate `pg_graphql` queries. - -### Workspace Query Runner - -Runs the generated queries on the database and parses the result. \ No newline at end of file diff --git a/packages/twenty-docs/docs/contributor/server/queue.mdx b/packages/twenty-docs/docs/contributor/server/queue.mdx deleted file mode 100644 index 4425f9865..000000000 --- a/packages/twenty-docs/docs/contributor/server/queue.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Message Queue -sidebar_position: 5 -sidebar_custom_props: - icon: TbSchema ---- - -Queues facilitate async operations to be performed. They can be used for performing background tasks such as sending a welcome email on register. -Each use case will have its own queue class extended from `MessageQueueServiceBase`. - -Currently, queue supports two drivers which can be configurred by env variable `MESSAGE_QUEUE_TYPE`. -1. `pg-boss`: this is the default driver, which uses [pg-boss](https://github.com/timgit/pg-boss) under the hood. -2. `bull-mq`: this uses [bull-mq](https://bullmq.io/) under the hood. - -## Steps to create and use a new queue - -1. Add a queue name for your new queue under enum `MESSAGE_QUEUES`. -2. Provide the factory implementation of the queue with the queue name as the dependency token. -3. Inject the queue that you created in the required module/service with the queue name as the dependency token. -4. Add worker class with token based injection just like producer. - -### Example usage -```ts -class Resolver { - constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) {} - - async onSomeAction() { - //business logic - await this.queue.add(someData); - } -} - -//async worker -class CustomWorker { - constructor(@Inject(MESSAGE_QUEUES.custom) private queue: MessageQueueService) { - this.initWorker(); - } - - async initWorker() { - await this.queue.work(async ({ id, data }) => { - //worker logic - }); - } -} - -``` - diff --git a/packages/twenty-docs/docs/contributor/server/server.mdx b/packages/twenty-docs/docs/contributor/server/server.mdx deleted file mode 100644 index 4082d33ac..000000000 --- a/packages/twenty-docs/docs/contributor/server/server.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Backend Development -sidebar_position: 0 -sidebar_custom_props: - icon: TbTerminal ---- - - -import DocCardList from '@theme/DocCardList'; - - - - -## Useful commands - -These commands should be exectued from packages/twenty-server folder. -From any other folder you can run `npx nx ` twenty-server. - -### First time setup - -``` -npx nx database:reset # setup the database with dev seeds -``` - -### Starting the app - -``` -npx nx start -``` - -### Lint - -``` -npx nx lint -``` - -### Test - -``` -npx nx test:unit -``` - -### Resetting the database - -If you want to reset the database, you can run the following command: - -```bash -npx nx database:reset -``` - -:::warning - -This will drop the database and re-run the migrations and seed. - -Make sure to back up any data you want to keep before running this command. - -::: - -## Tech Stack - -Twenty primarily uses NestJS for the backend. - -Prisma was the first ORM we used. But in order to allow users to create custom fields and custom objects, a lower-level made more sense as we need to have fine-grained control. The project now uses TypeORM. - -Here's what the tech stack now looks like. - - -**Core** -- [NestJS](https://nestjs.com/) -- [TypeORM](https://typeorm.io/) -- [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server) - -**Database** -- [Postgres](https://www.postgresql.org/) - -**Third-party integrations** -- [Sentry](https://sentry.io/welcome/) for tracking bugs - -**Testing** -- [Jest](https://jestjs.io/) - -**Tooling** -- [Yarn](https://yarnpkg.com/) -- [ESLint](https://eslint.org/) - -**Development** -- [AWS EKS](https://aws.amazon.com/eks/) \ No newline at end of file diff --git a/packages/twenty-docs/docs/contributor/server/zapier.mdx b/packages/twenty-docs/docs/contributor/server/zapier.mdx deleted file mode 100644 index 4407474ce..000000000 --- a/packages/twenty-docs/docs/contributor/server/zapier.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Zapier App -sidebar_position: 2 -sidebar_custom_props: - icon: TbBrandZapier ---- - -Effortlessly sync Twenty with 3000+ apps using [Zapier](https://zapier.com/). Automate tasks, boost productivity, and supercharge your customer relationships! - -## About Zapier - -Zapier is a tool that allows you automate workflows by connecting the apps that your team uses everyday. The fundamental concept of Zapier is automation workflows, called Zaps, and include triggers and actions. - -You can learn more about how Zapier works [here](https://zapier.com/how-it-works). - -## Setup - -### Step 1: Install Zapier packages - -```bash -cd packages/twenty-zapier -yarn -``` - -### Step 2: Login with the CLI - -Use your Zapier credentials to log in using the CLI: - -```bash -zapier login -``` - -### Step 3: Set environment variables - -From the `packages/twenty-zapier` folder, run: - -```bash -cp .env.example .env -``` -Run the application locally, go to [http://localhost:3000/settings/developers](http://localhost:3000/settings/developers/api-keys), and generate an API key. - -Replace the **YOUR_API_KEY** value in the `.env` file with the API key you just generated. - -## Development - -:::caution Note - -Make sure to run `yarn build` before any `zapier` command. - -::: - -### Test -```bash -yarn test -``` -### Lint -```bash -yarn format -``` -### Watch and compile as you edit code -```bash -yarn watch -``` -### Validate your Zapier app -```bash -yarn validate -``` -### Deploy your Zapier app -```bash -yarn deploy -``` -### List all Zapier CLI commands -```bash -zapier -``` diff --git a/packages/twenty-docs/docs/index.mdx b/packages/twenty-docs/docs/index.mdx deleted file mode 100644 index 160b8bbe1..000000000 --- a/packages/twenty-docs/docs/index.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -id: homepage -sidebar_position: 0 -sidebar_class_name: display-none -title: Welcome -hide_title: true -hide_table_of_contents: true -custom_edit_url: null -pagination_next: null ---- -import ThemedImage from '@theme/ThemedImage'; - - -Twenty is a CRM designed to fit your unique business needs. -It is maintained by a community of 200+ developers that care about building high-quality software. - -There are three different ways to get started: -- **Managed Cloud:** The fastest and easiest way to try the app -- **Local Setup:** If you're a developer and would like to contribute to the app -- **Self-Hosting:** If you know how to run a server and want to host the app yourself - - -Once you're setup, you can check the "Extending" or "Contributing" section to start building. - - - diff --git a/packages/twenty-docs/docs/start/_category_.json b/packages/twenty-docs/docs/start/_category_.json deleted file mode 100644 index 3562d433d..000000000 --- a/packages/twenty-docs/docs/start/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Getting Started", - "position": 1 -} diff --git a/packages/twenty-docs/docs/start/cloud.mdx b/packages/twenty-docs/docs/start/cloud.mdx deleted file mode 100644 index 84538217b..000000000 --- a/packages/twenty-docs/docs/start/cloud.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Managed Cloud -sidebar_position: 1 -sidebar_custom_props: - icon: TbRocket ---- -import ThemedImage from '@theme/ThemedImage'; -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - -The easiest way to try the app is to sign up on [app.twenty.com](https://app.twenty.com). - -We offer a free trial but require a credit-card to signup. - -If you just want to play around with a test instance you can use these credentials on [demo.twenty.com](https://demo.twenty.com): - -``` -email: noah@demo.dev -password: Applecar2025 -``` - -Expect the demo to occasionnaly have bugs; it's used for testing purposes and therefore is running a version of the software that's newer than the production environment. \ No newline at end of file diff --git a/packages/twenty-docs/docs/start/local-setup.mdx b/packages/twenty-docs/docs/start/local-setup.mdx deleted file mode 100644 index b73eda911..000000000 --- a/packages/twenty-docs/docs/start/local-setup.mdx +++ /dev/null @@ -1,226 +0,0 @@ ---- -title: Local Setup -sidebar_position: 2 -sidebar_custom_props: - icon: TbDeviceDesktop ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - -Follow this guide if you would like to setup the project locally to contribute. - -## Prerequisites - - - - -Before you can install and use Twenty, make sure you install the following on your computer: -- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) -- [Node v18](https://nodejs.org/en/download) -- [yarn v4](https://yarnpkg.com/getting-started/install) -- [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md) - -:::info Note -`npm` won't work, you should use `yarn` instead. Yarn is now shipped with Node.js, so you don't need to install it separately. -You only have to run `corepack enable` to enable Yarn if you haven't done it yet. -::: - - - - - -1. Install WSL -Open PowerShell as Administrator and run: - -```powershell -wsl --install -``` -You should now see a prompt to restart your computer. If not, restart it manually. - -Upon restart, a powershell window will open and install Ubuntu. This may take up some time. -You'll see a prompt to create a username and password for your Ubuntu installation. - -2. Install and configure git - -```bash -sudo apt-get install git -git config --global user.name "Your Name" -git config --global user.email "youremail@domain.com" -``` - -3. Install Node.js, nvm, yarn -```bash -sudo apt-get install curl -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash -corepack enable -``` -Close and reopen your terminal to start using nvm. - - - - ---- - -## Step 1: Git Clone - -In your terminal, run the following command. - - - - -If you haven't already set up SSH keys, you can learn how to do so [here](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/about-ssh). -```bash -git clone git@github.com:twentyhq/twenty.git -``` - - - -```bash -git clone https://github.com/twentyhq/twenty.git -``` - - - - -## Step 2: Position yourself at the root - -```bash -cd twenty -``` - -You should run all commands in the following steps from the root of the project. - -## Step 3: Set up a PostgreSQL Database -We rely on [pg_graphql](https://github.com/supabase/pg_graphql) and recommend you use the scripts below to provision a database with the right extensions. -You can access the database at [localhost:5432](localhost:5432), with user `twenty` and password `twenty` . - - - - Option 1: To provision your database locally: - ```bash - make postgres-on-linux - ``` - - Option 2: If you have docker installed: - ```bash - make postgres-on-docker - ``` - - - Option 1: To provision your database locally with `brew`: - ```bash - make postgres-on-macos-intel #for intel architecture - make postgres-on-macos-arm #for M1/M2/M3 architecture - ``` - - Option 2: If you have docker installed: - ```bash - make postgres-on-docker - ``` - - - Option 1 : To provision your database locally: - ```bash - make postgres-on-linux - ``` - - Note: you might need to run `sudo apt-get install build-essential` before running the above command if you don't have the build tools installed. - - Option 2: If you have docker installed: - Running Docker on WSL adds an extra layer of complexity. - Only use this option if you are comfortable with the extra steps involved, including turning on [Docker Desktop WSL2](https://docs.docker.com/desktop/wsl). - ```bash - make postgres-on-docker - ``` - - - - -## Step 4: Setup environment variables - -Use environment variables or `.env` files to configure your project. - -Copy the `.env.example` files in `/front` and `/server`: -```bash -cp ./packages/twenty-front/.env.example ./packages/twenty-front/.env -cp ./packages/twenty-server/.env.example ./packages/twenty-server/.env -``` - -## Step 5: Installing dependencies - -:::info - -Use `nvm` to install the correct `node` version. The `.nvmrc` ensures all contributors use the same version. - -::: - -To build Twenty server and seed some data into your database, run the following commands: -```bash -nvm install # installs recommended node version -nvm use # use recommended node version - -yarn -``` - -## Step 6: Running the project - -Setup your database with the following command: -```bash -npx nx database:reset twenty-server -``` - -Start the server and the frontend: -```bash -npx nx start twenty-server -npx nx start twenty-front -``` - -Alternatively, you can start both applications at once: -```bash -npx nx start -``` - -Twenty's server will be up and running at [http://localhost:3000/graphql](http://localhost:3000/graphql). -Twenty's frontend will be running at [http://localhost:3001](http://localhost:3001). Just login using the seeded demo account: `tim@apple.dev` (password: `Applecar2025`) to start using Twenty. - - -## Troubleshooting - -#### CR line breaks found [Windows] - -This is due to the line break characters of Windows and the git configuration. Try running: - -``` -git config --global core.autocrlf false -``` - -Then delete the repository and clone it again. - -#### Missing metadata schema - -During Twenty installation, you need to provision your postgres database with the right schemas, extensions, and users. -If you're successful in running this provisioning, you should have `default` and `metadata` schemas in your database. -If you don't, make sure you don't have more than one postgres instance running on your computer. - -#### Cannot find module 'twenty-emails' or its corresponding type declarations. - -You have to build the package `twenty-emails` before running the initialization of the database with `npx nx run twenty-emails:build` - -#### Missing twenty-x package - -Make sure to run yarn in the root directory and then run `npx nx server:dev twenty-server`. If this still doesn't work try building the missing package manually. - -#### Lint on Save not working - -This should work out of the box with the eslint extension installed. If this doens't work try adding this to your vscode setting (on the dev container scope): - -``` -"editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" -} -``` - -#### Docker container build - -To successfully build Docker images, ensure that your system has a minimum of 2GB of memory available. For users of Docker Desktop, please verify that you've allocated sufficient resources to Docker within the application's settings. diff --git a/packages/twenty-docs/docs/start/self-hosting/_category_.json b/packages/twenty-docs/docs/start/self-hosting/_category_.json deleted file mode 100644 index 254ec2489..000000000 --- a/packages/twenty-docs/docs/start/self-hosting/_category_.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "position": 3, - "collapsible": true, - "collapsed": true -} diff --git a/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx b/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx deleted file mode 100644 index 8e40ade6b..000000000 --- a/packages/twenty-docs/docs/start/self-hosting/cloud-providers.mdx +++ /dev/null @@ -1,437 +0,0 @@ ---- -title: Vendor-specific instructions -sidebar_position: 3 -sidebar_custom_props: - icon: TbCloud ---- - -:::info -This document is maintained by the community. It might contain issues. -Feel free to join our discord if you need assistance. -::: - - -## Render - -[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/twentyhq/twenty) - -## RepoCloud - -[![Deploy on RepoCloud](https://d16t0pc4846x52.cloudfront.net/deploy.png)](https://repocloud.io/details/?app_id=259) - - -## Azure Container Apps - -### About - -Hosts Twenty CRM using Azure Container Apps. -The solution provisions file shares, a container apps environment with three containers, and a log analytics workspace. - -The file shares are used to store uploaded images and files through the UI, and to store database backups. - -### Prerequisites - -- Terraform installed https://developer.hashicorp.com/terraform/install -- An Azure subscription with permissions to create resources - -### Step by step instructions: - -1. Create a new folder and copy all the files from below -2. Run `terraform init` -3. Run `terraform plan -out tfplan` -4. Run `terraform apply tfplan` -5. Connect to server `az containerapp exec --name twenty-server -g twenty-crm-rg` -6. Initialize the database from the server `yarn database:init:prod` -7. Go to https://your-twenty-front-fqdn - located in the portal - -#### Production docker containers - -This uses the prebuilt images found on [docker hub](https://hub.docker.com/r/twentycrm/). - -#### Environment Variables - -- Is set in respective tf-files -- See docs [Setup Environment Variables](https://docs.twenty.com/start/self-hosting/) for usage -- After deployment you could can set `IS_SIGN_UP_DISABLED=true` (and run `terraform plan/apply` again) to disable new workspaces from being created - -#### Security and networking - -- Container `twenty-db` accepts only ingress TCP traffic from other containers in the environment. No external ingress traffic allowed -- Container `twenty-server` accepts external traffic over HTTPS -- Container `twenty-front` accepts external traffic over HTTPS - -It´s highly recommended to enable [built-in authentication](https://learn.microsoft.com/en-us/azure/container-apps/authentication) for `twenty-front` using one of the supported providers. - -Use the [custom domain](https://learn.microsoft.com/en-us/azure/container-apps/custom-domains-certificates) feature on the `twenty-front` container if you would like an easier domain name. - -#### Files - -##### providers.tf - -```hcl -# providers.tf - -terraform { - required_providers { - azapi = { - source = "Azure/azapi" - } - } -} - -provider "azapi" { -} - -provider "azurerm" { - features {} -} - -provider "azuread" { -} - -provider "random" { -} -``` - -##### main.tf - -```hcl -# main.tf - -# Create a resource group -resource "azurerm_resource_group" "main" { - name = "twenty-crm-rg" - location = "North Europe" -} - -# Variables -locals { - app_env_name = "twenty" - - server_name = "twenty-server" - server_tag = "latest" - - front_app_name = "twenty-front" - front_tag = "latest" - - db_app_name = "twenty-postgres" - db_tag = "latest" - - db_user = "twenty" - db_password = "twenty" - - storage_mount_db_name = "twentydbstoragemount" - storage_mount_server_name = "twentyserverstoragemount" - - cpu = 1.0 - memory = "2Gi" -} - -# Set up a Log Analytics workspace -resource "azurerm_log_analytics_workspace" "main" { - name = "${local.app_env_name}-law" - location = azurerm_resource_group.main.location - resource_group_name = azurerm_resource_group.main.name - sku = "PerGB2018" - retention_in_days = 30 -} - -# Create a storage account -resource "random_pet" "example" { - length = 2 - separator = "" -} - -resource "azurerm_storage_account" "main" { - name = "twentystorage${random_pet.example.id}" - resource_group_name = azurerm_resource_group.main.name - location = azurerm_resource_group.main.location - account_tier = "Standard" - account_replication_type = "LRS" - large_file_share_enabled = true -} - -# Create db file storage -resource "azurerm_storage_share" "db" { - name = "twentydatabaseshare" - storage_account_name = azurerm_storage_account.main.name - quota = 50 - enabled_protocol = "SMB" -} - -# Create backend file storage -resource "azurerm_storage_share" "server" { - name = "twentyservershare" - storage_account_name = azurerm_storage_account.main.name - quota = 50 - enabled_protocol = "SMB" -} - -# Create a Container App Environment -resource "azurerm_container_app_environment" "main" { - name = "${local.app_env_name}-env" - location = azurerm_resource_group.main.location - resource_group_name = azurerm_resource_group.main.name - log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id -} - -# Connect the db storage share to the container app environment -resource "azurerm_container_app_environment_storage" "db" { - name = local.storage_mount_db_name - container_app_environment_id = azurerm_container_app_environment.main.id - account_name = azurerm_storage_account.main.name - share_name = azurerm_storage_share.db.name - access_key = azurerm_storage_account.main.primary_access_key - access_mode = "ReadWrite" -} - -# Connect the server storage share to the container app environment -resource "azurerm_container_app_environment_storage" "server" { - name = local.storage_mount_server_name - container_app_environment_id = azurerm_container_app_environment.main.id - account_name = azurerm_storage_account.main.name - share_name = azurerm_storage_share.server.name - access_key = azurerm_storage_account.main.primary_access_key - access_mode = "ReadWrite" -} -``` - -##### frontend.tf - -```hcl -# frontend.tf - -resource "azurerm_container_app" "twenty_front" { - name = local.front_app_name - container_app_environment_id = azurerm_container_app_environment.main.id - resource_group_name = azurerm_resource_group.main.name - revision_mode = "Single" - - depends_on = [azurerm_container_app.twenty_server] - - ingress { - allow_insecure_connections = false - external_enabled = true - target_port = 3000 - transport = "http" - traffic_weight { - percentage = 100 - latest_revision = true - } - } - - template { - min_replicas = 1 - # things starts to fail when using more than 1 replica - max_replicas = 1 - container { - name = "twenty-front" - image = "docker.io/twentycrm/twenty-front:${local.front_tag}" - cpu = local.cpu - memory = local.memory - - env { - name = "REACT_APP_SERVER_BASE_URL" - value = "https://${azurerm_container_app.twenty_server.ingress[0].fqdn}" - } - } - } -} - -# Set CORS rules for frontend app using AzAPI -resource "azapi_update_resource" "cors" { - type = "Microsoft.App/containerApps@2023-05-01" - resource_id = azurerm_container_app.twenty_front.id - body = jsonencode({ - properties = { - configuration = { - ingress = { - corsPolicy = { - allowedOrigins = ["*"] - } - } - } - } - }) - depends_on = [azurerm_container_app.twenty_front] -} -``` - -##### backend.tf - -```hcl -# backend.tf - -# Create three random UUIDs -resource "random_uuid" "access_token_secret" {} -resource "random_uuid" "login_token_secret" {} -resource "random_uuid" "refresh_token_secret" {} -resource "random_uuid" "file_token_secret" {} - -resource "azurerm_container_app" "twenty_server" { - name = local.server_name - container_app_environment_id = azurerm_container_app_environment.main.id - resource_group_name = azurerm_resource_group.main.name - revision_mode = "Single" - - depends_on = [azurerm_container_app.twenty_db, azurerm_container_app_environment_storage.server] - - ingress { - allow_insecure_connections = false - external_enabled = true - target_port = 3000 - transport = "http" - traffic_weight { - percentage = 100 - latest_revision = true - } - } - - template { - min_replicas = 1 - max_replicas = 1 - volume { - name = "twenty-server-data" - storage_type = "AzureFile" - storage_name = local.storage_mount_server_name - } - - container { - name = local.server_name - image = "docker.io/twentycrm/twenty-server:${local.server_tag}" - cpu = local.cpu - memory = local.memory - - volume_mounts { - name = "twenty-server-data" - path = "/app/packages/twenty-server/.local-storage" - } - - # Environment variables - env { - name = "IS_SIGN_UP_DISABLED" - value = false - } - env { - name = "SIGN_IN_PREFILLED" - value = false - } - env { - name = "STORAGE_TYPE" - value = "local" - } - env { - name = "STORAGE_LOCAL_PATH" - value = ".local-storage" - } - env { - name = "PG_DATABASE_URL" - value = "postgres://${local.db_user}:${local.db_password}@${local.db_app_name}:5432/default" - } - env { - name = "FRONT_BASE_URL" - value = "https://${local.front_app_name}" - } - env { - name = "ACCESS_TOKEN_SECRET" - value = random_uuid.access_token_secret.result - } - env { - name = "LOGIN_TOKEN_SECRET" - value = random_uuid.login_token_secret.result - } - env { - name = "REFRESH_TOKEN_SECRET" - value = random_uuid.refresh_token_secret.result - } - env { - name = "FILE_TOKEN_SECRET" - value = random_uuid.file_token_secret.result - } - } - } -} - -# Set CORS rules for server app using AzAPI -resource "azapi_update_resource" "server_cors" { - type = "Microsoft.App/containerApps@2023-05-01" - resource_id = azurerm_container_app.twenty_server.id - body = jsonencode({ - properties = { - configuration = { - ingress = { - corsPolicy = { - allowedOrigins = ["*"] - } - } - } - } - }) - depends_on = [azurerm_container_app.twenty_server] -} -``` - -##### database.tf - -```hcl -# database.tf - -resource "azurerm_container_app" "twenty_db" { - name = local.db_app_name - container_app_environment_id = azurerm_container_app_environment.main.id - resource_group_name = azurerm_resource_group.main.name - revision_mode = "Single" - - depends_on = [azurerm_container_app_environment_storage.db] - - ingress { - allow_insecure_connections = false - external_enabled = false - target_port = 5432 - transport = "tcp" - traffic_weight { - percentage = 100 - latest_revision = true - } - } - - template { - min_replicas = 1 - max_replicas = 1 - container { - name = local.db_app_name - image = "docker.io/twentycrm/twenty-postgres:${local.db_tag}" - cpu = local.cpu - memory = local.memory - - volume_mounts { - name = "twenty-db-data" - path = "/var/lib/postgresql/data" - } - - env { - name = "POSTGRES_USER" - value = "postgres" - } - env { - name = "POSTGRES_PASSWORD" - value = "postgres" - } - env { - name = "POSTGRES_DB" - value = "default" - } - } - - volume { - name = "twenty-db-data" - storage_type = "AzureFile" - storage_name = local.storage_mount_db_name - } - } -} -``` - -## Others - -Please feel free to Open a PR to add more Cloud Provider options. diff --git a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx b/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx deleted file mode 100644 index 3cbf57ad9..000000000 --- a/packages/twenty-docs/docs/start/self-hosting/docker-compose.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Docker Compose (easy) -sidebar_position: 2 -sidebar_custom_props: - icon: TbBrandDocker ---- -# Step by step instructions: - -## One command installation - -Install the project with the command below. By default, it installs the latest version from the main branch. -```bash -bash <(curl -sL https://git.new/20) -``` - -## Custom Installation: - -Set VERSION for a specific docker image version, BRANCH for a specific clone branch: -```bash -VERSION=x.y.z BRANCH=branch-name bash <(curl -sL https://git.new/20) -``` - -## Manual installation - -1. Copy the [.env.example](https://github.com/twentyhq/twenty/blob/main/packages/twenty-docker/.env.example) into a `.env` in the same directory where your `docker-compose.yml` file will be -2. Run the command `openssl rand -base64 32` four times, make note of the string for each -3. In your .env file, replace the three "replace_me_with_a_random_string_access" with the four random strings you just generated. - -``` -ACCESS_TOKEN_SECRET=replace_me_with_a_random_string_access -LOGIN_TOKEN_SECRET=replace_me_with_a_random_string_login -REFRESH_TOKEN_SECRET=replace_me_with_a_random_string_refresh -FILE_TOKEN_SECRET=replace_me_with_a_random_string_refresh -``` - -4. Copy the [docker-compose.yml](https://github.com/twentyhq/twenty/blob/main/packages/twenty-docker/docker-compose.yml) in the same directory as your `.env` file. -5. Run the command `docker-compose up -d` -6. Go to http://localhost:3000 and see your docker instance. - -## Troubleshooting - -### Not able to login - -If you encounter errors, (not able to log into the application after inputting an email) after the inital setup, try running the following commands and see if that solves your issue. -``` -docker exec -it twenty-server-1 yarn -docker exec -it twenty-server-1 npx nx database:reset -``` - -### Cannot connect to server, running behind a reverse proxy - -Complete step three and four with: - -3. Update `SERVER_URL=https://` in your `.env` - -### Persistence - -By default the docker-compose will create volumes for the Database and local storage of the Server. Note that the containers will not persist data if your server is not configured to be stateful (for example Heroku). You probably want to configure a special stateful resource for this purpose. diff --git a/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx b/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx deleted file mode 100644 index 13b2aff38..000000000 --- a/packages/twenty-docs/docs/start/self-hosting/self-hosting.mdx +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: Self-Hosting -sidebar_position: 1 -sidebar_custom_props: - icon: TbServer ---- - - -import DocCardList from '@theme/DocCardList'; - -import OptionTable from '@site/src/theme/OptionTable' -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - -# Setup Server - - - -# Setup Messaging & Calendar sync - -Twenty offers integrations with Gmail and Google Calendar. To enable these features, you need to connect to register the following recurring jobs: -``` -# from your worker container -yarn command:prod cron:messaging:messages-import -yarn command:prod cron:messaging:message-list-fetch -``` - -# Setup Environment Variables - -## Frontend - - - - -## Backend - -### Config - - - -### Security - - -### Tokens - -', 'Secret used for the access tokens'], - ['ACCESS_TOKEN_EXPIRES_IN', '30m', 'Access token expiration time'], - ['LOGIN_TOKEN_SECRET', '', 'Secret used for the login tokens'], - ['LOGIN_TOKEN_EXPIRES_IN', '15m', 'Login token expiration time'], - ['REFRESH_TOKEN_SECRET', '', 'Secret used for the refresh tokens'], - ['REFRESH_TOKEN_EXPIRES_IN', '90d', 'Refresh token expiration time'], - ['REFRESH_TOKEN_COOL_DOWN', '1m', 'Refresh token cooldown'], - ['FILE_TOKEN_SECRET', '', 'Secret used for the file tokens'], - ['FILE_TOKEN_EXPIRES_IN', '1d', 'File token expiration time'], - ['API_TOKEN_EXPIRES_IN', '1000y', 'Api token expiration time'], - ]}> - -### Auth - - - -### Email - - - -#### Email SMTP Server configuration examples - - - - - - You will need to provision an [App Password](https://support.google.com/accounts/answer/185833). - - EMAIL_SMTP_HOST=smtp.gmail.com - - EMAIL_SMTP_PORT=465 - - EMAIL_SMTP_USER=gmail_email_address - - EMAIL_SMTP_PASSWORD='gmail_app_password' - - - - - - Keep in mind that if you have 2FA enabled, you will need to provision an [App Password](https://support.microsoft.com/en-us/account-billing/manage-app-passwords-for-two-step-verification-d6dc8c6d-4bf7-4851-ad95-6d07799387e9). - - EMAIL_SMTP_HOST=smtp.office365.com - - EMAIL_SMTP_PORT=587 - - EMAIL_SMTP_USER=office365_email_address - - EMAIL_SMTP_PASSWORD='office365_password' - - - - - - **smtp4dev** is a fake SMTP email server for development and testing. - - Run the smtp4dev image: `docker run --rm -it -p 8090:80 -p 2525:25 rnwood/smtp4dev` - - Access the smtp4dev ui here: [http://localhost:8090](http://localhost:8090) - - Set the following env variables: - - EMAIL_SMTP_HOST=localhost - - EMAIL_SMTP_PORT=2525 - - - - - -### Storage - - - -### Message Queue - - - -### Logging - - - - -### Data enrichment and AI - - - - -### Support Chat - -', 'Suport chat key'], - ['SUPPORT_FRONT_CHAT_ID', '', 'Support chat id'], - ]}> - -### Telemetry - - - -### Debug / Development - - - -### Workspace Cleaning - - - -### Captcha - - diff --git a/packages/twenty-docs/docs/start/self-hosting/upgrade-guide.mdx b/packages/twenty-docs/docs/start/self-hosting/upgrade-guide.mdx deleted file mode 100644 index 0afcf554d..000000000 --- a/packages/twenty-docs/docs/start/self-hosting/upgrade-guide.mdx +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Upgrade guide -sidebar_position: 4 -sidebar_class_name: coming-soon -sidebar_custom_props: - icon: TbServer ---- - diff --git a/packages/twenty-docs/docs/ui-components/_category_.json b/packages/twenty-docs/docs/ui-components/_category_.json deleted file mode 100644 index 89ff27960..000000000 --- a/packages/twenty-docs/docs/ui-components/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "UI Components", - "position": 1 -} diff --git a/packages/twenty-docs/docs/ui-components/display/_category_.json b/packages/twenty-docs/docs/ui-components/display/_category_.json deleted file mode 100644 index 02fc981b5..000000000 --- a/packages/twenty-docs/docs/ui-components/display/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "Display", - "position": 1, - "collapsible": true, - "collapsed": false, - "customProps": { - "icon": "TbAppWindow" - } -} diff --git a/packages/twenty-docs/docs/ui-components/display/app-tooltip.mdx b/packages/twenty-docs/docs/ui-components/display/app-tooltip.mdx deleted file mode 100644 index 95636c512..000000000 --- a/packages/twenty-docs/docs/ui-components/display/app-tooltip.mdx +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: App Tooltip -sidebar_position: 6 -sidebar_custom_props: - icon: TbTooltip ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import appTooltipCode from '!!raw-loader!@site/src/ui/display/appTooltipCode.js' -import overflowingTextWithTooltipCode from '!!raw-loader!@site/src/ui/display/overflowingTextWithTooltipCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -A brief message that displays additional information when a user interacts with an element. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional CSS class for additional styling
anchorSelectCSS selectorSelector for the tooltip anchor (the element that triggers the tooltip)
contentstringThe content you want to display within the tooltip
delayHidenumberThe delay in seconds before hiding the tooltip after the cursor leaves the anchor
offsetnumberThe offset in pixels for positioning the tooltip
noArrowbooleanIf `true`, hides the arrow on the tooltip
isOpenbooleanIf `true`, the tooltip is open by default
place`PlacesType` string from `react-tooltip`Specifies the placement of the tooltip. Values include `bottom`, `left`, `right`, `top`, `top-start`, `top-end`, `right-start`, `right-end`, `bottom-start`, `bottom-end`, `left-start`, and `left-end`
positionStrategy`PositionStrategy` string from `react-tooltip`Position strategy for the tooltip. Has two values: `absolute` and `fixed`
- -
- - -
- -## Overflowing Text with Tooltip - -Handles overflowing text and displays a tooltip when the text overflows. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
textstringThe content you want to display in the overflowing text area
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/display/checkmark.mdx b/packages/twenty-docs/docs/ui-components/display/checkmark.mdx deleted file mode 100644 index 621437830..000000000 --- a/packages/twenty-docs/docs/ui-components/display/checkmark.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Checkmark -sidebar_position: 1 -sidebar_custom_props: - icon: TbCheck ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import checkmarkCode from '!!raw-loader!@site/src/ui/display/checkmarkCode.js' -import animatedCheckmarkCode from '!!raw-loader!@site/src/ui/display/animatedCheckmarkCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -Represents a successful or completed action. - - - - - - - - - - -Extends `React.ComponentPropsWithoutRef<'div'>` and accepts all the props of a regular `div` element. - - - - - -## Animated Checkmark - -Represents a checkmark icon with the added feature of animation. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
isAnimatingbooleanControls whether the checkmark is animating`false`
colorstringColor of the checkmarkTheme's gray0
durationnumberThe duration of the animation in seconds0.5 seconds
sizenumberThe size of the checkmark28 pixels
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/display/chip.mdx b/packages/twenty-docs/docs/ui-components/display/chip.mdx deleted file mode 100644 index f8040b915..000000000 --- a/packages/twenty-docs/docs/ui-components/display/chip.mdx +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: Chip -sidebar_position: 2 -sidebar_custom_props: - icon: TbLayoutList ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import chipCode from '!!raw-loader!@site/src/ui/display/chipCode.js' -import entityChipCode from '!!raw-loader!@site/src/ui/display/entityChipCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -A visual element that you can use as a clickable or non-clickable container with a label, optional left and right components, and various styling options to display labels and tags. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
size`ChipSize` enumSpecifies the size of the chip. Has two options: `large` and `small`small
disabledbooleanIndicates whether the chip is disabledfalse
clickablebooleanSpecifies whether the chip is clickabletrue
labelstringRepresents the text content or label inside the chip
maxWidthstringSpecifies the maximum width of the chip200px
variant`ChipVariant` enumSpecifies the visual style or variant of the chip. Has four options: `regular`, `highlighted`, `transparent`, and `rounded`regular
accent`ChipAccent` enumDetermines the text color or accent color of the chip. Has two options: `text-primary` and `text-secondary`text-primary
leftComponent`React.ReactNode`An optional React/node component that you can place on the left side of the chip
rightComponent`React.ReactNode`An optional React/node component that you can place on the right side of the chip
classNamestringAn optional class name to apply additional custom styles to the chip
- -
-
- -## Examples - -### Transparent Disabled Chip - - { - return ( - - ); -}; - -`} -/> - -
- -### Disabled Chip with Tooltip - - { - return ( - - ); -}; - -`} -/> - - - -## Entity Chip - -A Chip-like element to display information about an entity. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
linkToEntitystringThe link to the entity
entityIdstringThe unique identifier for the entity
namestringThe name of the entity
pictureUrlstringThe URL of the entity's picture
avatarTypeAvatar TypeThe type of avatar you want to display. Has two options: `rounded` and `squared`rounded
variant`EntityChipVariant` enumVariant of the entity chip you want to display. Has two options: `regular` and `transparent`regular
LeftIconIconComponentA React component representing an icon. Displayed on the left side of the chip
- - -
-
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/display/icons.mdx b/packages/twenty-docs/docs/ui-components/display/icons.mdx deleted file mode 100644 index 222cf7ab1..000000000 --- a/packages/twenty-docs/docs/ui-components/display/icons.mdx +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: Icons -sidebar_position: 3 -sidebar_custom_props: - icon: TbIcons ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import tablerIconExampleCode from '!!raw-loader!@site/src/ui/display/tablerIconExampleCode.js' -import iconAddressBookCode from '!!raw-loader!@site/src/ui/display/iconAddressBookCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -A list of icons used throughout our app. - -## Tabler Icons - -We use Tabler icons for React throughout the app. - - - - - -``` -yarn add @tabler/icons-react -``` - - - - - -You can import each icon as a component. Here's an example: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
sizenumberThe height and width of the icon in pixels24
colorstringThe color of the iconscurrentColor
strokenumberThe stroke width of the icon in pixels2
- -
- -
- - -## Custom Icons - -In addition to Tabler icons, the app also uses some custom icons. - -### Icon Address Book - -Displays an address book icon. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
sizenumberThe height and width of the icon in pixels24
strokenumberThe stroke width of the icon in pixels2
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/display/soon-pill.mdx b/packages/twenty-docs/docs/ui-components/display/soon-pill.mdx deleted file mode 100644 index 3c8e7febe..000000000 --- a/packages/twenty-docs/docs/ui-components/display/soon-pill.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: Soon Pill -sidebar_position: 4 -sidebar_custom_props: - icon: TbPill ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import soonPillCode from '!!raw-loader!@site/src/ui/display/soonPillCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -A small badge or "pill" to indicate something is coming soon. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
- -
-
- diff --git a/packages/twenty-docs/docs/ui-components/display/tag.mdx b/packages/twenty-docs/docs/ui-components/display/tag.mdx deleted file mode 100644 index 1303b574c..000000000 --- a/packages/twenty-docs/docs/ui-components/display/tag.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Tag -sidebar_position: 5 -sidebar_custom_props: - icon: TbTag ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import tagCode from '!!raw-loader!@site/src/ui/display/tagCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -Component to visually categorize or label content. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional name for additional styling
colorstringColor of the tag. Options include: `green`, `turquoise`, `sky`, `blue`, `purple`, `pink`, `red`, `orange`, `yellow`, `gray`
textstringThe content of the tag
onClickfunctionOptional function called when a user clicks on the tag
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/feedback/_category_.json b/packages/twenty-docs/docs/ui-components/feedback/_category_.json deleted file mode 100644 index bb7023e29..000000000 --- a/packages/twenty-docs/docs/ui-components/feedback/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "Feedback", - "position": 2, - "collapsible": true, - "collapsed": false, - "customProps": { - "icon": "TbForms" - } -} diff --git a/packages/twenty-docs/docs/ui-components/feedback/progress-bar.mdx b/packages/twenty-docs/docs/ui-components/feedback/progress-bar.mdx deleted file mode 100644 index 54ea0e15e..000000000 --- a/packages/twenty-docs/docs/ui-components/feedback/progress-bar.mdx +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Progress Bar -sidebar_position: 1 -sidebar_custom_props: - icon: TbLoader2 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import progressBarCode from '!!raw-loader!@site/src/ui/feedback/progressBarCode.js' -import circularProgressBarCode from '!!raw-loader!@site/src/ui/feedback/circularProgressBarCode.js' -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -Indicates progress or countdown and moves from right to left. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
durationnumberThe total duration of the progress bar animation in milliseconds3
delaynumberThe delay in starting the progress bar animation in milliseconds0
easingstringEasing function for the progress bar animationeaseInOut
barHeightnumberThe height of the bar in pixels24
barColorstringThe color of the bargray80
autoStartbooleanIf `true`, the progress bar animation starts automatically when the component mounts`true`
- -
-
- - -## Circular Progress Bar - -Indicates the progress of a task, often used in loading screens or areas where you want to communicate ongoing processes to the user. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
sizenumberThe size of the circular progress bar50
barWidthnumberThe width of the progress bar line5
barColorstringThe color of the progress barcurrentColor
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/_category_.json b/packages/twenty-docs/docs/ui-components/input/_category_.json deleted file mode 100644 index c354b365b..000000000 --- a/packages/twenty-docs/docs/ui-components/input/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "Input", - "position": 3, - "collapsible": true, - "collapsed": false, - "customProps": { - "icon": "TbInputSearch" - } -} diff --git a/packages/twenty-docs/docs/ui-components/input/block-editor.mdx b/packages/twenty-docs/docs/ui-components/input/block-editor.mdx deleted file mode 100644 index 88a7060e6..000000000 --- a/packages/twenty-docs/docs/ui-components/input/block-editor.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Block Editor -sidebar_position: 11 -sidebar_custom_props: - icon: TbTemplate ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import blockEditorCode from '!!raw-loader!@site/src/ui/input/blockEditorCode.js' - -Uses a block-based rich text editor from [BlockNote](https://www.blocknotejs.org/) to allow users to edit and view blocks of content. - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
editor`BlockNoteEditor`The block editor instance or configuration
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/button.mdx b/packages/twenty-docs/docs/ui-components/input/button.mdx deleted file mode 100644 index 1ab481b08..000000000 --- a/packages/twenty-docs/docs/ui-components/input/button.mdx +++ /dev/null @@ -1,795 +0,0 @@ ---- -title: Buttons -sidebar_position: 1 -sidebar_custom_props: - icon: TbSquareRoundedPlusFilled ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import buttonCode from '!!raw-loader!@site/src/ui/input/button/buttonCode.js' -import buttonGroupCode from '!!raw-loader!@site/src/ui/input/button/buttonGroupCode.js' -import floatingButtonCode from '!!raw-loader!@site/src/ui/input/button/floatingButtonCode.js' -import floatingButtonGroupCode from '!!raw-loader!@site/src/ui/input/button/floatingButtonGroupCode.js' -import floatingIconButtonCode from '!!raw-loader!@site/src/ui/input/button/floatingIconButtonCode.js' -import floatingIconButtonGroupCode from '!!raw-loader!@site/src/ui/input/button/floatingIconButtonGroupCode.js' -import lightButtonCode from '!!raw-loader!@site/src/ui/input/button/lightButtonCode.js' -import lightIconButtonCode from '!!raw-loader!@site/src/ui/input/button/lightIconButtonCode.js' -import mainButtonCode from '!!raw-loader!@site/src/ui/input/button/mainButtonCode.js' -import roundedIconButtonCode from '!!raw-loader!@site/src/ui/input/button/roundedIconButtonCode.js' - -A list of buttons and button groups used throughout the app. - -## Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional class name for additional styling
Icon`React.ComponentType`An optional icon component that's displayed within the button
titlestringThe text content of the button
fullWidthbooleanDefines whether the button should span the whole width of its container`false`
variantstringThe visual style variant of the button. Options include `primary`, `secondary`, and `tertiary`primary
sizestringThe size of the button. Has two options: `small` and `medium`medium
positionstringThe position of the button in relation to its siblings. Options include: `standalone`, `left`, `right`, and `middle`standalone
accentstringThe accent color of the button. Options include: `default`, `blue`, and `danger`default
soonbooleanIndicates if the button is marked as "soon" (such as for upcoming features)`false`
disabledbooleanSpecifies whether button is disabled or not`false`
focusbooleanDetermines if the button has focus`false`
onClickfunctionA callback function that triggers when the user clicks on the button
- -
- -
- -## Button Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
variantstringThe visual style variant of the buttons within the group. Options include `primary`, `secondary`, and `tertiary`
sizestringThe size of the buttons within the group. Has two options: `medium` and `small`
accentstringThe accent color of the buttons within the group. Options include `default`, `blue` and `danger`
classNamestringOptional class name for additional styling
childrenReactNodeAn array of React elements representing the individual buttons within the group
- -
- -
- - -## Floating Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional name for additional styling
Icon`React.ComponentType`An optional icon component that's displayed within the button
titlestringThe text content of the button
sizestringThe size of the button. Has two options: `small` and `medium`small
positionstringThe position of the button in relation to its sublings. Options include: `standalone`, `left`, `middle`, `right`
applyShadowbooleanDetermines whether to apply shadow to a button`true`
applyBlurbooleanDetermines whether to apply a blur effect to the button`true`
disabledbooleanDetermines whether the button is disabled`false`
focusbooleanIndicates if the button has focus`false`
- -
- -
- -## Floating Button Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
sizestringThe size of the button. Has two options: `small` and `medium`small
childrenReactNodeAn array of React elements representing the individual buttons within the group
- -
- -
- -## Floating Icon Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional name for additional styling
Icon`React.ComponentType`An optional icon component that's displayed within the button
sizestringThe size of the button. Has two options: `small` and `medium`small
positionstringThe position of the button in relation to its siblings. Options include: `standalone`, `left`, `right`, and `middle`standalone
applyShadowbooleanDetermines whether to apply shadow to a button`true`
applyBlurbooleanDetermines whether to apply a blur effect to the button`true`
disabledbooleanDetermines whether the button is disabled`false`
focusbooleanIndicates if the button has focus`false`
onClickfunctionA callback function that triggers when the user clicks on the button
isActivebooleanDetermines if the button is in an active state
- -
- -
- -## Floating Icon Button Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional name for additional styling
sizestringThe size of the button. Has two options: `small` and `medium`
iconButtonsarrayAn array of objects, each representing an icon button in the group. Each object should include the icon component you want to display in the button, the function you want to call when a user clicks on the button, and whether the button should be active or not.
- -
- -
- -## Light Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional name for additional styling
icon`React.ReactNode`The icon you want to display in the button
titlestringThe text content of the button
accentstringThe accent color of the button. Options include: `secondary` and `tertiary`secondary
activebooleanDetermines if the button is in an active state`false`
disabledbooleanDetermines whether the button is disabled`false`
focusbooleanIndicates if the button has focus`false`
onClickfunctionA callback function that triggers when the user clicks on the button
- -
- -
- -## Light Icon Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional name for additional styling
testIdstringTest identifier for the button
Icon`React.ComponentType`An optional icon component that's displayed within the button
titlestringThe text content of the button
sizestringThe size of the button. Has two options: `small` and `medium`small
accentstringThe accent color of the button. Options include: `secondary` and `tertiary`secondary
activebooleanDetermines if the button is in an active state`false`
disabledbooleanDetermines whether the button is disabled`false`
focusbooleanIndicates if the button has focus`false`
onClickfunctionA callback function that triggers when the user clicks on the button
- -
- -
- -## Main Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
titlestringThe text content of the button
fullWidthbooleanefines whether the button should span the whole width of its container`false`
variantstringThe visual style variant of the button. Options include `primary` and `secondary`primary
soonbooleanIndicates if the button is marked as "soon" (such as for upcoming features)`false`
Icon`React.ComponentType`An optional icon component that's displayed within the button
React `button` props`React.ComponentProps<'button'>`Additional props from React's `button` element
- -
- -
- -## Rounded Icon Button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
Icon`React.ComponentType`An optional icon component that's displayed within the button
React `button` props`React.ButtonHTMLAttributes`Additional props from React's `button` element
-
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/checkbox.mdx b/packages/twenty-docs/docs/ui-components/input/checkbox.mdx deleted file mode 100644 index f3783f446..000000000 --- a/packages/twenty-docs/docs/ui-components/input/checkbox.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Checkbox -sidebar_position: 4 -sidebar_custom_props: - icon: TbCheckbox ---- - - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import checkboxCode from '!!raw-loader!@site/src/ui/input/components/checkboxCode.js' - -Used when a user needs to select multiple values from several options. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
checkedbooleanIndicates whether the checkbox is checked
indeterminatebooleanIndicates whether the checkbox is in an indeterminate state (neither checked nor unchecked)
onChangefunctionThe callback function you want to trigger when the checkbox state changes
onCheckedChangefunctionThe callback function you want to trigger when the `checked` state changes
variantstringThe visual style variant of the box. Options include: `primary`, `secondary`, and `tertiary`primary
sizestringThe size of the checkbox. Has two options: `small` and `large`small
shapestringThe shape of the checkbox. Has two options: `squared` and `rounded`squared
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/color-scheme.mdx b/packages/twenty-docs/docs/ui-components/input/color-scheme.mdx deleted file mode 100644 index 5f7e424ae..000000000 --- a/packages/twenty-docs/docs/ui-components/input/color-scheme.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Color Scheme -sidebar_position: 2 -sidebar_custom_props: - icon: TbColorFilter ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import colorSchemeCardCode from '!!raw-loader!@site/src/ui/input/color-scheme/colorSchemeCardCode.js' -import colorSchemePickerCode from '!!raw-loader!@site/src/ui/input/color-scheme/colorSchemePickerCode.js' - -import { SandpackEditor} from '@site/src/ui/SandpackEditor' - -## Color Scheme Card - -Represents different color schemes and is specially tailored for light and dark themes. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
variantstringThe color scheme variant. Options include `Dark`, `Light`, and `System`light
selectedbooleanIf `true`, displays a checkmark to indicate the selected color scheme
additional props`React.ComponentPropsWithoutRef<'div'>`Standard HTML `div` element props
- -
- -
- -## Color Scheme Picker - -Allows users to choose between different color schemes. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
value`Color Scheme`The currently selected color scheme
onChangefunctionThe callback function you want to trigger when a user selects a color scheme
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/icon-picker.mdx b/packages/twenty-docs/docs/ui-components/input/icon-picker.mdx deleted file mode 100644 index 379a83dee..000000000 --- a/packages/twenty-docs/docs/ui-components/input/icon-picker.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Icon Picker -sidebar_position: 5 -sidebar_custom_props: - icon: TbColorPicker ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import iconPickerCode from '!!raw-loader!@site/src/ui/input/components/iconPickerCode.js' - -A dropdown-based icon picker that allows users to select an icon from a list. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
disabledbooleanDisables the icon picker if set to `true`
onChangefunctionThe callback function triggered when the user selects an icon. It receives an object with `iconKey` and `Icon` properties
selectedIconKeystringThe key of the initially selected icon
onClickOutsidefunctionCallback function triggered when the user clicks outside the dropdown
onClosefunctionCallback function triggered when the dropdown is closed
onOpenfunctionCallback function triggered when the dropdown is opened
variantstringThe visual style variant of the clickable icon. Options include: `primary`, `secondary`, and `tertiary`secondary
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/image-input.mdx b/packages/twenty-docs/docs/ui-components/input/image-input.mdx deleted file mode 100644 index 8c2a93a00..000000000 --- a/packages/twenty-docs/docs/ui-components/input/image-input.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Image Input -sidebar_position: 6 -sidebar_custom_props: - icon: TbUpload ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import imageInputCode from '!!raw-loader!@site/src/ui/input/components/imageInputCode.js' - -Allows users to upload and remove an image. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
picturestringThe image source URL
onUploadfunctionThe function called when a user uploads a new image. It receives the `File` object as a parameter
onRemovefunctionThe function called when the user clicks on the remove button
onAbortfunctionThe function called when a user clicks on the abort button during image upload
isUploadingbooleanIndicates whether an image is currently being uploaded`false`
errorMessagestringAn optional error message to display below the image input
disabledbooleanIf `true`, the entire input is disabled, and the buttons are not clickable`false`
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/radio.mdx b/packages/twenty-docs/docs/ui-components/input/radio.mdx deleted file mode 100644 index 9cca67f83..000000000 --- a/packages/twenty-docs/docs/ui-components/input/radio.mdx +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: Radio -sidebar_position: 7 -sidebar_custom_props: - icon: TbCircleDot ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import radioCode from '!!raw-loader!@site/src/ui/input/components/radioCode.js' -import radioGroupCode from '!!raw-loader!@site/src/ui/input/components/radioGroupCode.js' - -Used when users may only choose one option from a series of options. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
style`React.CSS` propertiesAdditional inline styles for the component
classNamestringOptional CSS class for additional styling
checkedbooleanIndicates whether the radio button is checked
valuestringThe label or text associated with the radio button
onChangefunctionThe function called when the selected radio button is changed
onCheckedChangefunctionThe function called when the `checked` state of the radio button changes
sizestringThe size of the radio button. Options include: `large` and `small`small
disabledbooleanIf `true`, the radio button is disabled and not clickablefalse
labelPositionstringThe position of the label text relative to the radio button. Has two options: `left` and `right`right
- -
- -
- -## Radio Group - -Groups together related radio buttons. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
valuestringThe value of the currently selected radio button
onChangefunctionThe callback function triggered when the radio button is changed
onValueChangefunctionThe callback function triggered when the selected value in the group changes.
children`React.ReactNode`Allows you to pass React components (such as Radio) as children to the Radio Group
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/select.mdx b/packages/twenty-docs/docs/ui-components/input/select.mdx deleted file mode 100644 index ef83cbb81..000000000 --- a/packages/twenty-docs/docs/ui-components/input/select.mdx +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Select -sidebar_position: 8 -sidebar_custom_props: - icon: TbSelect ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import selectCode from '!!raw-loader!@site/src/ui/input/components/selectCode.js' - -Allows users to pick a value from a list of predefined options. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional CSS class for additional styling
disabledbooleanWhen set to `true`, disables user interaction with the component
dropdownScopeIdstringRequired prop that uniquely identifies the dropdown scope
labelstringThe label to describe the purpose of the `Select` component
onChangefunctionThe function called when the selected values change
optionsarrayRepresents the options available for the `Selected` component. It's an array of objects where each object has a `value` (the unique identifier), `label` (the unique identifier), and an optional `Icon`
valuestringRepresents the currently selected value. It should match one of the `value` properties in the `options` array
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/text.mdx b/packages/twenty-docs/docs/ui-components/input/text.mdx deleted file mode 100644 index 91812f4b1..000000000 --- a/packages/twenty-docs/docs/ui-components/input/text.mdx +++ /dev/null @@ -1,322 +0,0 @@ ---- -title: Text -sidebar_position: 3 -sidebar_custom_props: - icon: TbTextSize ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import textInputCode from '!!raw-loader!@site/src/ui/input/components/textInputCode.js' -import autosizeTextInputCode from '!!raw-loader!@site/src/ui/input/components/autosizeTextInputCode.js' -import entityTitleDoubleTextInputCode from '!!raw-loader!@site/src/ui/input/components/entityTitleDoubleTextInputCode.js' -import textAreaCode from '!!raw-loader!@site/src/ui/input/components/textAreaCode.js' - -## Text Input - -Allows users to enter and edit text. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
classNamestringOptional name for additional styling
labelstringRepresents the label for the input
onChangefunctionThe function called when the input value changes
fullWidthbooleanIndicates whether the input should take up 100% of the width
disableHotkeysbooleanIndicates whether hotkeys are enabled for the input`false`
errorstringRepresents the error message to be displayed. When provided, it also adds an icon error on the right side of the input
onKeyDownfunctionCalled when a key is pressed down while the input field is focused. Receives a `React.KeyboardEvent` as an argument
RightIconIconComponentAn optional icon component displayed on the right side of the input
- -The component also accepts other HTML input element props. - -
- -
- - -## Autosize Text Input - -Text input component that automatically adjusts its height based on the content. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
onValidatefunctionThe callback function you want to trigger when the user validates the input
minRowsnumberThe minimum number of rows for the text area1
placeholderstringThe placeholder text you want to display when the text area is empty
onFocusfunctionThe callback function you want to trigger when the text area gains focus
variantstringThe variant of the input. Options include: `default`, `icon`, and `button`default
buttonTitlestringThe title for the button (only applicable for the button variant)
valuestringThe initial value for the text areaEmpty string
- -
- -
- - -## Entity Title Double Text Input - -Displays a pair of text inputs side by side, allowing the user to edit two related values simultaneously. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
firstValuestringThe value for the first text input
secondValuestringThe value for the second text input
firstValuePlaceholderstringPlaceholder text for the first text input, displayed when the input is empty
secondValuePlaceholderstringPlaceholder text for the second text input, displayed when the input is empty
onChangefunctionThe callback function you want to trigger when the text input changes
- -
-
- -## Text Area - -Allows you to create multi-line text inputs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
disabledbooleanIndicates whether the text area is disabled
minRowsnumberMinimum number of visible rows for the text area. 1
onChangefunctionCallback function triggered when the text area content changes
placeholderstringPlaceholder text displayed when the text area is empty
valuestringThe current value of the text areaEmpty string
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/input/toggle.mdx b/packages/twenty-docs/docs/ui-components/input/toggle.mdx deleted file mode 100644 index 4d93dd35b..000000000 --- a/packages/twenty-docs/docs/ui-components/input/toggle.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Toggle -sidebar_position: 10 -sidebar_custom_props: - icon: TbToggleRight ---- - - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import toggleCode from '!!raw-loader!@site/src/ui/input/components/toggleCode.js' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
valuebooleanThe current state of the toggle`false`
onChangefunctionCallback function triggered when the toggle state changes
colorstringColor of the toggle when it's in the "on" state. If not provided, it uses the theme's blue color
toggleSizestringSize of the toggle, affecting both height and weight. Has two options: `small` and `medium`medium
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/navigation/_category_.json b/packages/twenty-docs/docs/ui-components/navigation/_category_.json deleted file mode 100644 index f02c4767a..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/_category_.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "label": "Navigation", - "position": 4, - "collapsible": true, - "collapsed": false, - "customProps": { - "icon": "TbNavigation" - } -} diff --git a/packages/twenty-docs/docs/ui-components/navigation/bread-crumb.mdx b/packages/twenty-docs/docs/ui-components/navigation/bread-crumb.mdx deleted file mode 100644 index 14265e356..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/bread-crumb.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Breadcrumb -sidebar_position: 1 -sidebar_custom_props: - icon: TbSquareChevronsRight ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import breadcrumbCode from '!!raw-loader!@site/src/ui/navigation/breadcrumbCode.js' - -Renders a breadcrumb navigation bar. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional class name for additional styling
linksarrayAn array of objects, each representing a breadcrumb link. Each object has a `children` property (the text content of the link) and an optional `href` property (the URL to navigate to when the link is clicked)
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/navigation/link.mdx b/packages/twenty-docs/docs/ui-components/navigation/link.mdx deleted file mode 100644 index 08260e436..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/link.mdx +++ /dev/null @@ -1,237 +0,0 @@ ---- -title: Links -sidebar_position: 2 -sidebar_custom_props: - icon: TbLink ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import contactLinkCode from '!!raw-loader!@site/src/ui/navigation/link/contactLinkCode.js' -import rawLinkCode from '!!raw-loader!@site/src/ui/navigation/link/rawLinkCode.js' -import roundedLinkCode from '!!raw-loader!@site/src/ui/navigation/link/roundedLinkCode.js' -import socialLinkCode from '!!raw-loader!@site/src/ui/navigation/link/socialLinkCode.js' - - -## Contact Link - -A stylized link component for displaying contact information. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional name for additional styling
hrefstringThe target URL or path for the link
onClickfunctionCallback function to be triggered when the link is clicked
children`React.ReactNode`The content to be displayed inside the link
- -
- -
- -## Raw Link - -A stylized link component for displaying links. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
classNamestringOptional name for additional styling
hrefstringThe target URL or path for the link
onClickfunctionCallback function to be triggered when the link is clicked
children`React.ReactNode`The content to be displayed inside the link
- -
- -
- -## Rounded Link - -A rounded-styled link with a Chip component for links. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
hrefstringThe target URL or path for the link
children`React.ReactNode`The content to be displayed inside the link
onClickfunctionCallback function to be triggered when the link is clicked
- -
- -
- -## Social Link - -Stylized social links, with support for various social link types, such as URLs, LinkedIn, and X (or Twitter). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
hrefstringThe target URL or path for the link
children`React.ReactNode`The content to be displayed inside the link
typestringThe type of social links. Options include: `url`, `LinkedIn`, and `Twitter`
onClickfunctionCallback function to be triggered when the link is clicked
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/navigation/menu-item.mdx b/packages/twenty-docs/docs/ui-components/navigation/menu-item.mdx deleted file mode 100644 index 4a1de7906..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/menu-item.mdx +++ /dev/null @@ -1,768 +0,0 @@ ---- -title: Menu Item -sidebar_position: 3 -sidebar_custom_props: - icon: TbMenu ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import menuItemCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemCode.js' -import menuItemCommandCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemCommandCode.js' -import menuItemDraggableCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemDraggableCode.js' -import menuItemMultiSelectAvatarCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemMultiSelectAvatarCode.js' -import menuItemMultiSelectCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemMultiSelectCode.js' -import menuItemNavigateCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemNavigateCode.js' -import menuItemSelectAvatarCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemSelectAvatarCode.js' -import menuItemSelectCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemSelectCode.js' -import menuItemSelectColorCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemSelectColorCode.js' -import menuItemToggleCode from '!!raw-loader!@site/src/ui/navigation/menu-item/menuItemToggleCode.js' - -A versatile menu item designed to be used in a menu or navigation list. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
accentstringSpecifies the accent color of the menu item. Options include: `default`, `danger`, and `placeholder`default
textstringThe text content of the menu item
iconButtonsarrayAn array of objects representing additional icon buttons associated with the menu item
isTooltipOpenbooleanControls the visibility of the tooltip associated with the menu item
testIdstringThe data-testid attribute for testing purposes
onClickfunctionCallback function triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -## Variants - -The different variants of the menu item component include the following: - -### Command - -A command-style menu item within a menu to indicate keyboard shortcuts. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
textstringThe text content of the menu item
firstHotKeystringThe first keyboard shortcut associated with the command
secondHotKeystringThe second keyboard shortcut associated with the command
isSelectedbooleanIndicates whether the menu item is selected or highlighted
onClickfunctionCallback function triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -### Draggable - -A draggable menu item component designed to be used in a menu or list where items can be dragged, and additional actions can be performed through icon buttons. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
accentstringThe accent color of the menu item. It can either be `default`, `placeholder`, and `danger`default
iconButtonsarrayAn array of objects representing additional icon buttons associated with the menu item
isTooltipOpenbooleanControls the visibility of the tooltip associated with the menu item
onClickfunctionCallback function to be triggered when the link is clicked
textstringThe text content of the menu item
isDragDisabledbooleanIndicates whether dragging is disabled`false`
classNamestringOptional name for additional styling
- -
- -
- -### Multi Select - -Provides a way to implement multi-select functionality with an associated checkbox. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
textstringThe text content of the menu item
selectedbooleanIndicates whether the menu item is selected (checked)
onSelectChangefunctionCallback function triggered when the checkbox state changes
classNamestringOptional name for additional styling
- -
- -
- -### Multi Select Avatar - -A multi-select menu item with an avatar, a checkbox for selection, and textual content. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
avatar`ReactNode`The avatar or icon to be displayed on the left side of the menu item
textstringThe text content of the menu item
selectedbooleanIndicates whether the menu item is selected (checked)
onSelectChangefunctionCallback function triggered when the checkbox state changes
classNamestringOptional name for additional styling
- -
- -
- -### Navigate - -A menu item featuring an optional left icon, textual content, and a right-chevron icon. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
textstringThe text content of the menu item
onClickfunctionCallback function to be triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -### Select - -A selectable menu item, featuring optional left content (icon and text) and an indicator (check icon) for the selected state. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
textstringThe text content of the menu item
selectedbooleanIndicates whether the menu item is selected (checked)
disabledbooleanIndicates whether the menu item is disabled
hoveredbooleanIndicates whether the menu item is currently being hovered over
onClickfunctionCallback function to be triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -### Select Avatar - -A selectable menu item with an avatar, featuring optional left content (avatar and text) and an indicator (check icon) for the selected state. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
avatar`ReactNode`The avatar or icon to be displayed on the left side of the menu item
textstringThe text content of the menu item
selectedbooleanIndicates whether the menu item is selected (checked)
disabledbooleanIndicates whether the menu item is disabled
hoveredbooleanIndicates whether the menu item is currently being hovered over
testIdstringThe data-testid attribute for testing purposes
onClickfunctionCallback function to be triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -### Select Color - -A selectable menu item with a color sample for scenarios where you want users to choose a color from a menu. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescriptionDefault
colorstringThe theme color to be displayed as a sample in the menu item. Options include: `green`, `turquoise`, `sky`, `blue`, `purple`, `pink`, `red`, `orange`, `yellow`, and `gray`
selectedbooleanIndicates whether the menu item is selected (checked)
disabledbooleanIndicates whether the menu item is disabled
hoveredbooleanIndicates whether the menu item is currently being hovered over
variantstringThe variant of the color sample. It can either be `default` or `pipeline`default
onClickfunctionCallback function to be triggered when the menu item is clicked
classNamestringOptional name for additional styling
- -
- -
- -### Toggle - -A menu item with an associated toggle switch to allow users to enable or disable a specific feature - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
LeftIconIconComponentAn optional left icon displayed before the text in the menu item
textstringThe text content of the menu item
toggledbooleanIndicates whether the toggle switch is in the "on" or "off" state
onToggleChangefunctionCallback function triggered when the toggle switch state changes
toggleSizestringThe size of the toggle switch. It can be either 'small' or 'medium'
classNamestringOptional name for additional styling
- -
- -
diff --git a/packages/twenty-docs/docs/ui-components/navigation/navigation-bar.mdx b/packages/twenty-docs/docs/ui-components/navigation/navigation-bar.mdx deleted file mode 100644 index 2e2e98d98..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/navigation-bar.mdx +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Navigation Bar -sidebar_position: 4 -sidebar_custom_props: - icon: TbRectangle ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import navBarCode from '!!raw-loader!@site/src/ui/navigation/navBarCode.js' - -Renders a navigation bar that contains multiple `NavigationBarItem` components. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
activeItemNamestringThe name of the currently active navigation item
itemsarrayAn array of objects representing each navigation item. Each object contains the `name` of the item, the `Icon` component to display, and an `onClick` function to be called when the item is clicked
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/navigation/step-bar.mdx b/packages/twenty-docs/docs/ui-components/navigation/step-bar.mdx deleted file mode 100644 index 9af8838e2..000000000 --- a/packages/twenty-docs/docs/ui-components/navigation/step-bar.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Step Bar -sidebar_position: 5 -sidebar_custom_props: - icon: TbCircleCheckFilled ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import { SandpackEditor} from '@site/src/ui/SandpackEditor' -import stepBarCode from '!!raw-loader!@site/src/ui/navigation/stepBarCode.js' - -Displays progress through a sequence of numbered steps by highlighting the active step. It renders a container with steps, each represented by the `Step` component. - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropsTypeDescription
activeStepnumberThe index of the currently active step. This determines which step should be visually highlighted
- -
- -
\ No newline at end of file diff --git a/packages/twenty-docs/docs/ui-components/ui-components.mdx b/packages/twenty-docs/docs/ui-components/ui-components.mdx deleted file mode 100644 index ebc75f8af..000000000 --- a/packages/twenty-docs/docs/ui-components/ui-components.mdx +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: UI Components -sidebar_position: 0 -displayed_sidebar: uiDocsSidebar -sidebar_custom_props: - isSidebarRoot: true - icon: TbLayoutGrid ---- diff --git a/packages/twenty-docs/docusaurus.config.js b/packages/twenty-docs/docusaurus.config.js deleted file mode 100644 index 0f9aaef17..000000000 --- a/packages/twenty-docs/docusaurus.config.js +++ /dev/null @@ -1,145 +0,0 @@ -// @ts-check -// Note: type annotations allow type checking and IDEs autocompletion - -import { themes } from 'prism-react-renderer'; - -const lightCodeTheme = themes.github; -const darkCodeTheme = themes.dracula; - -const filterOutCategory = (items, categoryNameToExclude) => { - return items.reduce((filteredItems, item) => { - if (item.type === 'category' && item.label === categoryNameToExclude) { - // Skip adding the item if the category should be excluded - return filteredItems; - } else if (item.type === 'category') { - // Recursively filter sub-categories - return filteredItems.concat({ - ...item, - items: filterOutCategory(item.items, categoryNameToExclude), - }); - } else { - // Include the item if it's not a category to be excluded - return filteredItems.concat(item); - } - }, []); -}; - -/** @type {import('@docusaurus/types').Config} */ -const config = { - title: 'Twenty - Documentation', - tagline: 'Twenty is cool', - favicon: 'img/logo-square-dark.ico', - - // Prevent search engines from indexing the doc for selected environments - noIndex: process.env.SHOULD_INDEX_DOC === 'false', - - // Set the production url of your site here - url: 'https://docs.twenty.com', - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' - baseUrl: '/', - onBrokenLinks: 'throw', - onBrokenMarkdownLinks: 'warn', - - headTags: [], - - // Even if you don't use internalization, you can use this field to set useful - // metadata like html lang. For example, if your site is Chinese, you may want - // to replace "en" with "zh-Hans". - i18n: { - defaultLocale: 'en', - locales: ['en'], - }, - plugins: ['docusaurus-node-polyfills'], - presets: [ - [ - 'classic', - /** @type {import('@docusaurus/preset-classic').Options} */ - ({ - docs: { - breadcrumbs: false, - sidebarPath: require.resolve('./sidebars.js'), - sidebarCollapsible: false, - routeBasePath: '/', - editUrl: - 'https://github.com/twentyhq/twenty/tree/main/packages/twenty-docs', - sidebarItemsGenerator: async ({ - defaultSidebarItemsGenerator, - ...args - }) => { - const sidebarItems = await defaultSidebarItemsGenerator(args); - - return filterOutCategory(sidebarItems, 'UI Components'); - }, - }, - blog: false, - theme: { - customCss: require.resolve('./src/css/custom.css'), - }, - }), - ], - ], - - themeConfig: - /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ - ({ - // Replace with your project's social card - image: 'img/social-card.png', - colorMode: { - defaultMode: 'light', - respectPrefersColorScheme: false, - }, - docs: { - sidebar: { - autoCollapseCategories: true, - }, - }, - navbar: { - title: 'for Developers', - logo: { - alt: 'Twenty', - src: 'img/logo-square-dark.svg', - srcDark: 'img/logo-square-light.svg', - }, - items: [ - /*{ - to: 'https://github.com/twentyhq/twenty/releases', - label: 'Releases', - position: 'right', - },*/ - { - type: 'custom-github-link', - position: 'right', - }, - ], - }, - algolia: { - appId: 'J2OX2P2QAO', - apiKey: 'e3de1c1c0b50bd5ea3ffa1ee7ea3f56d', - indexName: 'twenty-developer-docs', - - // Optional: see doc section below - contextualSearch: true, - // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them. - // externalUrlRegex: 'external\\.com|domain\\.com', - // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs - /* replaceSearchResultPathname: { - from: '/docs/', // or as RegExp: /\/docs\// - to: '/', - },*/ - // Optional: Algolia search parameters - searchParameters: {}, - // Optional: path for search page that enabled by default (`false` to disable it) - searchPagePath: 'search', - }, - /* footer: { - copyright: `© ${new Date().getFullYear()} Twenty. Docs generated with Docusaurus.`, - },*/ - prism: { - theme: lightCodeTheme, - darkTheme: darkCodeTheme, - }, - }), -}; - -module.exports = config; diff --git a/packages/twenty-docs/package.json b/packages/twenty-docs/package.json deleted file mode 100644 index 0c63bac10..000000000 --- a/packages/twenty-docs/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "twenty-docs", - "version": "0.12.2", - "private": true, - "scripts": { - "nx": "NX_DEFAULT_PROJECT=twenty-docs node ../../node_modules/nx/bin/nx.js", - "docusaurus": "npx docusaurus", - "start": "npx docusaurus start --host 0.0.0.0 --port 5001", - "build": "npx docusaurus build", - "swizzle": "npx docusaurus swizzle", - "deploy": "npx docusaurus deploy", - "clear": "npx docusaurus clear", - "serve": "npx docusaurus serve", - "write-translations": "npx docusaurus write-translations", - "write-heading-ids": "npx docusaurus write-heading-ids", - "typecheck": "npx tsc" - }, - "overrides": { - "trim": "^0.0.3", - "got": "^11.8.5" - }, - "browserslist": { - "production": [ - ">0.5%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "engines": { - "node": ">=16.14" - } -} diff --git a/packages/twenty-docs/sidebars.js b/packages/twenty-docs/sidebars.js deleted file mode 100644 index 2a6ec4fa1..000000000 --- a/packages/twenty-docs/sidebars.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ - -// @ts-check - -const backToHomeLink = { - /** @type {"ref"} */ - type: 'ref', - id: 'homepage', - label: 'Back to home', - className: 'menu__list-item--home', - customProps: { - icon: 'TbArrowBackUp', - iconSize: 20, - }, -}; - -/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ -const sidebars = { - docsSidebar: [ - { - type: 'doc', - id: 'homepage', - customProps: { - type: 'search-bar', - }, - }, - { type: 'autogenerated', dirName: '.' }, - { - type: 'category', - label: 'Extending', - items: [ - { - type: 'category', - label: 'Rest APIs', - collapsible: true, - collapsed: true, - customProps: { - icon: 'TbApi', - }, - items: [ - { - type: 'link', - label: 'Core API', - href: '/rest-api/core', - }, - { - type: 'link', - label: 'Metadata API', - href: '/rest-api/metadata', - }, - ], - }, - { - type: 'category', - label: 'GraphQL APIs', - collapsible: true, - collapsed: true, - customProps: { - icon: 'TbBrandGraphql', - }, - items: [ - { - type: 'link', - label: 'Core API', - href: '/graphql/core', - }, - { - type: 'link', - label: 'Metadata API', - href: '/graphql/metadata', - }, - ], - }, - { - type: 'category', - label: 'UI Kit', - collapsible: true, - collapsed: true, - customProps: { - icon: 'TbComponents', - }, - items: [ - { - type: 'link', - label: 'Storybook', - href: 'https://storybook.twenty.com', - }, - { - type: 'link', - label: 'Components', - href: '/ui-components/', - }, - ], - }, - ], - }, - ], - uiDocsSidebar: [{ type: 'autogenerated', dirName: 'ui-components' }], -}; - -module.exports = sidebars; diff --git a/packages/twenty-docs/src/components/graphql-playground.tsx b/packages/twenty-docs/src/components/graphql-playground.tsx deleted file mode 100644 index 3c2e333d4..000000000 --- a/packages/twenty-docs/src/components/graphql-playground.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { explorerPlugin } from '@graphiql/plugin-explorer'; -import { Theme, useTheme } from '@graphiql/react'; -import { createGraphiQLFetcher } from '@graphiql/toolkit'; -import { SubDoc } from '@site/src/components/token-form'; -import Layout from '@theme/Layout'; -import { GraphiQL } from 'graphiql'; - -import Playground from './playground'; - -import explorerCss from '!css-loader!@graphiql/plugin-explorer/dist/style.css'; -import graphiqlCss from '!css-loader!graphiql/graphiql.css'; - -const SubDocToPath = { - core: 'graphql', - metadata: 'metadata', -}; - -// Docusaurus does SSR for custom pages, but we need to load GraphiQL in the browser -const GraphQlComponent = ({ token, baseUrl, path }) => { - const explorer = explorerPlugin({ - showAttribution: true, - }); - - const fetcher = createGraphiQLFetcher({ - url: baseUrl + '/' + path, - }); - - // We load graphiql style using useEffect as it breaks remaining docs style - useEffect(() => { - const createAndAppendStyle = (css) => { - const styleElement = document.createElement('style'); - styleElement.innerHTML = css.toString(); - document.head.append(styleElement); - return styleElement; - }; - - const styleElement1 = createAndAppendStyle(graphiqlCss); - const styleElement2 = createAndAppendStyle(explorerCss); - - return () => { - styleElement1.remove(); - styleElement2.remove(); - }; - }, []); - - if (!baseUrl || !token) { - return <>; - } - - return ( -
- -
- ); -}; - -const GraphQlPlayground = ({ subDoc }: { subDoc: SubDoc }) => { - const [token, setToken] = useState(); - const [baseUrl, setBaseUrl] = useState(); - const { setTheme } = useTheme(); - - useEffect(() => { - window.localStorage.setItem( - 'graphiql:theme', - window.localStorage.getItem('theme') || 'light', - ); - - const handleThemeChange = (ev) => { - if (ev.key === 'theme') { - setTheme(ev.newValue as Theme); - } - }; - - window.addEventListener('storage', handleThemeChange); - - return () => window.removeEventListener('storage', handleThemeChange); - }, []); - - const children = ( - - ); - - return ( - - - {() => ( - - )} - - - ); -}; -export default GraphQlPlayground; diff --git a/packages/twenty-docs/src/components/playground.tsx b/packages/twenty-docs/src/components/playground.tsx deleted file mode 100644 index af96e2c19..000000000 --- a/packages/twenty-docs/src/components/playground.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState } from 'react'; -import { TbLoader2 } from 'react-icons/tb'; - -import TokenForm, { TokenFormProps } from '../components/token-form'; - -const Playground = ({ - children, - setOpenApiJson, - setToken, - setBaseUrl, - subDoc, -}: Partial & - Omit< - TokenFormProps, - 'isTokenValid' | 'setIsTokenValid' | 'setLoadingState' - >) => { - const [isTokenValid, setIsTokenValid] = useState(false); - const [isLoading, setIsLoading] = useState(false); - return ( -
- - {!isTokenValid && ( -
-
- A token is required as APIs are dynamically generated for each - workspace based on their unique metadata.
Generate your token - under{' '} - - Settings > Developers - -
- {isLoading && ( -
- -
- )} -
- )} - {children} -
- ); -}; - -export default Playground; diff --git a/packages/twenty-docs/src/components/token-form.css b/packages/twenty-docs/src/components/token-form.css deleted file mode 100644 index 48016ae3e..000000000 --- a/packages/twenty-docs/src/components/token-form.css +++ /dev/null @@ -1,146 +0,0 @@ -.form-container { - height: 45px; - overflow: hidden; - border-bottom: 1px solid var(--ifm-color-secondary-light); - position: sticky; - top: var(--ifm-navbar-height); - padding: 0px 8px; - background: var(--ifm-color-secondary-contrast-background); - z-index: 2; - display: flex; -} - -.form { - display: flex; - height: 45px; - gap: 10px; - width: 50%; - margin-left: auto; - flex: 0.7; -} - -.link { - color: white; - text-decoration: underline; - position: relative; - font-weight: bold; - transition: color 0.3s ease; - - &:hover { - color: #ddd; - } -} - -.input { - padding: 6px; - margin: 5px 0 5px 0; - max-width: 460px; - width: 100%; - box-sizing: border-box; - background-color: #f3f3f3; - border: 1px solid #ddd; - border-radius: 4px; - padding-left:30px; - height: 32px; -} - -.input[disabled] { - color: rgb(153, 153, 153) -} - -[data-theme='dark'] .input { - background-color: #16233f; -} - -.inputWrapper { - display: flex; - align-items: center; - flex: 1; - position: relative; -} - -.inputIcon { - display: flex; - align-items: center; - position: absolute; - top: 0; - height: 100%; - padding: 5px; - color: #B3B3B3; -} - -[data-theme='dark'] .inputIcon { - color: white; -} - -.select { - padding: 6px; - margin: 5px 0 5px 0; - max-width: 460px; - width: 100%; - box-sizing: border-box; - background-color: #f3f3f3; - border: 1px solid #ddd; - border-radius: 4px; - height: 32px; - flex: 1; -} - -[data-theme='dark'] .select { - background-color: #16233f; -} - - -.invalid { - border: 1px solid #f83e3e; -} - -.token-invalid { - color: #f83e3e; - font-size: 12px; -} - -.not-visible { - visibility: hidden; -} - -.loader { - color: #16233f; - font-size: 2rem; - animation: animate 2s infinite; -} - -[data-theme='dark'] .loader { - color: #a3c0f8; -} - -@keyframes animate { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(720deg); - } -} - -.loader-container { - display: flex; - justify-content: center; - align-items: center; - height: 50px; -} - - -.backButton { - position: absolute; - display: flex; - left: 8px; - height: 100%; - align-items: center; - cursor: pointer; - color: #999999; - - &:hover { - color: #16233f; - } -} \ No newline at end of file diff --git a/packages/twenty-docs/src/components/token-form.tsx b/packages/twenty-docs/src/components/token-form.tsx deleted file mode 100644 index 1b333ac82..000000000 --- a/packages/twenty-docs/src/components/token-form.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { TbApi, TbChevronLeft, TbLink } from 'react-icons/tb'; -import { useHistory, useLocation } from '@docusaurus/router'; -import { parseJson } from 'nx/src/utils/json'; - -import tokenForm from '!css-loader!./token-form.css'; - -export type SubDoc = 'core' | 'metadata'; -export type TokenFormProps = { - setOpenApiJson?: (json: object) => void; - setToken?: (token: string) => void; - setBaseUrl?: (baseUrl: string) => void; - isTokenValid?: boolean; - setIsTokenValid?: (boolean) => void; - setLoadingState?: (boolean) => void; - subDoc?: SubDoc; -}; - -const TokenForm = ({ - setOpenApiJson, - setToken, - setBaseUrl: submitBaseUrl, - isTokenValid, - setIsTokenValid, - subDoc, - setLoadingState, -}: TokenFormProps) => { - const history = useHistory(); - const location = useLocation(); - const [isLoading, setIsLoading] = useState(false); - const [locationSetting, setLocationSetting] = useState( - parseJson(localStorage.getItem('baseUrl'))?.locationSetting ?? 'production', - ); - const [baseUrl, setBaseUrl] = useState( - parseJson(localStorage.getItem('baseUrl'))?.baseUrl ?? - 'https://api.twenty.com', - ); - const token = - parseJson(localStorage.getItem('TryIt_securitySchemeValues'))?.bearerAuth ?? - ''; - - const updateLoading = (loading: boolean) => { - setIsLoading(loading); - setLoadingState(loading); - }; - - const updateToken = async (event: React.ChangeEvent) => { - localStorage.setItem( - 'TryIt_securitySchemeValues', - JSON.stringify({ bearerAuth: event.target.value }), - ); - await submitToken(event.target.value); - }; - - const updateBaseUrl = (baseUrl: string, locationSetting: string) => { - let url: string; - if (locationSetting === 'production') { - url = 'https://api.twenty.com'; - } else if (locationSetting === 'demo') { - url = 'https://api-demo.twenty.com'; - } else if (locationSetting === 'localhost') { - url = 'http://localhost:3000'; - } else { - url = baseUrl?.endsWith('/') - ? baseUrl.substring(0, baseUrl.length - 1) - : baseUrl; - } - - setBaseUrl(url); - setLocationSetting(locationSetting); - submitBaseUrl?.(url); - localStorage.setItem( - 'baseUrl', - JSON.stringify({ baseUrl: url, locationSetting }), - ); - }; - - const validateToken = (openApiJson) => { - setIsTokenValid(!!openApiJson.tags); - }; - - const getJson = async (token: string) => { - updateLoading(true); - - return await fetch(baseUrl + '/open-api/' + (subDoc ?? 'core'), { - headers: { Authorization: `Bearer ${token}` }, - }) - .then((res) => res.json()) - .then((result) => { - validateToken(result); - updateLoading(false); - - return result; - }) - .catch(() => { - updateLoading(false); - setIsTokenValid(false); - }); - }; - - const submitToken = async (token) => { - if (isLoading) return; - - const json = await getJson(token); - - setToken && setToken(token); - - setOpenApiJson && setOpenApiJson(json); - }; - - useEffect(() => { - (async () => { - updateBaseUrl(baseUrl, locationSetting); - await submitToken(token); - })(); - }, []); - - // We load playground style using useEffect as it breaks remaining docs style - useEffect(() => { - const styleElement = document.createElement('style'); - styleElement.innerHTML = tokenForm.toString(); - document.head.append(styleElement); - - return () => styleElement.remove(); - }, []); - - return ( -
-
-
history.goBack()}> - - Back -
-
- -
-
-
- -
- - updateBaseUrl(event.target.value, locationSetting) - } - onBlur={() => submitToken(token)} - /> -
-
-
- -
- -
-
- -
-
-
- ); -}; - -export default TokenForm; diff --git a/packages/twenty-docs/src/css/custom.css b/packages/twenty-docs/src/css/custom.css deleted file mode 100644 index 60dd700a8..000000000 --- a/packages/twenty-docs/src/css/custom.css +++ /dev/null @@ -1,350 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap'); -@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono&display=swap'); - -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ - -/* You can override the default Infima variables here. */ -:root { - --ifm-global-radius: 8px; - --ifm-code-font-size: 14px; - --ifm-font-family-base: "Inter",BlinkMacSystemFont,-apple-system,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue","Helvetica","Arial",sans-serif; - --ifm-font-family-monospace: 'Roboto Mono',SFMono-Regular, Menlo, Monaco, Consolas,'Liberation Mono', 'Courier New', monospace; - --ifm-font-size-base: 14px; - --ifm-base-spacing: 14px; - --ifm-line-height-base: 145%; - --ifm-font-weight-base: var(--twenty-body-regular-font-weight); - --ifm-color-primary: #11181c; - --ifm-code-font-size: 95%; - --docsearch-key-gradient: none !important; - --docsearch-key-shadow: 0 0 0 0.5px var(--docsearch-muted-color) !important; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); - --ifm-toc-padding-vertical: 0.5rem; - --ifm-breadcrumb-border-radius: 8px; - --ifm-navbar-link-color: #687076; - --ifm-link-decoration: underline; - - --ifm-heading-font-weight: 600; - - --ifm-h1-font-size: 1.7rem !important; - --ifm-h2-font-size: 1.25rem !important; - --ifm-h3-font-size: 1rem !important; - --ifm-h4-font-size: 0.875rem !important; - --ifm-h5-font-size: 0.85rem !important; - - --ifm-spacing-horizontal: 2rem; - - --ifm-menu-link-padding-vertical: 0.2rem; - - --list-items-border-color: #ebebeb; - --category-icon-background-color: #ebebeb; - --category-icon-border-color: #d6d6d6; - --level-1-color: #B3B3B3; - - --dark-docsearch-hit-title-color: #444950; - --dark-docsearch-hit-mark-color: #11181c; - --dark-docsearch-hit-general-color: #969faf; - --light-docsearch-hit-title-color: #bec3c9; - --light-docsearch-hit-mark-color: #ffffff; - --light-docsearch-hit-general-color: #7f8497; -} - -.markdown > h1 { - --ifm-h1-font-size: 1.7rem !important; -} -.markdown > h2 { - --ifm-h2-font-size: 1.25rem; -} -.markdown > h3 { - --ifm-h3-font-size: 1rem; -} -.markdown > h4 { - --ifm-h4-font-size: 0.875rem; -} -.markdown > h5 { - --ifm-h5-font-size: 0.85rem; -} - -/* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme='dark'] { - --ifm-color-primary: #fff; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); - --list-items-border-color: #292929; - --category-icon-background-color: #292929; - --category-icon-border-color: #333333; - --level-1-color: #666666; -} - -body { - margin: 0; - font-family: 'Inter'; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -html { - font-size: 14px; -} - -.container { - padding-top: 48px !important; -} - -.DocSearch-Button { - margin: inherit !important; - height: 32px !important; - border-radius: 0 !important; - margin-top: 12px !important; - background: inherit !important; - color: var(--ifm-navbar-link-color) !important; - - :hover { - box-shadow: none !important; - } -} - -.DocSearch-Button-Placeholder { - padding: 0 100px 0 6px !important; -} - -.DocSearch-Button { - display: none !important; -} - - -.DocSearch-Button-Key { - height: 14px !important; - width: 14px !important; - font-size: 9px !important; - padding: none !important; - top: inherit !important; -} - -.DocSearch-Button-Keys { - min-width: inherit !important; -} - -.search-menu-item { - padding-top: 12px; -} -.menu__link:hover > .DocSearch-Button-Keys { - display: flex !important; -} - -.theme-edit-this-page { - font-size: 70%; -} -.theme-edit-this-page svg { - height: 14px; - width: 14px; -} - -li.coming-soon { - display: flex; -} - -li.coming-soon a { - display: flex; - justify-content: space-between; - pointer-events: none; - cursor: default; -} - -a.menu__link, a.navbar__item { - text-decoration: none; - font-size: 13px; -} - -.menu__link--external { - align-items: center; -} - -li.coming-soon a::after { - float: right; - content: "soon"; - border-color: #373737; - border: 1px solid; - border-radius: 4px; - text-align: center; - float:right; - padding-left: 6px; - padding-right: 6px; - padding-bottom: 2px; - font-size: 80%; -} - -.theme-doc-sidebar-item-category-level-1 > .menu__link { - font-size: 12px; - color: var(--level-1-color); -} - -.theme-doc-sidebar-item-category-level-1 > .menu__link:hover{ - color:inherit -} - -.menu__list-item--level1 > .menu__link--active { - color: inherit; -} - - -.menu__list-item--level1 > .menu__link--active > .icon-and-text { - color: black; -} - - -[data-theme='dark'] .menu__list-item--level1 > .menu__link--active > .icon-and-text { - color: white; -} - -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-title { - color: var(--dark-docsearch-hit-title-color) !important; -} - -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] mark { - color: var(--dark-docsearch-hit-mark-color) !important; -} - -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-action, -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-icon, -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-path, -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-text, -[data-theme='dark'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-Tree { - color: var(--dark-docsearch-hit-general-color) !important; -} - - -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-title { - color: var(--light-docsearch-hit-title-color) !important; -} - -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] mark { - color: var(--light-docsearch-hit-mark-color) !important; -} - -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-action, -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-icon, -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-path, -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-text, -[data-theme='light'] ul > .DocSearch-Hit[aria-selected='true'] .DocSearch-Hit-Tree { - color: var(--light-docsearch-hit-general-color) !important; -} - -[data-theme='light'] .menu__list-item--level1 > .menu__link--active > .icon-and-text { - color: initial; -} - - - - -.menu__list-item--level1 > .menu__link--active, -.menu__list-item--level1 > .menu__link:hover { - background: inherit; -} - -.theme-doc-sidebar-item-category-level-1 { - padding-top: 1.5rem; -} - -.theme-doc-sidebar-item-category-level-2 { - cursor: pointer; -} -.theme-doc-sidebar-item-category-level-2 .menu__list { - border-left: 1px solid var(--list-items-border-color); - margin-left: var(--ifm-menu-link-padding-horizontal); -} - -.menu__list-item--home { - font-size: 13px; - margin: 1.5rem 0; -} - -.theme-doc-sidebar-item-link-level-1.menu__list-item--root .sidebar-item-icon { - background-clip: content-box; - background-color: var(--category-icon-background-color); - border: 1px solid var(--category-icon-border-color); - border-radius: 8px; - padding: 3px; - margin-right: 16px; -} -.theme-doc-sidebar-item-link-level-1.menu__list-item--root .sidebar-item-icon svg { - height: 22px; - width: 22px; - padding: 1px; -} - -.sidebar-item-icon { - display: flex; - vertical-align: center; - margin-right: 0.5rem; -} - -.icon-and-text { - display: flex; - align-items: center; -} - -.fullHeightPlayground { - height: calc(100vh - var(--ifm-navbar-height) - 45px); -} - -.display-none { - display: none; -} - -.table-of-contents__link { - text-decoration: none; -} - -a.table-of-contents__link:hover{ - text-decoration: underline; -} - -.docs-image { - max-width: 100%; - display: flex; - align-self: center; - width: 80%; -} - -.pagination-nav__link{ - text-decoration: none; -} - -.tabs-container { - padding: 20px; -} - -.card{ - text-decoration: none; - border-radius: 8px !important; - margin-right: -28px; - -} - - -.header-github-link:hover { - opacity: 0.6; -} - - -.hidden { -display: none !important; -} - -.navbar__title { - color: var(--ifm-link-color); - font-family: 'IBM Plex Mono', 'Courier New', Courier, monospace; - font-size: 11px; -} - -.navbar__brand { - text-decoration: none; -} - -.navbar__link { - color: var(--ifm-link-color); -} -@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap'); diff --git a/packages/twenty-docs/src/pages/graphql/core.tsx b/packages/twenty-docs/src/pages/graphql/core.tsx deleted file mode 100644 index 365ba3674..000000000 --- a/packages/twenty-docs/src/pages/graphql/core.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -import GraphQlPlayground from '../../components/graphql-playground'; - -const CoreGraphql = () => { - return ; -}; - -export default CoreGraphql; diff --git a/packages/twenty-docs/src/pages/graphql/metadata.tsx b/packages/twenty-docs/src/pages/graphql/metadata.tsx deleted file mode 100644 index a5d760d6d..000000000 --- a/packages/twenty-docs/src/pages/graphql/metadata.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; - -import GraphQlPlayground from '../../components/graphql-playground'; - -const CoreGraphql = () => { - return ; -}; - -export default CoreGraphql; diff --git a/packages/twenty-docs/src/pages/rest-api/core.tsx b/packages/twenty-docs/src/pages/rest-api/core.tsx deleted file mode 100644 index abc4be281..000000000 --- a/packages/twenty-docs/src/pages/rest-api/core.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { API } from '@stoplight/elements'; -import Layout from '@theme/Layout'; - -import Playground from '../../components/playground'; - -import spotlightTheme from '!css-loader!@stoplight/elements/styles.min.css'; - -const RestApiComponent = ({ openApiJson }) => { - // We load spotlightTheme style using useEffect as it breaks remaining docs style - useEffect(() => { - const styleElement = document.createElement('style'); - styleElement.innerHTML = spotlightTheme.toString(); - document.head.append(styleElement); - - return () => styleElement.remove(); - }, []); - - return ( -
- -
- ); -}; - -const restApi = () => { - const [openApiJson, setOpenApiJson] = useState({}); - - const children = ; - - return ( - - - {() => ( - - )} - - - ); -}; - -export default restApi; diff --git a/packages/twenty-docs/src/pages/rest-api/metadata.tsx b/packages/twenty-docs/src/pages/rest-api/metadata.tsx deleted file mode 100644 index b41356311..000000000 --- a/packages/twenty-docs/src/pages/rest-api/metadata.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { API } from '@stoplight/elements'; -import Layout from '@theme/Layout'; - -import Playground from '../../components/playground'; - -import spotlightTheme from '!css-loader!@stoplight/elements/styles.min.css'; - -const RestApiComponent = ({ openApiJson }) => { - // We load spotlightTheme style using useEffect as it breaks remaining docs style - useEffect(() => { - const styleElement = document.createElement('style'); - styleElement.innerHTML = spotlightTheme.toString(); - document.head.append(styleElement); - - return () => styleElement.remove(); - }, []); - - return ( -
- -
- ); -}; - -const restApi = () => { - const [openApiJson, setOpenApiJson] = useState({}); - - const children = ; - - return ( - - - {() => ( - - )} - - - ); -}; - -export default restApi; diff --git a/packages/twenty-docs/src/theme/DocCard/index.js b/packages/twenty-docs/src/theme/DocCard/index.js deleted file mode 100644 index b2fe82fbf..000000000 --- a/packages/twenty-docs/src/theme/DocCard/index.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import isInternalUrl from '@docusaurus/isInternalUrl'; -import Link from '@docusaurus/Link'; -import { - findFirstCategoryLink, - useDocById, -} from '@docusaurus/theme-common/internal'; -import { translate } from '@docusaurus/Translate'; -import clsx from 'clsx'; - -import * as icons from '../icons'; - -import styles from './styles.module.css'; - -function CardContainer({ href, children }) { - return ( - - {children} - - ); -} -function CardLayout({ href, icon, title, description }) { - return ( - -

- - {typeof icon === 'function' ? icon() : icon} - {' '} - {title} -

- {description && ( -

- {description} -

- )} -
- ); -} - -function CardCategory({ item }) { - const href = findFirstCategoryLink(item); - // Unexpected: categories that don't have a link have been filtered upfront - if (!href) { - return null; - } - return ( - - ); -} - -function CardLink({ item }) { - const customIcon = item.customProps.icon; - const icon = icons[customIcon] || (isInternalUrl(item.href) ? '📄️' : '🔗'); - const doc = useDocById(item.docId ?? undefined); - - return ( - - ); -} - -export default function DocCard({ item }) { - switch (item.type) { - case 'link': - return ; - case 'category': - return ; - default: - throw new Error(`unknown item type ${JSON.stringify(item)}`); - } -} diff --git a/packages/twenty-docs/src/theme/DocCard/styles.module.css b/packages/twenty-docs/src/theme/DocCard/styles.module.css deleted file mode 100644 index 02bd36e25..000000000 --- a/packages/twenty-docs/src/theme/DocCard/styles.module.css +++ /dev/null @@ -1,35 +0,0 @@ -.cardContainer { - --ifm-link-color: var(--ifm-color-emphasis-800); - --ifm-link-hover-color: var(--ifm-color-emphasis-700); - --ifm-link-hover-decoration: none; - - border: 1px solid var(--ifm-color-emphasis-200); - transition: all var(--ifm-transition-fast) ease; - transition-property: border, box-shadow; - - -} - -.cardContainer:hover { - border-color: var(--ifm-color-primary); - box-shadow: 0 3px 6px 0 rgb(0 0 0 / 20%); -} - -.cardContainer *:last-child { - margin-bottom: 0px; - -} - -.cardTitle { - font-size: 1.2rem; - display: flex -} - -.cardDescription { - font-size: 0.8rem; -} - -.icon { - font-size: 1.5rem; - padding-right: 0.5rem; -} diff --git a/packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js b/packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js deleted file mode 100644 index 83a90bf77..000000000 --- a/packages/twenty-docs/src/theme/DocSidebarItem/Category/index.js +++ /dev/null @@ -1,103 +0,0 @@ -import Link from "@docusaurus/Link"; -import isInternalUrl from "@docusaurus/isInternalUrl"; -import { - Collapsible, - ThemeClassNames, - useCollapsible, -} from "@docusaurus/theme-common"; -import { isActiveSidebarItem } from "@docusaurus/theme-common/internal"; -import DocSidebarItems from "@theme/DocSidebarItems"; -import IconExternalLink from "@theme/Icon/ExternalLink"; -import clsx from "clsx"; -import React from "react"; -import * as icons from "../../icons"; - -const DocSidebarItemCategory = ({ - item, - onItemClick, - activePath, - level, - index, - ...props -}) => { - const { - href, - label, - className, - collapsible, - autoAddBaseUrl, - customProps = {}, - items, - } = item; - const isActive = isActiveSidebarItem(item, activePath); - const isInternalLink = isInternalUrl(href); - const IconComponent = customProps?.icon ? icons[customProps.icon] : undefined; - - const { collapsed, setCollapsed } = useCollapsible({ - initialState: () => collapsible && !isActive && item.collapsed, - }); - - return ( -
  • - { - onItemClick?.(item); - - if (!collapsible) return; - - if (href) { - setCollapsed(false); - return; - } - - e.preventDefault(); - setCollapsed((previousCollapsed) => !previousCollapsed); - }} - {...props} - > - {IconComponent ? ( - - - - - {label} - - ) : ( - label - )} - - {!!href && !isInternalLink && } - - {!customProps.isSidebarRoot && ( - - - - )} -
  • - ); -}; - -export default DocSidebarItemCategory; diff --git a/packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js b/packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js deleted file mode 100644 index a533a59d8..000000000 --- a/packages/twenty-docs/src/theme/DocSidebarItem/Link/index.js +++ /dev/null @@ -1,62 +0,0 @@ -import Link from "@docusaurus/Link"; -import isInternalUrl from "@docusaurus/isInternalUrl"; -import { ThemeClassNames } from "@docusaurus/theme-common"; -import { isActiveSidebarItem } from "@docusaurus/theme-common/internal"; -import IconExternalLink from "@theme/Icon/ExternalLink"; -import clsx from "clsx"; -import React from "react"; -import * as icons from "../../icons"; - -const DocSidebarItemLink = ({ - item, - onItemClick, - activePath, - level, - index, - ...props -}) => { - const { href, label, className, autoAddBaseUrl, customProps = {} } = item; - const isActive = isActiveSidebarItem(item, activePath); - const isInternalLink = isInternalUrl(href); - const IconComponent = customProps?.icon ? icons[customProps.icon] : null; - - return ( -
  • - onItemClick(item) : undefined, - })} - {...props} - > - - {IconComponent && ( - - - - )} - {label} - - {!isInternalLink && } - -
  • - ); -}; - -export default DocSidebarItemLink; diff --git a/packages/twenty-docs/src/theme/DocSidebarItem/index.js b/packages/twenty-docs/src/theme/DocSidebarItem/index.js deleted file mode 100644 index 034cee964..000000000 --- a/packages/twenty-docs/src/theme/DocSidebarItem/index.js +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { TbSearch } from 'react-icons/tb'; -import DocSidebarItem from '@theme-original/DocSidebarItem'; -import SearchBar from '@theme-original/SearchBar'; - -const CustomComponents = { - 'search-bar': () => { - const openSearchModal = () => { - const searchInput = document.querySelector('#search-bar'); - if (searchInput) { - searchInput.focus(); - } - - const event = new KeyboardEvent('keydown', { - key: 'k', - code: 'KeyK', - keyCode: 75, - which: 75, - // If the shortcut is Cmd+K on Mac or Ctrl+K on Windows/Linux, set the respective key to true: - metaKey: true, // for Cmd+K (Mac) - // ctrlKey: true, // for Ctrl+K (Windows/Linux) - bubbles: true, - }); - - // Dispatch the event - window.dispatchEvent(event); - }; - - return ( - <> -
  • - - - - - - - Search - - - - K - - -
  • - - ); - }, -}; - -export default function DocSidebarItemWrapper(props) { - const CustomComponent = CustomComponents[props.item?.customProps?.type]; - if (CustomComponent) { - return ; - } - - return ( - <> - - - ); -} diff --git a/packages/twenty-docs/src/theme/Icon/DarkMode/index.js b/packages/twenty-docs/src/theme/Icon/DarkMode/index.js deleted file mode 100644 index 5907ac11c..000000000 --- a/packages/twenty-docs/src/theme/Icon/DarkMode/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { TbMoon } from 'react-icons/tb'; -import { useColorMode } from '@docusaurus/theme-common'; - -const IconDarkMode = (props) => { - const { colorMode } = useColorMode(); - return colorMode === 'dark' ? : <>; -}; - -export default IconDarkMode; diff --git a/packages/twenty-docs/src/theme/Icon/Home/index.js b/packages/twenty-docs/src/theme/Icon/Home/index.js deleted file mode 100644 index 7221139ae..000000000 --- a/packages/twenty-docs/src/theme/Icon/Home/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import React from "react"; -import { TbHome } from "react-icons/tb"; -const IconHome = (props) => ; - -export default IconHome; diff --git a/packages/twenty-docs/src/theme/Icon/LightMode/index.js b/packages/twenty-docs/src/theme/Icon/LightMode/index.js deleted file mode 100644 index 19019e82c..000000000 --- a/packages/twenty-docs/src/theme/Icon/LightMode/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { TbSun } from 'react-icons/tb'; -import { useColorMode } from '@docusaurus/theme-common'; - -const IconLightMode = (props) => { - const { colorMode } = useColorMode(); - return colorMode === 'light' ? : <>; -}; - -export default IconLightMode; diff --git a/packages/twenty-docs/src/theme/Navbar/Search/index.js b/packages/twenty-docs/src/theme/Navbar/Search/index.js deleted file mode 100644 index ee931b4c8..000000000 --- a/packages/twenty-docs/src/theme/Navbar/Search/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import React from 'react'; - -export default function SearchWrapper(props) { - return <>; -} diff --git a/packages/twenty-docs/src/theme/NavbarItem/ComponentTypes.js b/packages/twenty-docs/src/theme/NavbarItem/ComponentTypes.js deleted file mode 100644 index c760d3355..000000000 --- a/packages/twenty-docs/src/theme/NavbarItem/ComponentTypes.js +++ /dev/null @@ -1,24 +0,0 @@ -import GithubLink from '@site/src/theme/NavbarItem/GithubLink'; -import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; -import DocNavbarItem from '@theme/NavbarItem/DocNavbarItem'; -import DocSidebarNavbarItem from '@theme/NavbarItem/DocSidebarNavbarItem'; -import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; -import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem'; -import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; -import HtmlNavbarItem from '@theme/NavbarItem/HtmlNavbarItem'; -import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem'; -import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem'; - -const ComponentTypes = { - default: DefaultNavbarItem, - localeDropdown: LocaleDropdownNavbarItem, - search: SearchNavbarItem, - dropdown: DropdownNavbarItem, - html: HtmlNavbarItem, - doc: DocNavbarItem, - docSidebar: DocSidebarNavbarItem, - docsVersion: DocsVersionNavbarItem, - docsVersionDropdown: DocsVersionDropdownNavbarItem, - 'custom-github-link': GithubLink, -}; -export default ComponentTypes; diff --git a/packages/twenty-docs/src/theme/NavbarItem/GithubLink.tsx b/packages/twenty-docs/src/theme/NavbarItem/GithubLink.tsx deleted file mode 100644 index bb2c958a8..000000000 --- a/packages/twenty-docs/src/theme/NavbarItem/GithubLink.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import { TbBrandGithub } from 'react-icons/tb'; - -const GithubLink = () => { - return ( - - - - ); -}; - -export default GithubLink; diff --git a/packages/twenty-docs/src/theme/OptionTable/index.js b/packages/twenty-docs/src/theme/OptionTable/index.js deleted file mode 100644 index 816821c3e..000000000 --- a/packages/twenty-docs/src/theme/OptionTable/index.js +++ /dev/null @@ -1,29 +0,0 @@ -import styles from "./style.module.css"; -import React from "react"; - -export default function OptionTable({ options }) { - return ( -
    - - - - - - - - - - {options.map(([option, example, description]) => ( - - - - - - ))} - -
    VariableExampleDescription
    - {option} - {example}{description}
    -
    - ); -} diff --git a/packages/twenty-docs/src/theme/OptionTable/style.module.css b/packages/twenty-docs/src/theme/OptionTable/style.module.css deleted file mode 100644 index f232e1dad..000000000 --- a/packages/twenty-docs/src/theme/OptionTable/style.module.css +++ /dev/null @@ -1,87 +0,0 @@ -.container { - mask-image: linear-gradient( - to right, - transparent 0.8em, - white 1.5em, - white calc(100% - 1.5em), - transparent calc(100% - 0.8em) - ); - - overflow-x: auto; - overscroll-behavior-x: contain; - padding-left: 1.5rem; - padding-right: 1.5rem; - padding-bottom: 1rem; - margin-bottom: 1rem; - margin-top: 1.5rem; - margin-left: -1.5rem; - margin-right: -1.5rem; -} - -.container::-webkit-scrollbar { - appearance: none; -} - -.optionsTable { - width: 100%; - font-size: 0.875rem; - line-height: 1.25rem; - border-collapse: collapse; - display: inline-table; -} - -.tableHeader { - background: transparent; -} - -.tableHeaderRow { - padding-top: 1rem; - padding-bottom: 1rem; - border-bottom-width: 1px; - text-align: left; - border-top: none; -} - -.tableHeaderCell { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - font-weight: 600; - border-top: none; - border-left: none; - border-right: none; -} - -.tableBody { - color: var(--ifm-color-content); - vertical-align: baseline; -} - -.tableRow { - border-bottom-width: 1px; - border-left: none; - border-right: none; - border-color: var(--ifm-color-content); -} - -.tableOptionCell { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", - monospace; - font-size: 0.75rem; - line-height: 1rem; - font-weight: 600; - line-height: 1.5rem; - white-space: pre; - color: var(--ifm-color-primary-light); - border-right: none; - border-left: none; -} - -.tableDescriptionCell { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - padding-left: 1.5rem; - border-right: none; - border-left: none; -} diff --git a/packages/twenty-docs/src/theme/icons.js b/packages/twenty-docs/src/theme/icons.js deleted file mode 100644 index 85e365241..000000000 --- a/packages/twenty-docs/src/theme/icons.js +++ /dev/null @@ -1,79 +0,0 @@ -export { - TbAddressBook, - TbApi, - TbApps, - TbAppWindow, - TbArrowBackUp, - TbArrowBigRight, - TbArticle, - TbAugmentedReality, - TbBolt, - TbBrandDocker, - TbBrandFigma, - TbBrandGithub, - TbBrandGraphql, - TbBrandVscode, - TbBrandWindows, - TbBrandZapier, - TbBug, - TbBugOff, - TbChartDots, - TbCheck, - TbCheckbox, - TbChecklist, - TbChevronLeft, - TbCircleCheckFilled, - TbCircleDot, - TbCloud, - TbColorFilter, - TbColorPicker, - TbComponents, - TbDeviceDesktop, - TbExclamationCircle, - TbEyeglass, - TbFaceIdError, - TbFlag, - TbFolder, - TbForms, - TbIcons, - TbInfoCircle, - TbInputSearch, - TbKeyboard, - TbLayoutGrid, - TbLayoutList, - TbLink, - TbLoader2, - TbMenu, - TbNavigation, - TbNote, - TbNotebook, - TbPaint, - TbPencil, - TbPill, - TbPlus, - TbRectangle, - TbRocket, - TbSchema, - TbScript, - TbSelect, - TbServer, - TbSlideshow, - TbSquareChevronsRight, - TbSquareRoundedPlusFilled, - TbTable, - TbTag, - TbTargetArrow, - TbTemplate, - TbTerminal, - TbTerminal2, - TbTextPlus, - TbTextSize, - TbToggleRight, - TbTooltip, - TbTopologyStar, - TbUpload, - TbUsers, - TbVariable, - TbVocabulary, - TbZoomQuestion, -} from 'react-icons/tb'; diff --git a/packages/twenty-docs/src/ui/SandpackEditor.js b/packages/twenty-docs/src/ui/SandpackEditor.js deleted file mode 100644 index 5a380562e..000000000 --- a/packages/twenty-docs/src/ui/SandpackEditor.js +++ /dev/null @@ -1,109 +0,0 @@ -import { SandpackProvider, SandpackLayout, SandpackCodeEditor, SandpackPreview } from "@codesandbox/sandpack-react"; -import uiModule from "!!raw-loader!@site/src/ui/generated/index.cjs"; -import uiComponentsCSS from '!!raw-loader!@site/src/ui/uiComponents.css' - -export const SandpackEditor = ({ availableComponentPaths, componentCode}) => { - const fakePackagesJson = availableComponentPaths.reduce((acc, componentPath, index) => { - acc[`/node_modules/${componentPath}/package.json`] = { - hidden: true, - code: JSON.stringify({ - name: componentPath, - main: "./index.js", - }), - }; - return acc; - }, {}); - - const fakeIndexesJs = availableComponentPaths.reduce((acc, componentPath, index) => { - acc[`/node_modules/${componentPath}/index.js`] = { - hidden: true, - code: uiModule, - }; - return acc; - } - , {}); - - return ( - - - -);`, - }, - "/App.tsx": { - hidden: true, - code: `import { ThemeProvider } from "@emotion/react"; -import { lightTheme, darkTheme } from "${availableComponentPaths[0]}"; -import { MyComponent } from "./MyComponent.tsx"; - -import './uiComponents.css' - -console.log("lightTheme", lightTheme); - -export default function App() { -return ( - -); -};`, - }, - "/MyComponent.tsx": { - code: componentCode, - }, - "/uiComponents.css": { - code: uiComponentsCSS, - hidden: true, - }, - ...fakePackagesJson, - ...fakeIndexesJs, - }} - customSetup={{ - entry: "/index.js", - dependencies: { - react: "latest", - "react-dom": "latest", - "react-scripts": "^5.0.0", - "@emotion/react": "^11.10.6", - "@emotion/styled": "latest", - "@tabler/icons-react": "latest", - "hex-rgb": "latest", - "framer-motion": "latest", - uuid: "latest", - "react-tooltip": "latest", - "react-router-dom": "latest", - "@sniptt/guards": "latest", - "react-router": "latest", - "@apollo/client": "latest", - graphql: "latest", - "react-textarea-autosize": "latest", - "react-hotkeys-hook": "latest", - recoil: "latest", - "@floating-ui/react": "latest", - "ts-key-enum": "latest", - "deep-equal": "latest", - "lodash.debounce": "latest", - "react-loading-skeleton": "latest", - "zod": "latest", - "@blocknote/react": 'latest', - 'react-responsive': 'latest' - - }, - }} - > - - - - - - ); -}; diff --git a/packages/twenty-docs/src/ui/display/animatedCheckmarkCode.js b/packages/twenty-docs/src/ui/display/animatedCheckmarkCode.js deleted file mode 100644 index 995dfc1c0..000000000 --- a/packages/twenty-docs/src/ui/display/animatedCheckmarkCode.js +++ /dev/null @@ -1,12 +0,0 @@ -import { AnimatedCheckmark } from 'twenty-ui'; - -export const MyComponent = () => { - return ( - - ); -}; diff --git a/packages/twenty-docs/src/ui/display/appTooltipCode.js b/packages/twenty-docs/src/ui/display/appTooltipCode.js deleted file mode 100644 index 9de71e4fe..000000000 --- a/packages/twenty-docs/src/ui/display/appTooltipCode.js +++ /dev/null @@ -1,22 +0,0 @@ -import { AppTooltip } from "@/ui/display/tooltip/AppTooltip"; - -export const MyComponent = () => { - return ( - <> -

    - Customer Insights -

    - - - ); -}; diff --git a/packages/twenty-docs/src/ui/display/checkmarkCode.js b/packages/twenty-docs/src/ui/display/checkmarkCode.js deleted file mode 100644 index 47282737d..000000000 --- a/packages/twenty-docs/src/ui/display/checkmarkCode.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Checkmark } from 'twenty-ui'; - -export const MyComponent = () => { - return ; -}; diff --git a/packages/twenty-docs/src/ui/display/chipCode.js b/packages/twenty-docs/src/ui/display/chipCode.js deleted file mode 100644 index f25021f2b..000000000 --- a/packages/twenty-docs/src/ui/display/chipCode.js +++ /dev/null @@ -1,17 +0,0 @@ -import { Chip } from 'twenty-ui'; - -export const MyComponent = () => { - return ( - - ); -}; diff --git a/packages/twenty-docs/src/ui/display/entityChipCode.js b/packages/twenty-docs/src/ui/display/entityChipCode.js deleted file mode 100644 index e3093fb3c..000000000 --- a/packages/twenty-docs/src/ui/display/entityChipCode.js +++ /dev/null @@ -1,18 +0,0 @@ -import { BrowserRouter as Router } from 'react-router-dom'; -import { EntityChip, IconTwentyStar } from 'twenty-ui'; - -export const MyComponent = () => { - return ( - - - - ); -}; diff --git a/packages/twenty-docs/src/ui/display/iconAddressBookCode.js b/packages/twenty-docs/src/ui/display/iconAddressBookCode.js deleted file mode 100644 index 89044322e..000000000 --- a/packages/twenty-docs/src/ui/display/iconAddressBookCode.js +++ /dev/null @@ -1,5 +0,0 @@ -import { IconAddressBook } from 'twenty-ui'; - -export const MyComponent = () => { - return ; -}; diff --git a/packages/twenty-docs/src/ui/display/overflowingTextWithTooltipCode.js b/packages/twenty-docs/src/ui/display/overflowingTextWithTooltipCode.js deleted file mode 100644 index db24bccff..000000000 --- a/packages/twenty-docs/src/ui/display/overflowingTextWithTooltipCode.js +++ /dev/null @@ -1,8 +0,0 @@ -import { OverflowingTextWithTooltip } from 'twenty-ui'; - -export const MyComponent = () => { - const crmTaskDescription = - 'Follow up with client regarding their recent product inquiry. Discuss pricing options, address any concerns, and provide additional product information. Record the details of the conversation in the CRM for future reference.'; - - return ; -}; diff --git a/packages/twenty-docs/src/ui/display/soonPillCode.js b/packages/twenty-docs/src/ui/display/soonPillCode.js deleted file mode 100644 index 6ddaeaff1..000000000 --- a/packages/twenty-docs/src/ui/display/soonPillCode.js +++ /dev/null @@ -1,5 +0,0 @@ -import { SoonPill } from "@/ui/display/pill/components/SoonPill"; - -export const MyComponent = () => { - return ; -}; diff --git a/packages/twenty-docs/src/ui/display/tablerIconExampleCode.js b/packages/twenty-docs/src/ui/display/tablerIconExampleCode.js deleted file mode 100644 index 922c833d0..000000000 --- a/packages/twenty-docs/src/ui/display/tablerIconExampleCode.js +++ /dev/null @@ -1,5 +0,0 @@ -import { IconArrowLeft } from "@tabler/icons-react"; - -export const MyComponent = () => { - return ; -}; diff --git a/packages/twenty-docs/src/ui/display/tagCode.js b/packages/twenty-docs/src/ui/display/tagCode.js deleted file mode 100644 index e2dff03c1..000000000 --- a/packages/twenty-docs/src/ui/display/tagCode.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Tag } from "@/ui/display/tag/components/Tag"; - -export const MyComponent = () => { - return ( - console.log("click")} - /> - ); -}; diff --git a/packages/twenty-docs/src/ui/feedback/circularProgressBarCode.js b/packages/twenty-docs/src/ui/feedback/circularProgressBarCode.js deleted file mode 100644 index 7c5806a7a..000000000 --- a/packages/twenty-docs/src/ui/feedback/circularProgressBarCode.js +++ /dev/null @@ -1,5 +0,0 @@ -import { CircularProgressBar } from "@/ui/feedback/progress-bar/components/CircularProgressBar"; - -export const MyComponent = () => { - return ; -}; diff --git a/packages/twenty-docs/src/ui/feedback/progressBarCode.js b/packages/twenty-docs/src/ui/feedback/progressBarCode.js deleted file mode 100644 index 26b73f84b..000000000 --- a/packages/twenty-docs/src/ui/feedback/progressBarCode.js +++ /dev/null @@ -1,14 +0,0 @@ -import { ProgressBar } from "@/ui/feedback/progress-bar/components/ProgressBar"; - -export const MyComponent = () => { - return ( - - ); -}; diff --git a/packages/twenty-docs/src/ui/generated/dark-noise-JHVNKF2E.jpg b/packages/twenty-docs/src/ui/generated/dark-noise-JHVNKF2E.jpg deleted file mode 100644 index 6fc95715e9d469efc3d977509c986163270c8ab9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26053 zcmbrlX;f2L+bz0wIzk8t7$7mAfdmL4ViK$XLSYCR16mlG(3GH|6_w7YAoWrhLXQDM z4+WGUs0b8AqX=RH(ilQxQ(8qY2!Uz~#TKOivZ>+p!ksFTsBPMxLU3kmgL3p_{i>=-KTStTZ%^TUgiL zuT8f1d1n+RevUDw>|L~c|KHI5A7uY~z@-02$o?0w{}0zRz`~)ej|VpZ`@v_2cLXC2 z_Bw7EvI#mtEMJ{7R?FCpaqM*sUM8_s{{t>sJ>$J)bYzNqG4&_0-TB=dWj6F@D+li7 zL=~oeY@t}X1(bPjN4VpOxdFQ+kNrf0&)`*B;wu$pVZvi)8pD2F3(k$yR@?97Teu3a zI{>~pe{y7|Qu|;+W=@IC&d?Ys(b;=svaSS+0mmKvslG8Xk3zoVlehXkb`eC0^AZsv z*@lxKw_SECe@{8P%?lGkzj}W!gQO*wt%vp1U%h`Dys`uI!}{6hW6U@a2QBe7lM)5W zEbCpTOzZ{VJzVxLvrW|{-;S6b@p>6aT6@Yn>C=z4wOZm}$VYqHQ5TWNz^9)YVxH4u zDHYH+i+8Qw^@*OrGUv7CfBiU0*k%YDN@W+VXA;p+po34P__d^?3$Zzz7@K6AyupwI&sk2XT_1jC zIzm0t%v*1FDB^vR;13l@7M{UNx`$t_Qi-G1NlF~m!W?eV`a!ROIenB+i&pa~@t4WO z=LvXPHvC-d$N8jrCA~sCSj^GG&uS)72`E)Rb6@}FwZ&?Cdb~1SioR650yyxD;ol&- z1JY+U)J!<%hZ?P^>b(8_fu~GDdpOHB)m3VjRzitHoQ+T%6x69|HcdWRsHlYw?N(Q6 zBTnwRpln^+*H*F;IQ8NF>24t;eg8iKkHZr(5 zOk#B9bn1VcLN@#nO)LW3Ljm4FP%_*vDfaK_F?a&}MQXh@W3!K(>oy zX*1k3B^yBEBL4l!Y2D{-EG?z9Z(n{dhwjpO&#E-&NOs*a)KIpIi4C~%a}56Ffw3o} z%H%5UBcn{HeNL*qsr-yx!lDEu|$O-d(IQyw>~kJzOi7x$LO5fnN3 z3o-E}9oZHpn~cEB;h$$gEn;??SYkeV%$%>j8z=8B+<8P1F+;`y{!phJ=y$Q!CjEvF zi`w!tu5oryzLJd*D%}?V#u-FI++v9^7_vLp9r~DMvd2OyXku8FN-NZL1ID#*x;tFb z+kil7xNU`j@5yl_L(Q3liShnmEO2c74XD$sLy=Vp!tl-Nw>%GnS1+?d9*T~OsZdL5 z*jVbfO1$Ra;jX~uwxHvCDYwEaMyQVlTR0#%UhC{x=^%SNFZgZXpBtj*ZoZ771^dH~Cm=_z_%mRAuI(an1?oW%@CfUcAhNx+993D$gwo|k$ zic#8OAN~2uukXOi5fZI1KDeLq7wzyZ_iAl?$E~k^+ddlEX)Sb*-ht@DvWX{@l%~JCs8AO23+pa2Qv#9BX>!Vp24vV zvz8a^$DXz%M@-Nt_3?pfC%p;NW;<1_mSMWfk7dL¬?5MdcHkL@;)EY!!ECpJ!V zh>UtnT_xjev_;*iTxkzv)sV& zjOpj)mWQ#DPrxbh^BNNNg*=n?IofGD$ibr0Rp?Lo^uvzu{2P)T1aF-26(}`w!h?A~ zy732Fetpg>?Xa78OGt;KCxFLdLMoRIggwg)lc1&-x%IKUiGc@>E_Jntrv{zvAuo97 zKB0(sPMVRg6uuz$Qex;mP&CBQ&WNR>7Fv=R^G)@qr9-pM<+OqoHYC)K5Ww;$g>&lo zyRw>zD%XYKAs;+By(sXOUDA0VfjWEC+2T0nM(ppuHcQfp%6~u$)zhLeaZZK-K7)pb z9m?-pJ*V_6O^n*=2M!;|8&|oyl!E5-KzkyvdPAg>(i?EaQcXw=!+AK-OspfCILJ1z zz;e=q^iTn3nprj1Q~hRn5g}IwrEFR-zfOYpLoVBsL9#41%D+f(q$oLMQ_^27hcmze zjH6@l?BAglJ(TJ)WT9oD(fxJhSSz<76Fu$4Aq&_|8m=vCLdo#lSi=6q#$bdfiFWpZmxJTPk{l@=Ht`7oyMESyT=*>lE%q#J}d=XY%c-DchA{V`O}PL^7pczYVzEpROsoOQl>1mf3F4CIFtb7HehrB z>;OWY2MKjvs@*;A)=K{D#|H8WPgCp~c0Uw*xmpgVq%6lyR_N|r8SXcggr_tCp}Z^z zPP!6`xBz@oIyal8T27~o7(eu&#kh!Tv4p3}<~zam`ruhh9&gI%6)eqom=J6XJb({Oecer=mIOyc#mD8===Tv6n>U&v(9iQKh?Wf3sH|X_oREQrI@@KQb zKDkNJF1v<(%`$!^hE-c~Fm~oDfNqMkPP&x|4+M}33A#*PVV?);P(>K^@@+#F6-xCv zA+B#L{r;f8t~ocHHaOCDD=H<{*(6#7lbcG&;lx0biC+Xup?z2ABPBx1bXnN|>UB1V zkT^?^T8AU$S)&n7rzq%_<@TBOlAO6tYYrh7#48&!a2)ua*-XJFRpHMBjLqzI-vn7` zm+n{-2M7eB?8LbbrB_#wut)A4_Rl?R?`vbEdHVp7dtSJ#z}?51T~rqwJ54&cX_TfJ zaEbt?UxGaZ%wHKZ~#Jjgs5TJtZtBa0)ceJvdahSPm2J?!nQc`Te$g z#?{;C8cD1w2R@u+KKzD%0V%6r23@ZVx~DJS;j^@Me;i1E1~oNE0upBH{2a`$#^eQr zd)!WMSIqu;tGX%9sTTR!hDh{KuAiv!bNJqmWn0bEN(f^w{wXUV03Oz%Ob^$j$t-I+--y;k9YndvX{9PCvk<^y{w^8lw| z8R>MEsEsoF;8Ni)d|Vnca_=A|lT@=DOMwPRw?rOzjmh{fN3m<*lyaenx1P>S-E>08 z(fyB;kCpzp?vs>X#a&N!>C1e4t-0BAS4%-cqZsTwE1x=1Ql$4aTeRG*PCrCRxo1i% z<-lyOelI~1Iaih^KUSwnTn|lpZYyQy%ytX7jR!Fw(`w->G4hS4w{d;dSD4w#wS{lh zp3=r}-A|_jD1erUO#KIpKKSf26G0#C#k!jZ;TwG&%6wxG;ZC)vrN5&|MKe5t!=)d> z5@b80=lXPSV+-#$_XrLGqEtEwzqF^@M%G!o)5lRXz5?U#d=fu~t_9ZQw|@^#fA*NG zQT*OlvQ6H8YxY*ngnO)FFX+Y!SXrwq_8TScuJ5q*t2Ioq3bg%ct z&IbzmXQi3BvR%c@5)oH-i08ByG(>dGwVs#=W3NZr;{E*SzhzGI-WVS(aj}L74S`HMovCWROotn=&Fv)97->RRuFMSc4@+R`h6o>()K)X z&aAF0^8TZ$xNv{8gTmz0Wyk)>-`n4tZ#t~z0ZfS|u}S|fVS21!(uqqH*#)DHXKU4t zi~}qP0$iDCdOt1k7P`esdnMzeBPEM?7Y1LD0#j`1$z67D#w|#GhB5nDU8a%^MFd)5 zQahIi0$iF6aoWe|$I8_!^QO$=5yY+K&N64%2GmE=&PHkvzk{=!^1WV>JSWD2H$Qe9 zt!P$n(37yhn#ekr#Vj=N3fXbUf8=DONch~{*paI=`9{h?(NQXT&mIDGsI;=^3!k20 zvg_CJ!Wh`(u-jHHRl8UT!mliZA+9o}KHf5W$rOrV2L1al<^hp#y1C0jEEs9;T;bj7 zIutpLGuvd&HeEL%*~ist*=UAmyUf%#POd8V7!%`Oy7!cp7!kNr=5Bkzvs#fw$0KFK zn~)8iJ(Xp_D`bld=fKk0wR)AHPp3C&qAtM;TeYNnzjI#`!GMpfd4p~4JCbD{sE@=P zvn_LW(DyK}N9ILxGXRee*lwAV|E@v57P9ZQxAW7uWJV%r_vAg!Zb9&a=81OWWYh)o``wc;?s`Z|i{@)^q!q$8-v-)H^3gBYO;;*C-^%QK zYh>rT6F|?eJa+8Fi*1(V#A(&_!Ae<|=LY7rz3VXqwl+)fz`O*^~2G5kTewH;BH_Gu`0TMyCMZ5iUq6O7HhI0)=z@Z0z#f<8*tMMGub|FIxD|9->_rHUeb2Awps%BfK7c^HoRp z0x#nh&wOsu9>u}4(eMD$wOoeD^0!xvkJ+x+8X4sDV|FE|-|53lrO}Yy3!Kh&goALXvNHf)yHw)E=e1l0-%0}0p3q}8 zc}(_bid7`OL9uAYj`yZ|0Yyi{CjtwL*tdeq?OabrT|Rd$UE1O$++6kbk#IOM0a8|Ls2)X8BnhCA<98Q233_}t0msBC z`lTwb7Zru#!l?lfd+u~e7764d$U}6FHA$B!m0e>`PQg-?seUw*(ENv=S0em)2v}fB zZzD8G!#8r#*0q)#{scM3C1@nZtlv|lKlnzXpCOE$Y3Qf+j`VM$Px|kS(aCQ)TGmtx z*ku#|ZmKjvM;bPQZRDoNk>DoU;-{{!dZ&a!ewYabYT?6apL%Z%bnm7j51f7yabPJr zYFcM2%Br+T&}@WFXyuMCERUU3NDA-xM2aKg3wgu7)?*NSFMtiI{Nm!7>V}O30d5x4 z=*LRVf9O9-Ijt}6kA}7hFpI~Wu;hcM(6O0k@p3zFNleKsPQP|Vf(z|br<(`i>YQx4 zO$|reGT`H!MyE~oI?d%V$fkQ{`OH-4U(eb|)HY$g4gEO9VRkHb<+n}(K(SHy3pNP8 zbjR1GMR7V#PDu;HZ zfB(gk3TSd{2hS($eB5DeH%IS*CIg%G=9`cfJN3*)ZtS=yk*52X$kgz9!X!yok4f0vF3l{h*c-thpNlbP z?E1#(B3=wGe_M*_P>2|GZH_9|JnF@e)P8iD8Lt`B+zZUfxc`fzSb0K1RT;Kvz0k5fub0=Ac%H9?x z%HP@~9=vifWGdt8+{RRX)iDWp6PQKY_+!;*ED)0DwP!#$XqPhR{z!Rr*snSXKz4Q$ zBxYP}SD8ePvS8Uek7Z-h3NWylGWHw?68Z$3K6KZP2qM-F4w&cd&d(D1i@gssXy3@8 zvqhfgRE)uxv74u-il`eTJ}wITQiR5SbIEALj*-iodlpQYBnO-aks zzQXlv1G@4x0e${fyu|fab0R#%q2`3{QsL(EHDP z5vUWE^aS%>GjyacfemJ?)#QAnYl5SUED0mJ{8%iudo`Q#Q&9lo8LV{;QPQ*|a<0f% zJv{H;6C7)Ji=M{!w(^24OAuWl6&ZQ~WkC!$zp!;oX(YI{dfJw;=T5>!;Jy`gpAlPs zwo@Wvp7x|$G_~2@`{D_d8erQ8>og4d2fQk@b?uw9gAO2AdmAzo`|VJ#mXY{cMBhBl zG1#HZ;qZ=5bj0OkUcPq;Y14w^;VXePPH?to()GaW{OgbPt1AB#-NJv>6m;CB%uxa9 z0$0`#R{wDgkIx?-7HdOCt3SH*g~=OzT6+s~hzXTIyJ+UucW>2?o&t*nZ z0W*DP^4H)D&iQOjW8?EOnUPH{fXqtY=^t2A1qEhcD{HmPY8kUf&dPUK>U9UsIrMO9 z<3x3NWgOGiXRiMNAkNZ{y1$pw;hfThT6z^p*v~4B%FQ*eHn=CzU%*dI)qmdI4RJ?Q z#XafiaO5=lt8~lab0Pt}W8hz=&GfWaLU!Zp{BiP)zedS?FU*gXcX*z+_JYg`BOzHe z3yTvLpFuF2W50cB^-@ue@oV(=_n+CC8MgfkalY~swC{bGnsdZDzrw@$A3dD2Qh$XR zQ-D~cCdeM%Qup?M_TF`1Y<=hwScqp z5aiCp@P!2N*|r7!?InVbznp0u;%HSqgStbzn?V088xF>IKK>n6bd0r58w%8%R=o;p z<7|7-Z5NoJbE!2r&al0t*`tjw!Qzhab=Z0gU|7A7CK_r<8&0w=cE-sot8eUgmElq0Mfg2sIl{AL0OO(gd?750 zoBEL{V9P<`NYu6>PfdhD<~&|v7pO0uDfxRLqVIwQ7oBifo7t(G69Bal(zeK0!^B(W zRZ(F9(|NaeHi+nqSrJx#P86R5@R}lYySw(9sai-PP#f8`-wm~DMvY8_sXoBxPVeiy zH9LQNK~>VM76zg8U=pPVH7FWNVvP8}NcryxVO~aIksb!u3^NWyVs0kH)?#BRfI3r! z8OnWH@m%p^5hCsDua;xO7EQFxL!Ko5qyWBIqhac5My zu_d_`5rq;I!zBw&Ge|bDdd$JL{>37%N796cx87e8fdgv4?6?=Y<5{6EZE5;DfJaJa z93s{{5ae^PvwR|9*VU_`mrw0y_~6ab6q9EC^sUs&?-|fLoIiVSZ@xvDH<3NHCAeRS zIBEXDa4({BHELUmi$E z_1hR&)!n(^%V^(Xk803Pv>)!d#39?uswhD{+gy{d#DT;`n0fM zkpsHpJDO=%?8&FLh~h}Rw3WKER|TmFgMi(o3mmcgHdfCy?-c6S?^kx` zdy7+kwjLLSc>jdt${{>6li(}S`;V>xus1a5vXEX6Ec`emz?9NwpCPU?MUNh8l~S)C zHdN+C$gk{O(*(nMG(o(%HEnQEkKH!(u1& z&UN!{(wp+$U%mP?LWe+gxLPVVEzExjklTtTpIBRmOS3GAcd43z(13BM>&boN+3N~; zdw14;N4e_m*^xtfiqTA8i<@P^Ho>sIbKR1??DesS-m~>Cw{KDk@w1PpiI>mVROZaq zm19~OAcp-ftCnXAw4-K!FDi|v%20)7S#N|oNCgg<+P%5<<*&cvB<|21pD#Dw7Z(ve z6sm7pV@8TV=uss*Q=OyPg+Wgz<-+$=O7oW2D;y@!hy@Ax{jgDBQL5dQwuUXZ~pWqn{-xm>j^^WsmQ{PWp`Tg{;z6wh0!N{R1^PYaHKXx9Jr|0R z0pm#}u~D;`JJ|vcazVEs5TwddhLbQ#wOwjhk-pdFgJaBhxZ%Lt;fA2$8SLGlF}BZ{ z&u(fzh{;wZPF{!Yi$FS`z5UQ{2jKjL{=u0!)ti;}q^u#Owr#p^*p#16^g3G<4SW)B zVaD%!l#N`r#dEWxpP;OT6}pu(!zWM@Q{G%(CgvD%mbDg0UokSypAZo-9*r5hB>MK%zteY+v6&M zM!?bHn)(f=8Oe+GnIbSd5ck#@Vb&-MAW64=?p?jzd&bRkuP9B%v{%f2z;S(gTm?Xl zTKmswa2f{TDK0gf3v@+)z}blv*T7Bp$j_m83iKV|4(z)4qrZWZK|69JGMG6}dClOG zNiie`G#(n1JgsSRJ$ENaQ(|wz6y2OF-A?|dW;By{83WMA(}AtM*;oLv^0ObM)ZZ|4 ze^NQz8c{O{R#yr)3$0chV{eW2Ms&TD4f?P*E30TB0$I~DSS&54*D7AF%K9)P37QFS zjtuHrK6!Q$&Je%>8M_*m(0Ev3B$UOO+S(R@vAhAATz=|M^qh-eJ&Aepi&`dp*5d_nyUaIPHg?s^o*GI>;eSJqm!q<_z*xS7yT|chTeW ztxJ+B*+nV``la)$;@ENUMG_nD;K+Tt$>R{y4!RN( zZ9_SORY{fB1(kRz5SNxjzwwAj?AEKGuJDigwv%m_-DJC^YQT{qh50E^~`PY&pf7 zY|xHb0HZtCXMTa~zXRSof7(%4P1S9qC!cjFyOe0MI#z*wo~^Xo${09CVi@d!@gd5U z(l^Pz3FOo0M;FRTM)4)a$N4}z>$7F#YO+7ZrT^|l?92`qUbb?=Ge+IDm=z6aed?U4 zPTOv%@<6N?un+o25d6cs3*D%2>=qO2NZ!TDntUQQ&AB%HdY=dtmUW^6dBpw0HPAYX;Du|yHk0BXnkd@SgO1h;rPmPEhOwpfSihR#z3OyUe;^j}PfQDsLq2CIv z6<+JAu1`;5;ywnyU5NBf_~FjWlGqOR`j$5Ak$6Jh+3qfR0op5prax(0xs1SF_xWQ0 zD}oxdGzCY}68uK3v4V#$9rxS)XRiw^7oS64)9h@zbK$ zme#y38o+^PUV|Fd1Ps1HLri;IqNAVo#P3Dvq^mb9B%o=@pyqiq+W>J>gjlD&SF~3@ z1eX}w?;B?4^uf~{N6{mKu_0wA&0w1#9dSF&*|_SI=iLcdVY={gBZ>4evGyTkQrRgUJQ?wlx!#0levE z2l$6$l~wZgc-un4YM~r~R^pKY)Ti|TU1ooN8~670z_+xd4rW-YAJ7L&b+OIGzno+- zRq5Q(yNSQyR~VS$(rHf#lI(nCtaWLH@OAY$H?@+-)kJidls@9m# z(Rq7L=i{ETX3t(J2h zXleEM2i&My_O^O?>5KYVG8Gn4#G-=1ECzJ0v@l(_))q%?D5VY-+qTcnY?1haV;Iou zwU!au-FT9Ew8TJI2-EZi5dVzZ&Tw94Q7t4y8O}V3F>Bz@FYQ)8cVJzes~G;2?B?FP z=jmo1U}xcdtBv92n9cK^7=0$tv?*)Uh=c*c5r5$Y{!9Ue^*WON06ejPpl=k? zdLkxm?7l}Ek7Y#A1;}zy*tlvvNa9jWo!c}fHn7Zz9_m+z_S>E$VFI%bhBa?8;I?@6 z(j*7neyJ`7HiFkf}^EXibprs@s{akFTw2kiSko3 z-3vu|-F&~hMM<8Yc!v*JknPPM-*S;SZ*=X?NIpeC=jp8mqhy0Snc0}&woxip+e!lO zHXBb+f5|a(!vZSKQIW>LwG|6@{eP+k?olP zm`3o1j98r6e*jC<Pr6t3YLH1FG#~L!7r5w!Us)ybykT9-mUs1o?_qk$HRQsy@&4VdDkbZiqS0^0;HctatqIvN<GS4hMS1s)80+j6Ufwp!eL@Bhjo@iI4Q(=T433g;f>T>5|UmR!CbeJ!k^{s_9!w%P5eA;9H#^3X)!q_6N z&N6?-Q{syW#C``HkTh<)=3biJu@B;ksS4~7Q;~GyuR}shSQkeh#wRiCj=m0APgB*~ zAS*Xj@v}4hRQx^_8aRL^FSP-m*nw-8l?7;O)S5n)v&arsgs#X@ zqJl|E^J9l!uyw_TWFBr$ zjEEhBH#eF6gnx7KQ(J9&JiQqP^rgRZZ0-o&(h#j?i^RW}>6P62l&V0s3jLQY2h&$Z zySTgLfXKT-Ywjuomev*LKbtVrK43Qu7#Z*M53N|-(p=;$?~^y!#45(k=S>UofltTf zpv>CtMMBP{i*;9Thz}`pU`0BeC9~Xj{{SjLxeB>Q-&&FMywBZvsrWt&@zv;^DY%^* zvLl2KgL!?>WF2>y4!XNtwG#NUiD#BT{185-6`g?Ia*N!3zXwXQwHgZ6+@i@F*Jeif zzkSdz7w?Mht3|}f%11E0rAZ9*jDhrCJ*>f^`SW{hv>W^aup07}7!(HKwGrWQSZ~Q$ zqN8%a*4}7(>GYd}RuUWxm58KP{q!NuGd7#%mop&UN#1epNJ}3GJq9SorB5 zE2%RNJb!%ap#R6CaT;6Hu|Yxo3M3-A2f-}me&pQqiuEX`5xI>IYC)Z{px+0XI39d$ zU^j@w5)K<9%8(I+xt_8w%1_B+4`T7p0N+Ns;g>98Nox(?Yh(<<(~2qV`U8Bmt^TkC zS46b7#-i}X{ZX4042!*6)TC+}hM&@Qe+j{ABahUcoa)xC%5k~ZY1rQAym^Io^d5YB z_jf=rcB@;HSLGHfQ;fN^bfXDJVh$9RSXN+}ldxwn__LzyC?UVl&-n6(b7n19dfL02 zov{+_Eix3+-eD_zwqR`TIvs~3oe_xjT0=XUBXNg=R5skm)}B0qMn~*p=S43TK5@WU;V<xY!1w!`X}NLP;|x5%_D_tLs^ywLd+<7q%T5?Cf~=wkKnJ4_2Y$N!?llXhDv9kE?k>kXqOB?;uf(PL zyO2~IqkH#7U28dWrJw(>Th&{vA`R9yZ8=CY9HGC!SwbYO?(oi@6BYD0m1Kf_58mBu zAl6aA7_8+!5s=!O5dnf$%wT~9nQ;j9tFN)IXxRw}<*-gwZSTkI^UP$p8ry++8k zI~d6*cM>5Zf1&0!_$0x_$(K$S6*O@dQkGKwHH^7-D`Z*UH>+5VI8vxwf5YmIK^~nS zsbqv7I1psUiE$EbqZn{>iF~aqHmN>`O*5lJ-3JU6sGo&)czCC3_!tQ$0b7F0xw6@X z`#Gyv?ZD3-JHK63iFqC|tpiQ?oq#N3Mw-!3ml5v&cLAagi<{jm*}I zhF68cz(S*ElEEh=0GU6f9k!dlhya=id)YEThvMm$MPCkP%zH9~!wW4al?VwOQP@gQ zALHX8nu$ZJ+<8B!^#@#oMes5T3=M})X4o^&TYcekM=x2nKuP)i-jGFbxc%0a))S{y`$x9??lfW&RPL6!NL-7~1Sw@)ETW?o&$`fma zwMe?&F}gh&b>4hp81-dypJrhH*z@7k(3fRNARXJmjD2OWJ{#)FIy&qo9*=#Z|~$$p~LiyEpIty%Lk0c>p9fA zib|Z#3Y%4O{oorzDZ{B6mXlv72hILIsKN2Iy4YMi)`y(S&ap116}MTtedr@{46+vY zC_ThUW`(hTzdKr$s6~vI3V$j!gx9TFgeWATqfRml$j=S-%}w; zZe)voBm*enqCd;VR%M72lNL6dz&G{ZqZ}ObJ#P?7E2u?B5CKbPEk~4cH-AzrII>^sL$^)N`=Tu)rJ;Tu z$HIwuyM!Yz`Z$+ELbo`MD5k$ZG2VOHGvEwz&camFqC?V(M%2bgfZ@6v-fL0e0d)k{ zIzOXE`nk2sGvk6vEOtgi=O)}PeeYoq>}=9!{-<0b9~$q+aA^g;MO0{C#`M?^7)tl;O=mt+!~6Y}NmK^>)JTI5BJ5h$D7@&Gd^+qa?T+&jPQO zl>3<*a?z!VM2jyF8)9-e$)`7GcCr>Z?QRuNGYM^j?hl54EH>ypitazTcwx zjz#O1LGXCw79~Kj^c}Y;h!B`Dj*SJc1#fAQl3@VYegArWbrm4#XYpM zTg!|lqr$mu%mHTk4+t#iJ(5-fdyC#MCKZ+)tuUeh+st`FF3l~H-g5T#unw%D=^9Fq z2xB+@sJw{)*rhlFZT}}@3N(GfAn6d{iW9Zy5WSKl2c~jFaCS&-J7>!Zb6K|(i%xm+ zh^`_ZoJ@VUC6ntTXpH5ysDpxz4gxv&ZRF0cLtoOI%rjCl=G5E211Cz>!}OVjT@QJw zK1V2wu?l9nYlN)V1QT?3orGz1AZO7tDz#sCOXp9PHF=7h=3hJ7ZaHU~FyNrFd0kxp z)|P2KhE-AoL3t%(&wDi7Y@Ldk?*N9H(l#=d3>lSly3Tf)4mb7x%u9@Jr9x3iH5~sCNaPT@E(KO|;^Y_OU;sYf&|6M@g|!2jl5&3bi_5l&k!qM<=DW zyfVj;K+@AKEK#S4v|e+r+K1jnZYCr7hKax9;v7L7^yCn>ww2-GvwA9Vr+{Q(TwD<$ zdXgNr#jMW_#4RMPPk1j)hm_v6R~gBNPs%?ncMZ)a7IOfpv|sB~$V_2iAz_5{rjNEgqBVYO0ZRaYe&mZ$HYEwTFiS= zqfl1xAIc<28?!_@t6K1#BbSn*Kd>ARy5H3`y|1p742=NTkTwpi?W*X2 z^`^^@>EtNi=uYq*r^VqG7E`v>VG@JHv=JX(klKh1^>eWiH}qAL&Hqk_42}h8fIz}i z$v$s5!TOg8n41)P3zGOiHYKxpWV^*Spvb6$-{u@HC+@H>1Axvy z816*sH<=_~b`U_?+sIfB>u=QOJM3~G(%R-N7 zzi>E3g1RL*S322}CZSL6|NVJnN||~q4;INhHp8{{f}TjcoomEkdeoHBHf3+Zq=M^N z0u`jjEX4xnnvV$@kHfS^njZmsjNh+x#0IYO3k%+i1xi4_gmEM#S-h*viQt|br>t5* zkX63R9E)iNM@J42J`69t!Y38)i<*j}+`E@d0RrzhbHB@Lvof)$E*B|u z-_UC<%nqwID4#c$m^ekouu}sPT~AFsd)h5x58E}>mDJLE%>u|Iw3Ca;(~%v<)39B3 z;$sOuA$pUqrtR-0k5HskXtCncq;u-GGaXurY?VBhsR+*^SmQh0bcjw;gOzlg{cl`F*UIxeQ;ONVxu2 zz_GfEryftwKHFAw-BapOa?fOssu2*_th7x5Xc=uQDHL)e;F2au>4gE^CbV4N@16Vk zE3tsl)RY-t5i3uQfYl-+bvnfhKYsUArnR4{%A!KA*_6;H6As%;w$cLgiSUFl1WR6< z;1#&FR?2XO{0p@GuZkZWi?7IEFbH%aSu9R}IMKfQ= z&RkynZhw`P#Kd|v?DDft+5MBzg>0EU)qlQMgAFv0yZUm_e1Wm`EHst#{a#1G$&V7x z!?_;2X?q;K9-v_|_>ORue<9A+CO?f=*fxGYMJ=+!B+?;-01-~~h@7)~+*`>=J*#4S zB8jr5x@se4jYhsKKs0puB{!NR;+LBk*lzSp!{hsrJ+ru?Bw7(4L>*QI-G62fs0DW_ z$#~2+;@c1$^K-=?k5aG_XTk`vWWzspqABP4U&SBt)^}PIzcssFFmUxg2h0Uk^I`W4 zxwVG&C3e8n*2r%b-GA;wb|nXLqGhzMH>Gs3QdEiM^ZCT(vhWG-3eCR^%25)eWuDc$ zdbs?!U9c@b$QM1No!rLPU~DBb5}X$HN1WkZIC?F`H2#72hf|X4Oh~ueGnTkrlwtyAd(!5%q zH-E!9=f3ZA-PiS*)&pN&By!vW>m_Qn=`U8so*v|JoGMa2erk1+jJd=+%5U96kcJ^+ z3n#Yemck8gU@Ifmy2C@0Xb|EAPLRRqg3d3KUZ#QYmp%5tIwyD znLPp>$BlV5=9H4W$<5C*W3&=eV}1njE@l7M(0M;Qsp+oB&BMHT^oAfLKK4Kl>#B9yyPkqhjNm+l!nDWMgmCNp3T~Pbm^A$mU z(1<3qx_Ie>NA)9?%&$?$>{#=veQeZhgwgAYw8Z^7HV?Z~4;y%k^A5IMGYUpQy-PT7|8WDEhi*%u~(gl^7%&ymSWstom_X5;Jx*%s@U2 zalMLaJ53gA`$B)-Jz0w=3)l&_cX1RvqT4Bb7;V%Qy`1ulSSkDrv^$OavN^N;>Kf_w zwHbNf%;1SGGtI0c;|)NliD~DOwS>6TRu9H(3PpU+`EgRR1+xsH7b#H~>?mmZ%NOg3&zS4~w;%O6daY-r~{bTGu{4>Xzx3bteU7Ko; zTAn-sgsj5c`*UbF{L%%mjDXp z=B_1u!d5WXoJE|wwBCqz;y@r&k? zxV;JAAB8IAG)b-vH24&r(T_`8wm)Mcyj*@xG3M{1WA>j_v0=l9{v?g=Qx+4O(DcFb zKb^#*WJH$DAV=kIf7oFqE{6*60lgV_v)yE|g7wU2+~V3Yo<7th+*D?YB}gsAKIi4c zEmiz%u4j=)uJbZ;Df_DXWT)QtePFGH&{ADc=Xy`qTbjy9-o-vj$m`n_l@q(YldiToLcZ)eHEkd+H-+S5Zr2n)YSDrCJxj(?gsWHtO{ zEehz}2&tYnr^ZoK*{zS;pf_Jq?GAtQGiz@j@DTUlZojv;ec^s8Y0J+|TW^Zt%|nMm z4RYu!yPoSudqLu98hJKWt*O7fP`%$$N}wa^QrNyfmR*=j|W zJI_z~Ba|CLAfLqeB#Idy_aMmjSJN`q>+x?tlO*6-S5sf)s?RMJ>GSsE`8@y~wMUDm zu6UcM2{TCmgZKUW`4-M{ShXmJtGiR$#IWf|vh?U(O9WPw$F##yK0&yXvTNtHfNPE< z>tUJKvHI($u=U^@;CgZ(wOUs_s5HGGbZo=WF+Pcx#)Lq**sz5WPx zpw1kT={{BwRNA>Gv7uBuJG-OfEl-+^7iEM#@RWB!<*nH4LyY}F!vjxd^4trw{5+W}isU8Y1Zu~mP*0qD8n}g{S z4ja}-=FQvp>cjY9LYw}9G5-;RPs6+jQx0B}wU_8Wk#3tlWPmK~+SozZLS#5W|7Lx9 z5b8+vJxj($W_v}h0Q~SYt@;Xo(eoUWHts2qi^$>GG~HNPFLJLHY_!`s99ldK3rVbe zkry1%^0ikucJ%qy)J#0AN_9jm$rxzUJ}NMF=Pw(+*Dc!EGr8{@7BJXa$BY_(?9a?A z4?Z^M!vD?uW0R?`R`edHTCE@6%jt&_RjHGLQJG6cmQA({Go77`D(%ozgWiaR*+X$v zt$+EnosOR)Cfba|i`%cc$T#4SQS!%!rRu8znWqRz9h0?NM;FYW=|0)Ij2CMx?ue<$tjs^5&|y-d@Due*`)sm+#Vx(_&>SyjQdb zH%(4Iq#kPa=qUPEoL}tmkq);^HV7v1u!<+W>UQXV zpr7cO=az2VE_!4Zl?T)O=lu-pGDW|Qtt^xVzBy1}=twfMdi5|N(b-KB5Bn&8Z+6{P z(TJuFsWG?U*?ya;WbIQs@*>Rw?CD}r{inNRXWP^-dgK`cipK;SQe1lU^l@SV(D`^{ zU=jg`mn&D9_A6Ed1L&PcS(K(*kThm^VRh3$adXavc{#gqFQITFepOMdF9^X56b(b9 zqo!j)6?0R(ywZI4T7|{&bzc+jnIh5YIs_Z0TSo5O!%@%S)#vbS;HH^b&vMc?9vN@K ze+0*!4(xp2HrFPvj2@Rt8jW&Tb;ShXgVs|3vc&x-hd!uHh^8H#8Ym6XqIJL*bONl! zRck27_zIVH(Sj1^QNz$HXn!r*NVdAAX`VaDeG_Cuz#l443M%_@z6D^SGBynrW5P~j z7x!XEh8WTT?2xLYcdYv5&hfNZcL#&HU`O&qu_my{WdIDnSHN9a=Qq?9RdYg+S~jg| zGTKr7!9$7fK&^c&rg-$x%*4*Qu&8kaLe%TuAiSqsyb-K{q;L-pYfY~&px3W#J93Ql zDZH`LJ{oKY+yyRc)aHC$rr-)HK;Z)>{sYmNoUpZW4;K0Rl{@7)0P`UVo}&5 zD)_YnzEp}8&7eaWQMxe%O1?cml7xMWEcUhf$A6ELyD>*6&&dU|A_E4J+hWOpr}#!$ zvV`@Z*Q3kClI$(-Q_yO6mBL0%C>NLU^W^8&PSQ_}Q-*WSqcPgUqM`BSldHhf|CB2$ zhbRjUbnobjj-+v|N1@jdZXoMQEx<}nYpr71)A>o zBhXI;za94581<4;B>KB;3Y^Y!197{BaKw*5umywFU9S9Aw7Dn~7ftITwWcx{3E7L$ z8b>qCmU%VF2 z9ll5WTM8kE4PV*5Vr1>rjk%Quud@A_X@*-?drSpDp- ze$i2a=e;HU1z1gKw$sU6|92_<--&LR3X7UXgp+J#Khxg|mUXV#IM%k|CSE!$J8NR| z0KE*g+_}H6n1RPWMaZKs?)aQ?WM>%B70o zJDBLbUuUka>vqY+#SQWTaN=R__`^_VRG3U3#e3!A6eWIT#bvk7Q7_b@oL!6iW6azp zN@p;Za3`+QRAWNlY5Nr3C7uTGBTTUj*8r?SA6=|{r1KE1b{!9<%|MGX{lr^Q`%30Z5Y&^QF& z11n%b!he5}lxm?eMskBwOrHJ3247jG-3LVPrLP{+0v+f377Ho7f5-KxiPlmn18z)( z!)nn+Zd)wa%nQs^FDma-%W@sVW}*61o#>PuWiOzg1IU@(OFy85}(TiTtS&k10LWJ@wF7=`t$l3{^vo_56!Xr>mnKBMN) z?unOLYjje<-7Sqc6!rvc1Vz1myL;U~)c(-g<@ql78+R6C z##L@ul&|W_2RVRsC!nuS6CgNbICyj8+KtI^Kw-9F`sJM9KwlX)Q~o8uunc4&IWVpN zH;7wvGV4>r?ai&lsSvB)AJI0JV#XKrhxG>fovY^!#OU>Y6bn1rEIBW&V7I~Yh8`Kq z8Bd2B&F?){f9GNk%PKhZ7niohy8wZAP1GI2kkT(_+<7_7F_RT+P-@C|&gp&u1mfL8 z>f=O=8z@duHK*r449oM)&OCx7bsB;(7q-)}*HU%-8?F2xe)F~(T00*dKNRk01m0jW z`=W!bw_1<=rG&dnTn9 z&_*uKFDNq#qLhYL17OpJE5;$0f=(dU4}$kqGG$xQ^)Jbg!|=i_@@tvrIpZw?OO3Jb zF@oWpfWo1lQy&wVA9~%q#yT;7RTHP=DBauKiR4`?W&196iG$j-W^OE@{|U`C`1Bip z+V@yPid8KVvFWh%EJlWl=y4bewus#lyf#;02Mwo>duvAG#yQTAP4vr;nFi`iX)%Mv z`Nk^@_-Y^MO`cC-YX`gE-F9Jh3P=;zG88!YL)1F$?#6+{~*3BY>xq}9dH zlGP$e8n77CEmRPUxwN_qmT}hkj zhDhlDV()g9`!{7f!5yPkJ+=R_II=QPHr-TfH4ca}MMhKHPToSei0vnt8(Pk^dn_94 z|6v{osxED$tKA_?UPL&J6gSPW6{^quBP|iGe$xf^|FQm(Ta~D75}}$2zmrZX+gf@g z=2=ttWC&HNU!N#g>9>zF$Rfv)Cx-8pwnN+pO>{}$K~R~mp6%3{S;dYfc`xF?8FL3= zaM2)=6MT@SIbW`^T6~!i-DU53@w_c4;wHHCKn*%eW@y&e5Gf4;BmHy-!G}*3r=_9V zZx=02A9x`}Kil!uFbsI6wUV?|hs6pW@y7UUUOLGvxio3e%XvtX4^F+`Q&X8yW9@ms z-h7}kQn$}7AH5cCILM>|)RJ^d73jy&=0)@%z2@uAn_0vm%Rtj)*~yYF*dueuTdyaQ z44-aAG+k#O>u_>k$o2FxmTL%*X4jB0?a9)^!DkYZnf>?59MlbR_^$-GeK8xr@7RE# z;$u0&4eB8>IHKbXli%#-J19o0jBCNJ&E~Es-PGRo66WXa?{0Qcrg^RUv8TU{6#iL@ zI=R?f79>n;WT%*qu~cmZ{1!yX{oJix`z$mv^hq1baSHj0E4@Qj&R2(=o7ldSA6AM2 z$qA5NS;!dyKU9nEw6HDF7>OXB(cn;+LGJJ|V5W^X8N?|v%Zzx9=%>cr-dPmqt2Y_~IE_xD%9|*2KzzKvE3+r%<%e$0 zTj-?V&hKm-tZ>uP4}|JRA8X~;=NvF#59C?~|B$1t;XW+3M6cL1iJ1iHxM>uBH^0;* z$w<WH?yY5tv;S?Nt^MzOlB7(E%>D_6 zJdz`Jie0IZw@z2rO{?44dak#2nY|SV`h^Dgj6)BU4pq1UoMX>)Y8PzeTsv&uzr~@E zxy(S?BldaCn*QC9d*K4659q^;vgd2;MQKTK(@EJR^NKwOD8^A}59>h<*yi{Z(~$%` z?_I_ttIgTpbQaoKkIfQsp> zv*RmKZ|lY<`%Y9FiQS~-7i|TP$gl!P%kb#tbblJF)8UdQH|+4XPlK$-+I8TXehez; z7;wxbNoJWMPu~Y$@~6yxrMRQV5^To;)mmB?fZ39S;ViE1e|C|z8S-%~JDy0VYZ5&i zkKJrTyI12>mlbYQrLpX(bPE;v>}p#7S4yBoV}p2H~1(3#pw_L~TY)sr8-gwh1j+jJ+ zcicI{h4tp?`+#rpilyT9h9lK^rroA%nrO$+BUSBoCh-?)&OvZD$HmPhZ#1Vmv*f!n zRz}ea<6A?t>9LykvOr*bWbM`ivguP-b!yRf0k*T6wW{PeTh#H9x%@(3nKAs_w?IFY$GI$#y$FZr@&`j`Y8RqPK@@n)M ztKTpilD_;W?^*SE&+z5yLZ+6`4M;k(6vH^*NOH&$nb#1WukH4eSAx})wZ-5hh+l+P zFY^e5VMbgyC8O5iSK>MA)8(mcCuGNcfe|pM1kJH%yuxU6v4tdVwmd3%WdDb*oe_9; zy%#n#$evk{7sFy^PgIZpJ-n&l`Dhr1!)&=_%s7SSXt%^3%dU*!Tz-^ef$gPlsX`^_ z4U1FG1m2uW-u&f@6RU}pvsUg$=z6pB6@C!ibmi*1X=6gh<9fy6z*>}xyh-dciwWN} z0xd?Zt8Nn(6^rBHw5j5PYzDGuXoyx|B#Rh@@H`^5I89J=AFr<5A%{^h#wF?Vc#{6F z?*L28f<|3f<5BZL5n*|#rOd>+NnW8?op?PSwjft+J$c|^d7RWJ&ee|A>vP(AwJI;Z z6j3?c2sAG^NLK#u*XZFJae>(k+Yk$B_=D!{;t!A;(9LR}dDat&ovtA0nH^hTGzb-S z=O(1GwWlzFuheZaXnxSojTX=igl4gp9wJOtBdU-=hJAGrj1!aK{U+mo3Kz#>vNx7U z#nBXD2%pdK0d>@zp@?^g>UFMR%*-;y<_n+cYi+dJC=jLTE}^98sff`w>|ml*rDR=N z9yv&`sL8fr+qAHavWDmm4xgs>ewg_c7X3wqpqH<0_W86NQC$jRM4UGmg$B7bT(BEe z1@d6Apfk0H>}@d42I!{^Y2Mqm!&3Q=49ESLRnD3D@M6pzh0gtBK=(Q>e9ux>hbSmw z&etLqmF9!qcMfUO6nDln1Mny?6 z0%FD;f`xm@)3|eu8V;(IvhSeGESAH=x6^QJBk3wS`89v-?0(fQqe{8n7B&GBROqn9 zd2hoYV@Gq~%*m}uGuhDZ#49Wv+-fYs`X|PUqmD`pxh|LVv5)0NC$o<87c!^Yfa{ z-nZQo@AIj{xVkQ?`943Dts|SY|2bQdw2%`x)80%@U>2p&3_CJz1Ra0<6NC`0G35B#hTp6BeDCab!KQoT#`Y$= zZYMEkpY^bmt@ZM&fg!W3;+Bl(F_;@|*Jl2<-l;G^8`UM#*;-BuA3HGCQ&n($0wy#g zd(-_i&UaT2mc1 zHtZ<6h;eCk@V1H!a{?%xHlFFNM5Sr{?E9`-uYX@(;KZ&8;brC!3E}WMA45OP!u>~< z@4mjvyrloqCL+)N z&1b&FBAQKTEsj9>?Dc52i+=Bn4@_AsVDt^y49YOKcOXTd)lgc#re~ol?|^UZl>Rv` z6#-lQo&`aCqy8?Q8v0ZZ`gN}9JO;L^#iGo15yO)GxA2vP-<>#=c>edSuyE~Tv=V>!q>Wvq%TNV}JWfT{;D zwhpA!POSgSOq86yYxC-|LT4&_gj0bOWt;v9E-d0sOfPnfS2`%dv<=3}q%{UN|5Y8Z zgoPV|XtIXKO2~L2l`ar}WVuco-m?xVnG*a%fyua#t+uU}!Yzhq5TzX7t)d><-Jjv* zP)8~|%%Eg*TJF;Q;rtf|qywWvT1nRW3M9Vnyy z4ocCO2^jLHQ#2IPno7%J>kTIz(0Dg~rq zm3}QPb%t90zsvKYYVWGXCzqVYC1CsUWL zJGropxL*?G+ttL%Xr1hx=*>4;<9{|T5o!T#4vr%I8LJjC%Ov!}Zoa#Sg!V_@SCFd2 z?X^f+?OW9D^L}G>{*6a|`Z=1`(ZtFVm6nrBWFsWVmbFj_-)Jvb=Rd2d$TB%L2F`GR zYZy~((8qQUbNKxj-Esbqhj%|gQ&AEH z!j3F5D&(x{^AET486M3{CuGvr3y8;t>ka7N-9l++%CVm}jQw&02GGGzh{~**@&e$0 zTLQCmC5MiP7Jf{uVZBd7?6;^mxo^OE4485JCy+HYYoUL$ZgwwyKrhY&u=xbJm0~%I zjqw+YLZ>Bk)aBQ@7A;27`f;b7aY8ZWyD&u(gi3-(Jf* zL48}97q!`&toFW;^fjcP%jNC$;wph-!m(yE%%y-Xu{ws8fZWt8izVZDZ~3v>#tn2S z#j{;~@qgg!2G5k-z@|V~S!&)^8iXY0yaVbE4<$$nqS}f-jk1- z*Hx{rdk+8r=1aCB3tPDxaa_#DLX8q+`o?<=#wI^S$k+)iRp7CS6ou6ksVe`rgba(${Pn__default.default(e,{format:"array"}).slice(0,-1).join(",")},${o})`;var Mo={primary:d.blueAccent25,secondary:d.blueAccent20,tertiary:d.blueAccent15,quaternary:d.blueAccent10,accent3570:d.blueAccent35,accent4060:d.blueAccent40},Ao={primary:d.blueAccent75,secondary:d.blueAccent80,tertiary:d.blueAccent85,quaternary:d.blueAccent90,accent3570:d.blueAccent70,accent4060:d.blueAccent60};var Do={duration:{instant:.075,fast:.15,normal:.3}};var Fo="./dark-noise-JHVNKF2E.jpg";var zo="./light-noise-JRI6I6YG.png";var No={noisy:`url(${zo.toString()});`,primary:p.gray0,secondary:p.gray10,tertiary:p.gray15,quaternary:p.gray20,danger:d.red10,transparent:{primary:f(p.gray0,.8),secondary:f(p.gray10,.8),strong:f(p.gray100,.16),medium:f(p.gray100,.08),light:f(p.gray100,.04),lighter:f(p.gray100,.02),danger:f(d.red,.08)},overlay:f(p.gray80,.8),radialGradient:`radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${p.gray60} 100%)`,radialGradientHover:`radial-gradient(76.32% 95.59% at 50% 0%, #505050 0%, ${p.gray60} 100%)`},Uo={noisy:`url(${Fo.toString()});`,primary:p.gray85,secondary:p.gray80,tertiary:p.gray75,quaternary:p.gray70,danger:d.red80,transparent:{primary:f(p.gray85,.8),secondary:f(p.gray80,.8),strong:f(p.gray0,.14),medium:f(p.gray0,.1),light:f(p.gray0,.06),lighter:f(p.gray0,.03),danger:f(d.red,.08)},overlay:f(p.gray80,.8),radialGradient:`radial-gradient(50% 62.62% at 50% 0%, #505050 0%, ${p.gray60} 100%)`,radialGradientHover:`radial-gradient(76.32% 95.59% at 50% 0%, #505050 0%, ${p.gray60} 100%)`};var Oo={light:"blur(6px)",strong:"blur(20px)"};var Vo={radius:{xs:"2px",sm:"4px",md:"8px",xl:"20px",pill:"999px",rounded:"100%"}},Wo={color:{strong:p.gray25,medium:p.gray20,light:p.gray15,secondaryInverted:p.gray50,inverted:p.gray60,danger:d.red20},...Vo},Yo={color:{strong:p.gray55,medium:p.gray65,light:p.gray70,secondaryInverted:p.gray35,inverted:p.gray20,danger:d.red70},...Vo};var Xo={extraLight:`0px 1px 0px 0px ${f(p.gray100,.04)}`,light:`0px 2px 4px 0px ${f(p.gray100,.04)}, 0px 0px 4px 0px ${f(p.gray100,.08)}`,strong:`2px 4px 16px 0px ${f(p.gray100,.12)}, 0px 2px 4px 0px ${f(p.gray100,.04)}`,underline:`0px 1px 0px 0px ${f(p.gray100,.32)}`},_o={extraLight:`0px 1px 0px 0px ${f(p.gray100,.04)}`,light:`0px 2px 4px 0px ${f(p.gray100,.04)}, 0px 0px 4px 0px ${f(p.gray100,.08)}`,strong:`2px 4px 16px 0px ${f(p.gray100,.16)}, 0px 2px 4px 0px ${f(p.gray100,.08)}`,underline:`0px 1px 0px 0px ${f(p.gray100,.32)}`};var Go={size:{xxs:"0.625rem",xs:"0.85rem",sm:"0.92rem",md:"1rem",lg:"1.23rem",xl:"1.54rem",xxl:"1.85rem"},weight:{regular:400,medium:500,semiBold:600},family:"Inter, sans-serif"},qo={color:{primary:p.gray60,secondary:p.gray50,tertiary:p.gray40,light:p.gray35,extraLight:p.gray30,inverted:p.gray0,danger:d.red},...Go},Ko={color:{primary:p.gray20,secondary:p.gray35,tertiary:p.gray45,light:p.gray50,extraLight:p.gray55,inverted:p.gray100,danger:d.red},...Go};var Qo={size:{sm:14,md:16,lg:20,xl:40},stroke:{sm:1.6,md:2,lg:2.5}};var Jo={size:{sm:"300px",md:"400px",lg:"53%"}};var Zo={text:{green:d.green60,turquoise:d.turquoise60,sky:d.sky60,blue:d.blue60,purple:d.purple60,pink:d.pink60,red:d.red60,orange:d.orange60,yellow:d.yellow60,gray:d.gray60},background:{green:d.green20,turquoise:d.turquoise20,sky:d.sky20,blue:d.blue20,purple:d.purple20,pink:d.pink20,red:d.red20,orange:d.orange20,yellow:d.yellow20,gray:d.gray20}},jo={text:{green:d.green10,turquoise:d.turquoise10,sky:d.sky10,blue:d.blue10,purple:d.purple10,pink:d.pink10,red:d.red10,orange:d.orange10,yellow:d.yellow10,gray:d.gray10},background:{green:d.green60,turquoise:d.turquoise60,sky:d.sky60,blue:d.blue60,purple:d.purple60,pink:d.pink60,red:d.red60,orange:d.orange60,yellow:d.yellow60,gray:d.gray60}};var et={lineHeight:{lg:1.5,md:1.2},iconSizeMedium:16,iconSizeSmall:14,iconStrikeLight:1.6,iconStrikeMedium:2,iconStrikeBold:2.5};var ot={color:d,grayScale:p,icon:Qo,modal:Jo,text:et,blur:Oo,animation:Do,snackBar:{success:{background:"#16A26B",color:"#D0F8E9"},error:{background:"#B43232",color:"#FED8D8"},info:{background:d.gray80,color:p.gray0}},spacingMultiplicator:4,spacing:(...e)=>e.map(o=>`${o*4}px`).join(" "),betweenSiblingsGap:"2px",table:{horizontalCellMargin:"8px",checkboxColumnWidth:"32px"},rightDrawerWidth:"500px",clickableElementBackgroundTransition:"background 0.1s ease",lastLayerZIndex:2147483647},En={...ot,accent:Mo,background:No,border:Wo,tag:Zo,boxShadow:Xo,font:qo,name:"light"},Hn={...ot,accent:Ao,background:Uo,border:Yo,tag:jo,boxShadow:_o,font:Ko,name:"dark"},Y=768;var Dn=F__default.default.div` - align-items: center; - background-color: ${({theme:e})=>e.color.blue}; - border-radius: 50%; - display: flex; - height: 20px; - justify-content: center; - width: 20px; -`,Oe=({className:e})=>{let o=react.useTheme();return jsxRuntime.jsx(Dn,{className:e,children:jsxRuntime.jsx(iconsReact.IconCheck,{color:o.grayScale.gray0,size:14})})};var ht=({isAnimating:e=!1,color:o,duration:r=.5,size:t=28})=>{let n=react.useTheme();return jsxRuntime.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 52 52",width:t,height:t,children:jsxRuntime.jsx(framerMotion.motion.path,{fill:"none",stroke:o??n.grayScale.gray0,strokeWidth:4,d:"M14 27l7.8 7.8L38 14",pathLength:"1",strokeDasharray:"1",strokeDashoffset:e?"1":"0",animate:{strokeDashoffset:e?"0":"1"},transition:{duration:r}})})};var On=(n=>(n.Top="top",n.Left="left",n.Right="right",n.Bottom="bottom",n))(On||{}),Vn=F__default.default(reactTooltip.Tooltip)` - backdrop-filter: ${({theme:e})=>e.blur.strong}; - background-color: ${({theme:e})=>f(e.color.gray80,.8)}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - - box-shadow: ${({theme:e})=>e.boxShadow.light}; - color: ${({theme:e})=>e.grayScale.gray0}; - - font-size: ${({theme:e})=>e.font.size.sm}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - - max-width: 40%; - overflow: visible; - - padding: ${({theme:e})=>e.spacing(2)}; - - word-break: break-word; - - z-index: ${({theme:e})=>e.lastLayerZIndex}; -`,xt=({anchorSelect:e,className:o,content:r,delayHide:t,isOpen:n,noArrow:a,offset:i,place:c,positionStrategy:s})=>jsxRuntime.jsx(Vn,{anchorSelect:e,className:o,content:r,delayHide:t,isOpen:n,noArrow:a,offset:i,place:c,positionStrategy:s});var Qn=F__default.default.div` - cursor: ${({cursorPointer:e})=>e?"pointer":"inherit"}; - font-family: inherit; - font-size: inherit; - - font-weight: inherit; - max-width: 100%; - overflow: hidden; - text-decoration: inherit; - - text-overflow: ellipsis; - white-space: nowrap; -`,X=({text:e,className:o})=>{let r=`title-id-${uuid.v4()}`,t=ze.useRef(null),[n,a]=ze.useState(!1);return ze.useEffect(()=>{let c=(e?.length??0)>0&&t.current?t.current?.scrollHeight>t.current?.clientHeight||t.current.scrollWidth>t.current.clientWidth:!1;n!==c&&a(c);},[n,e]),jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Qn,{"data-testid":"tooltip",className:o,ref:t,id:r,cursorPointer:n,children:e}),n&&reactDom.createPortal(jsxRuntime.jsx("div",{onClick:c=>{c.stopPropagation(),c.preventDefault();},children:jsxRuntime.jsx(xt,{anchorSelect:`#${r}`,content:e??"",delayHide:0,offset:5,noArrow:!0,place:"bottom",positionStrategy:"absolute"})}),document.body)]})};var kt=(r=>(r.Large="large",r.Small="small",r))(kt||{}),jn=(r=>(r.TextPrimary="text-primary",r.TextSecondary="text-secondary",r))(jn||{}),We=(n=>(n.Highlighted="highlighted",n.Regular="regular",n.Transparent="transparent",n.Rounded="rounded",n))(We||{}),ea=F__default.default.div` - align-items: center; - - background-color: ${({theme:e,variant:o})=>o==="highlighted"?e.background.transparent.light:o==="rounded"?e.background.transparent.lighter:"transparent"}; - border-color: ${({theme:e,variant:o})=>o==="rounded"?e.border.color.medium:"none"}; - border-radius: ${({theme:e,variant:o})=>o==="rounded"?"50px":e.border.radius.sm}; - border-style: ${({variant:e})=>e==="rounded"?"solid":"none"}; - border-width: ${({variant:e})=>e==="rounded"?"1px":"0px"}; - - color: ${({theme:e,disabled:o,accent:r})=>o?e.font.color.light:r==="text-primary"?e.font.color.primary:e.font.color.secondary}; - cursor: ${({clickable:e,disabled:o,variant:r})=>o||r==="transparent"?"inherit":e?"pointer":"inherit"}; - display: inline-flex; - font-weight: ${({theme:e,accent:o})=>o==="text-secondary"?e.font.weight.medium:"inherit"}; - gap: ${({theme:e})=>e.spacing(1)}; - - height: ${({size:e})=>e==="large"?"16px":"12px"}; - max-width: ${({maxWidth:e})=>e||"200px"}; - - overflow: hidden; - padding: ${({theme:e,variant:o})=>o==="rounded"?"3px 8px":e.spacing(1)}; - user-select: none; - - :hover { - ${({variant:e,theme:o,disabled:r})=>{if(!r)return "background-color: "+(e==="highlighted"?o.background.transparent.medium:e==="regular"?o.background.transparent.light:"transparent")+";"}} - } - :active { - ${({variant:e,theme:o,disabled:r})=>{if(!r)return "background-color: "+(e==="highlighted"?o.background.transparent.strong:e==="regular"?o.background.transparent.medium:"transparent")+";"}} - } -`,oa=F__default.default.span` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -`,ie=({size:e="small",label:o,disabled:r=!1,clickable:t=!0,variant:n="regular",leftComponent:a,rightComponent:i,accent:c="text-primary",maxWidth:s,className:m,onClick:l})=>jsxRuntime.jsxs(ea,{"data-testid":"chip",clickable:t,variant:n,accent:c,size:e,disabled:r,className:m,maxWidth:s,onClick:l,children:[a,jsxRuntime.jsx(oa,{children:jsxRuntime.jsx(X,{text:o})}),i]});var Ye=(e,o,r)=>{let t=0;for(let a=0;ae?e?.startsWith("data:")||e?.startsWith("https:")?e:`${vt}/${e}`:null;var ia=F__default.default.div` - align-items: center; - background-color: ${({avatarUrl:e,colorId:o})=>guards.isNonEmptyString(e)?"none":Ye(o,75,85)}; - ${({avatarUrl:e})=>guards.isNonEmptyString(e)?`background-image: url(${e});`:""} - background-position: center; - background-size: cover; - border-radius: ${e=>e.type==="rounded"?"50%":"2px"}; - color: ${({colorId:e})=>Ye(e,75,25)}; - cursor: ${({onClick:e})=>e?"pointer":"default"}; - display: flex; - - flex-shrink: 0; - font-size: ${({size:e})=>{switch(e){case"xl":return "16px";case"lg":return "13px";case"md":default:return "12px";case"sm":return "10px";case"xs":return "8px"}}}; - font-weight: ${({theme:e})=>e.font.weight.medium}; - - height: ${({size:e})=>{switch(e){case"xl":return "40px";case"lg":return "24px";case"md":default:return "16px";case"sm":return "14px";case"xs":return "12px"}}}; - justify-content: center; - width: ${({size:e})=>{switch(e){case"xl":return "40px";case"lg":return "24px";case"md":default:return "16px";case"sm":return "14px";case"xs":return "12px"}}}; - - &:hover { - box-shadow: ${({theme:e,onClick:o})=>o?"0 0 0 4px "+e.background.transparent.light:"unset"}; - } -`,$t=({avatarUrl:e,className:o,size:r="md",placeholder:t,colorId:n=t,onClick:a,type:i="squared"})=>{let c=!guards.isNonEmptyString(e),[s,m]=ze.useState(!1);return ze.useEffect(()=>{e&&new Promise(l=>{let u=new Image;u.onload=()=>l(!1),u.onerror=()=>l(!0),u.src=Xe(e);}).then(l=>{m(l);});},[e]),jsxRuntime.jsx(ia,{className:o,avatarUrl:Xe(e),placeholder:t,size:r,type:i,colorId:n??"",onClick:a,children:(c||s)&&t?.[0]?.toLocaleUpperCase()})};var da=(r=>(r.Regular="regular",r.Transparent="transparent",r))(da||{}),$u=({linkToEntity:e,entityId:o,name:r,avatarUrl:t,avatarType:n="rounded",variant:a="regular",LeftIcon:i,className:c})=>{let s=reactRouterDom.useNavigate(),m=react.useTheme(),l=u=>{e&&(u.preventDefault(),u.stopPropagation(),s(e));};return guards.isNonEmptyString(r)?jsxRuntime.jsx(ie,{label:r,variant:e?a==="regular"?"highlighted":"regular":"transparent",leftComponent:i?jsxRuntime.jsx(i,{size:m.icon.size.md,stroke:m.icon.stroke.sm}):jsxRuntime.jsx($t,{avatarUrl:t,colorId:o,placeholder:r,size:"sm",type:n}),clickable:!!e,onClick:l,className:c}):jsxRuntime.jsx(jsxRuntime.Fragment,{})};var ua=e=>jsxRuntime.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"icon icon-tabler icon-tabler-address-book",width:24,height:24,viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[jsxRuntime.jsx("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),jsxRuntime.jsx("path",{d:"M20 6v12a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2z"}),jsxRuntime.jsx("path",{d:"M10 16h6"}),jsxRuntime.jsx("path",{d:"M13 11m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"}),jsxRuntime.jsx("path",{d:"M4 8h3"}),jsxRuntime.jsx("path",{d:"M4 12h3"}),jsxRuntime.jsx("path",{d:"M4 16h3"})]}),wt=ua;var Eu=e=>{let o=e.size??24,r=e.stroke??2;return jsxRuntime.jsx(wt,{height:o,width:o,strokeWidth:r})};var ba=F__default.default.span` - align-items: center; - background: ${({theme:e})=>e.background.transparent.light}; - border-radius: ${({theme:e})=>e.border.radius.pill}; - color: ${({theme:e})=>e.font.color.light}; - display: inline-block; - font-size: ${({theme:e})=>e.font.size.xs}; - font-style: normal; - font-weight: ${({theme:e})=>e.font.weight.medium}; - gap: ${({theme:e})=>e.spacing(2)}; - height: ${({theme:e})=>e.spacing(4)}; - justify-content: flex-end; - line-height: ${({theme:e})=>e.text.lineHeight.lg}; - padding: ${({theme:e})=>`0 ${e.spacing(2)}`}; -`,Tt=({className:e})=>jsxRuntime.jsx(ba,{className:e,children:"Soon"});var Pt=zod.z.enum(Ho);var Sa=F__default.default.h3` - align-items: center; - background: ${({color:e,theme:o})=>o.tag.background[e]}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - color: ${({color:e,theme:o})=>o.tag.text[e]}; - display: inline-flex; - font-size: ${({theme:e})=>e.font.size.md}; - font-style: normal; - font-weight: ${({theme:e})=>e.font.weight.regular}; - height: ${({theme:e})=>e.spacing(5)}; - margin: 0; - overflow: hidden; - padding: 0 ${({theme:e})=>e.spacing(2)}; -`,Ia=F__default.default.span` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -`,Yu=({className:e,color:o,text:r,onClick:t})=>jsxRuntime.jsx(Sa,{className:e,color:Pt.catch("gray").parse(o),onClick:t,children:jsxRuntime.jsx(Ia,{children:r})});var La=F__default.default.div` - height: ${({barHeight:e})=>e}px; - overflow: hidden; - width: 100%; -`,Ra=F__default.default(framerMotion.motion.div)` - height: 100%; - width: 100%; -`,Zu=ze.forwardRef(({duration:e=3,delay:o=0,easing:r="easeInOut",barHeight:t=24,barColor:n,autoStart:a=!0,className:i},c)=>{let s=react.useTheme(),m=framerMotion.useAnimation(),l=ze.useRef(0),u=ze.useRef(e),g=ze.useCallback(async()=>(l.current=Date.now(),m.start({scaleX:0,transition:{duration:u.current/1e3,delay:o/1e3,ease:r}})),[m,o,r]);return ze.useImperativeHandle(c,()=>({...m,start:async()=>g(),pause:async()=>{let x=Date.now()-l.current;return u.current=u.current-x,m.stop()}})),ze.useEffect(()=>{a&&g();},[m,o,e,r,a,g]),jsxRuntime.jsx(La,{className:i,barHeight:t,children:jsxRuntime.jsx(Ra,{style:{originX:0,backgroundColor:n??s.color.gray80},initial:{scaleX:1},animate:m,exit:{scaleX:0}})})});var ng=({size:e=50,barWidth:o=5,barColor:r="currentColor"})=>{let t=framerMotion.useAnimation(),n=ze.useMemo(()=>2*Math.PI*(e/2-o),[e,o]);return ze.useEffect(()=>{(async()=>{let i=Math.max(5,n/10),c=[`${i} ${n-i}`,`${i*2} ${n-i*2}`,`${i*3} ${n-i*3}`,`${i*2} ${n-i*2}`,`${i} ${n-i}`];await t.start({strokeDasharray:c,rotate:[0,720],transition:{strokeDasharray:{duration:2,ease:"linear",repeat:1/0,repeatType:"loop"},rotate:{duration:2,ease:"linear",repeat:1/0,repeatType:"loop"}}});})();},[n,t]),jsxRuntime.jsx(framerMotion.motion.svg,{width:e,height:e,animate:t,children:jsxRuntime.jsx(framerMotion.motion.circle,{cx:e/2,cy:e/2,r:e/2-o,fill:"none",stroke:r,strokeWidth:o,strokeLinecap:"round"})})};var Aa=F__default.default.button` - align-items: center; - ${({theme:e,variant:o,accent:r,disabled:t,focus:n})=>{switch(o){case"primary":switch(r){case"default":return ` - background: ${e.background.secondary}; - border-color: ${t?"transparent":n?e.color.blue:e.background.transparent.light}; - color: ${t?e.font.color.extraLight:e.font.color.secondary}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - &:hover { - background: ${t?e.background.secondary:e.background.tertiary}; - } - &:active { - background: ${t?e.background.secondary:e.background.quaternary}; - } - `;case"blue":return ` - background: ${t?e.color.blue20:e.color.blue}; - border-color: ${t?"transparent":n?e.color.blue:e.background.transparent.light}; - border-width: ${!t&&n?"1px 1px !important":0}; - color: ${e.grayScale.gray0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - &:hover { - background: ${t?e.color.blue20:e.color.blue50}; - } - &:active { - background: ${t?e.color.blue20:e.color.blue60}; - } - `;case"danger":return ` - background: ${t?e.color.red20:e.color.red}; - border-color: ${t?"transparent":n?e.color.red:e.background.transparent.light}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.color.red10}`:"none"}; - color: ${e.grayScale.gray0}; - &:hover { - background: ${t?e.color.red20:e.color.red50}; - } - &:active { - background: ${t?e.color.red20:e.color.red50}; - } - `}break;case"secondary":case"tertiary":switch(r){case"default":return ` - background: ${n?e.background.transparent.primary:"transparent"}; - border-color: ${o==="secondary"?!t&&n?e.color.blue:e.background.transparent.light:n?e.color.blue:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - color: ${t?e.font.color.extraLight:e.font.color.secondary}; - &:hover { - background: ${t?"transparent":e.background.transparent.light}; - } - &:active { - background: ${t?"transparent":e.background.transparent.light}; - } - `;case"blue":return ` - background: ${n?e.background.transparent.primary:"transparent"}; - border-color: ${o==="secondary"?n?e.color.blue:e.color.blue20:n?e.color.blue:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - color: ${t?e.accent.accent4060:e.color.blue}; - &:hover { - background: ${t?"transparent":e.accent.tertiary}; - } - &:active { - background: ${t?"transparent":e.accent.secondary}; - } - `;case"danger":return ` - background: ${t?"transparent":e.background.transparent.primary}; - border-color: ${o==="secondary"?n?e.color.red:e.border.color.danger:n?e.color.red:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.color.red10}`:"none"}; - color: ${t?e.color.red20:e.font.color.danger}; - &:hover { - background: ${t?"transparent":e.background.danger}; - } - &:active { - background: ${t?"transparent":e.background.danger}; - } - `}}}} - - border-radius: ${({position:e,theme:o})=>{switch(e){case"left":return `${o.border.radius.sm} 0px 0px ${o.border.radius.sm}`;case"right":return `0px ${o.border.radius.sm} ${o.border.radius.sm} 0px`;case"middle":return "0px";case"standalone":return o.border.radius.sm}}}; - border-style: solid; - border-width: ${({variant:e,position:o})=>{switch(e){case"primary":case"secondary":return o==="middle"?"1px 0px":"1px";case"tertiary":return "0"}}}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - font-family: ${({theme:e})=>e.font.family}; - font-weight: 500; - gap: ${({theme:e})=>e.spacing(1)}; - height: ${({size:e})=>e==="small"?"24px":"32px"}; - padding: ${({theme:e})=>`0 ${e.spacing(2)}`}; - - transition: background 0.1s ease; - - white-space: nowrap; - - width: ${({fullWidth:e})=>e?"100%":"auto"}; - - &:focus { - outline: none; - } -`,Da=F__default.default(Tt)` - margin-left: auto; -`,_=({className:e,Icon:o,title:r,fullWidth:t=!1,variant:n="primary",size:a="medium",accent:i="default",position:c="standalone",soon:s=!1,disabled:m=!1,focus:l=!1,onClick:u})=>{let g=react.useTheme();return jsxRuntime.jsxs(Aa,{fullWidth:t,variant:n,size:a,position:c,disabled:s||m,focus:l,accent:i,className:e,onClick:u,children:[o&&jsxRuntime.jsx(o,{size:g.icon.size.sm}),r,s&&jsxRuntime.jsx(Da,{})]})};var Na=F__default.default.div` - border-radius: ${({theme:e})=>e.border.radius.md}; - display: flex; -`,fg=({className:e,children:o,variant:r,size:t,accent:n})=>jsxRuntime.jsx(Na,{className:e,children:ze__namespace.default.Children.map(o,(a,i)=>{if(!ze__namespace.default.isValidElement(a))return null;let c;i===0?c="left":i===o.length-1?c="right":c="middle";let s={position:c,variant:r,accent:n,size:t};return r&&(s.variant=r),n&&(s.variant=r),t&&(s.size=t),ze__namespace.default.cloneElement(a,s)})});var Wa=F__default.default.button` - align-items: center; - backdrop-filter: ${({applyBlur:e})=>e?"blur(20px)":"none"}; - background: ${({theme:e})=>e.background.primary}; - - border: ${({focus:e,theme:o})=>e?`1px solid ${o.color.blue}`:"none"}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-shadow: ${({theme:e,applyShadow:o,focus:r})=>o?`0px 2px 4px 0px ${e.background.transparent.light}, 0px 0px 4px 0px ${e.background.transparent.medium}${r?`,0 0 0 3px ${e.color.blue10}`:""}`:r?`0 0 0 3px ${e.color.blue10}`:"none"}; - color: ${({theme:e,disabled:o,focus:r})=>o?e.font.color.extraLight:r?e.color.blue:e.font.color.secondary}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - - flex-direction: row; - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - gap: ${({theme:e})=>e.spacing(1)}; - height: ${({size:e})=>e==="small"?"24px":"32px"}; - padding: ${({theme:e})=>`0 ${e.spacing(2)}`}; - transition: background 0.1s ease; - - white-space: nowrap; - - &:hover { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.lighter}; - } - - &:active { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.medium}; - } - - &:focus { - outline: none; - } -`,Sg=({className:e,Icon:o,title:r,size:t="small",applyBlur:n=!0,applyShadow:a=!0,disabled:i=!1,focus:c=!1})=>{let s=react.useTheme();return jsxRuntime.jsxs(Wa,{disabled:i,focus:c&&!i,size:t,applyBlur:n,applyShadow:a,className:e,children:[o&&jsxRuntime.jsx(o,{size:s.icon.size.sm}),r]})};var Ga=F__default.default.div` - backdrop-filter: blur(20px); - border-radius: ${({theme:e})=>e.border.radius.md}; - box-shadow: ${({theme:e})=>`0px 2px 4px 0px ${e.background.transparent.light}, 0px 0px 4px 0px ${e.background.transparent.medium}`}; - display: inline-flex; -`,$g=({children:e,size:o,className:r})=>jsxRuntime.jsx(Ga,{className:r,children:ze__namespace.default.Children.map(e,(t,n)=>{let a;n===0?a="left":n===e.length-1?a="right":a="middle";let i={position:a,size:o,applyShadow:!1,applyBlur:!1};return o&&(i.size=o),ze__namespace.default.cloneElement(t,i)})});var Ja=F__default.default.button` - align-items: center; - backdrop-filter: ${({applyBlur:e})=>e?"blur(20px)":"none"}; - background: ${({theme:e,isActive:o})=>o?e.background.transparent.medium:e.background.primary}; - border: ${({focus:e,theme:o})=>e?`1px solid ${o.color.blue}`:"transparent"}; - border-radius: ${({position:e,theme:o})=>{switch(e){case"left":return `${o.border.radius.sm} 0px 0px ${o.border.radius.sm}`;case"right":return `0px ${o.border.radius.sm} ${o.border.radius.sm} 0px`;case"middle":return "0px";case"standalone":return o.border.radius.sm}}}; - box-shadow: ${({theme:e,applyShadow:o,focus:r})=>o?`0px 2px 4px ${e.background.transparent.light}, 0px 0px 4px ${e.background.transparent.medium}${r?`,0 0 0 3px ${e.color.blue10}`:""}`:r?`0 0 0 3px ${e.color.blue10}`:"none"}; - box-sizing: border-box; - color: ${({theme:e,disabled:o,focus:r})=>o?e.font.color.extraLight:r?e.color.blue:e.font.color.tertiary}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - gap: ${({theme:e})=>e.spacing(1)}; - justify-content: center; - padding: 0; - position: relative; - transition: background ${({theme:e})=>e.animation.duration.instant}s - ease; - white-space: nowrap; - - ${({position:e,size:o})=>{let r=(o==="small"?24:32)-(e==="standalone"?0:4);return ` - height: ${r}px; - width: ${r}px; - `}} - - &:hover { - background: ${({theme:e,isActive:o})=>!!o}; - } - - &:active { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.medium}; - } - - &:focus { - outline: none; - } -`,Ut=({className:e,Icon:o,size:r="small",position:t="standalone",applyShadow:n=!0,applyBlur:a=!0,disabled:i=!1,focus:c=!1,onClick:s,isActive:m})=>{let l=react.useTheme();return jsxRuntime.jsx(Ja,{disabled:i,focus:c&&!i,size:r,applyShadow:n,applyBlur:a,className:e,position:t,onClick:s,isActive:m,children:o&&jsxRuntime.jsx(o,{size:l.icon.size.md})})};var ja=F__default.default.div` - backdrop-filter: blur(20px); - background-color: ${({theme:e})=>e.background.primary}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-shadow: ${({theme:e})=>`0px 2px 4px 0px ${e.background.transparent.light}, 0px 0px 4px 0px ${e.background.transparent.medium}`}; - display: inline-flex; - gap: 2px; - padding: 2px; -`,se=({iconButtons:e,size:o,className:r})=>jsxRuntime.jsx(ja,{className:r,children:e.map(({Icon:t,onClick:n,isActive:a},i)=>{let c=e.length===1?"standalone":i===0?"left":i===e.length-1?"right":"middle";return jsxRuntime.jsx(Ut,{applyBlur:!1,applyShadow:!1,Icon:t,onClick:n,position:c,size:o,isActive:a},`floating-icon-button-${i}`)})});var ti=F__default.default.button` - align-items: center; - background: transparent; - border: ${({theme:e,focus:o})=>o?`1px solid ${e.color.blue}`:"none"}; - - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-shadow: ${({theme:e,focus:o})=>o?`0 0 0 3px ${e.color.blue10}`:"none"}; - color: ${({theme:e,accent:o,active:r,disabled:t,focus:n})=>{switch(o){case"secondary":return r||n?e.color.blue:t?e.font.color.extraLight:e.font.color.secondary;case"tertiary":return r||n?e.color.blue:t?e.font.color.extraLight:e.font.color.tertiary}}}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - gap: ${({theme:e})=>e.spacing(1)}; - height: 24px; - padding: ${({theme:e})=>`0 ${e.spacing(2)}`}; - - transition: background 0.1s ease; - - white-space: nowrap; - - &:hover { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.light}; - } - - &:focus { - outline: none; - } - - &:active { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.medium}; - } -`,Ug=({className:e,Icon:o,title:r,active:t=!1,accent:n="secondary",disabled:a=!1,focus:i=!1,onClick:c})=>{let s=react.useTheme();return jsxRuntime.jsxs(ti,{onClick:c,disabled:a,focus:i&&!a,accent:n,className:e,active:t,children:[!!o&&jsxRuntime.jsx(o,{size:s.icon.size.sm}),r]})};var ci=F__default.default.button` - align-items: center; - background: transparent; - border: none; - - border: ${({disabled:e,theme:o,focus:r})=>!e&&r?`1px solid ${o.color.blue}`:"none"}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-shadow: ${({disabled:e,theme:o,focus:r})=>!e&&r?`0 0 0 3px ${o.color.blue10}`:"none"}; - color: ${({theme:e,accent:o,active:r,disabled:t,focus:n})=>{switch(o){case"secondary":return r||n?e.color.blue:t?e.font.color.extraLight:e.font.color.secondary;case"tertiary":return r||n?e.color.blue:t?e.font.color.extraLight:e.font.color.tertiary}}}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - gap: ${({theme:e})=>e.spacing(1)}; - height: ${({size:e})=>e==="small"?"24px":"32px"}; - justify-content: center; - padding: 0; - transition: background 0.1s ease; - - white-space: nowrap; - - width: ${({size:e})=>e==="small"?"24px":"32px"}; - - &:hover { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.light}; - } - - &:focus { - outline: none; - } - - &:active { - background: ${({theme:e,disabled:o})=>o?"transparent":e.background.transparent.medium}; - } -`,Wt=({"aria-label":e,className:o,testId:r,Icon:t,active:n=!1,size:a="small",accent:i="secondary",disabled:c=!1,focus:s=!1,onClick:m,title:l})=>{let u=react.useTheme();return jsxRuntime.jsx(ci,{"data-testid":r,"aria-label":e,onClick:m,disabled:c,focus:s&&!c,accent:i,className:o,size:a,active:n,title:l,children:t&&jsxRuntime.jsx(t,{size:u.icon.size.md,stroke:u.icon.stroke.sm})})};var pi=F__default.default.button` - align-items: center; - background: ${({theme:e,variant:o,disabled:r})=>{if(r)return e.background.secondary;switch(o){case"primary":return e.background.radialGradient;case"secondary":return e.background.primary;default:return e.background.primary}}}; - border: 1px solid; - border-color: ${({theme:e,disabled:o,variant:r})=>{if(o)return e.background.transparent.lighter;switch(r){case"primary":return e.background.transparent.light;case"secondary":return e.border.color.medium;default:return e.background.primary}}}; - border-radius: ${({theme:e})=>e.border.radius.md}; - ${({theme:e,disabled:o})=>o?"":`box-shadow: ${e.boxShadow.light};`} - color: ${({theme:e,variant:o,disabled:r})=>{if(r)return e.font.color.light;switch(o){case"primary":return e.grayScale.gray0;case"secondary":return e.font.color.primary;default:return e.font.color.primary}}}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.semiBold}; - gap: ${({theme:e})=>e.spacing(2)}; - justify-content: center; - outline: none; - padding: ${({theme:e})=>e.spacing(2)} ${({theme:e})=>e.spacing(3)}; - width: ${({fullWidth:e})=>e?"100%":"auto"}; - ${({theme:e,variant:o})=>{switch(o){case"secondary":return ` - &:hover { - background: ${e.background.tertiary}; - } - `;default:return ` - &:hover { - background: ${e.background.radialGradientHover}}; - } - `}}}; -`,Kg=({Icon:e,title:o,fullWidth:r=!1,variant:t="primary",type:n,onClick:a,disabled:i,className:c})=>{let s=react.useTheme();return jsxRuntime.jsxs(pi,{className:c,disabled:i,fullWidth:r,onClick:a,type:n,variant:t,children:[e&&jsxRuntime.jsx(e,{size:s.icon.size.sm}),o]})};var fi=F__default.default.button` - align-items: center; - background: ${({theme:e})=>e.color.blue}; - border: none; - - border-radius: 50%; - color: ${({theme:e})=>e.font.color.inverted}; - - cursor: pointer; - display: flex; - height: 20px; - - justify-content: center; - - outline: none; - padding: 0; - transition: - color 0.1s ease-in-out, - background 0.1s ease-in-out; - - &:disabled { - background: ${({theme:e})=>e.background.quaternary}; - color: ${({theme:e})=>e.font.color.tertiary}; - cursor: default; - } - width: 20px; -`,Xt=({Icon:e,onClick:o,disabled:r,className:t})=>{let n=react.useTheme();return jsxRuntime.jsx(fi,{className:t,disabled:r,onClick:o,children:jsxRuntime.jsx(e,{size:n.icon.size.md})})};var bi=F__default.default.div` - align-items: flex-end; - background: ${({variant:e,theme:o})=>{switch(e){case"Dark":return o.grayScale.gray75;case"Light":default:return o.grayScale.gray15}}}; - border: ${({variant:e,theme:o})=>{switch(e){case"Dark":return `1px solid ${o.grayScale.gray70};`;case"Light":default:return `1px solid ${o.grayScale.gray20};`}}}; - border-radius: ${({theme:e})=>e.border.radius.md}; - box-sizing: border-box; - cursor: pointer; - display: flex; - height: 80px; - justify-content: flex-end; - overflow: hidden; - padding-left: ${({theme:e})=>e.spacing(6)}; - padding-top: ${({theme:e})=>e.spacing(6)}; - width: 120px; -`,hi=F__default.default(framerMotion.motion.div)` - background: ${({theme:e,variant:o})=>{switch(o){case"Dark":return e.grayScale.gray75;case"Light":return e.grayScale.gray0}}}; - - border-left: ${({variant:e,theme:o})=>{switch(e){case"Dark":return `1px solid ${o.grayScale.gray60};`;case"Light":default:return `1px solid ${o.grayScale.gray20};`}}}; - border-radius: ${({theme:e})=>e.border.radius.md} 0px 0px 0px; - border-top: ${({variant:e,theme:o})=>{switch(e){case"Dark":return `1px solid ${o.grayScale.gray60};`;case"Light":default:return `1px solid ${o.grayScale.gray20};`}}}; - box-sizing: border-box; - color: ${({variant:e,theme:o})=>{switch(e){case"Dark":return o.grayScale.gray30;case"Light":default:return o.grayScale.gray60}}}; - display: flex; - flex: 1; - font-size: 20px; - height: 56px; - padding-left: ${({theme:e})=>e.spacing(2)}; - padding-top: ${({theme:e})=>e.spacing(2)}; -`,qe=({variant:e,controls:o,style:r,className:t,onClick:n,onMouseEnter:a,onMouseLeave:i})=>jsxRuntime.jsx(bi,{className:t,variant:e,style:r,onClick:n,onMouseEnter:a,onMouseLeave:i,children:jsxRuntime.jsx(hi,{animate:o,variant:e,children:"Aa"})}),Gt=F__default.default.div` - position: relative; - width: 120px; -`,xi=F__default.default.div` - border-radius: ${({theme:e})=>e.border.radius.md}; - cursor: pointer; - display: flex; - height: 80px; - overflow: hidden; - position: relative; - width: 120px; -`,qt=F__default.default(framerMotion.motion.div)` - bottom: 0px; - padding: ${({theme:e})=>e.spacing(2)}; - position: absolute; - right: 0px; -`,Kt={initial:{opacity:0},animate:{opacity:1},exit:{opacity:0}},le=({variant:e,selected:o,onClick:r})=>{let t=framerMotion.useAnimation(),n=()=>{t.start({height:61,fontSize:"22px",transition:{duration:.1}});},a=()=>{t.start({height:56,fontSize:"20px",transition:{duration:.1}});};return e==="System"?jsxRuntime.jsxs(Gt,{children:[jsxRuntime.jsxs(xi,{onMouseEnter:n,onMouseLeave:a,onClick:r,children:[jsxRuntime.jsx(qe,{style:{borderTopRightRadius:0,borderBottomRightRadius:0},controls:t,variant:"Light"}),jsxRuntime.jsx(qe,{style:{borderTopLeftRadius:0,borderBottomLeftRadius:0},controls:t,variant:"Dark"})]}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:o&&jsxRuntime.jsx(qt,{variants:Kt,initial:"initial",animate:"animate",exit:"exit",transition:{duration:.3},children:jsxRuntime.jsx(Oe,{})},"system")})]}):jsxRuntime.jsxs(Gt,{children:[jsxRuntime.jsx(qe,{onMouseEnter:n,onMouseLeave:a,controls:t,variant:e,onClick:r}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:o&&jsxRuntime.jsx(qt,{variants:Kt,initial:"initial",animate:"animate",exit:"exit",transition:{duration:.3},children:jsxRuntime.jsx(Oe,{})},e)})]})};var Si=F__default.default.div` - display: flex; - flex-direction: row; - > * + * { - margin-left: ${({theme:e})=>e.spacing(4)}; - } -`,Qe=F__default.default.div` - display: flex; - flex-direction: column; -`,Je=F__default.default.span` - color: ${({theme:e})=>e.font.color.secondary}; - font-size: ${({theme:e})=>e.font.size.xs}; - font-weight: ${({theme:e})=>e.font.weight.medium}; - margin-top: ${({theme:e})=>e.spacing(2)}; -`,df=({value:e,onChange:o,className:r})=>jsxRuntime.jsxs(Si,{className:r,children:[jsxRuntime.jsxs(Qe,{children:[jsxRuntime.jsx(le,{onClick:()=>o("Light"),variant:"Light",selected:e==="Light"}),jsxRuntime.jsx(Je,{children:"Light"})]}),jsxRuntime.jsxs(Qe,{children:[jsxRuntime.jsx(le,{onClick:()=>o("Dark"),variant:"Dark",selected:e==="Dark"}),jsxRuntime.jsx(Je,{children:"Dark"})]}),jsxRuntime.jsxs(Qe,{children:[jsxRuntime.jsx(le,{onClick:()=>o("System"),variant:"System",selected:e==="System"}),jsxRuntime.jsx(Je,{children:"System settings"})]})]});var Jt=recoil.atom({key:"pendingHotkeyState",default:null});var je=(e,...o)=>{console.debug(e,o);};var de=recoil.atom({key:"internalHotkeysEnabledScopesState",default:[]});var jt=()=>recoil.useRecoilCallback(({snapshot:e})=>({callback:o,hotkeysEvent:r,keyboardEvent:t,scope:n,preventDefault:a=!0})=>{let i=e.getLoadable(de).valueOrThrow();if(!i.includes(n)){je(`%cI can't call hotkey (${r.keys}) because I'm in scope [${n}] and the active scopes are : [${i.join(", ")}]`,"color: gray; ");return}return je(`%cI can call hotkey (${r.keys}) because I'm in scope [${n}] and the active scopes are : [${i.join(", ")}]`,"color: green;"),a&&(t.stopPropagation(),t.preventDefault(),t.stopImmediatePropagation()),o(t,r)},[]);var C=(e,o,r,t,n={enableOnContentEditable:!0,enableOnFormTags:!0,preventDefault:!0})=>{let[a,i]=recoil.useRecoilState(Jt),c=jt();return reactHotkeysHook.useHotkeys(e,(s,m)=>{c({keyboardEvent:s,hotkeysEvent:m,callback:()=>{if(!a){o(s,m);return}i(null);},scope:r,preventDefault:!!n.preventDefault});},{enableOnContentEditable:n.enableOnContentEditable,enableOnFormTags:n.enableOnFormTags},t)};var oo=5,Ti=(t=>(t.Default="default",t.Icon="icon",t.Button="button",t))(Ti||{}),Pi=F__default.default.div` - width: 100%; -`,Li=F__default.default.div` - display: flex; - position: relative; - width: 100%; -`,Ri=F__default.default(wi__default.default)` - background: ${({theme:e,variant:o})=>o==="button"?"transparent":e.background.tertiary}; - border: none; - border-radius: 5px; - color: ${({theme:e})=>e.font.color.primary}; - font-family: inherit; - font-size: ${({theme:e})=>e.font.size.md}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - line-height: 16px; - overflow: auto; - - &:focus { - border: none; - outline: none; - } - - &::placeholder { - color: ${({theme:e})=>e.font.color.light}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - } - padding: ${({variant:e})=>e==="button"?"8px 0":"8px"}; - resize: none; - width: 100%; -`,Bi=F__default.default.div` - height: 0; - position: relative; - right: 26px; - top: 6px; - width: 0px; -`,Ei=F__default.default(_)` - margin-left: ${({theme:e})=>e.spacing(2)}; -`,Hi=F__default.default.div` - color: ${({theme:e})=>e.font.color.light}; - font-weight: ${({theme:e})=>e.font.weight.medium}; - line-height: 150%; - width: 100%; -`,Mi=F__default.default.div` - align-items: center; - display: flex; - justify-content: space-between; - margin-top: ${({theme:e,isTextAreaHidden:o})=>o?0:e.spacing(4)}; -`,Ai=F__default.default.div` - cursor: text; - padding-bottom: ${({theme:e})=>e.spacing(1)}; - padding-top: ${({theme:e})=>e.spacing(1)}; -`,Ff=({placeholder:e,onValidate:o,minRows:r=1,onFocus:t,variant:n="default",buttonTitle:a,value:i="",className:c})=>{let[s,m]=ze.useState(!1),[l,u]=ze.useState(n==="button"),[g,x]=ze.useState(i),S=!g,b=g.split(/\s|\n/).filter(y=>y).length;C(["shift+enter","enter"],(y,A)=>{A.shift||!s||(y.preventDefault(),o?.(g),x(""));},"text-input",[o,g,x,s],{enableOnContentEditable:!0,enableOnFormTags:!0}),C("esc",y=>{s&&(y.preventDefault(),x(""));},"text-input",[o,x,s],{enableOnContentEditable:!0,enableOnFormTags:!0});let h=y=>{let A=y.currentTarget.value;x(A);},k=()=>{o?.(g),x("");},I=r>oo?oo:r;return jsxRuntime.jsx(jsxRuntime.Fragment,{children:jsxRuntime.jsxs(Pi,{className:c,children:[jsxRuntime.jsxs(Li,{children:[!l&&jsxRuntime.jsx(Ri,{autoFocus:n==="button",placeholder:e??"Write a comment",maxRows:oo,minRows:I,onChange:h,value:g,onFocus:()=>{t?.(),m(!0);},onBlur:()=>m(!1),variant:n}),n==="icon"&&jsxRuntime.jsx(Bi,{children:jsxRuntime.jsx(Xt,{onClick:k,Icon:iconsReact.IconArrowRight,disabled:S})})]}),n==="button"&&jsxRuntime.jsxs(Mi,{isTextAreaHidden:l,children:[jsxRuntime.jsx(Hi,{children:l?jsxRuntime.jsx(Ai,{onClick:()=>{u(!1),t?.();},children:"Write a comment"}):`${b} word${b===1?"":"s"}`}),jsxRuntime.jsx(Ei,{title:a??"Comment",disabled:S,onClick:k})]})]})})};var zi=(t=>(t.Primary="primary",t.Secondary="secondary",t.Tertiary="tertiary",t))(zi||{}),Ni=(r=>(r.Squared="squared",r.Rounded="rounded",r))(Ni||{}),Ui=(r=>(r.Large="large",r.Small="small",r))(Ui||{}),Oi=F__default.default.div` - align-items: center; - display: flex; - position: relative; -`,Vi=F__default.default.input` - cursor: pointer; - margin: 0; - opacity: 0; - position: absolute; - z-index: 10; - - & + label { - --size: ${({checkboxSize:e})=>e==="large"?"18px":"12px"}; - cursor: pointer; - height: calc(var(--size) + 2px); - padding: 0; - position: relative; - width: calc(var(--size) + 2px); - } - - & + label:before { - --size: ${({checkboxSize:e})=>e==="large"?"18px":"12px"}; - background: ${({theme:e,indeterminate:o,isChecked:r})=>o||r?e.color.blue:"transparent"}; - border-color: ${({theme:e,indeterminate:o,isChecked:r,variant:t})=>{switch(!0){case(o||r):return e.color.blue;case t==="primary":return e.border.color.inverted;case t==="tertiary":return e.border.color.medium;default:return e.border.color.secondaryInverted}}}; - border-radius: ${({theme:e,shape:o})=>o==="rounded"?e.border.radius.rounded:e.border.radius.sm}; - border-style: solid; - border-width: ${({variant:e})=>e==="tertiary"?"2px":"1px"}; - content: ''; - cursor: pointer; - display: inline-block; - height: var(--size); - width: var(--size); - } - - & + label > svg { - --padding: ${({checkboxSize:e,variant:o})=>e==="large"||o==="tertiary"?"2px":"1px"}; - --size: ${({checkboxSize:e})=>e==="large"?"16px":"12px"}; - height: var(--size); - left: var(--padding); - position: absolute; - stroke: ${({theme:e})=>e.grayScale.gray0}; - top: var(--padding); - width: var(--size); - } -`,ue=({checked:e,onChange:o,onCheckedChange:r,indeterminate:t,variant:n="primary",size:a="small",shape:i="squared",className:c})=>{let[s,m]=ze__namespace.useState(!1);ze__namespace.useEffect(()=>{m(e);},[e]);let l=g=>{o?.(g),r?.(g.target.checked),m(g.target.checked);},u="checkbox"+uuid.v4();return jsxRuntime.jsxs(Oi,{className:c,children:[jsxRuntime.jsx(Vi,{autoComplete:"off",type:"checkbox",id:u,name:"styled-checkbox","data-testid":"input-checkbox",checked:s,indeterminate:t,variant:n,checkboxSize:a,shape:i,isChecked:s,onChange:l}),jsxRuntime.jsx("label",{htmlFor:u,children:t?jsxRuntime.jsx(iconsReact.IconMinus,{}):s?jsxRuntime.jsx(iconsReact.IconCheck,{}):jsxRuntime.jsx(jsxRuntime.Fragment,{})})]})};var ge=e=>react.css` - background-color: transparent; - border: none; - color: ${e.theme.font.color.primary}; - font-family: ${e.theme.font.family}; - font-size: inherit; - font-weight: inherit; - outline: none; - padding: ${e.theme.spacing(0)} ${e.theme.spacing(2)}; - - &::placeholder, - &::-webkit-input-placeholder { - color: ${e.theme.font.color.light}; - font-family: ${e.theme.font.family}; - font-weight: ${e.theme.font.weight.medium}; - } -`,tr=e=>react.css` - transition: background 0.1s ease; - &:hover { - background: ${e.theme.background.transparent.light}; - } -`;var no=({refs:e,callback:o,mode:r="compareHTMLRef",enabled:t=!0})=>{let[n,a]=ze.useState(!1);ze.useEffect(()=>{let i=s=>{if(r==="compareHTMLRef"){let m=e.filter(l=>!!l.current).some(l=>l.current?.contains(s.target));a(m);}if(r==="comparePixels"){let m=e.filter(l=>!!l.current).some(l=>{if(!l.current)return !1;let{x:u,y:g,width:x,height:S}=l.current.getBoundingClientRect(),b="clientX"in s?s.clientX:s.changedTouches[0].clientX,h="clientY"in s?s.clientY:s.changedTouches[0].clientY;return !(bu+x||hg+S)});a(m);}},c=s=>{r==="compareHTMLRef"&&!e.filter(l=>!!l.current).some(l=>l.current?.contains(s.target))&&!n&&o(s),r==="comparePixels"&&!e.filter(l=>!!l.current).some(l=>{if(!l.current)return !1;let{x:u,y:g,width:x,height:S}=l.current.getBoundingClientRect(),b="clientX"in s?s.clientX:s.changedTouches[0].clientX,h="clientY"in s?s.clientY:s.changedTouches[0].clientY;return !(bu+x||hg+S)})&&!n&&o(s);};if(t)return document.addEventListener("mousedown",i,{capture:!0}),document.addEventListener("click",c,{capture:!0}),document.addEventListener("touchstart",i,{capture:!0}),document.addEventListener("touchend",c,{capture:!0}),()=>{document.removeEventListener("mousedown",i,{capture:!0}),document.removeEventListener("click",c,{capture:!0}),document.removeEventListener("touchstart",i,{capture:!0}),document.removeEventListener("touchend",c,{capture:!0});}},[e,o,r,t,n]);};var ao=e=>e!=null;var rr=F__default.default.input` - margin: 0; - ${ge} - width: 100%; -`;var Zi=F__default.default.span` - pointer-events: none; - position: fixed; - visibility: hidden; -`,io=({children:e,node:o=e(void 0)})=>{let r=ze.useRef(null),[t,n]=ze.useState(void 0);return ze.useLayoutEffect(()=>{if(!r.current)return;let a=new ResizeObserver(()=>{r.current&&n({width:r.current.offsetWidth,height:r.current.offsetHeight});});return a.observe(r.current),()=>a.disconnect()},[r]),jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(Zi,{ref:r,children:o}),t&&e(t)]})};var nr={commandMenu:!0,goto:!1,keyboardShortcutMenu:!1},ar={scope:"app",customScopes:{commandMenu:!0,goto:!0,keyboardShortcutMenu:!0}};var ee=recoil.atom({key:"currentHotkeyScopeState",default:ar});var fe=recoil.atom({key:"previousHotkeyScopeState",default:null});var ir=(e,o)=>e?.commandMenu===o?.commandMenu&&e?.goto===o?.goto&&e?.keyboardShortcutMenu===o?.keyboardShortcutMenu,cr=()=>recoil.useRecoilCallback(({snapshot:e,set:o})=>async(r,t)=>{let n=e.getLoadable(ee).valueOrThrow();if(n.scope===r){if(ao(t)){if(ir(n?.customScopes,t))return}else if(ir(n?.customScopes,nr))return}let a={scope:r,customScopes:{commandMenu:t?.commandMenu??!0,goto:t?.goto??!1,keyboardShortcutMenu:t?.keyboardShortcutMenu??!1}},i=[];a.customScopes?.commandMenu&&i.push("command-menu"),a?.customScopes?.goto&&i.push("goto"),a?.customScopes?.keyboardShortcutMenu&&i.push("keyboard-shortcut-menu"),i.push(a.scope),o(de,i),o(ee,a);},[]);var B=()=>{let e=cr(),o=recoil.useRecoilCallback(({snapshot:t,set:n})=>()=>{let a=t.getLoadable(fe).valueOrThrow();a&&(e(a.scope,a.customScopes),n(fe,null));},[e]);return {setHotkeyScopeAndMemorizePreviousScope:recoil.useRecoilCallback(({snapshot:t,set:n})=>(a,i)=>{let c=t.getLoadable(ee).valueOrThrow();e(a,i),n(fe,c);},[e]),goBackToPreviousHotkeyScope:o}};var ic=F__default.default.div` - align-items: center; - display: flex; - justify-content: center; - text-align: center; -`,lr=F__default.default(rr)` - margin: 0 ${({theme:e})=>e.spacing(.5)}; - padding: 0; - width: ${({width:e})=>e?`${e}px`:"auto"}; - - &:hover:not(:focus) { - background-color: ${({theme:e})=>e.background.transparent.light}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - cursor: pointer; - padding: 0 ${({theme:e})=>e.spacing(1)}; - } -`,Wy=({firstValue:e,secondValue:o,firstValuePlaceholder:r,secondValuePlaceholder:t,onChange:n,className:a})=>{let{goBackToPreviousHotkeyScope:i,setHotkeyScopeAndMemorizePreviousScope:c}=B(),s=()=>{c("text-input");},m=()=>{i();};return jsxRuntime.jsxs(ic,{className:a,children:[jsxRuntime.jsx(io,{node:e||r,children:l=>jsxRuntime.jsx(lr,{width:l?.width,placeholder:r,value:e,onFocus:s,onBlur:m,onChange:u=>{n(u.target.value,o);}})}),jsxRuntime.jsx(io,{node:o||t,children:l=>jsxRuntime.jsx(lr,{width:l?.width,autoComplete:"off",placeholder:t,value:o,onFocus:s,onChange:u=>{n(e,u.target.value);}})})]})};var dr=recoil.atom({key:"iconsState",default:{}});var mr=()=>{let e=recoil.useRecoilValue(dr),o=iconsReact.Icon123;return {getIcons:()=>e,getIcon:n=>n?e[n]??o:o}};var ur=({hotkey:e,onHotkeyTriggered:o})=>(C(e.key,()=>o(),e.scope,[o]),jsxRuntime.jsx(jsxRuntime.Fragment,{}));var gr=e=>ze.useContext(e);var q=(e,o)=>{let t=gr(e)?.scopeId;if(o)return o;if(t)return t;throw new Error("Scope id is not provided and cannot be found in context.")};var be=e=>ze.createContext(e??null);var he=be();var xe=(e,o)=>recoil.useRecoilState(e({scopeId:o}));var $=({key:e,defaultValue:o})=>recoil.atomFamily({key:e,default:o});var fr=$({key:"dropdownHotkeyScopeScopedState",defaultValue:null});var yr=$({key:"dropdownWidthScopedState",defaultValue:160});var br=$({key:"isDropdownOpenScopedState",defaultValue:!1});var hr=({scopeId:e})=>{let[o,r]=xe(br,e),[t,n]=xe(fr,e),[a,i]=xe(yr,e);return {isDropdownOpen:o,setIsDropdownOpen:r,dropdownHotkeyScope:t,setDropdownHotkeyScope:n,dropdownWidth:a,setDropdownWidth:i}};var E=e=>{let{setHotkeyScopeAndMemorizePreviousScope:o,goBackToPreviousHotkeyScope:r}=B(),t=q(he,e?.dropdownScopeId),{dropdownHotkeyScope:n,setDropdownHotkeyScope:a,isDropdownOpen:i,setIsDropdownOpen:c,dropdownWidth:s,setDropdownWidth:m}=hr({scopeId:t}),l=()=>{r(),c(!1);},u=()=>{c(!0),n&&o(n.scope,n.customScopes);};return {scopeId:t,isDropdownOpen:i,closeDropdown:l,toggleDropdown:()=>{i?l():u();},openDropdown:u,dropdownHotkeyScope:n,setDropdownHotkeyScope:a,dropdownWidth:s,setDropdownWidth:m}};var xr=(e,o)=>yc__default.default(e,o);var Sr=({dropdownHotkeyScopeFromParent:e})=>{let{dropdownHotkeyScope:o,setDropdownHotkeyScope:r}=E();ze.useEffect(()=>{xr(e,o)||r(e);},[o,e,r]);};var xc=F__default.default.div` - backdrop-filter: ${({disableBlur:e})=>e?"none":"blur(20px)"}; - background: ${({theme:e})=>e.background.secondary}; - border: 1px solid ${({theme:e})=>e.border.color.medium}; - border-radius: ${({theme:e})=>e.border.radius.md}; - - box-shadow: ${({theme:e})=>e.boxShadow.strong}; - - display: flex; - - flex-direction: column; - - width: ${({width:e})=>e?`${typeof e=="number"?`${e}px`:e}`:"160px"}; -`,Se=xc;var Ir=({onDropdownClose:e,onDropdownOpen:o})=>{let{isDropdownOpen:r}=E();return ze.useEffect(()=>{r?o?.():e?.();},[r,e,o]),null};var ke=({className:e,clickableComponent:o,dropdownComponents:r,dropdownMenuWidth:t,hotkey:n,dropdownHotkeyScope:a,dropdownPlacement:i="bottom-end",dropdownOffset:c={x:0,y:0},onClickOutside:s,onClose:m,onOpen:l})=>{let u=ze.useRef(null),{isDropdownOpen:g,toggleDropdown:x,closeDropdown:S,dropdownWidth:b}=E(),h=[];c.x&&h.push(react$2.offset({crossAxis:c.x})),c.y&&h.push(react$2.offset({mainAxis:c.y}));let{refs:k,floatingStyles:I}=react$2.useFloating({placement:i,middleware:[react$2.flip(),...h],whileElementsMounted:react$2.autoUpdate}),y=()=>{x();};return no({refs:[u],callback:()=>{s?.(),g&&S();}}),Sr({dropdownHotkeyScopeFromParent:a}),C(tsKeyEnum.Key.Escape,()=>{S();},a.scope,[S]),jsxRuntime.jsxs("div",{ref:u,className:e,children:[o&&jsxRuntime.jsx("div",{ref:k.setReference,onClick:x,children:o}),n&&jsxRuntime.jsx(ur,{hotkey:n,onHotkeyTriggered:y}),g&&jsxRuntime.jsx(Se,{width:t??b,"data-select-disable":!0,ref:k.setFloating,style:I,children:r}),jsxRuntime.jsx(Ir,{onDropdownClose:m,onDropdownOpen:l})]})};var Ce=recoil.atom({key:"scroll/isScollingState",default:!1});var Cr=({scrollableRef:e})=>{let o=recoil.useRecoilCallback(({snapshot:n})=>()=>{n.getLoadable(Ce).getValue()||e.current?.classList.remove("scrolling");}),r=recoil.useRecoilCallback(({set:n})=>()=>{n(Ce,!0),e.current?.classList.add("scrolling");}),t=recoil.useRecoilCallback(({set:n})=>()=>{n(Ce,!1),Lc__default.default(o,1e3)();});ze.useEffect(()=>{let n=e.current;return n?.addEventListener("scrollend",t),n?.addEventListener("scroll",r),()=>{n?.removeEventListener("scrollend",t),n?.removeEventListener("scroll",r);}},[o,r,t,e]);};var Hc=ze.createContext({current:null}),Mc=F__default.default.div` - display: flex; - height: 100%; - overflow: auto; - scrollbar-gutter: stable; - width: 100%; - - &.scrolling::-webkit-scrollbar-thumb { - background-color: ${({theme:e})=>e.border.color.medium}; - } -`,$r=({children:e,className:o})=>{let r=ze.useRef(null);return Cr({scrollableRef:r}),jsxRuntime.jsx(Hc.Provider,{value:r,children:jsxRuntime.jsx(Mc,{ref:r,className:o,children:e})})};var Ac=F__default.default.div` - --padding: ${({theme:e})=>e.spacing(1)}; - - align-items: flex-start; - display: flex; - - flex-direction: column; - gap: 2px; - height: 100%; - max-height: ${({hasMaxHeight:e})=>e?"180px":"none"}; - overflow-y: auto; - - padding: var(--padding); - padding-right: 0; - - width: calc(100% - 1 * var(--padding)); -`,Dc=F__default.default($r)` - width: 100%; -`,Fc=F__default.default.div` - align-items: flex-start; - display: flex; - - flex-direction: column; - gap: 2px; - height: 100%; - width: 100%; -`,ve=({children:e,hasMaxHeight:o})=>jsxRuntime.jsx(Ac,{hasMaxHeight:o,children:jsxRuntime.jsx(Dc,{children:jsxRuntime.jsx(Fc,{children:e})})});var Nc=F__default.default.div` - --vertical-padding: ${({theme:e})=>e.spacing(1)}; - - align-items: center; - - display: flex; - flex-direction: row; - height: calc(36px - 2 * var(--vertical-padding)); - padding: var(--vertical-padding) 0; - - width: 100%; -`,Uc=F__default.default.input` - ${ge} - - font-size: ${({theme:e})=>e.font.size.sm}; - width: 100%; - - &[type='number']::-webkit-outer-spin-button, - &[type='number']::-webkit-inner-spin-button { - -webkit-appearance: none; - margin: 0; - } - - &[type='number'] { - -moz-appearance: textfield; - } -`,Pr=ze.forwardRef(({value:e,onChange:o,autoFocus:r,placeholder:t="Search",type:n},a)=>jsxRuntime.jsx(Nc,{children:jsxRuntime.jsx(Uc,{autoComplete:"off",autoFocus:r,onChange:o,placeholder:t,type:n,value:e,ref:a})}));var Vc=F__default.default.div` - background-color: ${({theme:e})=>e.border.color.light}; - height: 1px; - - width: 100%; -`,Lr=Vc;var $e=({children:e,dropdownScopeId:o})=>jsxRuntime.jsx(he.Provider,{value:{scopeId:o},children:e});var Rr=$({key:"selectableItemIdsScopedState",defaultValue:[[]]});var Br=$({key:"selectableListOnEnterScopedState",defaultValue:void 0});var Er=$({key:"selectedItemIdScopedState",defaultValue:null});var Hr=({key:e,defaultValue:o})=>recoil.atomFamily({key:e,default:o});var po=Hr({key:"isSelectedItemIdMapScopedFamilyState",defaultValue:!1});var Mr=recoil.selectorFamily({key:"isSelectedItemIdScopedFamilySelector",get:({scopeId:e,itemId:o})=>({get:r})=>r(po({scopeId:e,familyKey:o})),set:({scopeId:e,itemId:o})=>({set:r},t)=>r(po({scopeId:e,familyKey:o}),t)});var we=(e,o)=>e({scopeId:o});var _c="UNDEFINED_SELECTABLE_ITEM_ID",O=({selectableListScopeId:e,itemId:o})=>{let r=Mr({scopeId:e,itemId:o??_c}),t=we(Er,e),n=we(Rr,e),a=we(Br,e);return {isSelectedItemIdSelector:r,selectableItemIdsState:n,selectedItemIdState:t,selectableListOnEnterState:a}};var oe=(e,o)=>e.getLoadable(o).getValue();var Dr=(e,o)=>{let r=(n,a)=>{if(a)for(let i=0;ii=>{let{selectedItemIdState:c,selectableItemIdsState:s}=O({selectableListScopeId:e}),m=oe(n,c),l=oe(n,s),u=r(l,m),x=(S=>{if(!m||!u)return l[0][0];let{row:b,col:h}=u;if(l.length===0)return;let k=l.length===1,I,y;switch(S){case"up":I=k?b:Math.max(0,b-1),y=k?Math.max(0,h-1):h;break;case"down":I=k?b:Math.min(l.length-1,b+1),y=k?Math.min(l[b].length-1,h+1):h;break;case"left":I=b,y=Math.max(0,h-1);break;case"right":I=b,y=Math.min(l[b].length-1,h+1);break;default:I=b,y=h;}return l[I][y]})(i);if(m!==x){if(x){let{isSelectedItemIdSelector:S}=O({selectableListScopeId:e,itemId:x});a(S,!0),a(c,x);}if(m){let{isSelectedItemIdSelector:S}=O({selectableListScopeId:e,itemId:m});a(S,!1);}}},[e]);return C(tsKeyEnum.Key.ArrowUp,()=>t("up"),o,[]),C(tsKeyEnum.Key.ArrowDown,()=>t("down"),o,[]),C(tsKeyEnum.Key.ArrowLeft,()=>t("left"),o,[]),C(tsKeyEnum.Key.ArrowRight,()=>t("right"),o,[]),C(tsKeyEnum.Key.Enter,recoil.useRecoilCallback(({snapshot:n})=>()=>{let{selectedItemIdState:a,selectableListOnEnterState:i}=O({selectableListScopeId:e}),c=oe(n,a),s=oe(n,i);c&&s?.(c);},[e]),o,[]),jsxRuntime.jsx(jsxRuntime.Fragment,{})};var K=be();var Fr=e=>{let{selectableListScopeId:o,itemId:r}=e??{},t=q(K,o),{selectedItemIdState:n,selectableItemIdsState:a,isSelectedItemIdSelector:i,selectableListOnEnterState:c}=O({selectableListScopeId:t,itemId:r});return {scopeId:t,isSelectedItemIdSelector:i,selectableItemIdsState:a,selectedItemIdState:n,selectableListOnEnterState:c}};var Te=e=>{let o=q(K,e?.selectableListId),{selectableItemIdsState:r,isSelectedItemIdSelector:t,selectableListOnEnterState:n}=Fr({selectableListScopeId:o,itemId:e?.itemId}),a=recoil.useSetRecoilState(r),i=recoil.useSetRecoilState(n),c=recoil.useRecoilValue(t);return {setSelectableItemIds:a,isSelectedItemId:c,setSelectableListOnEnter:i,selectableListId:o,isSelectedItemIdSelector:t}};var Nr=({children:e,selectableListScopeId:o})=>jsxRuntime.jsx(K.Provider,{value:{scopeId:o},children:e});var Pe=(e,o)=>{let r=[...e],t=[];for(;r.length;)t.push(r.splice(0,o));return t};var Or=({children:e,selectableListId:o,hotkeyScope:r,selectableItemIdArray:t,selectableItemIdMatrix:n,onEnter:a})=>{Dr(o,r);let{setSelectableItemIds:i,setSelectableListOnEnter:c}=Te({selectableListId:o});return ze.useEffect(()=>{c(()=>a);},[a,c]),ze.useEffect(()=>{if(!t&&!n)throw new Error("Either selectableItemIdArray or selectableItemIdsMatrix must be provided");n&&i(n),t&&i(Pe(t,1));},[t,n,i]),jsxRuntime.jsx(Nr,{selectableListScopeId:o,children:e})};var es=F__default.default.button` - align-items: center; - ${({theme:e,variant:o,accent:r,disabled:t,focus:n})=>{switch(o){case"primary":switch(r){case"default":return ` - background: ${e.background.secondary}; - border-color: ${t?"transparent":n?e.color.blue:e.background.transparent.light}; - color: ${t?e.font.color.extraLight:e.font.color.secondary}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - &:hover { - background: ${t?e.background.secondary:e.background.tertiary}; - } - &:active { - background: ${t?e.background.secondary:e.background.quaternary}; - } - `;case"blue":return ` - background: ${t?e.color.blue20:e.color.blue}; - border-color: ${t?"transparent":n?e.color.blue:e.background.transparent.light}; - border-width: ${!t&&n?"1px 1px !important":0}; - color: ${e.grayScale.gray0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - &:hover { - background: ${t?e.color.blue20:e.color.blue50}; - } - &:active { - background: ${t?e.color.blue20:e.color.blue60}; - } - `;case"danger":return ` - background: ${t?e.color.red20:e.color.red}; - border-color: ${t?"transparent":n?e.color.red:e.background.transparent.light}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.color.red10}`:"none"}; - color: ${e.grayScale.gray0}; - &:hover { - background: ${t?e.color.red20:e.color.red50}; - } - &:active { - background: ${t?e.color.red20:e.color.red50}; - } - `}break;case"secondary":case"tertiary":switch(r){case"default":return ` - background: ${n?e.background.transparent.primary:"transparent"}; - border-color: ${o==="secondary"?!t&&n?e.color.blue:e.background.transparent.light:n?e.color.blue:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - color: ${t?e.font.color.extraLight:e.font.color.secondary}; - &:hover { - background: ${t?"transparent":e.background.transparent.light}; - } - &:active { - background: ${t?"transparent":e.background.transparent.light}; - } - `;case"blue":return ` - background: ${n?e.background.transparent.primary:"transparent"}; - border-color: ${o==="secondary"?t?e.color.blue20:e.color.blue:n?e.color.blue:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.accent.tertiary}`:"none"}; - color: ${t?e.accent.accent4060:e.color.blue}; - &:hover { - background: ${t?"transparent":e.accent.tertiary}; - } - &:active { - background: ${t?"transparent":e.accent.secondary}; - } - `;case"danger":return ` - background: transparent; - border-color: ${o==="secondary"?e.border.color.danger:n?e.color.red:"transparent"}; - border-width: ${!t&&n?"1px 1px !important":0}; - box-shadow: ${!t&&n?`0 0 0 3px ${e.color.red10}`:"none"}; - color: ${t?e.color.red20:e.font.color.danger}; - &:hover { - background: ${t?"transparent":e.background.danger}; - } - &:active { - background: ${t?"transparent":e.background.danger}; - } - `}}}} - - border-radius: ${({position:e,theme:o})=>{switch(e){case"left":return `${o.border.radius.sm} 0px 0px ${o.border.radius.sm}`;case"right":return `0px ${o.border.radius.sm} ${o.border.radius.sm} 0px`;case"middle":return "0px";case"standalone":return o.border.radius.sm}}}; - border-style: solid; - border-width: ${({variant:e,position:o})=>{switch(e){case"primary":case"secondary":return o==="middle"?"1px 0px":"1px";case"tertiary":return "0"}}}; - box-sizing: content-box; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - flex-direction: row; - font-family: ${({theme:e})=>e.font.family}; - font-weight: 500; - gap: ${({theme:e})=>e.spacing(1)}; - height: ${({size:e})=>e==="small"?"24px":"32px"}; - justify-content: center; - padding: 0; - transition: background 0.1s ease; - - white-space: nowrap; - - width: ${({size:e})=>e==="small"?"24px":"32px"}; - - &:focus { - outline: none; - } -`,Wr=({className:e,Icon:o,variant:r="primary",size:t="medium",accent:n="default",position:a="standalone",disabled:i=!1,focus:c=!1,dataTestId:s,ariaLabel:m,onClick:l})=>{let u=react.useTheme();return jsxRuntime.jsx(es,{"data-testid":s,variant:r,size:t,position:a,disabled:i,focus:c,accent:n,className:e,onClick:l,"aria-label":m,children:o&&jsxRuntime.jsx(o,{size:u.icon.size.md})})};var ts=F__default.default.div` - display: flex; - flex-direction: row; - flex-wrap: wrap; - gap: ${({theme:e})=>e.spacing(.5)}; -`,rs=F__default.default(Wt)` - background: ${({theme:e,isSelected:o})=>o?e.background.transparent.medium:"transparent"}; -`,_r=e=>e.replace(/[A-Z]/g,o=>` ${o}`).trim(),ns=({iconKey:e,onClick:o,selectedIconKey:r,Icon:t})=>{let{isSelectedItemId:n}=Te({itemId:e});return jsxRuntime.jsx(rs,{"aria-label":_r(e),size:"medium",title:e,isSelected:e===r||n,Icon:t,onClick:o},e)},Zx=({disabled:e,dropdownScopeId:o="icon-picker",onChange:r,selectedIconKey:t,onClickOutside:n,onClose:a,onOpen:i,variant:c="secondary",className:s})=>{let[m,l]=ze.useState(""),{goBackToPreviousHotkeyScope:u,setHotkeyScopeAndMemorizePreviousScope:g}=B(),{closeDropdown:x}=E({dropdownScopeId:o}),{getIcons:S,getIcon:b}=mr(),h=S(),k=ze.useMemo(()=>{let y=h?Object.keys(h).filter(A=>A!==t&&(!m||[A,_r(A)].some(Ne=>Ne.toLowerCase().includes(m.toLowerCase())))):[];return (t?[t,...y]:y).slice(0,25)},[h,m,t]),I=ze.useMemo(()=>Pe(k.slice(),5),[k]);return jsxRuntime.jsx($e,{dropdownScopeId:o,children:jsxRuntime.jsx("div",{className:s,children:jsxRuntime.jsx(ke,{dropdownHotkeyScope:{scope:"icon-picker"},clickableComponent:jsxRuntime.jsx(Wr,{disabled:e,Icon:t?b(t):iconsReact.IconApps,variant:c}),dropdownMenuWidth:176,dropdownComponents:jsxRuntime.jsx(Or,{selectableListId:"icon-list",selectableItemIdMatrix:I,hotkeyScope:"icon-picker",onEnter:y=>{r({iconKey:y,Icon:b(y)}),x();},children:jsxRuntime.jsxs(Se,{width:176,children:[jsxRuntime.jsx(Pr,{placeholder:"Search icon",autoFocus:!0,onChange:y=>l(y.target.value)}),jsxRuntime.jsx(Lr,{}),jsxRuntime.jsx("div",{onMouseEnter:()=>{g("icon-picker");},onMouseLeave:u,children:jsxRuntime.jsx(ve,{children:jsxRuntime.jsx(ts,{children:k.map(y=>jsxRuntime.jsx(ns,{iconKey:y,onClick:()=>{r({iconKey:y,Icon:b(y)}),x();},selectedIconKey:t,Icon:b(y)},y))})})})]})}),onClickOutside:n,onClose:()=>{a?.(),l("");},onOpen:i})})})};var ss=F__default.default.div` - display: flex; - flex-direction: row; -`,ls=F__default.default.button` - align-items: center; - background: ${({theme:e,disabled:o})=>o?e.background.secondary:e.background.tertiary}; - border: none; - border-radius: ${({theme:e})=>e.border.radius.sm}; - color: ${({theme:e})=>e.font.color.light}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: flex; - height: 66px; - justify-content: center; - overflow: hidden; - padding: 0; - transition: background 0.1s ease; - - width: 66px; - - img { - height: 100%; - object-fit: cover; - width: 100%; - } - - ${({theme:e,withPicture:o,disabled:r})=>o||r?"":` - &:hover { - background: ${e.background.quaternary}; - } - `}; -`,ps=F__default.default.div` - display: flex; - flex: 1; - flex-direction: column; - justify-content: space-between; - margin-left: ${({theme:e})=>e.spacing(4)}; -`,ds=F__default.default.div` - display: flex; - flex-direction: row; - > * + * { - margin-left: ${({theme:e})=>e.spacing(2)}; - } -`,ms=F__default.default.span` - color: ${({theme:e})=>e.font.color.light}; - font-size: ${({theme:e})=>e.font.size.xs}; -`,us=F__default.default.span` - color: ${({theme:e})=>e.font.color.danger}; - font-size: ${({theme:e})=>e.font.size.xs}; - margin-top: ${({theme:e})=>e.spacing(1)}; -`,gs=F__default.default.input` - display: none; -`,i0=({picture:e,onUpload:o,onRemove:r,onAbort:t,isUploading:n=!1,errorMessage:a,disabled:i=!1,className:c})=>{let s=react.useTheme(),m=ze__namespace.default.useRef(null),l=()=>{m.current?.click();};return jsxRuntime.jsxs(ss,{className:c,children:[jsxRuntime.jsx(ls,{withPicture:!!e,disabled:i,onClick:l,children:e?jsxRuntime.jsx("img",{src:e||"/images/default-profile-picture.png",alt:"profile"}):jsxRuntime.jsx(iconsReact.IconFileUpload,{size:s.icon.size.md})}),jsxRuntime.jsxs(ps,{children:[jsxRuntime.jsxs(ds,{children:[jsxRuntime.jsx(gs,{type:"file",ref:m,accept:"image/jpeg, image/png, image/gif",onChange:u=>{o&&u.target.files&&o(u.target.files[0]);}}),n&&t?jsxRuntime.jsx(_,{Icon:iconsReact.IconX,onClick:t,variant:"secondary",title:"Abort",disabled:!e||i,fullWidth:!0}):jsxRuntime.jsx(_,{Icon:iconsReact.IconUpload,onClick:l,variant:"secondary",title:"Upload",disabled:i,fullWidth:!0}),jsxRuntime.jsx(_,{Icon:iconsReact.IconTrash,onClick:r,variant:"secondary",title:"Remove",disabled:!e||i,fullWidth:!0})]}),jsxRuntime.jsx(ms,{children:"We support your best PNGs, JPEGs and GIFs portraits under 10MB"}),a&&jsxRuntime.jsx(us,{children:a})]})]})};var Gr=({value:e,onChange:o,onValueChange:r,children:t})=>{let n=react.useTheme(),a=i=>{o?.(i),r?.(i.target.value);};return jsxRuntime.jsx(jsxRuntime.Fragment,{children:ze__namespace.default.Children.map(t,i=>ze__namespace.default.isValidElement(i)?ze__namespace.default.cloneElement(i,{style:{marginBottom:n.spacing(2)},checked:i.props.value===e,onChange:a}):i)})};var xs=(r=>(r.Large="large",r.Small="small",r))(xs||{}),Ss=(r=>(r.Left="left",r.Right="right",r))(Ss||{}),Is=F__default.default.div` - ${({labelPosition:e})=>e==="left"?` - flex-direction: row-reverse; - `:` - flex-direction: row; - `}; - align-items: center; - display: inline-flex; -`,ks=F__default.default(framerMotion.motion.input)` - -webkit-appearance: none; - appearance: none; - background-color: transparent; - border: 1px solid ${({theme:e})=>e.font.color.secondary}; - border-radius: 50%; - :hover { - background-color: ${({theme:e,checked:o})=>{if(!o)return e.background.tertiary}}; - outline: 4px solid - ${({theme:e,checked:o})=>o?f(e.color.blue,.12):e.background.tertiary}; - } - &:checked { - background-color: ${({theme:e})=>e.color.blue}; - border: none; - &::after { - background-color: ${({theme:e})=>e.grayScale.gray0}; - border-radius: 50%; - content: ''; - height: ${({"radio-size":e})=>e==="large"?"8px":"6px"}; - left: 50%; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); - width: ${({"radio-size":e})=>e==="large"?"8px":"6px"}; - } - } - &:disabled { - cursor: not-allowed; - opacity: 0.12; - } - height: ${({"radio-size":e})=>e==="large"?"18px":"16px"}; - position: relative; - width: ${({"radio-size":e})=>e==="large"?"18px":"16px"}; -`,Cs=F__default.default.label` - color: ${({theme:e})=>e.font.color.primary}; - cursor: pointer; - font-size: ${({theme:e})=>e.font.size.sm}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - margin-left: ${({theme:e,labelPosition:o})=>o==="right"?e.spacing(2):"0px"}; - margin-right: ${({theme:e,labelPosition:o})=>o==="left"?e.spacing(2):"0px"}; - opacity: ${({disabled:e})=>e?.32:1}; -`,vs=({checked:e,value:o,onChange:r,onCheckedChange:t,size:n="small",labelPosition:a="right",disabled:i=!1,className:c})=>jsxRuntime.jsxs(Is,{className:c,labelPosition:a,children:[jsxRuntime.jsx(ks,{type:"radio",id:"input-radio",name:"input-radio","data-testid":"input-radio",checked:e,value:o,"radio-size":n,disabled:i,onChange:m=>{r?.(m),t?.(m.target.checked);},initial:{scale:.95},animate:{scale:e?1.05:.95},transition:{type:"spring",stiffness:300,damping:20}}),o&&jsxRuntime.jsx(Cs,{htmlFor:"input-radio",labelPosition:a,disabled:i,children:o})]});vs.Group=Gr;var L=F__default.default.li` - --horizontal-padding: ${({theme:e})=>e.spacing(1)}; - --vertical-padding: ${({theme:e})=>e.spacing(2)}; - - align-items: center; - - background: ${({isKeySelected:e,theme:o})=>e?o.background.transparent.light:o.background.secondary}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - cursor: pointer; - - display: flex; - - flex-direction: row; - - font-size: ${({theme:e})=>e.font.size.sm}; - - gap: ${({theme:e})=>e.spacing(2)}; - - height: calc(32px - 2 * var(--vertical-padding)); - justify-content: space-between; - - padding: var(--vertical-padding) var(--horizontal-padding); - - ${tr}; - - ${({theme:e,accent:o})=>{switch(o){case"danger":return react.css` - color: ${e.font.color.danger}; - &:hover { - background: ${e.background.transparent.danger}; - } - `;case"placeholder":return react.css` - color: ${e.font.color.tertiary}; - `;case"default":default:return react.css` - color: ${e.font.color.secondary}; - `}}} - - position: relative; - user-select: none; - - width: calc(100% - 2 * var(--horizontal-padding)); -`,H=F__default.default.div` - font-size: ${({theme:e})=>e.font.size.sm}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - overflow: hidden; - padding-left: ${({theme:e,hasLeftIcon:o})=>o?"":e.spacing(1)}; - text-overflow: ellipsis; - white-space: nowrap; -`;F__default.default.div` - width: ${({theme:e})=>e.spacing(1)}; -`;var v=F__default.default.div` - align-items: center; - display: flex; - - flex-direction: row; - - gap: ${({theme:e})=>e.spacing(2)}; - min-width: 0; - width: 100%; -`,Kr=F__default.default.div` - align-items: center; - display: flex; - flex-direction: row; -`,Le=F__default.default(L)` - & .hoverable-buttons { - opacity: ${({isMenuOpen:e})=>e?1:0}; - pointer-events: none; - position: fixed; - right: ${({theme:e})=>e.spacing(2)}; - transition: opacity ${({theme:e})=>e.animation.duration.instant}s ease; - } - - &:hover { - & .hoverable-buttons { - opacity: 1; - pointer-events: auto; - } - } -`;var T=({LeftIcon:e,text:o,showGrip:r=!1})=>{let t=react.useTheme();return jsxRuntime.jsxs(v,{children:[r&&jsxRuntime.jsx(iconsReact.IconGripVertical,{size:t.icon.size.md,stroke:t.icon.stroke.sm,color:t.font.color.extraLight}),e&&jsxRuntime.jsx(e,{size:t.icon.size.md,stroke:t.icon.stroke.sm}),jsxRuntime.jsx(H,{hasLeftIcon:!!e,children:jsxRuntime.jsx(X,{text:o})})]})};var Qr=({LeftIcon:e,accent:o="default",text:r,iconButtons:t,isTooltipOpen:n,className:a,testId:i,onClick:c})=>{let s=Array.isArray(t)&&t.length>0;return jsxRuntime.jsxs(Le,{"data-testid":i??void 0,onClick:l=>{c&&(l.preventDefault(),l.stopPropagation(),c?.(l));},className:a,accent:o,isMenuOpen:!!n,children:[jsxRuntime.jsx(v,{children:jsxRuntime.jsx(T,{LeftIcon:e??void 0,text:r})}),jsxRuntime.jsx("div",{className:"hoverable-buttons",children:s&&jsxRuntime.jsx(se,{iconButtons:t,size:"small"})})]})};var Rs=F__default.default.div` - align-items: center; - background-color: ${({theme:e})=>e.background.transparent.lighter}; - border: 1px solid ${({theme:e})=>e.border.color.medium}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - color: ${({disabled:e,theme:o})=>e?o.font.color.tertiary:o.font.color.primary}; - cursor: ${({disabled:e})=>e?"not-allowed":"pointer"}; - display: ${({fullWidth:e})=>e?"flex":"inline-flex"}; - gap: ${({theme:e})=>e.spacing(1)}; - height: ${({theme:e})=>e.spacing(8)}; - justify-content: space-between; - padding: 0 ${({theme:e})=>e.spacing(2)}; -`,Jr=F__default.default.span` - color: ${({theme:e})=>e.font.color.light}; - display: block; - font-size: ${({theme:e})=>e.font.size.xs}; - font-weight: ${({theme:e})=>e.font.weight.semiBold}; - margin-bottom: ${({theme:e})=>e.spacing(1)}; - text-transform: uppercase; -`,Bs=F__default.default.div` - align-items: center; - display: flex; - gap: ${({theme:e})=>e.spacing(1)}; -`,Es=F__default.default(iconsReact.IconChevronDown)` - color: ${({disabled:e,theme:o})=>e?o.font.color.extraLight:o.font.color.tertiary}; -`,_0=({className:e,disabled:o,dropdownScopeId:r,fullWidth:t,label:n,onChange:a,options:i,value:c})=>{let s=react.useTheme(),m=i.find(({value:g})=>g===c)||i[0],{closeDropdown:l}=E({dropdownScopeId:r}),u=jsxRuntime.jsxs(Rs,{disabled:o,fullWidth:t,children:[jsxRuntime.jsxs(Bs,{children:[!!m?.Icon&&jsxRuntime.jsx(m.Icon,{color:o?s.font.color.light:s.font.color.primary,size:s.icon.size.md,stroke:s.icon.stroke.sm}),m?.label]}),jsxRuntime.jsx(Es,{disabled:o,size:s.icon.size.md})]});return o?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!!n&&jsxRuntime.jsx(Jr,{children:n}),u]}):jsxRuntime.jsx($e,{dropdownScopeId:r,children:jsxRuntime.jsxs("div",{className:e,children:[!!n&&jsxRuntime.jsx(Jr,{children:n}),jsxRuntime.jsx(ke,{dropdownMenuWidth:176,dropdownPlacement:"bottom-start",clickableComponent:u,dropdownComponents:jsxRuntime.jsx(ve,{children:i.map(g=>jsxRuntime.jsx(Qr,{LeftIcon:g.Icon,text:g.label,onClick:()=>{a?.(g.value),l();}},g.value))}),dropdownHotkeyScope:{scope:"select"}})]})})};var Zr=5,Ds=F__default.default(wi__default.default)` - background-color: ${({theme:e})=>e.background.transparent.lighter}; - border: 1px solid ${({theme:e})=>e.border.color.medium}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-sizing: border-box; - color: ${({theme:e})=>e.font.color.primary}; - font-family: inherit; - font-size: ${({theme:e})=>e.font.size.md}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - line-height: 16px; - overflow: auto; - padding: ${({theme:e})=>e.spacing(2)}; - padding-top: ${({theme:e})=>e.spacing(3)}; - resize: none; - width: 100%; - - &:focus { - outline: none; - } - - &::placeholder { - color: ${({theme:e})=>e.font.color.light}; - font-weight: ${({theme:e})=>e.font.weight.regular}; - } - - &:disabled { - color: ${({theme:e})=>e.font.color.tertiary}; - } -`,j0=({disabled:e,placeholder:o,minRows:r=1,value:t="",className:n,onChange:a})=>{let i=Math.min(r,Zr),{goBackToPreviousHotkeyScope:c,setHotkeyScopeAndMemorizePreviousScope:s}=B();return jsxRuntime.jsx(Ds,{placeholder:o,maxRows:Zr,minRows:i,value:t,onChange:u=>a?.(u.target.value),onFocus:()=>{s("text-input");},onBlur:()=>{c();},disabled:e,className:n})};var jr=(...e)=>o=>{for(let r of e)guards.isFunction(r)?r(o):r!=null&&(r.current=o);};var Ws=F__default.default.div` - display: inline-flex; - flex-direction: column; - width: ${({fullWidth:e})=>e?"100%":"auto"}; -`,Ys=F__default.default.span` - color: ${({theme:e})=>e.font.color.light}; - font-size: ${({theme:e})=>e.font.size.xs}; - font-weight: ${({theme:e})=>e.font.weight.semiBold}; - margin-bottom: ${({theme:e})=>e.spacing(1)}; - text-transform: uppercase; -`,Xs=F__default.default.div` - display: flex; - flex-direction: row; - width: 100%; -`,_s=F__default.default.input` - background-color: ${({theme:e})=>e.background.transparent.lighter}; - border: 1px solid ${({theme:e})=>e.border.color.medium}; - border-bottom-left-radius: ${({theme:e})=>e.border.radius.sm}; - border-right: none; - border-top-left-radius: ${({theme:e})=>e.border.radius.sm}; - color: ${({theme:e})=>e.font.color.primary}; - display: flex; - flex-grow: 1; - font-family: ${({theme:e})=>e.font.family}; - - font-weight: ${({theme:e})=>e.font.weight.regular}; - outline: none; - padding: ${({theme:e})=>e.spacing(2)}; - - width: 100%; - - &::placeholder, - &::-webkit-input-placeholder { - color: ${({theme:e})=>e.font.color.light}; - font-family: ${({theme:e})=>e.font.family}; - font-weight: ${({theme:e})=>e.font.weight.medium}; - } - - &:disabled { - color: ${({theme:e})=>e.font.color.tertiary}; - } -`,Gs=F__default.default.div` - color: ${({theme:e})=>e.color.red}; - font-size: ${({theme:e})=>e.font.size.xs}; - padding: ${({theme:e})=>e.spacing(1)}; -`,qs=F__default.default.div` - align-items: center; - background-color: ${({theme:e})=>e.background.transparent.lighter}; - border: 1px solid ${({theme:e})=>e.border.color.medium}; - border-bottom-right-radius: ${({theme:e})=>e.border.radius.sm}; - border-left: none; - border-top-right-radius: ${({theme:e})=>e.border.radius.sm}; - display: flex; - justify-content: center; - padding-right: ${({theme:e})=>e.spacing(1)}; -`,yo=F__default.default.div` - align-items: center; - color: ${({theme:e})=>e.font.color.light}; - cursor: ${({onClick:e})=>e?"pointer":"default"}; - display: flex; - justify-content: center; -`,on="password",Ks=({className:e,label:o,value:r,onChange:t,onFocus:n,onBlur:a,onKeyDown:i,fullWidth:c,error:s,required:m,type:l,disableHotkeys:u=!1,autoFocus:g,placeholder:x,disabled:S,tabIndex:b,RightIcon:h},k)=>{let I=react.useTheme(),y=ze.useRef(null),A=jr(k,y),{goBackToPreviousHotkeyScope:Ne,setHotkeyScopeAndMemorizePreviousScope:Cn}=B(),vn=J=>{n?.(J),u||Cn("text-input");},$n=J=>{a?.(J),u||Ne();};C([tsKeyEnum.Key.Escape,tsKeyEnum.Key.Enter],()=>{y.current?.blur();},"text-input");let[Ue,wn]=ze.useState(!1),Tn=()=>{wn(!Ue);};return jsxRuntime.jsxs(Ws,{className:e,fullWidth:c??!1,children:[o&&jsxRuntime.jsx(Ys,{children:o+(m?"*":"")}),jsxRuntime.jsxs(Xs,{children:[jsxRuntime.jsx(_s,{autoComplete:"off",ref:A,tabIndex:b??0,onFocus:vn,onBlur:$n,type:Ue?"text":l,onChange:J=>{t?.(J.target.value);},onKeyDown:i,autoFocus:g,disabled:S,placeholder:x,required:m,value:r}),jsxRuntime.jsxs(qs,{children:[s&&jsxRuntime.jsx(yo,{children:jsxRuntime.jsx(iconsReact.IconAlertCircle,{size:16,color:I.color.red})}),!s&&l===on&&jsxRuntime.jsx(yo,{onClick:Tn,"data-testid":"reveal-password-button",children:Ue?jsxRuntime.jsx(iconsReact.IconEyeOff,{size:I.icon.size.md}):jsxRuntime.jsx(iconsReact.IconEye,{size:I.icon.size.md})}),!s&&l!==on&&!!h&&jsxRuntime.jsx(yo,{children:jsxRuntime.jsx(h,{size:I.icon.size.md})})]})]}),s&&jsxRuntime.jsx(Gs,{children:s})]})},hS=ze.forwardRef(Ks);var js=F__default.default.div` - align-items: center; - background-color: ${({theme:e,isOn:o,color:r})=>o?r??e.color.blue:e.background.quaternary}; - border-radius: 10px; - cursor: pointer; - display: flex; - height: ${({toggleSize:e})=>e==="small"?16:20}px; - transition: background-color 0.3s ease; - width: ${({toggleSize:e})=>e==="small"?24:32}px; -`,el=F__default.default(framerMotion.motion.div)` - background-color: ${({theme:e})=>e.background.primary}; - border-radius: 50%; - height: ${({size:e})=>e==="small"?12:16}px; - width: ${({size:e})=>e==="small"?12:16}px; -`,nn=({value:e,onChange:o,color:r,toggleSize:t="medium",className:n})=>{let[a,i]=ze.useState(e??!1),c={on:{x:t==="small"?10:14},off:{x:2}},s=()=>{i(!a),o&&o(!a);};return ze.useEffect(()=>{e!==a&&i(e??!1);},[e]),jsxRuntime.jsx(js,{onClick:s,isOn:a,color:r,toggleSize:t,className:n,children:jsxRuntime.jsx(el,{animate:a?"on":"off",variants:c,size:t})})};var nl=F__default.default.div` - min-height: 200px; - width: 100%; - & .editor { - background: ${({theme:e})=>e.background.primary}; - font-size: 13px; - color: ${({theme:e})=>e.font.color.primary}; - } - & .editor [class^='_inlineContent']:before { - color: ${({theme:e})=>e.font.color.tertiary}; - font-style: normal !important; - } -`,LS=({editor:e})=>{let r=react.useTheme().name=="light"?"light":"dark";return jsxRuntime.jsx(nl,{children:jsxRuntime.jsx(react$1.BlockNoteView,{editor:e,theme:r})})};var cl=F__default.default.div` - display: flex; - overflow: hidden; - white-space: nowrap; - - a { - color: inherit; - overflow: hidden; - text-decoration: underline; - text-decoration-color: ${({theme:e})=>e.border.color.strong}; - text-overflow: ellipsis; - - &:hover { - text-decoration-color: ${({theme:e})=>e.font.color.primary}; - } - } -`,MS=({className:e,href:o,children:r,onClick:t})=>jsxRuntime.jsx("div",{children:jsxRuntime.jsx(cl,{className:e,children:jsxRuntime.jsx(reactRouterDom.Link,{target:"_blank",onClick:t,to:o,children:r})})});var pl=F__default.default.div` - display: flex; - overflow: hidden; - white-space: nowrap; - - a { - color: inherit; - overflow: hidden; - text-overflow: ellipsis; - } -`,NS=({className:e,href:o,children:r,onClick:t})=>jsxRuntime.jsx("div",{children:jsxRuntime.jsx(pl,{className:e,children:jsxRuntime.jsx(reactRouterDom.Link,{target:"_blank",onClick:t,to:o,children:r})})});var ul=F__default.default.div` - overflow: hidden; - white-space: nowrap; - - a { - color: inherit; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - } -`,cn=({children:e,href:o,onClick:r})=>jsxRuntime.jsx("div",{children:e!==""?jsxRuntime.jsx(ul,{children:jsxRuntime.jsx(reactRouterDom.Link,{target:"_blank",to:o,onClick:r,children:jsxRuntime.jsx(ie,{label:`${e}`,variant:"rounded",size:"small"})})}):jsxRuntime.jsx(jsxRuntime.Fragment,{})});var yl=(t=>(t.Url="url",t.LinkedIn="linkedin",t.Twitter="twitter",t))(yl||{}),bl=F__default.default(cn)` - overflow: hidden; - - a { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -`,KS=({children:e,href:o,onClick:r,type:t})=>{let n=e;if(t==="linkedin"){let a=o.match(/(?:https?:\/\/)?(?:www.)?linkedin.com\/(?:in|company)\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/);a&&a[1]?n=a[1]:n="LinkedIn";}if(t==="twitter"){let a=o.match(/(?:https?:\/\/)?(?:www.)?twitter.com\/([-a-zA-Z0-9@:%_+.~#?&//=]*)/);a&&a[1]?n=`@${a[1]}`:n="@twitter";}return jsxRuntime.jsx(bl,{href:o,onClick:r,children:n})};var xl=F__default.default.div` - align-items: center; - display: flex; - flex-direction: row; - gap: ${({theme:e})=>e.spacing(1)}; - justify-content: center; -`,Sl=F__default.default.div` - color: ${({theme:e})=>e.font.color.light}; - padding-bottom: ${({theme:e})=>e.spacing(1)}; - padding-left: ${({theme:e})=>e.spacing(2)}; - padding-right: ${({theme:e})=>e.spacing(2)}; - padding-top: ${({theme:e})=>e.spacing(1)}; - white-space: nowrap; -`,sn=F__default.default.div` - align-items: center; - background-color: ${({theme:e})=>e.background.secondary}; - border: 1px solid ${({theme:e})=>e.border.color.strong}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - box-shadow: ${({theme:e})=>e.boxShadow.underline}; - display: flex; - flex-direction: column; - - height: ${({theme:e})=>e.spacing(5)}; - height: 18px; - justify-content: center; - text-align: center; - width: ${({theme:e})=>e.spacing(4)}; -`,pn=({firstHotKey:e,secondHotKey:o,joinLabel:r="then"})=>jsxRuntime.jsx(Sl,{children:e&&jsxRuntime.jsxs(xl,{children:[jsxRuntime.jsx(sn,{children:e}),o&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[r,jsxRuntime.jsx(sn,{children:o})]})]})});var Cl=F__default.default(H)` - color: ${({theme:e})=>e.font.color.primary}; -`,vl=F__default.default.div` - align-items: center; - background: ${({theme:e})=>e.background.transparent.light}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - - display: flex; - - flex-direction: row; - - padding: ${({theme:e})=>e.spacing(1)}; -`,$l=F__default.default.div` - --horizontal-padding: ${({theme:e})=>e.spacing(1)}; - --vertical-padding: ${({theme:e})=>e.spacing(2)}; - align-items: center; - background: ${({isSelected:e,theme:o})=>e?o.background.transparent.light:o.background.primary}; - border-radius: ${({theme:e})=>e.border.radius.sm}; - color: ${({theme:e})=>e.font.color.secondary}; - cursor: pointer; - display: flex; - flex-direction: row; - font-size: ${({theme:e})=>e.font.size.sm}; - gap: ${({theme:e})=>e.spacing(2)}; - justify-content: space-between; - padding: var(--vertical-padding) var(--horizontal-padding); - position: relative; - transition: all 150ms ease; - transition-property: none; - user-select: none; - width: calc(100% - 2 * var(--horizontal-padding)); - &:hover { - background: ${({theme:e})=>e.background.transparent.light}; - } - &[data-selected='true'] { - background: ${({theme:e})=>e.background.tertiary}; - } - &[data-disabled='true'] { - color: ${({theme:e})=>e.font.color.light}; - cursor: not-allowed; - } - svg { - height: 16px; - width: 16px; - } -`,aI=({LeftIcon:e,text:o,firstHotKey:r,secondHotKey:t,className:n,isSelected:a,onClick:i})=>{let c=react.useTheme();return jsxRuntime.jsxs($l,{onClick:i,className:n,isSelected:a,children:[jsxRuntime.jsxs(v,{children:[e&&jsxRuntime.jsx(vl,{children:jsxRuntime.jsx(e,{size:c.icon.size.sm})}),jsxRuntime.jsx(Cl,{hasLeftIcon:!!e,children:o})]}),jsxRuntime.jsx(pn,{firstHotKey:r,secondHotKey:t})]})};var dI=({LeftIcon:e,accent:o="default",iconButtons:r,isTooltipOpen:t,onClick:n,text:a,isDragDisabled:i=!1,className:c})=>{let s=Array.isArray(r)&&r.length>0;return jsxRuntime.jsxs(Le,{onClick:n,accent:o,className:c,isMenuOpen:!!t,children:[jsxRuntime.jsx(T,{LeftIcon:e,text:a,showGrip:!i}),s&&jsxRuntime.jsx(se,{className:"hoverable-buttons",iconButtons:r})]})};var Pl=F__default.default.div` - align-items: center; - display: flex; - flex-direction: row; - gap: ${({theme:e})=>e.spacing(2)}; -`,hI=({LeftIcon:e,text:o,selected:r,className:t,onSelectChange:n})=>jsxRuntime.jsx(L,{className:t,onClick:()=>{n?.(!r);},children:jsxRuntime.jsxs(Pl,{children:[jsxRuntime.jsx(ue,{checked:r}),jsxRuntime.jsx(T,{LeftIcon:e,text:o})]})});var Bl=F__default.default.div` - align-items: center; - display: flex; - flex-direction: row; - gap: ${({theme:e})=>e.spacing(2)}; -`,vI=({avatar:e,text:o,selected:r,className:t,isKeySelected:n,onSelectChange:a})=>jsxRuntime.jsx(L,{className:t,onClick:()=>{a?.(!r);},isKeySelected:n,children:jsxRuntime.jsxs(Bl,{children:[jsxRuntime.jsx(ue,{checked:r}),jsxRuntime.jsxs(v,{children:[e,jsxRuntime.jsx(H,{hasLeftIcon:!!e,children:o})]})]})});var BI=({LeftIcon:e,text:o,className:r,onClick:t})=>{let n=react.useTheme();return jsxRuntime.jsxs(L,{onClick:t,className:r,children:[jsxRuntime.jsx(v,{children:jsxRuntime.jsx(T,{LeftIcon:e,text:o})}),jsxRuntime.jsx(iconsReact.IconChevronRight,{size:n.icon.size.sm})]})};var ne=F__default.default(L)` - ${({theme:e,selected:o,disabled:r,hovered:t})=>{if(o)return react.css` - background: ${e.background.transparent.light}; - &:hover { - background: ${e.background.transparent.medium}; - } - `;if(r)return react.css` - background: inherit; - &:hover { - background: inherit; - } - - color: ${e.font.color.tertiary}; - - cursor: default; - `;if(t)return react.css` - background: ${e.background.transparent.light}; - `}} -`,NI=({LeftIcon:e,text:o,selected:r,className:t,onClick:n,disabled:a,hovered:i})=>{let c=react.useTheme();return jsxRuntime.jsxs(ne,{onClick:n,className:t,selected:r,disabled:a,hovered:i,children:[jsxRuntime.jsx(T,{LeftIcon:e,text:o}),r&&jsxRuntime.jsx(iconsReact.IconCheck,{size:c.icon.size.sm})]})};var GI=({avatar:e,text:o,selected:r,className:t,onClick:n,disabled:a,hovered:i,testId:c})=>{let s=react.useTheme();return jsxRuntime.jsxs(ne,{onClick:n,className:t,selected:r,disabled:a,hovered:i,"data-testid":c,children:[jsxRuntime.jsxs(v,{children:[e,jsxRuntime.jsx(H,{hasLeftIcon:!!e,children:jsxRuntime.jsx(X,{text:o})})]}),r&&jsxRuntime.jsx(iconsReact.IconCheck,{size:s.icon.size.sm})]})};var yn=F__default.default.div` - background-color: ${({theme:e,colorName:o})=>e.tag.background[o]}; - border: 1px solid ${({theme:e,colorName:o})=>e.tag.text[o]}; - border-radius: 60px; - height: ${({theme:e})=>e.spacing(4)}; - width: ${({theme:e})=>e.spacing(3)}; - - ${({colorName:e,theme:o,variant:r})=>{if(r==="pipeline")return react.css` - align-items: center; - border: 0; - display: flex; - justify-content: center; - - &:after { - background-color: ${o.tag.text[e]}; - border-radius: ${o.border.radius.rounded}; - content: ''; - display: block; - height: ${o.spacing(1)}; - width: ${o.spacing(1)}; - } - `}} -`;var Ol={green:"Green",turquoise:"Turquoise",sky:"Sky",blue:"Blue",purple:"Purple",pink:"Pink",red:"Red",orange:"Orange",yellow:"Yellow",gray:"Gray"},ak=({color:e,selected:o,className:r,onClick:t,disabled:n,hovered:a,variant:i="default"})=>{let c=react.useTheme();return jsxRuntime.jsxs(ne,{onClick:t,className:r,selected:o,disabled:n,hovered:a,children:[jsxRuntime.jsxs(v,{children:[jsxRuntime.jsx(yn,{colorName:e,variant:i}),jsxRuntime.jsx(H,{hasLeftIcon:!0,children:Ol[e]})]}),o&&jsxRuntime.jsx(iconsReact.IconCheck,{size:c.icon.size.sm})]})};var mk=({LeftIcon:e,text:o,toggled:r,className:t,onToggleChange:n,toggleSize:a})=>jsxRuntime.jsxs(L,{className:t,onClick:()=>{n?.(!r);},children:[jsxRuntime.jsx(T,{LeftIcon:e,text:o}),jsxRuntime.jsx(Kr,{children:jsxRuntime.jsx(nn,{value:r,onChange:n,toggleSize:a})})]});var Xl=F__default.default.nav` - align-items: center; - color: ${({theme:e})=>e.font.color.extraLight}; - display: flex; - font-size: ${({theme:e})=>e.font.size.lg}; - font-weight: ${({theme:e})=>e.font.weight.semiBold}; - gap: ${({theme:e})=>e.spacing(2)}; - line-height: ${({theme:e})=>e.text.lineHeight.md}; -`,_l=F__default.default(reactRouterDom.Link)` - color: inherit; - text-decoration: none; -`,Gl=F__default.default.span` - color: ${({theme:e})=>e.font.color.tertiary}; -`,hk=({className:e,links:o})=>jsxRuntime.jsx(Xl,{className:e,children:o.map((r,t)=>jsxRuntime.jsxs(ze.Fragment,{children:[r.href?jsxRuntime.jsx(_l,{to:r.href,children:r.children}):jsxRuntime.jsx(Gl,{children:r.children}),te?o.background.transparent.light:"none"}; - border-radius: ${({theme:e})=>e.spacing(1)}; - cursor: pointer; - display: flex; - height: ${({theme:e})=>e.spacing(10)}; - justify-content: center; - transition: background-color ${({theme:e})=>e.animation.duration.fast}s - ease; - width: ${({theme:e})=>e.spacing(10)}; - - &:hover { - background-color: ${({theme:e})=>e.background.transparent.light}; - } -`,xn=({Icon:e,isActive:o,onClick:r})=>{let t=react.useTheme();return jsxRuntime.jsx(Jl,{isActive:o,onClick:r,children:jsxRuntime.jsx(e,{color:t.color.gray50,size:t.icon.size.lg})})};var jl=F__default.default.div` - display: flex; - gap: ${({theme:e})=>e.spacing(4)}; - justify-content: center; - padding: ${({theme:e})=>e.spacing(3)}; -`,Tk=({activeItemName:e,items:o})=>jsxRuntime.jsx(jl,{children:o.map(({Icon:r,name:t,onClick:n})=>jsxRuntime.jsx(xn,{Icon:r,isActive:e===t,onClick:n},t))});var Ae=()=>reactResponsive.useMediaQuery({query:`(max-width: ${Y}px)`});var tp=F__default.default.div` - align-items: center; - display: flex; - flex-grow: ${({isLast:e})=>e?"0":"1"}; - @media (max-width: ${Y}px) { - flex-grow: 0; - } -`,rp=F__default.default(framerMotion.motion.div)` - align-items: center; - border-radius: 50%; - border-style: solid; - border-width: 1px; - display: flex; - flex-basis: auto; - flex-shrink: 0; - height: 20px; - justify-content: center; - overflow: hidden; - position: relative; - width: 20px; -`,np=F__default.default.span` - color: ${({theme:e})=>e.font.color.tertiary}; - font-size: ${({theme:e})=>e.font.size.md}; - font-weight: ${({theme:e})=>e.font.weight.medium}; -`,ap=F__default.default.span` - color: ${({theme:e,isActive:o})=>o?e.font.color.primary:e.font.color.tertiary}; - font-size: ${({theme:e})=>e.font.size.md}; - font-weight: ${({theme:e})=>e.font.weight.medium}; - margin-left: ${({theme:e})=>e.spacing(2)}; - white-space: nowrap; -`,ip=F__default.default(framerMotion.motion.div)` - height: 2px; - margin-left: ${({theme:e})=>e.spacing(2)}; - margin-right: ${({theme:e})=>e.spacing(2)}; - overflow: hidden; - width: 100%; -`,Fe=({isActive:e=!1,isLast:o=!1,index:r=0,label:t,children:n})=>{let a=react.useTheme(),i=Ae(),c={active:{backgroundColor:a.font.color.primary,borderColor:a.font.color.primary,transition:{duration:.5}},inactive:{backgroundColor:a.background.transparent.lighter,borderColor:a.border.color.medium,transition:{duration:.5}}},s={active:{backgroundColor:a.font.color.primary,transition:{duration:.5}},inactive:{backgroundColor:a.border.color.medium,transition:{duration:.5}}};return jsxRuntime.jsxs(tp,{isLast:o,children:[jsxRuntime.jsxs(rp,{variants:c,animate:e?"active":"inactive",children:[e&&jsxRuntime.jsx(ht,{isAnimating:e,color:a.grayScale.gray0}),!e&&jsxRuntime.jsx(np,{children:r+1})]}),jsxRuntime.jsx(ap,{isActive:e,children:t}),!o&&!i&&jsxRuntime.jsx(ip,{variants:s,animate:e?"active":"inactive"}),e&&n]})};Fe.displayName="StepBar";var sp=F__default.default.div` - display: flex; - flex: 1; - justify-content: space-between; - @media (max-width: ${Y}px) { - align-items: center; - justify-content: center; - } -`,lp=({activeStep:e,children:o})=>{let r=Ae();return jsxRuntime.jsx(sp,{children:ze__namespace.default.Children.map(o,(t,n)=>ze__namespace.default.isValidElement(t)?t.type?.displayName!==Fe.displayName?t:r&&(e===-1?n!==0:n!==e)?null:ze__namespace.default.cloneElement(t,{index:n,isActive:n<=e,isLast:n===ze__namespace.default.Children.count(o)-1}):null)})};lp.Step=Fe; - -Object.defineProperty(exports, "ThemeProvider", { - enumerable: true, - get: function () { return react.ThemeProvider; } -}); -exports.AnimatedCheckmark = ht; -exports.AppTooltip = xt; -exports.AutosizeTextInput = Ff; -exports.AutosizeTextInputVariant = Ti; -exports.BlockEditor = LS; -exports.Breadcrumb = hk; -exports.Button = _; -exports.ButtonGroup = fg; -exports.Checkbox = ue; -exports.CheckboxShape = Ni; -exports.CheckboxSize = Ui; -exports.CheckboxVariant = zi; -exports.Checkmark = Oe; -exports.Chip = ie; -exports.ChipAccent = jn; -exports.ChipSize = kt; -exports.ChipVariant = We; -exports.CircularProgressBar = ng; -exports.ColorSchemeCard = le; -exports.ColorSchemePicker = df; -exports.ContactLink = MS; -exports.EntityChip = $u; -exports.EntityChipVariant = da; -exports.EntityTitleDoubleTextInput = Wy; -exports.FloatingButton = Sg; -exports.FloatingButtonGroup = $g; -exports.FloatingIconButton = Ut; -exports.FloatingIconButtonGroup = se; -exports.IconAddressBook = Eu; -exports.IconPicker = Zx; -exports.ImageInput = i0; -exports.LabelPosition = Ss; -exports.LightButton = Ug; -exports.LightIconButton = Wt; -exports.LinkType = yl; -exports.MainButton = Kg; -exports.MenuItem = Qr; -exports.MenuItemCommand = aI; -exports.MenuItemDraggable = dI; -exports.MenuItemMultiSelect = hI; -exports.MenuItemMultiSelectAvatar = vI; -exports.MenuItemNavigate = BI; -exports.MenuItemSelect = NI; -exports.MenuItemSelectAvatar = GI; -exports.MenuItemSelectColor = ak; -exports.MenuItemToggle = mk; -exports.NavigationBar = Tk; -exports.OverflowingTextWithTooltip = X; -exports.ProgressBar = Zu; -exports.Radio = vs; -exports.RadioGroup = Gr; -exports.RadioSize = xs; -exports.RawLink = NS; -exports.RoundedIconButton = Xt; -exports.RoundedLink = cn; -exports.Select = _0; -exports.SocialLink = KS; -exports.SoonPill = Tt; -exports.StepBar = lp; -exports.StyledMenuItemSelect = ne; -exports.Tag = Yu; -exports.TextArea = j0; -exports.TextInput = hS; -exports.Toggle = nn; -exports.TooltipPosition = On; -exports.colorLabels = Ol; -exports.darkTheme = Hn; -exports.lightTheme = En; diff --git a/packages/twenty-docs/src/ui/generated/index.d.cts b/packages/twenty-docs/src/ui/generated/index.d.cts deleted file mode 100644 index 20627aabd..000000000 --- a/packages/twenty-docs/src/ui/generated/index.d.cts +++ /dev/null @@ -1,968 +0,0 @@ -import * as _emotion_react from '@emotion/react'; -export { ThemeProvider } from '@emotion/react'; -import * as react_jsx_runtime from 'react/jsx-runtime'; -import * as react from 'react'; -import react__default, { ReactNode, MouseEvent, FunctionComponent, ComponentProps, InputHTMLAttributes } from 'react'; -import { motion, AnimationControls } from 'framer-motion'; -import { TablerIconsProps } from '@tabler/icons-react'; -import { PlacesType, PositionStrategy } from 'react-tooltip'; -import { BlockNoteEditor } from '@blocknote/core'; -import * as _emotion_styled from '@emotion/styled'; - -declare const lightTheme: { - accent: { - primary: string; - secondary: string; - tertiary: string; - quaternary: string; - accent3570: string; - accent4060: string; - }; - background: { - noisy: string; - primary: string; - secondary: string; - tertiary: string; - quaternary: string; - danger: string; - transparent: { - primary: string; - secondary: string; - strong: string; - medium: string; - light: string; - lighter: string; - danger: string; - }; - overlay: string; - radialGradient: string; - radialGradientHover: string; - primaryInverted: string; - primaryInvertedHover: string; - }; - border: { - radius: { - xs: string; - sm: string; - md: string; - xl: string; - pill: string; - rounded: string; - }; - color: { - strong: string; - medium: string; - light: string; - secondaryInverted: string; - inverted: string; - danger: string; - }; - }; - tag: { - [key: string]: { - [key: string]: string; - }; - }; - boxShadow: { - extraLight: string; - light: string; - strong: string; - underline: string; - }; - font: { - size: { - xxs: string; - xs: string; - sm: string; - md: string; - lg: string; - xl: string; - xxl: string; - }; - weight: { - regular: number; - medium: number; - semiBold: number; - }; - family: string; - color: { - primary: string; - secondary: string; - tertiary: string; - light: string; - extraLight: string; - inverted: string; - danger: string; - }; - }; - name: string; - color: { - yellow80: string; - yellow70: string; - yellow60: string; - yellow50: string; - yellow40: string; - yellow30: string; - yellow20: string; - yellow10: string; - green80: string; - green70: string; - green60: string; - green50: string; - green40: string; - green30: string; - green20: string; - green10: string; - turquoise80: string; - turquoise70: string; - turquoise60: string; - turquoise50: string; - turquoise40: string; - turquoise30: string; - turquoise20: string; - turquoise10: string; - sky80: string; - sky70: string; - sky60: string; - sky50: string; - sky40: string; - sky30: string; - sky20: string; - sky10: string; - blue80: string; - blue70: string; - blue60: string; - blue50: string; - blue40: string; - blue30: string; - blue20: string; - blue10: string; - purple80: string; - purple70: string; - purple60: string; - purple50: string; - purple40: string; - purple30: string; - purple20: string; - purple10: string; - pink80: string; - pink70: string; - pink60: string; - pink50: string; - pink40: string; - pink30: string; - pink20: string; - pink10: string; - red80: string; - red70: string; - red60: string; - red50: string; - red40: string; - red30: string; - red20: string; - red10: string; - orange80: string; - orange70: string; - orange60: string; - orange50: string; - orange40: string; - orange30: string; - orange20: string; - orange10: string; - gray80: string; - gray70: string; - gray60: string; - gray50: string; - gray40: string; - gray30: string; - gray20: string; - gray10: string; - blueAccent90: string; - blueAccent85: string; - blueAccent80: string; - blueAccent75: string; - blueAccent70: string; - blueAccent60: string; - blueAccent40: string; - blueAccent35: string; - blueAccent25: string; - blueAccent20: string; - blueAccent15: string; - blueAccent10: string; - green: string; - turquoise: string; - sky: string; - blue: string; - purple: string; - pink: string; - red: string; - orange: string; - yellow: string; - gray: string; - }; - grayScale: { - gray100: string; - gray90: string; - gray85: string; - gray80: string; - gray75: string; - gray70: string; - gray65: string; - gray60: string; - gray55: string; - gray50: string; - gray45: string; - gray40: string; - gray35: string; - gray30: string; - gray25: string; - gray20: string; - gray15: string; - gray10: string; - gray0: string; - }; - icon: { - size: { - sm: number; - md: number; - lg: number; - xl: number; - }; - stroke: { - sm: number; - md: number; - lg: number; - }; - }; - modal: { - size: { - sm: string; - md: string; - lg: string; - }; - }; - text: { - lineHeight: { - lg: number; - md: number; - }; - iconSizeMedium: number; - iconSizeSmall: number; - iconStrikeLight: number; - iconStrikeMedium: number; - iconStrikeBold: number; - }; - blur: { - light: string; - strong: string; - }; - animation: { - duration: { - instant: number; - fast: number; - normal: number; - }; - }; - snackBar: { - success: { - background: string; - color: string; - }; - error: { - background: string; - color: string; - }; - info: { - background: string; - color: string; - }; - }; - spacingMultiplicator: number; - spacing: (...args: number[]) => string; - betweenSiblingsGap: string; - table: { - horizontalCellMargin: string; - checkboxColumnWidth: string; - }; - rightDrawerWidth: string; - clickableElementBackgroundTransition: string; - lastLayerZIndex: number; -}; -type ThemeType = typeof lightTheme; -declare const darkTheme: ThemeType; - -type CheckmarkProps = react__default.ComponentPropsWithoutRef<'div'> & { - className?: string; -}; -declare const Checkmark: ({ className }: CheckmarkProps) => react_jsx_runtime.JSX.Element; - -type AnimatedCheckmarkProps = React.ComponentProps & { - isAnimating?: boolean; - color?: string; - duration?: number; - size?: number; -}; -declare const AnimatedCheckmark: ({ isAnimating, color, duration, size, }: AnimatedCheckmarkProps) => react_jsx_runtime.JSX.Element; - -declare enum ChipSize { - Large = "large", - Small = "small" -} -declare enum ChipAccent { - TextPrimary = "text-primary", - TextSecondary = "text-secondary" -} -declare enum ChipVariant { - Highlighted = "highlighted", - Regular = "regular", - Transparent = "transparent", - Rounded = "rounded" -} -type ChipProps = { - size?: ChipSize; - disabled?: boolean; - clickable?: boolean; - label: string; - maxWidth?: string; - variant?: ChipVariant; - accent?: ChipAccent; - leftComponent?: ReactNode; - rightComponent?: ReactNode; - className?: string; - onClick?: (event: MouseEvent) => void; -}; -declare const Chip: ({ size, label, disabled, clickable, variant, leftComponent, rightComponent, accent, maxWidth, className, onClick, }: ChipProps) => react_jsx_runtime.JSX.Element; - -type IconComponent = FunctionComponent<{ - className?: string; - color?: string; - size?: number; - stroke?: number; -}>; - -type AvatarType = 'squared' | 'rounded'; - -type EntityChipProps = { - linkToEntity?: string; - entityId: string; - name: string; - avatarUrl?: string; - avatarType?: AvatarType; - variant?: EntityChipVariant; - LeftIcon?: IconComponent; - className?: string; -}; -declare enum EntityChipVariant { - Regular = "regular", - Transparent = "transparent" -} -declare const EntityChip: ({ linkToEntity, entityId, name, avatarUrl, avatarType, variant, LeftIcon, className, }: EntityChipProps) => react_jsx_runtime.JSX.Element; - -type IconAddressBookProps = TablerIconsProps; -declare const IconAddressBook: (props: IconAddressBookProps) => JSX.Element; - -type SoonPillProps = { - className?: string; -}; -declare const SoonPill: ({ className }: SoonPillProps) => react_jsx_runtime.JSX.Element; - -declare const mainColors: { - green: string; - turquoise: string; - sky: string; - blue: string; - purple: string; - pink: string; - red: string; - orange: string; - yellow: string; - gray: string; -}; -type ThemeColor = keyof typeof mainColors; - -type TagProps = { - className?: string; - color: ThemeColor; - text: string; - onClick?: () => void; -}; -declare const Tag: ({ className, color, text, onClick }: TagProps) => react_jsx_runtime.JSX.Element; - -declare enum TooltipPosition { - Top = "top", - Left = "left", - Right = "right", - Bottom = "bottom" -} -type AppTooltipProps = { - className?: string; - anchorSelect?: string; - content?: string; - delayHide?: number; - offset?: number; - noArrow?: boolean; - isOpen?: boolean; - place?: PlacesType; - positionStrategy?: PositionStrategy; -}; -declare const AppTooltip: ({ anchorSelect, className, content, delayHide, isOpen, noArrow, offset, place, positionStrategy, }: AppTooltipProps) => react_jsx_runtime.JSX.Element; - -declare const OverflowingTextWithTooltip: ({ text, className, }: { - text: string | null | undefined; - className?: string | undefined; -}) => react_jsx_runtime.JSX.Element; - -type ProgressBarProps = { - duration?: number; - delay?: number; - easing?: string; - barHeight?: number; - barColor?: string; - autoStart?: boolean; - className?: string; -}; -type StyledBarProps = { - barHeight?: number; - className?: string; -}; -type ProgressBarControls = AnimationControls & { - start: () => Promise; - pause: () => Promise; -}; -declare const ProgressBar: react.ForwardRefExoticComponent>; - -interface CircularProgressBarProps { - size?: number; - barWidth?: number; - barColor?: string; -} -declare const CircularProgressBar: ({ size, barWidth, barColor, }: CircularProgressBarProps) => react_jsx_runtime.JSX.Element; - -type ButtonSize = 'medium' | 'small'; -type ButtonPosition = 'standalone' | 'left' | 'middle' | 'right'; -type ButtonVariant = 'primary' | 'secondary' | 'tertiary'; -type ButtonAccent = 'default' | 'blue' | 'danger'; -type ButtonProps = { - className?: string; - Icon?: IconComponent; - title?: string; - fullWidth?: boolean; - variant?: ButtonVariant; - size?: ButtonSize; - position?: ButtonPosition; - accent?: ButtonAccent; - soon?: boolean; - disabled?: boolean; - focus?: boolean; - onClick?: (event: react__default.MouseEvent) => void; -}; -declare const Button: ({ className, Icon, title, fullWidth, variant, size, accent, position, soon, disabled, focus, onClick, }: ButtonProps) => react_jsx_runtime.JSX.Element; - -type ButtonGroupProps = Pick & { - className?: string; - children: ReactNode[]; -}; -declare const ButtonGroup: ({ className, children, variant, size, accent, }: ButtonGroupProps) => react_jsx_runtime.JSX.Element; - -type FloatingButtonSize = 'small' | 'medium'; -type FloatingButtonPosition = 'standalone' | 'left' | 'middle' | 'right'; -type FloatingButtonProps = { - className?: string; - Icon?: IconComponent; - title?: string; - size?: FloatingButtonSize; - position?: FloatingButtonPosition; - applyShadow?: boolean; - applyBlur?: boolean; - disabled?: boolean; - focus?: boolean; -}; -declare const FloatingButton: ({ className, Icon, title, size, applyBlur, applyShadow, disabled, focus, }: FloatingButtonProps) => react_jsx_runtime.JSX.Element; - -type FloatingButtonGroupProps = Pick & { - children: react__default.ReactElement[]; - className?: string; -}; -declare const FloatingButtonGroup: ({ children, size, className, }: FloatingButtonGroupProps) => react_jsx_runtime.JSX.Element; - -type FloatingIconButtonSize = 'small' | 'medium'; -type FloatingIconButtonPosition = 'standalone' | 'left' | 'middle' | 'right'; -type FloatingIconButtonProps = { - className?: string; - Icon?: IconComponent; - size?: FloatingIconButtonSize; - position?: FloatingIconButtonPosition; - applyShadow?: boolean; - applyBlur?: boolean; - disabled?: boolean; - focus?: boolean; - onClick?: (event: react__default.MouseEvent) => void; - isActive?: boolean; -}; -declare const FloatingIconButton: ({ className, Icon, size, position, applyShadow, applyBlur, disabled, focus, onClick, isActive, }: FloatingIconButtonProps) => react_jsx_runtime.JSX.Element; - -type FloatingIconButtonGroupProps = Pick & { - iconButtons: { - Icon: IconComponent; - onClick?: (event: MouseEvent) => void; - isActive?: boolean; - }[]; -}; -declare const FloatingIconButtonGroup: ({ iconButtons, size, className, }: FloatingIconButtonGroupProps) => react_jsx_runtime.JSX.Element; - -type LightButtonAccent = 'secondary' | 'tertiary'; -type LightButtonProps = { - className?: string; - Icon?: IconComponent; - title?: string; - accent?: LightButtonAccent; - active?: boolean; - disabled?: boolean; - focus?: boolean; - onClick?: (event: MouseEvent) => void; -}; -declare const LightButton: ({ className, Icon, title, active, accent, disabled, focus, onClick, }: LightButtonProps) => react_jsx_runtime.JSX.Element; - -type LightIconButtonAccent = 'secondary' | 'tertiary'; -type LightIconButtonSize = 'small' | 'medium'; -type LightIconButtonProps = { - className?: string; - testId?: string; - Icon?: IconComponent; - title?: string; - size?: LightIconButtonSize; - accent?: LightIconButtonAccent; - active?: boolean; - disabled?: boolean; - focus?: boolean; - onClick?: (event: MouseEvent) => void; -} & Pick, 'aria-label' | 'title'>; -declare const LightIconButton: ({ "aria-label": ariaLabel, className, testId, Icon, active, size, accent, disabled, focus, onClick, title, }: LightIconButtonProps) => react_jsx_runtime.JSX.Element; - -type Variant = 'primary' | 'secondary'; -type Props = { - title: string; - fullWidth?: boolean; - variant?: Variant; - soon?: boolean; -} & react__default.ComponentProps<'button'>; -type MainButtonProps = Props & { - Icon?: IconComponent; -}; -declare const MainButton: ({ Icon, title, fullWidth, variant, type, onClick, disabled, className, }: MainButtonProps) => react_jsx_runtime.JSX.Element; - -type RoundedIconButtonProps = { - Icon: IconComponent; -} & React.ButtonHTMLAttributes; -declare const RoundedIconButton: ({ Icon, onClick, disabled, className, }: RoundedIconButtonProps) => react_jsx_runtime.JSX.Element; - -type ColorScheme = 'Dark' | 'Light' | 'System'; - -type ColorSchemeSegmentProps = { - variant: ColorScheme; - controls: AnimationControls; - className?: string; -} & react__default.ComponentPropsWithoutRef<'div'>; -type ColorSchemeCardProps = { - variant: ColorScheme; - selected?: boolean; -} & react__default.ComponentPropsWithoutRef<'div'>; -declare const ColorSchemeCard: ({ variant, selected, onClick, }: ColorSchemeCardProps) => react_jsx_runtime.JSX.Element; - -type ColorSchemePickerProps = { - value: ColorScheme; - className?: string; - onChange: (value: ColorScheme) => void; -}; -declare const ColorSchemePicker: ({ value, onChange, className, }: ColorSchemePickerProps) => react_jsx_runtime.JSX.Element; - -declare enum AutosizeTextInputVariant { - Default = "default", - Icon = "icon", - Button = "button" -} -type AutosizeTextInputProps = { - onValidate?: (text: string) => void; - minRows?: number; - placeholder?: string; - onFocus?: () => void; - variant?: AutosizeTextInputVariant; - buttonTitle?: string; - value?: string; - className?: string; -}; -declare const AutosizeTextInput: ({ placeholder, onValidate, minRows, onFocus, variant, buttonTitle, value, className, }: AutosizeTextInputProps) => react_jsx_runtime.JSX.Element; - -declare enum CheckboxVariant { - Primary = "primary", - Secondary = "secondary", - Tertiary = "tertiary" -} -declare enum CheckboxShape { - Squared = "squared", - Rounded = "rounded" -} -declare enum CheckboxSize { - Large = "large", - Small = "small" -} -type CheckboxProps = { - checked: boolean; - indeterminate?: boolean; - onChange?: (event: react.ChangeEvent) => void; - onCheckedChange?: (value: boolean) => void; - variant?: CheckboxVariant; - size?: CheckboxSize; - shape?: CheckboxShape; - className?: string; -}; -declare const Checkbox: ({ checked, onChange, onCheckedChange, indeterminate, variant, size, shape, className, }: CheckboxProps) => react_jsx_runtime.JSX.Element; - -type EntityTitleDoubleTextInputProps = { - firstValue: string; - secondValue: string; - firstValuePlaceholder: string; - secondValuePlaceholder: string; - onChange: (firstValue: string, secondValue: string) => void; - className?: string; -}; -declare const EntityTitleDoubleTextInput: ({ firstValue, secondValue, firstValuePlaceholder, secondValuePlaceholder, onChange, className, }: EntityTitleDoubleTextInputProps) => react_jsx_runtime.JSX.Element; - -type IconButtonVariant = 'primary' | 'secondary' | 'tertiary'; - -type IconPickerProps = { - disabled?: boolean; - dropdownScopeId?: string; - onChange: (params: { - iconKey: string; - Icon: IconComponent; - }) => void; - selectedIconKey?: string; - onClickOutside?: () => void; - onClose?: () => void; - onOpen?: () => void; - variant?: IconButtonVariant; - className?: string; -}; -declare const IconPicker: ({ disabled, dropdownScopeId, onChange, selectedIconKey, onClickOutside, onClose, onOpen, variant, className, }: IconPickerProps) => react_jsx_runtime.JSX.Element; - -type ImageInputProps = Omit, 'children'> & { - picture: string | null | undefined; - onUpload?: (file: File) => void; - onRemove?: () => void; - onAbort?: () => void; - isUploading?: boolean; - errorMessage?: string | null; - disabled?: boolean; - className?: string; -}; -declare const ImageInput: ({ picture, onUpload, onRemove, onAbort, isUploading, errorMessage, disabled, className, }: ImageInputProps) => react_jsx_runtime.JSX.Element; - -declare enum RadioSize { - Large = "large", - Small = "small" -} -declare enum LabelPosition { - Left = "left", - Right = "right" -} -type RadioProps = { - style?: react.CSSProperties; - className?: string; - checked?: boolean; - value?: string; - onChange?: (event: react.ChangeEvent) => void; - onCheckedChange?: (checked: boolean) => void; - size?: RadioSize; - disabled?: boolean; - labelPosition?: LabelPosition; -}; -declare const Radio: { - ({ checked, value, onChange, onCheckedChange, size, labelPosition, disabled, className, }: RadioProps): react_jsx_runtime.JSX.Element; - Group: ({ value, onChange, onValueChange, children, }: { - children?: react.ReactNode; - } & { - value?: string | undefined; - onChange?: ((event: react.ChangeEvent) => void) | undefined; - onValueChange?: ((value: string) => void) | undefined; - }) => react_jsx_runtime.JSX.Element; -}; - -type RadioGroupProps = react__default.PropsWithChildren & { - value?: string; - onChange?: (event: react__default.ChangeEvent) => void; - onValueChange?: (value: string) => void; -}; -declare const RadioGroup: ({ value, onChange, onValueChange, children, }: RadioGroupProps) => react_jsx_runtime.JSX.Element; - -type SelectProps = { - className?: string; - disabled?: boolean; - dropdownScopeId: string; - fullWidth?: boolean; - label?: string; - onChange?: (value: Value) => void; - options: { - value: Value; - label: string; - Icon?: IconComponent; - }[]; - value?: Value; -}; -declare const Select: ({ className, disabled, dropdownScopeId, fullWidth, label, onChange, options, value, }: SelectProps) => react_jsx_runtime.JSX.Element; - -type TextAreaProps = { - disabled?: boolean; - minRows?: number; - onChange?: (value: string) => void; - placeholder?: string; - value?: string; - className?: string; -}; -declare const TextArea: ({ disabled, placeholder, minRows, value, className, onChange, }: TextAreaProps) => react_jsx_runtime.JSX.Element; - -type TextInputComponentProps = Omit, 'onChange' | 'onKeyDown'> & { - className?: string; - label?: string; - onChange?: (text: string) => void; - fullWidth?: boolean; - disableHotkeys?: boolean; - error?: string; - RightIcon?: IconComponent; - onKeyDown?: (event: React.KeyboardEvent) => void; -}; -declare const TextInput: react.ForwardRefExoticComponent, "onChange" | "onKeyDown"> & { - className?: string | undefined; - label?: string | undefined; - onChange?: ((text: string) => void) | undefined; - fullWidth?: boolean | undefined; - disableHotkeys?: boolean | undefined; - error?: string | undefined; - RightIcon?: IconComponent | undefined; - onKeyDown?: ((event: React.KeyboardEvent) => void) | undefined; -} & react.RefAttributes>; - -type ToggleSize = 'small' | 'medium'; -type ToggleProps = { - value?: boolean; - onChange?: (value: boolean) => void; - color?: string; - toggleSize?: ToggleSize; - className?: string; -}; -declare const Toggle: ({ value, onChange, color, toggleSize, className, }: ToggleProps) => react_jsx_runtime.JSX.Element; - -interface BlockEditorProps { - editor: BlockNoteEditor; -} -declare const BlockEditor: ({ editor }: BlockEditorProps) => react_jsx_runtime.JSX.Element; - -type ContactLinkProps = { - className?: string; - href: string; - children?: react.ReactNode; - onClick?: (event: react.MouseEvent) => void; -}; -declare const ContactLink: ({ className, href, children, onClick, }: ContactLinkProps) => react_jsx_runtime.JSX.Element; - -type RawLinkProps = { - className?: string; - href: string; - children?: react.ReactNode; - onClick?: (event: react.MouseEvent) => void; -}; -declare const RawLink: ({ className, href, children, onClick, }: RawLinkProps) => react_jsx_runtime.JSX.Element; - -type RoundedLinkProps = { - href: string; - children?: react.ReactNode; - onClick?: (event: react.MouseEvent) => void; -}; -declare const RoundedLink: ({ children, href, onClick }: RoundedLinkProps) => react_jsx_runtime.JSX.Element; - -declare enum LinkType { - Url = "url", - LinkedIn = "linkedin", - Twitter = "twitter" -} -type SocialLinkProps = { - href: string; - children?: react.ReactNode; - type?: LinkType; - onClick?: (event: react.MouseEvent) => void; -}; -declare const SocialLink: ({ children, href, onClick, type, }: SocialLinkProps) => react_jsx_runtime.JSX.Element; - -type MenuItemAccent = 'default' | 'danger' | 'placeholder'; - -type MenuItemIconButton = { - Icon: IconComponent; - onClick?: (event: MouseEvent) => void; -}; -type MenuItemProps = { - LeftIcon?: IconComponent | null; - accent?: MenuItemAccent; - text: string; - iconButtons?: MenuItemIconButton[]; - isTooltipOpen?: boolean; - className?: string; - testId?: string; - onClick?: (event: MouseEvent) => void; -}; -declare const MenuItem: ({ LeftIcon, accent, text, iconButtons, isTooltipOpen, className, testId, onClick, }: MenuItemProps) => react_jsx_runtime.JSX.Element; - -type MenuItemCommandProps = { - LeftIcon?: IconComponent; - text: string; - firstHotKey?: string; - secondHotKey?: string; - className?: string; - isSelected?: boolean; - onClick?: () => void; -}; -declare const MenuItemCommand: ({ LeftIcon, text, firstHotKey, secondHotKey, className, isSelected, onClick, }: MenuItemCommandProps) => react_jsx_runtime.JSX.Element; - -type MenuItemDraggableProps = { - LeftIcon: IconComponent | undefined; - accent?: MenuItemAccent; - iconButtons?: MenuItemIconButton[]; - isTooltipOpen?: boolean; - onClick?: () => void; - text: string; - isDragDisabled?: boolean; - className?: string; -}; -declare const MenuItemDraggable: ({ LeftIcon, accent, iconButtons, isTooltipOpen, onClick, text, isDragDisabled, className, }: MenuItemDraggableProps) => react_jsx_runtime.JSX.Element; - -type MenuItemMultiSelectProps = { - LeftIcon?: IconComponent; - selected: boolean; - text: string; - className: string; - onSelectChange?: (selected: boolean) => void; -}; -declare const MenuItemMultiSelect: ({ LeftIcon, text, selected, className, onSelectChange, }: MenuItemMultiSelectProps) => react_jsx_runtime.JSX.Element; - -type MenuItemMultiSelectAvatarProps = { - avatar?: ReactNode; - selected: boolean; - isKeySelected?: boolean; - text: string; - className?: string; - onSelectChange?: (selected: boolean) => void; -}; -declare const MenuItemMultiSelectAvatar: ({ avatar, text, selected, className, isKeySelected, onSelectChange, }: MenuItemMultiSelectAvatarProps) => react_jsx_runtime.JSX.Element; - -type MenuItemNavigateProps = { - LeftIcon?: IconComponent; - text: string; - onClick?: () => void; - className?: string; -}; -declare const MenuItemNavigate: ({ LeftIcon, text, className, onClick, }: MenuItemNavigateProps) => react_jsx_runtime.JSX.Element; - -type MenuItemBaseProps = { - accent?: MenuItemAccent; - isKeySelected?: boolean; -}; - -declare const StyledMenuItemSelect: _emotion_styled.StyledComponent<{ - theme?: _emotion_react.Theme | undefined; - as?: react.ElementType | undefined; -} & MenuItemBaseProps & react.ClassAttributes & react.LiHTMLAttributes & { - theme?: _emotion_react.Theme | undefined; -} & { - selected: boolean; - disabled?: boolean | undefined; - hovered?: boolean | undefined; -}, {}, {}>; -type MenuItemSelectProps = { - LeftIcon: IconComponent | null | undefined; - selected: boolean; - text: string; - className?: string; - onClick?: () => void; - disabled?: boolean; - hovered?: boolean; -}; -declare const MenuItemSelect: ({ LeftIcon, text, selected, className, onClick, disabled, hovered, }: MenuItemSelectProps) => react_jsx_runtime.JSX.Element; - -type MenuItemSelectAvatarProps = { - avatar: ReactNode; - selected: boolean; - text: string; - className?: string; - onClick?: () => void; - disabled?: boolean; - hovered?: boolean; - testId?: string; -}; -declare const MenuItemSelectAvatar: ({ avatar, text, selected, className, onClick, disabled, hovered, testId, }: MenuItemSelectAvatarProps) => react_jsx_runtime.JSX.Element; - -type ColorSampleVariant = 'default' | 'pipeline'; - -type MenuItemSelectColorProps = { - selected: boolean; - className?: string; - onClick?: () => void; - disabled?: boolean; - hovered?: boolean; - color: ThemeColor; - variant?: ColorSampleVariant; -}; -declare const colorLabels: Record; -declare const MenuItemSelectColor: ({ color, selected, className, onClick, disabled, hovered, variant, }: MenuItemSelectColorProps) => react_jsx_runtime.JSX.Element; - -type MenuItemToggleProps = { - LeftIcon?: IconComponent; - toggled: boolean; - text: string; - className?: string; - onToggleChange?: (toggled: boolean) => void; - toggleSize?: ToggleSize; -}; -declare const MenuItemToggle: ({ LeftIcon, text, toggled, className, onToggleChange, toggleSize, }: MenuItemToggleProps) => react_jsx_runtime.JSX.Element; - -type BreadcrumbProps = { - className?: string; - links: { - children: string; - href?: string; - }[]; -}; -declare const Breadcrumb: ({ className, links }: BreadcrumbProps) => react_jsx_runtime.JSX.Element; - -type NavigationBarProps = { - activeItemName: string; - items: { - name: string; - Icon: IconComponent; - onClick: () => void; - }[]; -}; -declare const NavigationBar: ({ activeItemName, items, }: NavigationBarProps) => react_jsx_runtime.JSX.Element; - -type StepProps = React.PropsWithChildren & React.ComponentProps<'div'> & { - isActive?: boolean; - isLast?: boolean; - index?: number; - label: string; -}; - -type StepBarProps = react__default.PropsWithChildren & react__default.ComponentProps<'div'> & { - activeStep: number; -}; -declare const StepBar: { - ({ activeStep, children }: StepBarProps): react_jsx_runtime.JSX.Element; - Step: { - ({ isActive, isLast, index, label, children, }: StepProps): react_jsx_runtime.JSX.Element; - displayName: string; - }; -}; - -declare module '@emotion/react' { - interface Theme extends ThemeType { - } -} - -export { AnimatedCheckmark, type AnimatedCheckmarkProps, AppTooltip, type AppTooltipProps, AutosizeTextInput, AutosizeTextInputVariant, BlockEditor, Breadcrumb, Button, type ButtonAccent, ButtonGroup, type ButtonGroupProps, type ButtonPosition, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, CheckboxShape, CheckboxSize, CheckboxVariant, Checkmark, type CheckmarkProps, Chip, ChipAccent, ChipSize, ChipVariant, CircularProgressBar, ColorSchemeCard, type ColorSchemeCardProps, ColorSchemePicker, type ColorSchemePickerProps, type ColorSchemeSegmentProps, ContactLink, EntityChip, type EntityChipProps, EntityChipVariant, EntityTitleDoubleTextInput, type EntityTitleDoubleTextInputProps, FloatingButton, FloatingButtonGroup, type FloatingButtonGroupProps, type FloatingButtonPosition, type FloatingButtonProps, type FloatingButtonSize, FloatingIconButton, FloatingIconButtonGroup, type FloatingIconButtonGroupProps, type FloatingIconButtonPosition, type FloatingIconButtonProps, type FloatingIconButtonSize, IconAddressBook, IconPicker, ImageInput, LabelPosition, LightButton, type LightButtonAccent, type LightButtonProps, LightIconButton, type LightIconButtonAccent, type LightIconButtonProps, type LightIconButtonSize, LinkType, MainButton, MenuItem, MenuItemCommand, type MenuItemCommandProps, MenuItemDraggable, type MenuItemDraggableProps, type MenuItemIconButton, MenuItemMultiSelect, MenuItemMultiSelectAvatar, MenuItemNavigate, type MenuItemNavigateProps, type MenuItemProps, MenuItemSelect, MenuItemSelectAvatar, MenuItemSelectColor, MenuItemToggle, NavigationBar, OverflowingTextWithTooltip, ProgressBar, type ProgressBarControls, type ProgressBarProps, Radio, RadioGroup, type RadioProps, RadioSize, RawLink, RoundedIconButton, RoundedLink, Select, type SelectProps, SocialLink, SoonPill, StepBar, type StepBarProps, type StyledBarProps, StyledMenuItemSelect, Tag, TextArea, type TextAreaProps, TextInput, type TextInputComponentProps, Toggle, type ToggleProps, type ToggleSize, TooltipPosition, colorLabels, darkTheme, lightTheme }; diff --git a/packages/twenty-docs/src/ui/generated/light-noise-JRI6I6YG.png b/packages/twenty-docs/src/ui/generated/light-noise-JRI6I6YG.png deleted file mode 100644 index d7b3bc2c064a31ef0097871db02268610b349eb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9657 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 { - const BlockNoteEditor = useBlockNote(); - - return ; -}; diff --git a/packages/twenty-docs/src/ui/input/button/buttonCode.js b/packages/twenty-docs/src/ui/input/button/buttonCode.js deleted file mode 100644 index 9a3e4a6f4..000000000 --- a/packages/twenty-docs/src/ui/input/button/buttonCode.js +++ /dev/null @@ -1,20 +0,0 @@ -import { Button } from "@/ui/input/button/components/Button"; - -export const MyComponent = () => { - return ( -