From f9aa5969943083aef00aef53008d80b77b70df00 Mon Sep 17 00:00:00 2001 From: Gandharv Date: Thu, 29 Dec 2022 17:18:24 +0530 Subject: [PATCH] feat: app builder design changes (#5041) * feat: version manager, realtime avatars + popover addition --- frontend/assets/images/icons/clear.svg | 3 + .../editor/left-sidebar/comments-selected.svg | 5 + .../icons/editor/left-sidebar/comments.svg | 4 +- .../editor/left-sidebar/database-selected.svg | 4 + .../icons/editor/left-sidebar/database.svg | 93 +- .../editor/left-sidebar/debugger-selected.svg | 4 + .../icons/editor/left-sidebar/debugger.svg | 70 +- .../editor/left-sidebar/inspect-selected.svg | 5 + .../icons/editor/left-sidebar/inspect.svg | 15 +- .../editor/left-sidebar/page-selected.svg | 4 + .../images/icons/editor/left-sidebar/page.svg | 4 +- .../editor/left-sidebar/settings-selected.svg | 5 + .../icons/editor/left-sidebar/settings.svg | 49 +- .../editor/left-sidebar/sidebar-selected.svg | 5 + frontend/assets/translations/en.json | 16 +- frontend/package-lock.json | 815 ++++++++++++++++++ frontend/package.json | 1 + frontend/src/Editor/AppVersionsManager.jsx | 505 ----------- .../AppVersionsManager/CreateVersionModal.jsx | 161 ++++ .../AppVersionsManager/CustomSelect.jsx | 111 +++ .../AppVersionsManager/EditVersionModal.jsx | 75 ++ .../src/Editor/AppVersionsManager/List.jsx | 112 +++ frontend/src/Editor/Comment/CommentFooter.jsx | 13 +- .../Editor/CommentNotifications/Content.jsx | 52 -- .../src/Editor/CommentNotifications/index.jsx | 73 +- frontend/src/Editor/Editor.jsx | 228 ++--- frontend/src/Editor/Header/EditAppName.jsx | 50 ++ .../GlobalSettings.jsx} | 78 +- frontend/src/Editor/Header/HeaderActions.jsx | 111 +++ frontend/src/Editor/Icons/logo.svg | 31 +- frontend/src/Editor/Icons/tooljetdb.svg | 11 +- frontend/src/Editor/Inspector/Inspector.jsx | 218 ++--- .../src/Editor/LeftSidebar/SidebarComment.jsx | 8 +- .../Editor/LeftSidebar/SidebarDatasources.jsx | 100 ++- .../Editor/LeftSidebar/SidebarDebugger.jsx | 117 ++- .../Editor/LeftSidebar/SidebarInspector.jsx | 90 +- .../src/Editor/LeftSidebar/SidebarItem.jsx | 47 +- .../SidebarPageSelector/EditModal.jsx | 1 + .../SidebarPageSelector/GlobalSettings.jsx | 8 +- .../SidebarPageSelector/PageHandler.jsx | 12 +- .../LeftSidebar/SidebarPageSelector/index.js | 174 ---- .../LeftSidebar/SidebarPageSelector/index.jsx | 164 ++++ .../LeftSidebar/SidebarPinnedButton.jsx | 53 -- .../src/Editor/LeftSidebar/SidebarZoom.jsx | 78 -- .../LeftSidebar/{index.js => index.jsx} | 83 +- frontend/src/Editor/ManageAppUsers.jsx | 101 ++- frontend/src/Editor/RealtimeAvatars.jsx | 41 +- frontend/src/Editor/RealtimeEditor.jsx | 9 +- frontend/src/Editor/ReleaseVersionButton.jsx | 15 +- frontend/src/Editor/Viewer/Confirm.jsx | 61 +- .../src/Editor/Viewer/ViewerNavigation.jsx | 2 +- frontend/src/HomePage/Modal.jsx | 5 +- frontend/src/ManageSSO/ManageSSO.jsx | 2 +- .../src/OrganizationSettingsPage/index.jsx | 4 +- frontend/src/_components/ConfirmDialog.jsx | 73 +- frontend/src/_components/DarkModeToggle.jsx | 1 + .../CreateOrganization.jsx | 12 +- .../OrganizationManager/EditOrganization.jsx | 58 +- frontend/src/_hooks/usePinnedPopover.jsx | 22 - frontend/src/_styles/colors.scss | 12 +- .../_styles/editor/comment-notifications.scss | 2 +- frontend/src/_styles/editor/comments.scss | 4 - frontend/src/_styles/left-sidebar.scss | 45 +- frontend/src/_styles/popover.scss | 88 ++ frontend/src/_styles/queryManager.scss | 2 +- frontend/src/_styles/theme.scss | 150 +++- frontend/src/_ui/AlertDialog/index.jsx | 35 + frontend/src/_ui/Avatar/index.jsx | 2 +- frontend/src/_ui/JSONTreeViewer/JSONNode.jsx | 2 - .../src/_ui/JSONTreeViewer/JSONTreeViewer.jsx | 1 - frontend/src/_ui/LeftSidebar/Header.jsx | 6 +- frontend/src/_ui/Popover/index.jsx | 41 + frontend/src/_ui/Select/SelectComponent.jsx | 2 +- 73 files changed, 2734 insertions(+), 1930 deletions(-) create mode 100644 frontend/assets/images/icons/clear.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/comments-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/database-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/debugger-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/inspect-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/page-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/settings-selected.svg create mode 100644 frontend/assets/images/icons/editor/left-sidebar/sidebar-selected.svg delete mode 100644 frontend/src/Editor/AppVersionsManager.jsx create mode 100644 frontend/src/Editor/AppVersionsManager/CreateVersionModal.jsx create mode 100644 frontend/src/Editor/AppVersionsManager/CustomSelect.jsx create mode 100644 frontend/src/Editor/AppVersionsManager/EditVersionModal.jsx create mode 100644 frontend/src/Editor/AppVersionsManager/List.jsx create mode 100644 frontend/src/Editor/Header/EditAppName.jsx rename frontend/src/Editor/{LeftSidebar/SidebarGlobalSettings.jsx => Header/GlobalSettings.jsx} (88%) create mode 100644 frontend/src/Editor/Header/HeaderActions.jsx delete mode 100644 frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.js create mode 100644 frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.jsx delete mode 100644 frontend/src/Editor/LeftSidebar/SidebarPinnedButton.jsx delete mode 100644 frontend/src/Editor/LeftSidebar/SidebarZoom.jsx rename frontend/src/Editor/LeftSidebar/{index.js => index.jsx} (76%) delete mode 100644 frontend/src/_hooks/usePinnedPopover.jsx create mode 100644 frontend/src/_styles/popover.scss create mode 100644 frontend/src/_ui/AlertDialog/index.jsx create mode 100644 frontend/src/_ui/Popover/index.jsx diff --git a/frontend/assets/images/icons/clear.svg b/frontend/assets/images/icons/clear.svg new file mode 100644 index 0000000000..a2cae4757a --- /dev/null +++ b/frontend/assets/images/icons/clear.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/comments-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/comments-selected.svg new file mode 100644 index 0000000000..8374dae372 --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/comments-selected.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/comments.svg b/frontend/assets/images/icons/editor/left-sidebar/comments.svg index eadef129fc..252b2e42e0 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/comments.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/comments.svg @@ -1,3 +1,3 @@ - - + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/database-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/database-selected.svg new file mode 100644 index 0000000000..7ab55b5af0 --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/database-selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/database.svg b/frontend/assets/images/icons/editor/left-sidebar/database.svg index e08aede99c..d2a1a82239 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/database.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/database.svg @@ -1,92 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/debugger-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/debugger-selected.svg new file mode 100644 index 0000000000..438f98d3cb --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/debugger-selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/debugger.svg b/frontend/assets/images/icons/editor/left-sidebar/debugger.svg index 10c0a14e49..29017d7e5e 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/debugger.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/debugger.svg @@ -1,69 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/inspect-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/inspect-selected.svg new file mode 100644 index 0000000000..746ab06c98 --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/inspect-selected.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/inspect.svg b/frontend/assets/images/icons/editor/left-sidebar/inspect.svg index 1f17f65825..dbd16cbc36 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/inspect.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/inspect.svg @@ -1,11 +1,4 @@ - - - - ic_fluent_inspect_24_regular - Created with Sketch. - - - - - - \ No newline at end of file + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/page-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/page-selected.svg new file mode 100644 index 0000000000..b68ff49586 --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/page-selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/page.svg b/frontend/assets/images/icons/editor/left-sidebar/page.svg index 5a8f30b9af..651c4fa552 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/page.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/page.svg @@ -1,3 +1,3 @@ - - + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/settings-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/settings-selected.svg new file mode 100644 index 0000000000..918b890d6d --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/settings-selected.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/settings.svg b/frontend/assets/images/icons/editor/left-sidebar/settings.svg index e0c2acb711..a04859b7eb 100644 --- a/frontend/assets/images/icons/editor/left-sidebar/settings.svg +++ b/frontend/assets/images/icons/editor/left-sidebar/settings.svg @@ -1,46 +1,3 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + diff --git a/frontend/assets/images/icons/editor/left-sidebar/sidebar-selected.svg b/frontend/assets/images/icons/editor/left-sidebar/sidebar-selected.svg new file mode 100644 index 0000000000..746ab06c98 --- /dev/null +++ b/frontend/assets/images/icons/editor/left-sidebar/sidebar-selected.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/assets/translations/en.json b/frontend/assets/translations/en.json index e02e5362ae..6f7fa0c786 100644 --- a/frontend/assets/translations/en.json +++ b/frontend/assets/translations/en.json @@ -114,16 +114,16 @@ "preview": "Preview", "share": "Share", "shareModal": { - "makeApplicationPublic": "Make application public ?", + "makeApplicationPublic": "Make application public?", "shareableLink": "Get shareable link for this application", "copy": "copy", "embeddableLink": "Get embeddable link for this application", - "manageUsers": "Manage Users" + "manageUsers": "Users" }, "appVersionManager": { "version": "Version", "currentlyReleased": "Currently Released", - "createVersion": "Create Version", + "createVersion": "Create new version", "versionName": "Version Name", "createVersionFrom": "Create version from", "save": "Save", @@ -234,10 +234,10 @@ "menus": { "addWorkspace": "Add workspace", "menusList": { - "manageUsers": "Manage Users", - "manageGroups": "Manage Groups", - "manageSso": "Manage SSO", - "manageEnv": "Manage Workspace Variables" + "manageUsers": "Users", + "manageGroups": "Groups", + "manageSso": "SSO", + "manageEnv": "Workspace Variables" }, "manageUsers": { "usersAndPermission": "Users & Permissions", @@ -279,7 +279,7 @@ } }, "manageSSO": { - "manageSso": "Manage SSO", + "manageSso": "SSO", "generalSettings": { "title": "General Settings", "enableSignup": "Enable Signup", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3770aba394..901f026bd4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,6 +10,7 @@ "@dnd-kit/core": "^6.0.5", "@dnd-kit/sortable": "^7.0.1", "@dnd-kit/utilities": "^3.2.0", + "@radix-ui/react-popover": "^1.0.2", "@react-google-maps/api": "^2.1.1", "@sentry/react": "^7.12.0", "@sentry/tracing": "^7.12.0", @@ -17943,6 +17944,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", + "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" + }, + "node_modules/@floating-ui/dom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", + "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", + "dependencies": { + "@floating-ui/core": "^0.7.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz", + "integrity": "sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==", + "dependencies": { + "@floating-ui/dom": "^0.5.3", + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@googlemaps/js-api-loader": { "version": "1.11.1", "integrity": "sha512-2ug4uBu0onRXTAo7Yxkay5N7pdNIz3XpTElMTLdCtEfQDxikbjeR6GS8atVhblX+ubFBNlXvDzz7VtuXv0vMRQ==", @@ -19162,6 +19189,282 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.1.tgz", + "integrity": "sha512-1yientwXqXcErDHEv8av9ZVNEBldH8L9scVR3is20lL+jOCfcJyMFZFEY5cgIrgexsq1qggSXqiEL/d/4f+QXA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.2.tgz", + "integrity": "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.2" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.1.tgz", + "integrity": "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.2.tgz", + "integrity": "sha512-4tqZEl9w95R5mlZ/sFdgBnfhCBOEPepLIurBA5kt/qaAhldJ1tNQd0ngr0ET0AHbPotT4mwxMPr7a+MA/wbK0g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", + "integrity": "sha512-J4Vj7k3k+EHNWgcKrE+BLlQfpewxA7Zd76h5I0bIa+/EqaIZ3DuwrbPj49O3wqN+STnXsBuxiHLiF0iU3yfovw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.1.tgz", + "integrity": "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz", + "integrity": "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz", + "integrity": "sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz", + "integrity": "sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz", + "integrity": "sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, "node_modules/@react-dnd/asap": { "version": "4.0.0", "integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==" @@ -21137,6 +21440,31 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.9.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/aria-hidden/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/aria-query": { "version": "4.2.2", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", @@ -23112,6 +23440,11 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "node_modules/diff-sequences": { "version": "24.9.0", "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", @@ -25452,6 +25785,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", @@ -32949,6 +33290,61 @@ "version": "17.0.2", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/react-remove-scroll/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/react-rnd": { "version": "10.3.0", "integrity": "sha512-v+0TRPIaRWY25TYv02vLQHYpACbkX+4xKvsyIrUEy4bMpq0bP1oEiaxTorp0Xn72IVv0QZV1vOnZimgTEB/skw==", @@ -33080,6 +33476,33 @@ "@react-spring/zdog": "~9.2.0" } }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/react-table": { "version": "7.6.3", "integrity": "sha512-hfPF13zDLxPMpLKzIKCE8RZud9T/XrRTsaCIf8zXpWZIZ2juCl7qrGpo3AQw9eAetXV5DP7s2GDm+hht7qq5Dw==", @@ -35184,6 +35607,31 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-callback-ref/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/use-composed-ref": { "version": "1.1.0", "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", @@ -35228,6 +35676,32 @@ "react": "^16.8.0 || ^17.0.0" } }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar/node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, "node_modules/util": { "version": "0.10.3", "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", @@ -37794,6 +38268,28 @@ } } }, + "@floating-ui/core": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.7.3.tgz", + "integrity": "sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==" + }, + "@floating-ui/dom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz", + "integrity": "sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==", + "requires": { + "@floating-ui/core": "^0.7.3" + } + }, + "@floating-ui/react-dom": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-0.7.2.tgz", + "integrity": "sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==", + "requires": { + "@floating-ui/dom": "^0.5.3", + "use-isomorphic-layout-effect": "^1.1.1" + } + }, "@googlemaps/js-api-loader": { "version": "1.11.1", "integrity": "sha512-2ug4uBu0onRXTAo7Yxkay5N7pdNIz3XpTElMTLdCtEfQDxikbjeR6GS8atVhblX+ubFBNlXvDzz7VtuXv0vMRQ==", @@ -38727,6 +39223,217 @@ "version": "2.9.2", "integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==" }, + "@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-arrow": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.1.tgz", + "integrity": "sha512-1yientwXqXcErDHEv8av9ZVNEBldH8L9scVR3is20lL+jOCfcJyMFZFEY5cgIrgexsq1qggSXqiEL/d/4f+QXA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + } + }, + "@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-dismissable-layer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.2.tgz", + "integrity": "sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.2" + } + }, + "@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-focus-scope": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.1.tgz", + "integrity": "sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-popover": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.2.tgz", + "integrity": "sha512-4tqZEl9w95R5mlZ/sFdgBnfhCBOEPepLIurBA5kt/qaAhldJ1tNQd0ngr0ET0AHbPotT4mwxMPr7a+MA/wbK0g==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.2", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.1", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-popper": "1.0.1", + "@radix-ui/react-portal": "1.0.1", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-slot": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + } + }, + "@radix-ui/react-popper": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1.tgz", + "integrity": "sha512-J4Vj7k3k+EHNWgcKrE+BLlQfpewxA7Zd76h5I0bIa+/EqaIZ3DuwrbPj49O3wqN+STnXsBuxiHLiF0iU3yfovw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@floating-ui/react-dom": "0.7.2", + "@radix-ui/react-arrow": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.0", + "@radix-ui/react-use-rect": "1.0.0", + "@radix-ui/react-use-size": "1.0.0", + "@radix-ui/rect": "1.0.0" + } + }, + "@radix-ui/react-portal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.1.tgz", + "integrity": "sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.1" + } + }, + "@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz", + "integrity": "sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz", + "integrity": "sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.0" + } + }, + "@radix-ui/react-use-size": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz", + "integrity": "sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/rect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.0.tgz", + "integrity": "sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, "@react-dnd/asap": { "version": "4.0.0", "integrity": "sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==" @@ -52279,6 +52986,21 @@ "sprintf-js": "~1.0.2" } }, + "aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "aria-query": { "version": "4.2.2", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", @@ -53764,6 +54486,11 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "dev": true }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "diff-sequences": { "version": "24.9.0", "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", @@ -55532,6 +56259,11 @@ "has-symbols": "^1.0.1" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-package-type": { "version": "0.1.0", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", @@ -61065,6 +61797,41 @@ } } }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, + "react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "react-rnd": { "version": "10.3.0", "integrity": "sha512-v+0TRPIaRWY25TYv02vLQHYpACbkX+4xKvsyIrUEy4bMpq0bP1oEiaxTorp0Xn72IVv0QZV1vOnZimgTEB/skw==", @@ -61181,6 +61948,23 @@ "@react-spring/zdog": "~9.2.0" } }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "react-table": { "version": "7.6.3", "integrity": "sha512-hfPF13zDLxPMpLKzIKCE8RZud9T/XrRTsaCIf8zXpWZIZ2juCl7qrGpo3AQw9eAetXV5DP7s2GDm+hht7qq5Dw==", @@ -62747,6 +63531,21 @@ "version": "5.0.0", "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==" }, + "use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "use-composed-ref": { "version": "1.1.0", "integrity": "sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg==", @@ -62771,6 +63570,22 @@ "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", "requires": {} }, + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "dependencies": { + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + } + } + }, "util": { "version": "0.10.3", "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", diff --git a/frontend/package.json b/frontend/package.json index 7aeeb85550..4e5d41368e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,6 +6,7 @@ "@dnd-kit/core": "^6.0.5", "@dnd-kit/sortable": "^7.0.1", "@dnd-kit/utilities": "^3.2.0", + "@radix-ui/react-popover": "^1.0.2", "@react-google-maps/api": "^2.1.1", "@sentry/react": "^7.12.0", "@sentry/tracing": "^7.12.0", diff --git a/frontend/src/Editor/AppVersionsManager.jsx b/frontend/src/Editor/AppVersionsManager.jsx deleted file mode 100644 index 3da14ab3f0..0000000000 --- a/frontend/src/Editor/AppVersionsManager.jsx +++ /dev/null @@ -1,505 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; -import Modal from '../HomePage/Modal'; -import { toast } from 'react-hot-toast'; -import { appVersionService } from '@/_services'; -import { Confirm } from './Viewer/Confirm'; -import Select from '../_ui/Select'; -import defaultStyle from '../_ui/Select/styles'; -import { useTranslation } from 'react-i18next'; - -export const AppVersionsManager = function AppVersionsManager({ - appId, - editingVersion, - releasedVersionId, - setAppDefinitionFromVersion, - showCreateVersionModalPrompt, - closeCreateVersionModalPrompt, -}) { - const { t } = useTranslation(); - const [showDropDown, setShowDropDown] = useState(false); - const [showModal, setShowModal] = useState(false); - const [isCreatingVersion, setIsCreatingVersion] = useState(false); - const [isEditingVersion, setIsEditingVersion] = useState(false); - const [deletingVersion, setDeletingVersion] = useState({ name: null, id: null }); - const [updatingVersionId, setUpdatingVersionId] = useState(null); - const [isDeletingVersion, setIsDeletingVersion] = useState(false); - const [editingAppVersion, setEditingAppVersion] = useState(editingVersion); - const [versionName, setVersionName] = useState(''); - const [appVersions, setAppVersions] = useState([]); - const [showVersionDeletionConfirmation, setShowVersionDeletionConfirmation] = useState(false); - const [showVersionUpdateModal, setShowVersionUpdateModal] = useState(false); - const [mouseHoveredOnVersion, setMouseHoveredOnVersion] = useState(null); - const [createAppVersionFrom, setCreateAppVersionFrom] = useState(editingAppVersion); - - useEffect(() => { - setCreateAppVersionFrom(editingAppVersion); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [appVersions]); - - useEffect(() => { - setVersionName(''); - setShowModal(showCreateVersionModalPrompt); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [showCreateVersionModalPrompt]); - - useEffect(() => { - appVersionService.getAll(appId).then((data) => { - setAppVersions(data.versions); - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - setEditingAppVersion(editingVersion); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [editingVersion]); - - useEffect(() => { - appVersions[appVersions.findIndex((appVersion) => appVersion.id === editingVersion.id)] = editingAppVersion; - setCreateAppVersionFrom(editingAppVersion); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [editingAppVersion]); - - const wrapperRef = useRef(null); - useEffect(() => { - const handleClickOutside = (event) => { - if (!showVersionDeletionConfirmation && wrapperRef.current && !wrapperRef.current.contains(event.target)) { - setShowDropDown(false); - } - }; - document.addEventListener('mousedown', handleClickOutside); - return () => { - // Unbind the event listener on clean up - document.removeEventListener('mousedown', handleClickOutside); - }; - }, [wrapperRef, showVersionDeletionConfirmation]); - - const closeModal = () => { - setShowModal(false); - closeCreateVersionModalPrompt(); - }; - - const createVersion = (versionName, createAppVersionFrom) => { - versionName = versionName.trim(); - if (versionName.length > 25) { - toast.error('The version name should not be longer than 25 characters'); - setIsCreatingVersion(false); - return; - } - if (versionName == '') { - toast.error('The version name should not be empty'); - setIsCreatingVersion(false); - return; - } - setIsCreatingVersion(true); - appVersionService - .create(appId, versionName, createAppVersionFrom.id) - .then(() => { - closeModal(); - toast.success('Version Created'); - - appVersionService.getAll(appId).then((data) => { - setAppVersions(data.versions); - - const latestVersion = data.versions.at(0); - setAppDefinitionFromVersion(latestVersion); - setEditingAppVersion(latestVersion); - setVersionName(''); - }); - - setIsCreatingVersion(false); - }) - .catch((_error) => { - setIsCreatingVersion(false); - toast.error(_error?.error); - }); - }; - - const deleteAppVersion = (versionId) => { - setIsDeletingVersion(true); - appVersionService - .del(appId, versionId) - .then(() => { - toast.success('Version Deleted'); - - appVersionService.getAll(appId).then((data) => { - setAppVersions(data.versions); - - if (editingAppVersion.id === versionId) { - const latestVersion = data.versions.at(0); - setAppDefinitionFromVersion(latestVersion); - setEditingAppVersion(latestVersion); - } - }); - - setIsDeletingVersion(false); - setShowVersionDeletionConfirmation(false); - }) - .catch((_error) => { - setIsDeletingVersion(false); - setShowVersionDeletionConfirmation(false); - toast.error('Oops, something went wrong'); - }); - }; - - const selectVersion = (version) => { - appVersionService.getOne(appId, version.id).then((data) => { - setAppDefinitionFromVersion(data); - }); - }; - - const editVersionName = () => { - if (versionName.trim() !== '') { - setIsEditingVersion(true); - appVersionService - .save(appId, updatingVersionId, { name: versionName }) - .then(() => { - toast.success('Version name updated'); - appVersionService.getAll(appId).then((data) => { - const versions = data.versions; - setAppVersions(versions); - updatingVersionId === editingAppVersion.id && - versions.map((appVersion) => { - if (appVersion.id === updatingVersionId) { - setEditingAppVersion(appVersion); - setUpdatingVersionId(null); - } - }); - }); - setIsEditingVersion(false); - setShowVersionUpdateModal(false); - }) - .catch((_error) => { - setIsEditingVersion(false); - setShowVersionDeletionConfirmation(false); - toast.error(_error?.error); - }); - } else { - toast.error('The name of version should not be empty'); - setIsEditingVersion(false); - } - }; - - return ( -
- - {t('editor.appVersionManager.version', 'Version')} - - { - setShowDropDown(!showDropDown); - }} - > - - {releasedVersionId === editingAppVersion.id && } - - {editingAppVersion.name} - - - {showDropDown && ( - <> -
-
- {appVersions.map((version) => - releasedVersionId == version.id ? ( - <> -
selectVersion(version)} - > -
{version.name}
-
- - - {t('editor.appVersionManager.currentlyReleased', 'Currently Released')} - -
-
-
- - ) : ( - <> -
selectVersion(version)} - onMouseEnter={() => setMouseHoveredOnVersion(version.id)} - onMouseLeave={() => setMouseHoveredOnVersion(null)} - > -
- {version.name} -
- -
- - - -
-
-
- - ) - )} -
-
{ - setVersionName(''); - setShowModal(true); - }} - > - - {t('editor.appVersionManager.createVersion', 'Create Version')} - -
- deleteAppVersion(versionId)} - queryConfirmationData={deletingVersion.id} - onCancel={() => setShowVersionDeletionConfirmation(false)} - /> -
- - )} - -
- setShowVersionUpdateModal(false)} - title={t('editor.appVersionManager.editVersion', 'Edit Version')} - > -
-
- setVersionName(e.target.value)} - className="form-control" - placeholder={t('editor.appVersionManager.versionName', 'Version name')} - disabled={isEditingVersion} - value={versionName} - maxLength={25} - /> -
-
-
-
- - -
-
-
-
- ); -}; - -const CreateVersionModal = function CreateVersionModal({ - showModal, - setShowModal, - versionName, - setVersionName, - createAppVersionFrom, - setCreateAppVersionFrom, - createVersion, - isCreatingVersion, - appVersions, - showCreateVersionModalPrompt, -}) { - const { t } = useTranslation(); - const handleKeyPress = (event) => { - if (event.key === 'Enter') { - // eslint-disable-next-line no-undef - createVersion(versionName, createAppVersionFrom); - } - }; - const options = appVersions.map((version) => { - return { ...version, label: version.name, value: version }; - }); - const width = '100%'; - const height = 32; - const darkMode = localStorage.getItem('darkMode') === 'true'; - const customStyles = { - ...defaultStyle(darkMode, width, height), - option: (provided, state) => { - return { - ...provided, - backgroundColor: darkMode - ? state.isSelected - ? '#3650AF' - : 'rgb(31,40,55)' - : state.isSelected - ? '#7A95FB' - : 'white', - color: darkMode ? '#fff' : '#232e3c', - '&:hover': { - backgroundColor: darkMode - ? state.isSelected - ? '#1F2E64' - : '#323C4B' - : state.isSelected - ? '#3650AF' - : '#d8dce9', - }, - }; - }, - }; - return ( - setShowModal(false)} - > -
-
- - setVersionName(e.target.value)} - className="form-control" - data-cy="version-name-input-field" - placeholder={t('editor.appVersionManager.enterVersionName', 'Enter version name')} - disabled={isCreatingVersion} - value={versionName} - autoFocus={true} - onKeyPress={(e) => handleKeyPress(e)} - minLength="1" - maxLength="25" - /> -
-
- -
- -
- setVersionName(e.target.value)} + className="form-control" + placeholder={t('editor.appVersionManager.enterVersionName', 'Enter version name')} + disabled={isCreatingVersion} + value={versionName} + autoFocus={true} + minLength="1" + maxLength="25" + /> +
+
+ +
+ +
+ + + ); +}; diff --git a/frontend/src/Editor/AppVersionsManager/EditVersionModal.jsx b/frontend/src/Editor/AppVersionsManager/EditVersionModal.jsx new file mode 100644 index 0000000000..b6a09e9c0d --- /dev/null +++ b/frontend/src/Editor/AppVersionsManager/EditVersionModal.jsx @@ -0,0 +1,75 @@ +import React, { useState } from 'react'; +import { appVersionService } from '@/_services'; +import AlertDialog from '@/_ui/AlertDialog'; +import { toast } from 'react-hot-toast'; +import { useTranslation } from 'react-i18next'; +import { useHotkeys } from 'react-hotkeys-hook'; + +export const EditVersion = ({ + appId, + value: editingVersionId, + setAppVersions, + setShowEditAppVersion, + showEditAppVersion, +}) => { + const [isEditingVersion, setIsEditingVersion] = useState(false); + const [versionName, setVersionName] = useState(''); + const { t } = useTranslation(); + useHotkeys('enter', () => editVersion()); + + const editVersion = () => { + if (versionName.trim() === '') { + toast.error('The version name should not be empty'); + return; + } + + setIsEditingVersion(true); + appVersionService + .save(appId, editingVersionId, { name: versionName }) + .then(() => { + toast.success('Version name updated'); + appVersionService.getAll(appId).then((data) => { + const versions = data.versions; + setAppVersions(versions); + }); + setIsEditingVersion(false); + setShowEditAppVersion(false); + }) + .catch((error) => { + setIsEditingVersion(false); + toast.error(error?.error); + }); + }; + + return ( + showEditAppVersion(false)} + title={t('editor.appVersionManager.editVersion', 'Edit Version')} + > +
+
+ setVersionName(e.target.value)} + className="form-control" + placeholder={t('editor.appVersionManager.versionName', 'Version name')} + disabled={isEditingVersion} + value={versionName} + maxLength={25} + /> +
+
+
+
+ + +
+
+
+ ); +}; diff --git a/frontend/src/Editor/AppVersionsManager/List.jsx b/frontend/src/Editor/AppVersionsManager/List.jsx new file mode 100644 index 0000000000..26e9fbf246 --- /dev/null +++ b/frontend/src/Editor/AppVersionsManager/List.jsx @@ -0,0 +1,112 @@ +import React, { useState, useEffect } from 'react'; +import cx from 'classnames'; +import { appVersionService } from '@/_services'; +import { CustomSelect } from './CustomSelect'; +import { toast } from 'react-hot-toast'; + +export const AppVersionsManager = function ({ + appId, + editingVersion, + releasedVersionId, + setAppDefinitionFromVersion, + showCreateVersionModalPrompt, + closeCreateVersionModalPrompt, +}) { + const [appVersions, setAppVersions] = useState([]); + const [appVersionStatus, setGetAppVersionStatus] = useState(''); + + useEffect(() => { + setGetAppVersionStatus('loading'); + appVersionService + .getAll(appId) + .then((data) => { + setAppVersions(data.versions); + setGetAppVersionStatus('success'); + }) + .catch((error) => { + toast.error(error); + setGetAppVersionStatus('failure'); + }); + }, []); + + const selectVersion = (id) => { + appVersionService + .getOne(appId, id) + .then((data) => { + setAppDefinitionFromVersion(data); + }) + .catch((error) => { + toast.error(error); + }); + }; + + const deleteAppVersion = (versionId, versionName) => { + if (window.confirm(`Are you sure you want to delete this version - ${versionName}?`) === false) return; + const deleteingToastId = toast.loading('Deleting version...'); + appVersionService + .del(appId, versionId) + .then(() => { + toast.dismiss(deleteingToastId); + toast.success(`Version - ${versionName} Deleted`); + + appVersionService.getAll(appId).then((data) => { + setAppVersions(data.versions); + }); + }) + .catch((error) => { + toast.dismiss(deleteingToastId); + toast.error(error?.error ?? 'Oops, something went wrong'); + }); + }; + + const options = appVersions.map((appVersion) => ({ + value: appVersion.id, + appVersionName: appVersion.name, + label: ( +
+
+
+ {appVersion.name} + {appVersion.id === releasedVersionId && Currently released} +
+
+
{ + e.stopPropagation(); + deleteAppVersion(appVersion.id, appVersion.name); + }} + > + + + +
+
+ ), + })); + + const customSelectProps = { + appId, + appVersions, + setAppVersions, + setAppDefinitionFromVersion, + editingVersion, + showCreateVersionModalPrompt, + closeCreateVersionModalPrompt, + }; + + return ( +
+ selectVersion(id)} + {...customSelectProps} + /> +
+ ); +}; diff --git a/frontend/src/Editor/Comment/CommentFooter.jsx b/frontend/src/Editor/Comment/CommentFooter.jsx index c06e619215..270d43acbe 100644 --- a/frontend/src/Editor/Comment/CommentFooter.jsx +++ b/frontend/src/Editor/Comment/CommentFooter.jsx @@ -47,7 +47,7 @@ function CommentFooter({
-
+
diff --git a/frontend/src/Editor/CommentNotifications/Content.jsx b/frontend/src/Editor/CommentNotifications/Content.jsx index e029e98380..be048d7a97 100644 --- a/frontend/src/Editor/CommentNotifications/Content.jsx +++ b/frontend/src/Editor/CommentNotifications/Content.jsx @@ -3,8 +3,6 @@ import cx from 'classnames'; import { isEmpty } from 'lodash'; import { pluralize, hightlightMentionedUserInComment } from '@/_helpers/utils'; import moment from 'moment'; -import usePopover from '@/_hooks/use-popover'; -import { useSpring } from 'react-spring'; import useRouter from '@/_hooks/use-router'; import Spinner from '@/_ui/Spinner'; @@ -12,8 +10,6 @@ import Spinner from '@/_ui/Spinner'; const Content = ({ notifications, loading }) => { const router = useRouter(); const [selectedCommentId, setSelectedCommentId] = React.useState(router.query.commentId); - const [open, _trigger, _content] = usePopover(false); - const _popoverFadeStyle = useSpring({ opacity: open ? 1 : 0 }); React.useEffect(() => { if (router.query?.commentId) setSelectedCommentId(router.query?.commentId); @@ -72,54 +68,6 @@ const Content = ({ notifications, loading }) => { Total {pluralize(notifications.length, 'comment')} - {/*
- - - - e.stopPropagation()} - > -
-
- Show all -
- - - -
-
-
- Only mention of you -
- - - -
-
-
-
-
*/}
)}
{getContent()}
diff --git a/frontend/src/Editor/CommentNotifications/index.jsx b/frontend/src/Editor/CommentNotifications/index.jsx index 26cc80b35d..46227604da 100644 --- a/frontend/src/Editor/CommentNotifications/index.jsx +++ b/frontend/src/Editor/CommentNotifications/index.jsx @@ -1,8 +1,6 @@ import '@/_styles/editor/comment-notifications.scss'; - +import cx from 'classnames'; import React from 'react'; -import Tabs from 'react-bootstrap/Tabs'; -import Tab from 'react-bootstrap/Tab'; import { commentsService } from '@/_services'; @@ -11,32 +9,41 @@ import TabContent from './Content'; import useRouter from '@/_hooks/use-router'; const CommentNotifications = ({ socket, toggleComments, appVersionsId }) => { + const darkMode = localStorage.getItem('darkMode') === 'true'; + const [notifications, setNotifications] = React.useState([]); const [loading, setLoading] = React.useState(false); const [key, setKey] = React.useState('active'); const router = useRouter(); - async function fetchData(k) { - const isResolved = k === 'resolved'; + async function fetchData(selectedKey) { + const isResolved = selectedKey === 'resolved'; setLoading(true); const { data } = await commentsService.getNotifications(router.query.id, isResolved, appVersionsId); setLoading(false); setNotifications(data); } + React.useEffect(() => { fetchData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); React.useEffect(() => { - // Listen for messages socket?.addEventListener('message', function (event) { - if (event.data === 'notifications') fetchData(); + if (event.data === 'notifications') fetchData(key); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const handleClick = async (selectedKey) => { + setLoading(true); + await fetchData(selectedKey); + setLoading(false); + setKey(selectedKey); + }; + return (
@@ -61,23 +68,41 @@ const CommentNotifications = ({ socket, toggleComments, appVersionsId }) => {
- { - setKey(k); - setLoading(true); - await fetchData(k); - setLoading(false); - }} - className="dflex justify-content-center" - > - - - - - - - +
+
+ + +
+
+
); }; diff --git a/frontend/src/Editor/Editor.jsx b/frontend/src/Editor/Editor.jsx index c496c2d044..338885e2e5 100644 --- a/frontend/src/Editor/Editor.jsx +++ b/frontend/src/Editor/Editor.jsx @@ -1,6 +1,4 @@ -/* eslint-disable import/no-named-as-default */ import React from 'react'; -import cx from 'classnames'; import { datasourceService, dataqueryService, @@ -43,13 +41,10 @@ import { WidgetManager } from './WidgetManager'; import Fuse from 'fuse.js'; import config from 'config'; import queryString from 'query-string'; -import toast from 'react-hot-toast'; -import produce, { enablePatches, setAutoFreeze, applyPatches } from 'immer'; +import { toast } from 'react-hot-toast'; +import { produce, enablePatches, setAutoFreeze, applyPatches } from 'immer'; import Logo from './Icons/logo.svg'; -import EditIcon from './Icons/edit.svg'; -import MobileSelectedIcon from './Icons/mobile-selected.svg'; -import DesktopSelectedIcon from './Icons/desktop-selected.svg'; -import { AppVersionsManager } from './AppVersionsManager'; +import { AppVersionsManager } from './AppVersionsManager/List'; import { SearchBox } from '@/_components/SearchBox'; import { createWebsocketConnection } from '@/_helpers/websocketConnection'; import Tooltip from 'react-bootstrap/Tooltip'; @@ -58,10 +53,12 @@ import RealtimeAvatars from './RealtimeAvatars'; import RealtimeCursors from '@/Editor/RealtimeCursors'; import { initEditorWalkThrough } from '@/_helpers/createWalkThrough'; import { EditorContextWrapper } from './Context/EditorContextWrapper'; -// eslint-disable-next-line import/no-unresolved import Selecto from 'react-selecto'; import { withTranslation } from 'react-i18next'; import { v4 as uuid } from 'uuid'; +import EditAppName from './Header/EditAppName'; +import HeaderActions from './Header/HeaderActions'; +import { GlobalSettings } from './Header/GlobalSettings'; setAutoFreeze(false); enablePatches(); @@ -824,29 +821,6 @@ class EditorComponent extends React.Component { ); }; - saveApp = (id, attributes, notify = false) => { - appService.saveApp(id, attributes).then(() => { - if (notify) { - toast.success('App saved sucessfully'); - } - }); - }; - - saveAppName = (id, name, notify = false) => { - if (!name.trim()) { - toast("App name can't be empty or whitespace", { - icon: '🚨', - }); - - this.setState({ - app: { ...this.state.app, name: this.state.oldName }, - }); - - return; - } - this.saveApp(id, { name }, notify); - }; - getSourceMetaData = (dataSource) => { if (dataSource.plugin_id) { return dataSource.plugin?.manifest_file?.data.source; @@ -1159,35 +1133,6 @@ class EditorComponent extends React.Component { return canvasBackgroundColor; }; - renderLayoutIcon = (isDesktopSelected) => { - if (isDesktopSelected) - return ( - - this.setState({ - currentLayout: isDesktopSelected ? 'mobile' : 'desktop', - }) - } - data-cy="change-layout-button" - > - - - ); - - return ( - - this.setState({ - currentLayout: isDesktopSelected ? 'mobile' : 'desktop', - }) - } - data-cy="change-layout-button" - > - - - ); - }; - saveEditingVersion = () => { if (this.isVersionReleased()) { this.setState({ isSaving: false, showCreateVersionModalPrompt: true }); @@ -1724,6 +1669,12 @@ class EditorComponent extends React.Component { } else this.setState({ ...stateToBeUpdated }); }; + toggleCurrentLayout = (selectedLayout) => { + this.setState({ + currentLayout: selectedLayout, + }); + }; + render() { const { currentSidebarTab, @@ -1765,7 +1716,6 @@ class EditorComponent extends React.Component { return (
- {/* This is for viewer to show query confirmations */} 0} message={`Do you want to run this query - ${queryConfirmationList[0]?.queryName}?`} @@ -1785,7 +1735,8 @@ class EditorComponent extends React.Component { /> this.executeDeletepageRequest()} onCancel={() => this.cancelDeletePageRequest()} @@ -1797,41 +1748,28 @@ class EditorComponent extends React.Component { -

+

- {this.state.app && ( -
- this.setState({ oldName: e.target.value })} - onChange={(e) => this.onNameChanged(e.target.value)} - onBlur={(e) => this.saveAppName(this.state.app.id, e.target.value)} - className="form-control-plaintext form-control-plaintext-sm" - value={this.state.app.name} - data-cy="app-name-input" - /> - - - -
- )} - - {this.state.isSaving - ? 'Saving...' - : this.state.saveError - ? 'Could not save changes' - : 'All changes are saved'} - + + + {config.ENABLE_MULTIPLAYER_EDITING && } {editingVersion && ( )}
-
- - {this.props.t('editor.preview', 'Preview')} - -
-
+
{app.id && ( )}
-
+
+ + + + + + +
+
{app.id && ( runQuery(this, queryId, queryName)} - toggleAppMaintenance={this.toggleAppMaintenance} - is_maintenance_on={this.state.app.is_maintenance_on} ref={this.dataSourceModalRef} isSaving={this.state.isSaving} isUnsavedQueriesAvailable={this.state.isUnsavedQueriesAvailable} @@ -1951,7 +1901,7 @@ class EditorComponent extends React.Component { onScroll={(e) => { this.canvasContainerRef.current.scrollBy(e.direction[0] * 10, e.direction[1] * 10); }} - > + /> )}
-
-
- - - undo - - - undo - - - - - redo - - - -
-
- {this.renderLayoutIcon(currentLayout === 'desktop')} -
-
- diff --git a/frontend/src/Editor/Header/EditAppName.jsx b/frontend/src/Editor/Header/EditAppName.jsx new file mode 100644 index 0000000000..d4cbfd43c7 --- /dev/null +++ b/frontend/src/Editor/Header/EditAppName.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import EditIcon from '../Icons/edit.svg'; +import { appService } from '@/_services'; +import { toast } from 'react-hot-toast'; + +function EditAppName({ appId, appName, onNameChanged }) { + const darkMode = localStorage.getItem('darkMode') === 'true'; + const [name, setName] = React.useState(appName); + + React.useEffect(() => { + setName(appName); + }, [appName]); + + const saveAppName = async (name) => { + if (!name.trim()) { + toast("App name can't be empty or whitespace", { + icon: '🚨', + }); + return; + } + await appService + .saveApp(appId, { name }) + .then(() => { + onNameChanged(name); + }) + .catch(() => { + toast('Something went wrong while editing app name', { + icon: '🚨', + }); + }); + }; + + return ( +
+ setName(e.target.value)} + onBlur={(e) => saveAppName(e.target.value)} + className="form-control-plaintext form-control-plaintext-sm" + value={name} + data-cy="app-name-input" + /> + + + +
+ ); +} + +export default EditAppName; diff --git a/frontend/src/Editor/LeftSidebar/SidebarGlobalSettings.jsx b/frontend/src/Editor/Header/GlobalSettings.jsx similarity index 88% rename from frontend/src/Editor/LeftSidebar/SidebarGlobalSettings.jsx rename to frontend/src/Editor/Header/GlobalSettings.jsx index f85bb56a37..663adcd295 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarGlobalSettings.jsx +++ b/frontend/src/Editor/Header/GlobalSettings.jsx @@ -1,16 +1,18 @@ import React from 'react'; -import usePopover from '@/_hooks/use-popover'; +import cx from 'classnames'; +import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; +import Popover from 'react-bootstrap/Popover'; import { SketchPicker } from 'react-color'; import { Confirm } from '../Viewer/Confirm'; - -import { LeftSidebarItem } from './SidebarItem'; +import { HeaderSection } from '@/_ui/LeftSidebar'; +import { LeftSidebarItem } from '../LeftSidebar/SidebarItem'; import FxButton from '../CodeBuilder/Elements/FxButton'; import { CodeHinter } from '../CodeBuilder/CodeHinter'; import { resolveReferences } from '@/_helpers/utils'; import { useTranslation } from 'react-i18next'; import _ from 'lodash'; -export const LeftSidebarGlobalSettings = ({ +export const GlobalSettings = ({ globalSettings, globalSettingsChanged, darkMode, @@ -19,13 +21,14 @@ export const LeftSidebarGlobalSettings = ({ currentState, }) => { const { t } = useTranslation(); - const [open, trigger, content] = usePopover(false); const { hideHeader, canvasMaxWidth, canvasMaxWidthType, canvasMaxHeight, canvasBackgroundColor, backgroundFxQuery } = globalSettings; const [showPicker, setShowPicker] = React.useState(false); const [forceCodeBox, setForceCodeBox] = React.useState(true); const [realState, setRealState] = React.useState(currentState); const [showConfirmation, setConfirmationShow] = React.useState(false); + const [show, setShow] = React.useState(''); + const coverStyles = { position: 'fixed', top: '0px', @@ -45,28 +48,13 @@ export const LeftSidebarGlobalSettings = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(resolveReferences(backgroundFxQuery, realState))]); - return ( - <> - toggleAppMaintenance()} - onCancel={() => setConfirmationShow(false)} - darkMode={darkMode} - /> - -
-
+ const popoverContent = ( + + + + + +
{t('leftSidebar.Settings.hideHeader', 'Hide header for launched apps')} @@ -149,7 +137,7 @@ export const LeftSidebarGlobalSettings = ({
-
+
{t('leftSidebar.Settings.backgroundColorOfCanvas', 'Background color of canvas')} @@ -219,7 +207,39 @@ export const LeftSidebarGlobalSettings = ({
-
+ + + ); + + return ( + <> + toggleAppMaintenance()} + onCancel={() => setConfirmationShow(false)} + darkMode={darkMode} + /> + { + if (show) setShow('settings'); + else setShow(''); + }} + rootClose + trigger="click" + placement="bottom" + overlay={popoverContent} + > + + ); }; diff --git a/frontend/src/Editor/Header/HeaderActions.jsx b/frontend/src/Editor/Header/HeaderActions.jsx new file mode 100644 index 0000000000..019c6289ee --- /dev/null +++ b/frontend/src/Editor/Header/HeaderActions.jsx @@ -0,0 +1,111 @@ +import React from 'react'; +import cx from 'classnames'; + +function HeaderActions({ handleUndo, canUndo, handleRedo, canRedo, currentLayout, toggleCurrentLayout }) { + const darkMode = localStorage.getItem('darkMode') === 'true'; + + return ( +
+
+
+ + +
+
+ + + undo + + + undo + + + + + redo + + + +
+ ); +} + +export default HeaderActions; diff --git a/frontend/src/Editor/Icons/logo.svg b/frontend/src/Editor/Icons/logo.svg index 638458ebee..721dcf1e01 100644 --- a/frontend/src/Editor/Icons/logo.svg +++ b/frontend/src/Editor/Icons/logo.svg @@ -1,30 +1 @@ - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/Editor/Icons/tooljetdb.svg b/frontend/src/Editor/Icons/tooljetdb.svg index 967039b32d..0040a05f42 100644 --- a/frontend/src/Editor/Icons/tooljetdb.svg +++ b/frontend/src/Editor/Icons/tooljetdb.svg @@ -1,10 +1,3 @@ - - - - - - - - - + + diff --git a/frontend/src/Editor/Inspector/Inspector.jsx b/frontend/src/Editor/Inspector/Inspector.jsx index 3c5ac1eb9c..ab90811643 100644 --- a/frontend/src/Editor/Inspector/Inspector.jsx +++ b/frontend/src/Editor/Inspector/Inspector.jsx @@ -1,6 +1,5 @@ -import React, { useState, useRef, useLayoutEffect, useEffect } from 'react'; -import Tabs from 'react-bootstrap/Tabs'; -import Tab from 'react-bootstrap/Tab'; +import React, { useState, useRef, useEffect } from 'react'; +import cx from 'classnames'; import { componentTypes } from '../WidgetManager/components'; import { Table } from './Components/Table'; import { Chart } from './Components/Chart'; @@ -31,8 +30,6 @@ export const Inspector = ({ darkMode, switchSidebarTab, removeComponent, - handleEditorEscapeKeyPress, - appDefinitionLocalVersion, pages, }) => { const component = { @@ -42,13 +39,12 @@ export const Inspector = ({ parent: allComponents[selectedComponentId].parent, }; const [showWidgetDeleteConfirmation, setWidgetDeleteConfirmation] = useState(false); - const [key, setKey] = React.useState('properties'); // eslint-disable-next-line no-unused-vars - const [tabHeight, setTabHeight] = React.useState(0); //? - const tabsRef = useRef(null); + const [tabHeight, setTabHeight] = React.useState(0); const componentNameRef = useRef(null); const [newComponentName, setNewComponentName] = useState(component.component.name); const [inputRef, setInputFocus] = useFocus(); + const [selectedTab, setSelectedTab] = useState('properties'); const { t } = useTranslation(); useHotkeys('backspace', () => setWidgetDeleteConfirmation(true)); @@ -56,12 +52,6 @@ export const Inspector = ({ const componentMeta = componentTypes.find((comp) => component.component.component === comp.component); - useLayoutEffect(() => { - if (tabsRef.current) { - setTabHeight(tabsRef.current.querySelector('.nav-tabs').clientHeight); - } - }, []); - const isMounted = useMounted(); useEffect(() => { @@ -268,13 +258,41 @@ export const Inspector = ({ return ; }; - const handleTabSelect = (key) => { - setKey(key); - if (key == 'close-inpector' || key == 'close-inpector-light') { - switchSidebarTab(2); - handleEditorEscapeKeyPress(); - } - }; + const propertiesTab = isMounted && ( + + ); + + const stylesTab = ( +
+
+ +
+ {buildGeneralStyle()} +
+ ); return (
@@ -287,94 +305,86 @@ export const Inspector = ({ }} onCancel={() => setWidgetDeleteConfirmation(false)} /> -
- handleTabSelect(k)} className={`tabs-inspector ${darkMode && 'dark'}`}> - -
-
-
- setNewComponentName(e.target.value)} - type="text" - onKeyUp={(e) => { - if (e.keyCode === 13) handleComponentNameChange(newComponentName); - }} - onBlur={() => handleComponentNameChange(newComponentName)} - className="w-100 form-control-plaintext form-control-plaintext-sm mt-1" - value={newComponentName} - ref={inputRef} - data-cy="edit-widget-name" - /> - - - - - -
-
-
- {isMounted && ( - +
+
+
+ setNewComponentName(e.target.value)} + type="text" + onBlur={() => handleComponentNameChange(newComponentName)} + className="w-100 form-control-plaintext form-control-plaintext-sm mt-1" + value={newComponentName} + ref={inputRef} + data-cy="edit-widget-name" /> - )} - - -
-
- -
- {buildGeneralStyle()} -
-
- - + + -
- } - > - + +
+
+
switchSidebarTab(2)}> +
+ + + +
+
+
+
+
+ + +
+
+
+ {selectedTab === 'properties' && propertiesTab} + {selectedTab === 'styles' && stylesTab}
diff --git a/frontend/src/Editor/LeftSidebar/SidebarComment.jsx b/frontend/src/Editor/LeftSidebar/SidebarComment.jsx index e383a62b6c..48eefcb370 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarComment.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarComment.jsx @@ -4,7 +4,7 @@ import { LeftSidebarItem } from './SidebarItem'; import { commentsService } from '@/_services'; import useRouter from '@/_hooks/use-router'; -export const LeftSidebarComment = ({ toggleComments, appVersionsId, currentPageId }) => { +export const LeftSidebarComment = ({ toggleComments, selectedSidebarItem, appVersionsId, currentPageId }) => { const [isActive, toggleActive] = React.useState(false); const [notifications, setNotifications] = React.useState([]); const router = useRouter(); @@ -21,13 +21,13 @@ export const LeftSidebarComment = ({ toggleComments, appVersionsId, currentPageI return ( 0} - tip={appVersionsId ? 'toggle comments' : 'Comments section will be available once you save this application'} + selectedSidebarItem={selectedSidebarItem} + title={appVersionsId ? 'toggle comments' : 'Comments section will be available once you save this application'} icon={`comments`} - className={cx(`left-sidebar-item sidebar-zoom left-sidebar-layout position-relative sidebar-comments`, { + className={cx(`left-sidebar-item left-sidebar-layout sidebar-comments`, { disabled: !appVersionsId, active: isActive, })} - text={'Comments'} onClick={() => { toggleActive(!isActive); toggleComments(); diff --git a/frontend/src/Editor/LeftSidebar/SidebarDatasources.jsx b/frontend/src/Editor/LeftSidebar/SidebarDatasources.jsx index 692564b3d3..9ca3fba46b 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarDatasources.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarDatasources.jsx @@ -1,19 +1,21 @@ /* eslint-disable import/no-named-as-default */ import React from 'react'; -import usePopover from '../../_hooks/use-popover'; import { LeftSidebarItem } from './SidebarItem'; +import { Button, HeaderSection } from '@/_ui/LeftSidebar'; import { DataSourceManager } from '../DataSourceManager'; import { DataSourceTypes } from '../DataSourceManager/SourceComponents'; -import OverlayTrigger from 'react-bootstrap/esm/OverlayTrigger'; -import Tooltip from 'react-bootstrap/esm/Tooltip'; import { getSvgIcon } from '@/_helpers/appUtils'; import { datasourceService } from '@/_services'; import { ConfirmDialog } from '@/_components'; import toast from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; +import Popover from '@/_ui/Popover'; + export const LeftSidebarDataSources = ({ appId, editingVersionId, + selectedSidebarItem, + setSelectedSidebarItem, darkMode, dataSources = [], dataSourcesChanged, @@ -21,7 +23,6 @@ export const LeftSidebarDataSources = ({ toggleDataSourceManagerModal, showDataSourceManagerModal, }) => { - const [open, trigger, content] = usePopover(false); const [selectedDataSource, setSelectedDataSource] = React.useState(null); const [isDeleteModalVisible, setDeleteModalVisibility] = React.useState(false); const [isDeletingDatasource, setDeletingDatasource] = React.useState(false); @@ -65,10 +66,10 @@ export const LeftSidebarDataSources = ({ const renderDataSource = (dataSource, idx) => { const sourceMeta = getSourceMetaData(dataSource); - const icon = getSvgIcon(sourceMeta.kind.toLowerCase(), 25, 25, dataSource?.plugin?.icon_file?.data); + const icon = getSvgIcon(sourceMeta.kind.toLowerCase(), 16, 16, dataSource?.plugin?.icon_file?.data); return ( -
+
{ @@ -78,12 +79,12 @@ export const LeftSidebarDataSources = ({ className="col" > {icon} - + {dataSource.name}
- - + +
-
+ + +
{dataSources.length === 0 ? (
{ +export const LeftSidebarDebugger = ({ + darkMode, + selectedSidebarItem, + setSelectedSidebarItem, + errors, + debuggerActions, + currentPageId, +}) => { const { t } = useTranslation(); - const [open, trigger, content, popoverPinned, updatePopoverPinnedState] = usePinnedPopover(false); const [errorLogs, setErrorLogs] = React.useState([]); const [errorHistory, setErrorHistory] = React.useState({ appLevel: [], pageLevel: [] }); const [unReadErrorCount, setUnReadErrorCount] = React.useState({ read: 0, unread: 0 }); @@ -75,78 +81,53 @@ export const LeftSidebarDebugger = ({ darkMode, errors, debuggerActions, current return { ...prev, unread: unReadErrors }; }); - if (popoverPinned) { - setTimeout(() => { - setUnReadErrorCount((prev) => { - let copy = JSON.parse(JSON.stringify(prev)); - copy.read = errorLogs.length; - copy.unread = 0; - - return copy; - }); - }, 900); - } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [errorLogs.length, open]); - return ( - <> - -
-
-
- + const popoverContent = ( +
+ + +
+
-
+ + -
- {errorLogs.length === 0 && ( -
{t(`leftSidebar.Debugger.noErrors`, 'No errors found.')}
- )} +
+ {errorLogs.length === 0 && ( +
{t(`leftSidebar.Debugger.noErrors`, 'No errors found.')}
+ )} -
- {errorLogs.map((error, index) => ( - - ))} -
+
+ {errorLogs.map((error, index) => ( + + ))}
- +
+ ); + + return ( + { + if (!open) setSelectedSidebarItem(''); + }} + popoverContentClassName="p-0 sidebar-h-100-popover" + side="right" + popoverContent={popoverContent} + > + setSelectedSidebarItem('debugger')} + className={`left-sidebar-item left-sidebar-layout`} + badge={true} + count={unReadErrorCount.unread} + /> + ); }; diff --git a/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx b/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx index 09e55cd00b..4dc4f68682 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarInspector.jsx @@ -1,7 +1,6 @@ import React, { useMemo } from 'react'; -import usePinnedPopover from '@/_hooks/usePinnedPopover'; import { LeftSidebarItem } from './SidebarItem'; -import { SidebarPinnedButton } from './SidebarPinnedButton'; +import { HeaderSection } from '@/_ui/LeftSidebar'; import JSONTreeViewer from '@/_ui/JSONTreeViewer'; import _ from 'lodash'; import RunjsIcon from '../Icons/runjs.svg'; @@ -9,18 +8,19 @@ import RunTooljetDbIcon from '../Icons/tooljetdb.svg'; import RunpyIcon from '../Icons/runpy.svg'; import { toast } from 'react-hot-toast'; import { getSvgIcon } from '@/_helpers/appUtils'; +import Popover from '@/_ui/Popover'; export const LeftSidebarInspector = ({ darkMode, currentState, + selectedSidebarItem, + setSelectedSidebarItem, appDefinition, setSelectedComponent, removeComponent, runQuery, dataSources, }) => { - const [open, trigger, content, popoverPinned, updatePopoverPinnedState] = usePinnedPopover(false); - const componentDefinitions = JSON.parse(JSON.stringify(appDefinition))['components']; const queryDefinitions = appDefinition['queries']; const selectedComponent = React.useMemo(() => { @@ -125,12 +125,6 @@ export const LeftSidebarInspector = ({ return toast.success('Copied to the clipboard', { position: 'top-center' }); }; - const updatePinnedParentState = () => { - if (!popoverPinned) { - updatePopoverPinnedState(); - } - }; - const callbackActions = [ { for: 'queries', @@ -162,45 +156,45 @@ export const LeftSidebarInspector = ({ }, ]; - return ( - <> - -
- + + + +
+ -
- -
- +
+ ); + + return ( + { + if (!open) setSelectedSidebarItem(''); + }} + side="right" + popoverContentClassName="p-0 sidebar-h-100-popover sidebar-h-100-popover-inspector" + popoverContent={popoverContent} + > + setSelectedSidebarItem('inspect')} + icon="inspect" + className={`left-sidebar-item left-sidebar-layout left-sidebar-inspector`} + /> + ); }; diff --git a/frontend/src/Editor/LeftSidebar/SidebarItem.jsx b/frontend/src/Editor/LeftSidebar/SidebarItem.jsx index 5c9fa005d5..631667c5e9 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarItem.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarItem.jsx @@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next'; export const LeftSidebarItem = ({ tip = '', + selectedSidebarItem, className, icon, commentBadge, @@ -15,35 +16,35 @@ export const LeftSidebarItem = ({ ...rest }) => { const { t } = useTranslation(); + const displayIcon = selectedSidebarItem === icon ? `${icon}-selected` : icon; + + const content = ( +
+ {icon && ( +
+ + {commentBadge && } +
+ )} + {badge && } +

{text && t(`leftSidebar.${text}.text`, text)}

+
+ ); + + if (!tip) return content; return ( {t(`leftSidebar.${text}.tip`, tip)}} > -
-
- {icon && ( -
- - {commentBadge && } -
- )} - {badge && } -

{text && t(`leftSidebar.${text}.text`, text)}

-
-
+ {content}
); }; diff --git a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/EditModal.jsx b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/EditModal.jsx index 92545e4d18..5a1d32061f 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/EditModal.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/EditModal.jsx @@ -44,6 +44,7 @@ export const EditModal = ({ slug, page, show, handleClose, updatePageHandle, dar show={show} onHide={handleClose} size="sm" + animation={false} centered className={`${darkMode && 'theme-dark'} page-handle-edit-modal `} backdrop="static" diff --git a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/GlobalSettings.jsx b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/GlobalSettings.jsx index 091b6abd84..19bec4d3a8 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/GlobalSettings.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/GlobalSettings.jsx @@ -2,12 +2,7 @@ import React from 'react'; import { OverlayTrigger, Popover } from 'react-bootstrap'; import { Button } from '@/_ui/LeftSidebar'; -export const GlobalSettings = ({ - darkMode, - handlePopoverPinnedState, - showHideViewerNavigationControls, - showPageViwerPageNavitation, -}) => { +export const GlobalSettings = ({ darkMode, showHideViewerNavigationControls, showPageViwerPageNavitation }) => { const onChange = () => { showHideViewerNavigationControls(); }; @@ -17,7 +12,6 @@ export const GlobalSettings = ({ trigger={'click'} placement={'bottom-end'} rootClose={true} - onToggle={handlePopoverPinnedState} overlay={ diff --git a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/PageHandler.jsx b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/PageHandler.jsx index adec7e262b..4680c2113b 100644 --- a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/PageHandler.jsx +++ b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/PageHandler.jsx @@ -5,7 +5,7 @@ import { EditModal } from './EditModal'; import { SettingsModal } from './SettingsModal'; import _ from 'lodash'; import SortableList from '@/_components/SortableList'; -import toast from 'react-hot-toast'; +import { toast } from 'react-hot-toast'; export const PageHandler = ({ darkMode, @@ -16,7 +16,6 @@ export const PageHandler = ({ clonePage, hidePage, unHidePage, - updatePopoverPinnedState, homePageId, currentPageId, updateHomePage, @@ -51,13 +50,6 @@ export const PageHandler = ({ setShowSettingsModal(true); }; - React.useEffect(() => { - if (showPagehandlerMenu) { - updatePopoverPinnedState(true); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [showPagehandlerMenu]); - const handleCallback = (id) => { setIsHovered(false); switch (id) { @@ -129,7 +121,7 @@ export const PageHandler = ({
-
+
{page.name}
diff --git a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.js b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.js deleted file mode 100644 index 6f67b7d586..0000000000 --- a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.js +++ /dev/null @@ -1,174 +0,0 @@ -import React, { useState } from 'react'; -import Fuse from 'fuse.js'; -import { LeftSidebarItem } from '../SidebarItem'; -import usePinnedPopover from '@/_hooks/usePinnedPopover'; -import { Button, HeaderSection } from '@/_ui/LeftSidebar'; -import { SidebarPinnedButton } from '../SidebarPinnedButton'; -import { PageHandler, AddingPageHandler } from './PageHandler'; -import { GlobalSettings } from './GlobalSettings'; -import _ from 'lodash'; -import SortableList from '@/_components/SortableList'; - -const LeftSidebarPageSelector = ({ - appDefinition, - darkMode, - currentPageId, - addNewPage, - switchPage, - deletePage, - renamePage, - clonePage, - hidePage, - unHidePage, - updateHomePage, - updatePageHandle, - pages, - homePageId, - showHideViewerNavigationControls, - updateOnSortingPages, - updateOnPageLoadEvents, - currentState, - apps, - dataQueries, -}) => { - const [open, trigger, content, popoverPinned, updatePopoverPinnedState] = usePinnedPopover(false); - - const handlePopoverPinnedState = () => { - if (!popoverPinned) { - updatePopoverPinnedState(true); - } - }; - - const [allpages, setPages] = useState(pages); - - const [newPageBeingCreated, setNewPageBeingCreated] = useState(false); - - const filterPages = (value) => { - if (!value || value.length === 0) return clearSearch(); - - const fuse = new Fuse(pages, { keys: ['name'], threshold: 0.3 }); - const result = fuse.search(value); - setPages(result.map((item) => item.item)); - }; - - const clearSearch = () => { - setPages(pages); - }; - - React.useEffect(() => { - if (!_.isEqual(pages, allpages)) { - setPages(pages); - } - - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify({ pages })]); - - return ( - <> - -
-
event.stopPropagation()}> - - -
- - - - - -
-
- -
- -
-
- {allpages.length > 0 ? ( - - ) : ( -
-
- empty-page -

No pages found

-
-
- )} - - {newPageBeingCreated && ( -
- -
- )} -
-
-
-
- - ); -}; - -export default LeftSidebarPageSelector; diff --git a/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.jsx b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.jsx new file mode 100644 index 0000000000..fdc3290e88 --- /dev/null +++ b/frontend/src/Editor/LeftSidebar/SidebarPageSelector/index.jsx @@ -0,0 +1,164 @@ +import React, { useState } from 'react'; +import Fuse from 'fuse.js'; +import { LeftSidebarItem } from '../SidebarItem'; +import { Button, HeaderSection } from '@/_ui/LeftSidebar'; +import { PageHandler, AddingPageHandler } from './PageHandler'; +import { GlobalSettings } from './GlobalSettings'; +import _ from 'lodash'; +import SortableList from '@/_components/SortableList'; +import Popover from '@/_ui/Popover'; + +const LeftSidebarPageSelector = ({ + appDefinition, + selectedSidebarItem, + setSelectedSidebarItem, + darkMode, + currentPageId, + addNewPage, + switchPage, + deletePage, + renamePage, + clonePage, + hidePage, + unHidePage, + updateHomePage, + updatePageHandle, + pages, + homePageId, + showHideViewerNavigationControls, + updateOnSortingPages, + updateOnPageLoadEvents, + currentState, + apps, + dataQueries, +}) => { + const [allpages, setPages] = useState(pages); + + const [newPageBeingCreated, setNewPageBeingCreated] = useState(false); + const [showSearch, setShowSearch] = useState(false); + + const filterPages = (value) => { + if (!value || value.length === 0) return clearSearch(); + + const fuse = new Fuse(pages, { keys: ['name'], threshold: 0.3 }); + const result = fuse.search(value); + setPages(result.map((item) => item.item)); + }; + + const clearSearch = () => { + setPages(pages); + }; + + React.useEffect(() => { + if (!_.isEqual(pages, allpages)) { + setPages(pages); + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify({ pages })]); + + const popoverContent = ( +
+
event.stopPropagation()}> + + +
+ + + +
+
+ {showSearch && ( + + )} +
+ +
+
+ {allpages.length > 0 ? ( + + ) : ( +
+
+ empty-page +

No pages found

+
+
+ )} + + {newPageBeingCreated && ( +
+ +
+ )} +
+
+
+
+ ); + + return ( + { + if (!open) setSelectedSidebarItem(''); + }} + popoverContentClassName="p-0 sidebar-h-100-popover" + side="right" + popoverContent={popoverContent} + > + setSelectedSidebarItem('page')} + icon="page" + className={`left-sidebar-item left-sidebar-layout left-sidebar-page-selector`} + /> + + ); +}; + +export default LeftSidebarPageSelector; diff --git a/frontend/src/Editor/LeftSidebar/SidebarPinnedButton.jsx b/frontend/src/Editor/LeftSidebar/SidebarPinnedButton.jsx deleted file mode 100644 index aa56581abf..0000000000 --- a/frontend/src/Editor/LeftSidebar/SidebarPinnedButton.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import OverlayTrigger from 'react-bootstrap/OverlayTrigger'; -import Tooltip from 'react-bootstrap/Tooltip'; -import { Button } from '@/_ui/LeftSidebar'; - -export const SidebarPinnedButton = ({ state, component, updateState, darkMode }) => { - const tooltipMsg = state ? `Unpin ${component}` : `Pin ${component}`; - const pinnedIcon = !state ? 'pinned' : 'pinnedoff'; - const iconSrc = `assets/images/icons/editor/left-sidebar/${pinnedIcon}.svg`; - - // Todo: Uniform styles for all pinned buttons - - return ( - - {component === 'PageSelector' ? ( - - ) : ( -
- -
- )} -
- ); -}; - -function OverlayContainer({ children, tip }) { - return ( - <> - {tip}} - > - {children} - - - ); -} - -SidebarPinnedButton.OverlayContainer = OverlayContainer; diff --git a/frontend/src/Editor/LeftSidebar/SidebarZoom.jsx b/frontend/src/Editor/LeftSidebar/SidebarZoom.jsx deleted file mode 100644 index e94c6ce609..0000000000 --- a/frontend/src/Editor/LeftSidebar/SidebarZoom.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react'; -import usePopover from '@/_hooks/use-popover'; -import { LeftSidebarItem } from './SidebarItem'; - -export const LeftSidebarZoom = ({ onZoomChanged }) => { - const [open, trigger, content, setOpen] = usePopover(false); - const [text, setText] = React.useState(100); - return ( - <> - -
-
-
- - - { - setText(100); - onZoomChanged(1); - setOpen(false); - }} - > - - - { - setText(90); - onZoomChanged(0.9); - setOpen(false); - }} - > - - - { - setText(80); - onZoomChanged(0.8); - setOpen(false); - }} - > - - - { - setText(70); - onZoomChanged(0.7); - setOpen(false); - }} - > - - - { - setText(60); - onZoomChanged(0.6); - setOpen(false); - }} - > - - - -
100%
90%
80%
70%
60%
-
-
-
- - ); -}; diff --git a/frontend/src/Editor/LeftSidebar/index.js b/frontend/src/Editor/LeftSidebar/index.jsx similarity index 76% rename from frontend/src/Editor/LeftSidebar/index.js rename to frontend/src/Editor/LeftSidebar/index.jsx index 80d96c113c..66c9c42d9c 100644 --- a/frontend/src/Editor/LeftSidebar/index.js +++ b/frontend/src/Editor/LeftSidebar/index.jsx @@ -1,14 +1,12 @@ import '@/_styles/left-sidebar.scss'; import React, { useState, useImperativeHandle, forwardRef } from 'react'; -import { LeftSidebarItem } from './SidebarItem'; import { LeftSidebarInspector } from './SidebarInspector'; import { LeftSidebarDataSources } from './SidebarDatasources'; import { DarkModeToggle } from '../../_components/DarkModeToggle'; import useRouter from '../../_hooks/use-router'; import { LeftSidebarDebugger } from './SidebarDebugger'; import { LeftSidebarComment } from './SidebarComment'; -import { LeftSidebarGlobalSettings } from './SidebarGlobalSettings'; import LeftSidebarPageSelector from './SidebarPageSelector'; import { ConfirmDialog } from '@/_components'; import config from 'config'; @@ -18,6 +16,7 @@ export const LeftSidebar = forwardRef((props, ref) => { const { appId, switchDarkMode, + showComments, darkMode = false, components, toggleComments, @@ -26,18 +25,12 @@ export const LeftSidebar = forwardRef((props, ref) => { dataQueriesChanged, errorLogs, appVersionsId, - globalSettingsChanged, - globalSettings, debuggerActions, currentState, appDefinition, setSelectedComponent, removeComponent, runQuery, - toggleAppMaintenance, - is_maintenance_on, - isSaving, - isUnsavedQueriesAvailable, currentPageId, addNewPage, switchPage, @@ -54,6 +47,7 @@ export const LeftSidebar = forwardRef((props, ref) => { dataQueries, clonePage, } = props; + const [selectedSidebarItem, setSelectedSidebarItem] = useState(); const [showLeaveDialog, setShowLeaveDialog] = useState(false); const [showDataSourceManagerModal, toggleDataSourceManagerModal] = useState(false); @@ -62,19 +56,21 @@ export const LeftSidebar = forwardRef((props, ref) => { toggleDataSourceManagerModal(true); }, })); + + const handleSelectedSidebarItem = (item) => { + if(item === selectedSidebarItem) { + setSelectedSidebarItem(null); + } else { + setSelectedSidebarItem(item); + } + } + return (
- { apps={apps} dataQueries={dataQueries} /> + { toggleDataSourceManagerModal={toggleDataSourceManagerModal} showDataSourceManagerModal={showDataSourceManagerModal} /> - {config.COMMENT_FEATURE_ENABLE && ( )} - - { - if (isSaving || isUnsavedQueriesAvailable) { - setShowLeaveDialog(true); - } else { - router.push('/'); - } - }} - tip="Back to home" - icon="back" - className="left-sidebar-item no-border left-sidebar-layout" - text={'Back'} - data-cy="back-button" - /> { onCancel={() => setShowLeaveDialog(false)} />
- {/* */} +
diff --git a/frontend/src/Editor/ManageAppUsers.jsx b/frontend/src/Editor/ManageAppUsers.jsx index 20d1bceb6a..7b78ba3b8e 100644 --- a/frontend/src/Editor/ManageAppUsers.jsx +++ b/frontend/src/Editor/ManageAppUsers.jsx @@ -32,12 +32,18 @@ class ManageAppUsersComponent extends React.Component { } fetchAppUsers = () => { - appService.getAppUsers(this.props.app.id).then((data) => - this.setState({ - users: data.users, - isLoading: false, - }) - ); + appService + .getAppUsers(this.props.app.id) + .then((data) => + this.setState({ + users: data.users, + isLoading: false, + }) + ) + .catch((error) => { + this.setState({ isLoading: false }); + toast.error(error); + }); }; hideModal = () => { @@ -73,21 +79,29 @@ class ManageAppUsersComponent extends React.Component { }); // eslint-disable-next-line no-unused-vars - appService.setVisibility(this.state.app.id, newState).then((data) => { - this.setState({ - ischangingVisibility: false, - app: { - ...this.state.app, - is_public: newState, - }, - }); + appService + .setVisibility(this.state.app.id, newState) + .then((data) => { + this.setState({ + ischangingVisibility: false, + app: { + ...this.state.app, + is_public: newState, + }, + }); - if (newState) { - toast.success('Application is now public.'); - } else { - toast.success('Application visibility set to private'); - } - }); + if (newState) { + toast('Application is now public.'); + } else { + toast('Application visibility set to private'); + } + }) + .catch((error) => { + this.setState({ + ischangingVisibility: false, + }); + toast.error(error); + }); }; handleSetSlug = (event) => { @@ -124,11 +138,24 @@ class ManageAppUsersComponent extends React.Component { const embeddableLink = ``; return ( -
- - +
+ this.setState({ showModal: true })} + width="33" + height="33" + viewBox="0 0 33 33" + fill="none" + xmlns="http://www.w3.org/2000/svg" + > + + + {this.props.t('editor.share', 'Share')} -
- -
+
@@ -222,12 +244,7 @@ class ManageAppUsersComponent extends React.Component { - toast.success('Link copied to clipboard', { - hideProgressBar: true, - position: 'bottom-center', - }) - } + onCopy={() => toast.success('Embeddable link copied to clipboard')} >
); diff --git a/frontend/src/Editor/Viewer/Confirm.jsx b/frontend/src/Editor/Viewer/Confirm.jsx index c7fae968b8..e52dfcfaca 100644 --- a/frontend/src/Editor/Viewer/Confirm.jsx +++ b/frontend/src/Editor/Viewer/Confirm.jsx @@ -1,10 +1,10 @@ import React, { useState, useEffect } from 'react'; import Modal from 'react-bootstrap/Modal'; -import Button from 'react-bootstrap/Button'; import { useTranslation } from 'react-i18next'; export function Confirm({ show, + title, message, onConfirm, onCancel, @@ -38,25 +38,44 @@ export function Confirm({ }; return ( - <> - -
- {message} - - - - -
- + + {title && ( + + {title} + + + + + )} + {message} + + + + + ); } diff --git a/frontend/src/Editor/Viewer/ViewerNavigation.jsx b/frontend/src/Editor/Viewer/ViewerNavigation.jsx index 3c0e3fe91b..fa4eacb549 100644 --- a/frontend/src/Editor/Viewer/ViewerNavigation.jsx +++ b/frontend/src/Editor/Viewer/ViewerNavigation.jsx @@ -168,7 +168,7 @@ const ViewerHeader = ({
{showHeader && ( <> -

+

diff --git a/frontend/src/HomePage/Modal.jsx b/frontend/src/HomePage/Modal.jsx index eeee708090..9d9eb3a178 100644 --- a/frontend/src/HomePage/Modal.jsx +++ b/frontend/src/HomePage/Modal.jsx @@ -5,9 +5,10 @@ export default function Modal({ title, show, closeModal, customClassName, childr const darkMode = localStorage.getItem('darkMode') === 'true'; return ( closeModal(false)} - contentClassName={`home-modal-component${customClassName ? ` ${customClassName}` : ''} ${darkMode && 'dark'}`} + contentClassName={`home-modal-component animation-fade${customClassName ? ` ${customClassName}` : ''} ${ + darkMode && 'dark' + }`} show={show} size="md" backdrop={true} diff --git a/frontend/src/ManageSSO/ManageSSO.jsx b/frontend/src/ManageSSO/ManageSSO.jsx index 903bb6c485..761ed0e683 100644 --- a/frontend/src/ManageSSO/ManageSSO.jsx +++ b/frontend/src/ManageSSO/ManageSSO.jsx @@ -107,7 +107,7 @@ export function ManageSSO({ darkMode }) {

- {t('header.organization.menus.manageSSO.manageSso', 'Manage SSO')} + {t('header.organization.menus.manageSSO.manageSso', 'SSO')}

diff --git a/frontend/src/OrganizationSettingsPage/index.jsx b/frontend/src/OrganizationSettingsPage/index.jsx index 97e3a67afe..5b6896f7ea 100644 --- a/frontend/src/OrganizationSettingsPage/index.jsx +++ b/frontend/src/OrganizationSettingsPage/index.jsx @@ -41,7 +41,7 @@ export function OrganizationSettings(props) { fill="#C1C8CD" /> -  {t('header.organization.menus.menusList.manageUsers', 'Manage Users')} +  {t('header.organization.menus.menusList.manageUsers', 'Users')}
-  {t('header.organization.menus.menusList.manageSso', 'Manage SSO')} +  {t('header.organization.menus.menusList.manageSso', 'SSO')}
- -
- {message} - - - - -
- + + + + )} + {message} + + + + + ); } diff --git a/frontend/src/_components/DarkModeToggle.jsx b/frontend/src/_components/DarkModeToggle.jsx index b3959f8233..3849f3b52b 100644 --- a/frontend/src/_components/DarkModeToggle.jsx +++ b/frontend/src/_components/DarkModeToggle.jsx @@ -73,6 +73,7 @@ export const DarkModeToggle = function DarkModeToggle({ stroke="currentColor" style={{ cursor: 'pointer', + opacity: 0.6, ...svgContainerProps, }} > diff --git a/frontend/src/_components/OrganizationManager/CreateOrganization.jsx b/frontend/src/_components/OrganizationManager/CreateOrganization.jsx index c6ac63f5cb..34f17f2f84 100644 --- a/frontend/src/_components/OrganizationManager/CreateOrganization.jsx +++ b/frontend/src/_components/OrganizationManager/CreateOrganization.jsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { authenticationService, organizationService } from '@/_services'; -import Modal from '../../HomePage/Modal'; +import AlertDialog from '@/_ui/AlertDialog'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; @@ -34,12 +34,12 @@ export const CreateOrganization = ({ showCreateOrg, setShowCreateOrg }) => { }; return ( - setShowCreateOrg(false)} title={t('header.organization.createWorkspace', 'Create workspace')} > -
+
{
-
-
- + ); }; diff --git a/frontend/src/_components/OrganizationManager/EditOrganization.jsx b/frontend/src/_components/OrganizationManager/EditOrganization.jsx index 79e17fb117..1c695a82d1 100644 --- a/frontend/src/_components/OrganizationManager/EditOrganization.jsx +++ b/frontend/src/_components/OrganizationManager/EditOrganization.jsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { authenticationService, organizationService } from '@/_services'; -import Modal from '../../HomePage/Modal'; +import AlertDialog from '@/_ui/AlertDialog'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; @@ -31,36 +31,34 @@ export const EditOrganization = ({ showEditOrg, setShowEditOrg }) => { }; return ( - <> - setShowEditOrg(false)} - title={t('header.organization.editWorkspace', 'Edit workspace')} - > -
-
- setNewOrgName(e.target.value)} - className="form-control" - placeholder={t('header.organization.workspaceName', 'workspace name')} - disabled={isCreating} - value={newOrgName} - maxLength={25} - /> -
+ setShowEditOrg(false)} + title={t('header.organization.editWorkspace', 'Edit workspace')} + > +
+
+ setNewOrgName(e.target.value)} + className="form-control" + placeholder={t('header.organization.workspaceName', 'workspace name')} + disabled={isCreating} + value={newOrgName} + maxLength={25} + />
-
-
- - -
+
+
+
+ +
- - +
+ ); }; diff --git a/frontend/src/_hooks/usePinnedPopover.jsx b/frontend/src/_hooks/usePinnedPopover.jsx deleted file mode 100644 index d321cc6bf9..0000000000 --- a/frontend/src/_hooks/usePinnedPopover.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import usePopover from './use-popover'; - -const usePinnedPopover = (defaultOption = false) => { - const [open, trigger, content, setOpen] = usePopover(defaultOption); - const [popoverPinned, setPopoverPinned] = React.useState(defaultOption); - - const updatePopoverPinnedState = () => { - setPopoverPinned((prev) => !prev); - }; - - React.useEffect(() => { - if (popoverPinned) { - setOpen(true); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [popoverPinned]); - - return [open, trigger, content, popoverPinned, updatePopoverPinnedState]; -}; - -export default usePinnedPopover; diff --git a/frontend/src/_styles/colors.scss b/frontend/src/_styles/colors.scss index 4c34e21e0c..8647832871 100644 --- a/frontend/src/_styles/colors.scss +++ b/frontend/src/_styles/colors.scss @@ -70,6 +70,9 @@ $primary-light: unquote("rgb(#{$primary-rgb-darker})"); color: $primary !important; } +.color-light-green { + color: #46A758; +} .bg-white { background-color: $white; } @@ -77,7 +80,9 @@ $primary-light: unquote("rgb(#{$primary-rgb-darker})"); .bg-light-1 { background-color: #A6B6CC !important; } - +.bg-black { + background-color: $black !important; +} .bg-gray { background-color: $gray; } @@ -105,7 +110,7 @@ $primary-light: unquote("rgb(#{$primary-rgb-darker})"); color: #8092AB; } .color-white{ - color: white; + color: white !important; } .color-muted{ color: #DCDCDC; @@ -125,6 +130,9 @@ $primary-light: unquote("rgb(#{$primary-rgb-darker})"); .bg-dark-indigo { background: #1C274F !important; } +.bg-light-indigo-09 { + background: $color-light-indigo-09; +} .color-light-slate-11{ color: $color-light-slate-11; } diff --git a/frontend/src/_styles/editor/comment-notifications.scss b/frontend/src/_styles/editor/comment-notifications.scss index d61ee1e2a5..f1b9ba7ed0 100644 --- a/frontend/src/_styles/editor/comment-notifications.scss +++ b/frontend/src/_styles/editor/comment-notifications.scss @@ -42,7 +42,7 @@ } .comment-notification-nav-item { - background-color: #fff !important; + background-color: #fff; } .comment-notification-filter-popover { diff --git a/frontend/src/_styles/editor/comments.scss b/frontend/src/_styles/editor/comments.scss index f82d6b30f7..8d12a532f3 100644 --- a/frontend/src/_styles/editor/comments.scss +++ b/frontend/src/_styles/editor/comments.scss @@ -14,10 +14,6 @@ z-index: 3; } - .card-header { - border: 0 !important; - } - .mentioned-user { color: #218DE3; } diff --git a/frontend/src/_styles/left-sidebar.scss b/frontend/src/_styles/left-sidebar.scss index b25e752f93..5444ee449e 100644 --- a/frontend/src/_styles/left-sidebar.scss +++ b/frontend/src/_styles/left-sidebar.scss @@ -3,42 +3,39 @@ .left-sidebar { background: $white; + .sidebar-svg-icon { + &:hover { + background: #ECEEF0; + } + } + .left-sidebar-item { - // margin: 5px; text-align: center; - padding-top: 1vw; - padding-bottom: 1vw; - border-bottom: 1px solid $grey; + padding-top: 1rem; transition: all 0.2s ease-in-out; cursor: pointer; &:hover { - transform: scale(1.2); - .debugger-badge { display: none; } } } - .active { - background: #f4f6fa; - } .left-sidebar-stack-bottom { - width: 76px; + width: 48px; position: fixed; - bottom: 1vw; - height: 50px; + bottom: 0; text-align: center; } .popover { position: fixed; - left: 76px; + left: 48px; top: 55px; overflow: auto; max-height: 60%; } .datasources-popover { - top: 200px; + top: 160px; width: 200px; .add-btn { border: none; @@ -46,7 +43,7 @@ } } .debugger-popover { - top: 270px; + top: 220px; cursor: pointer; } .global-settings-popover { @@ -463,4 +460,22 @@ .viewer-footer { height: 48px; +} +.sidebar-comments { + position: fixed !important; + top: 0; + right: 260px; + padding: 5px 0 0 0 !important; +} +.sidebar-global-settings { + position: absolute; + left: 65px; + top: 8px; +} +.sidebar-h-100-popover { + height: 100vh; + margin-top: 45px; +} +.sidebar-h-100-popover-inspector { + min-width: 422px; } \ No newline at end of file diff --git a/frontend/src/_styles/popover.scss b/frontend/src/_styles/popover.scss new file mode 100644 index 0000000000..02016a29de --- /dev/null +++ b/frontend/src/_styles/popover.scss @@ -0,0 +1,88 @@ + +.PopoverContent { + outline: none; + border-radius: 4px; + padding: 12px; + width: 260px; + background-color: white; + animation-duration: 400ms; + animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); + will-change: transform, opacity; + box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03); + border-radius: 8px; +} + +.PopoverContent[data-state='open'][data-side='top'] { + animation-name: slideDownAndFade; +} +.PopoverContent[data-state='open'][data-side='right'] { + animation-name: slideLeftAndFade; +} +.PopoverContent[data-state='open'][data-side='bottom'] { + animation-name: slideUpAndFade; +} +.PopoverContent[data-state='open'][data-side='left'] { + animation-name: slideRightAndFade; +} + +.PopoverArrow { + fill: white; +} + +.PopoverClose { + font-family: inherit; + border-radius: 100%; + border: 0; + height: 25px; + width: 25px; + display: inline-flex; + align-items: center; + justify-content: center; + position: absolute; + top: 5px; + right: 5px; +} + +@keyframes slideUpAndFade { + from { + opacity: 0; + transform: translateY(2px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideRightAndFade { + from { + opacity: 0; + transform: translateX(-2px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +@keyframes slideDownAndFade { + from { + opacity: 0; + transform: translateY(-2px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideLeftAndFade { + from { + opacity: 0; + transform: translateX(2px); + } + to { + opacity: 1; + transform: translateX(0); + } +} diff --git a/frontend/src/_styles/queryManager.scss b/frontend/src/_styles/queryManager.scss index a87b9a9a6e..c2fca10071 100644 --- a/frontend/src/_styles/queryManager.scss +++ b/frontend/src/_styles/queryManager.scss @@ -48,7 +48,7 @@ $border-radius: 4px; z-index: 1; height: 350px; position: fixed; - left: 76px; //sidebar is 76px + left: 48px; right: 300px; bottom: 0; overflow-x: hidden; diff --git a/frontend/src/_styles/theme.scss b/frontend/src/_styles/theme.scss index d122270b2b..f1ed97e076 100644 --- a/frontend/src/_styles/theme.scss +++ b/frontend/src/_styles/theme.scss @@ -46,7 +46,7 @@ button { } .navbar { - max-height: 48px; + max-height: 45px; min-height: auto; .nav-item.active:after { @@ -257,9 +257,7 @@ button { .left-sidebar-layout { display: flex; justify-content: center; - flex-direction: column; font-size: 11px; - padding: 16px; align-items: center; letter-spacing: 0.2px; @@ -271,7 +269,7 @@ button { .left-sidebar { height: 100%; - width: 76px; + width: 48px; position: fixed; z-index: 2; left: 0; @@ -355,7 +353,7 @@ button { width: 300px; flex: 1 1 auto; top: 45px; - + border-top: 1px solid #E6E8EB; background-color: #fff; background-clip: border-box; border: solid rgba(0, 0, 0, 0.125); @@ -502,7 +500,7 @@ button { top: 45px; position: fixed; right: 300px; - left: 76px; + left: 48px; overflow-y: auto; overflow-x: scroll; -webkit-box-pack: center; @@ -1191,11 +1189,6 @@ button { } } -.ds-delete-btn { - border: none; - background: none; -} - .datasource-picker, .stripe-operation-options { @@ -4081,15 +4074,6 @@ input[type="text"] { width: 10% !important; } -.inspector-close-icon-wrapper { - border-left: 1px solid #e7eaef; - - svg { - margin-left: 10px; - } - -} - .tabs-inspector { position: sticky; top: 0; @@ -4157,7 +4141,8 @@ input[type="text"] { .tabs-inspector.nav-tabs { border: 0; - width: 81%; + width: 100%; + padding: 8px 16px; } .bg-primary-lt { @@ -4171,7 +4156,7 @@ input[type="text"] { .app-name { width: 250px; - left: 150px; + left: 100px; position: absolute; } @@ -4190,9 +4175,38 @@ input[type="text"] { color: #36af8b; } -.undo-redo-buttons { - flex: 1; - padding-left: 0.5rem; +.editor-header-actions { + display: flex; + align-items: center; + position: absolute; + left: 30%; + color: #868aa5; + white-space: nowrap; + font-weight: 400; + font-size: 12px; + letter-spacing: 0.5px; +} +.undo-button, .redo-button { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + padding: 6px; + gap: 10px; + width: 28px; + height: 28px; + background: #ECEEF0; + border-radius: 6px; + margin-right: 5px; + flex: none; + order: 0; + flex-grow: 0; +} + +.theme-dark { + .undo-button, .redo-button { + background: 0; + } } .app-version-menu { @@ -4691,6 +4705,15 @@ input[type="text"] { padding: 0 10px !important; } +.comment-notification-nav-item { + background: transparent; + border: 0; + font-size: 12px; + font-weight: 500; + opacity: 0.6; + height: 28px; + border-radius: 6px; +} // comment styles ::override .editor-sidebar { .nav-tabs { @@ -4700,6 +4723,24 @@ input[type="text"] { .nav-tabs .nav-link.active { background-color: transparent !important; } + + .inspector-nav-item { + background: transparent; + border: 0; + font-size: 12px; + font-weight: 500; + opacity: 0.6; + height: 28px; + border-radius: 6px; + } + + .inspector-component-title-input-holder { + padding: 16px 8px; + margin: 0; + padding-bottom: 0; + display: flex; + align-items: center; + } } .comment-card-wrapper { @@ -5279,7 +5320,10 @@ div#driver-page-overlay { .realtime-avatars { position: absolute; - left: 50%; + min-width: 118px; + right: 307px; + border-right: 1px solid #E6E8EB; + padding: 10px; } .widget-style-field-header { @@ -8488,6 +8532,59 @@ tbody { // ONBOARDING-SELF-HOST STYLES END-------> //ONBOARD STYLES END---------------------------->>>>> + +.app-versions-selector { + display: inline-flex; + align-items: center; + width: 176px; + height: 28px; + position: absolute; + left: 54%; + border-radius: 6px; +} +.app-version-list-item { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.app-version-name, .app-version-released { + font-weight: 400; + font-size: 12px; + line-height: 20px; +} +.app-version-delete { + display: none; +} +.custom-version-selector__option:hover .app-version-delete { + display: block; +} +.editor .editor-sidebar { + border-top: 1px solid #E6E8EB; +} +.editor .navbar-brand { + border-right: 1px solid #E6E8EB; + padding-right: 8px !important; +} +.theme-dark { + .editor .navbar-brand { + border-right: 1px solid #333c48; + } + .realtime-avatars { + border-right: 1px solid #333c48; + } +} +.modal-backdrop { + background-color: hsla(0, 0%, 0%, 0.439); +} +.ds-delete-btn { + display: none; + border: none; + background: none; +} +.ds-list-item:hover .ds-delete-btn { + display: block; +} + .toojet-db-table-footer { position: fixed; bottom: 0px; @@ -8505,5 +8602,4 @@ tbody { max-width: 30px; text-align: center; } - } \ No newline at end of file diff --git a/frontend/src/_ui/AlertDialog/index.jsx b/frontend/src/_ui/AlertDialog/index.jsx new file mode 100644 index 0000000000..92530783e1 --- /dev/null +++ b/frontend/src/_ui/AlertDialog/index.jsx @@ -0,0 +1,35 @@ +import React from 'react'; +import Modal from 'react-bootstrap/Modal'; +import cx from 'classnames'; + +export default function AlertDialog({ title, show, closeModal, customClassName, children }) { + const darkMode = localStorage.getItem('darkMode') === 'true'; + return ( + closeModal(false)} + contentClassName={cx('animation-fade home-modal-component', customClassName, { dark: darkMode })} + show={show} + size="md" + backdrop={true} + keyboard={true} + enforceFocus={false} + animation={false} + onEscapeKeyDown={() => closeModal()} + centered + data-cy={'modal-component'} + > + {title && ( + + {title} + + + )} + {children} + + ); +} diff --git a/frontend/src/_ui/Avatar/index.jsx b/frontend/src/_ui/Avatar/index.jsx index 509c07ed84..4c40600bbf 100644 --- a/frontend/src/_ui/Avatar/index.jsx +++ b/frontend/src/_ui/Avatar/index.jsx @@ -20,7 +20,7 @@ const Avatar = ({ text, image, avatarId, title = '', borderColor = '', borderSha { getAbsoluteNodePath, actionsList, fontSize, - updateParentState = () => null, inspectorTree, } = restProps; @@ -233,7 +232,6 @@ export const JSONNode = ({ data, ...restProps }) => { aria-current="true" onClick={() => { action.dispatchAction(data, currentNode); - updateParentState(); }} > {action.name} diff --git a/frontend/src/_ui/JSONTreeViewer/JSONTreeViewer.jsx b/frontend/src/_ui/JSONTreeViewer/JSONTreeViewer.jsx index 28bcb81ba8..d5ee9f0089 100644 --- a/frontend/src/_ui/JSONTreeViewer/JSONTreeViewer.jsx +++ b/frontend/src/_ui/JSONTreeViewer/JSONTreeViewer.jsx @@ -223,7 +223,6 @@ export class JSONTreeViewer extends React.Component { getOnSelectLabelDispatchActions={this.getOnSelectLabelDispatchActions} expandWithLabels={this.props.expandWithLabels ?? false} //expand and collapse: onclick of label getAbsoluteNodePath={this.getAbsoluteNodePath} - updateParentState={this.state.updateParentState} fontSize={this.props.fontSize ?? '12px'} inspectorTree={this.props.treeType === 'inspector'} /> diff --git a/frontend/src/_ui/LeftSidebar/Header.jsx b/frontend/src/_ui/LeftSidebar/Header.jsx index feabdecaf3..cfa7bdac82 100644 --- a/frontend/src/_ui/LeftSidebar/Header.jsx +++ b/frontend/src/_ui/LeftSidebar/Header.jsx @@ -2,16 +2,16 @@ import React from 'react'; import { SearchBoxComponent } from '@/_ui/Search'; const Header = ({ children, darkMode }) => { - return
{children}
; + return
{children}
; }; const PanelHeader = ({ children, title }) => { return (
-
+

{title}

-
{children}
+
{children}
); }; diff --git a/frontend/src/_ui/Popover/index.jsx b/frontend/src/_ui/Popover/index.jsx new file mode 100644 index 0000000000..739114feb5 --- /dev/null +++ b/frontend/src/_ui/Popover/index.jsx @@ -0,0 +1,41 @@ +import '@/_styles/popover.scss'; +import React from 'react'; +import cx from 'classnames'; +import * as Popover from '@radix-ui/react-popover'; + +const PopoverComponent = ({ + children, + fullWidth = true, + popoverContentClassName = '', + popoverContent, + hideCloseIcon = true, + handleToggle, + side = 'bottom', + showArrow = false, +}) => ( + + + {children} + + + + {popoverContent} + {!hideCloseIcon && ( + + + + + + )} + {showArrow && } + + + +); + +export default PopoverComponent; diff --git a/frontend/src/_ui/Select/SelectComponent.jsx b/frontend/src/_ui/Select/SelectComponent.jsx index 476d62cb89..cea9e95827 100644 --- a/frontend/src/_ui/Select/SelectComponent.jsx +++ b/frontend/src/_ui/Select/SelectComponent.jsx @@ -53,7 +53,7 @@ export const SelectComponent = ({ options = [], value, onChange, ...restProps }) isDisabled={isLoading} options={selectOptions} value={currentValue} - search={hasSearch} + isSearchable={hasSearch} onChange={handleOnChange} placeholder={placeholder} styles={customStyles}