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 ? (
-
- ) : (
-
-
-

-
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 ? (
+
+ ) : (
+
+
+

+
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);
- }}
- >
- | 100% |
-
- {
- setText(90);
- onZoomChanged(0.9);
- setOpen(false);
- }}
- >
- | 90% |
-
- {
- setText(80);
- onZoomChanged(0.8);
- setOpen(false);
- }}
- >
- | 80% |
-
- {
- setText(70);
- onZoomChanged(0.7);
- setOpen(false);
- }}
- >
- | 70% |
-
- {
- setText(60);
- onZoomChanged(0.6);
- setOpen(false);
- }}
- >
- | 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.props.t('editor.share', 'Share')}
-
-
-
+
-
{isLoading ? (
@@ -161,12 +183,12 @@ class ManageAppUsersComponent extends React.Component {
this.toggleAppVisibility()}
+ onClick={this.toggleAppVisibility}
checked={this.state.app.is_public}
disabled={this.state.ischangingVisibility}
/>
- {this.props.t('editor.shareModal.makeApplicationPublic', 'Make application public ?')}
+ {this.props.t('editor.shareModal.makeApplicationPublic', 'Make application public?')}
@@ -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')}
>
- {t('header.organization.menus.menusList.manageSso', 'Manage SSO')}
+ {t('header.organization.menus.menusList.manageSso', 'SSO')}
-
-
- {message}
-
-
- {t('globals.cancel', 'Cancel')}
-
-
+ {title && (
+
+ {title}
+
-
-
- >
+
+
+
+ )}
+
{message}
+
+
+ {t('globals.cancel', 'Cancel')}
+
+
+ {t('globals.yes', 'Yes')}
+
+
+
);
}
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')}
>
-
+
-
-
setShowCreateOrg(false)}>
+
+ setShowCreateOrg(false)}>
{t('globals.cancel', 'Cancel')}
{
-
+
);
};
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}
+ />
-
-
- setShowEditOrg(false)}>
- {t('globals.cancel', 'Cancel')}
-
-
- {t('globals.save', 'Save')}
-
-
+
+
+
+ setShowEditOrg(false)}>
+ {t('globals.cancel', 'Cancel')}
+
+
+ {t('globals.save', 'Save')}
+
-
- >
+
+
);
};
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}
+ closeModal()}
+ data-cy="modal-close-button"
+ >
+
+ )}
+ {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 (
-
+
-
{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}