mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 08:58:26 +00:00
parent
f877956100
commit
e091e5c662
6 changed files with 244 additions and 135 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import cx from 'classnames';
|
||||
import {
|
||||
datasourceService,
|
||||
dataqueryService,
|
||||
|
|
@ -19,9 +18,6 @@ import { componentTypes } from './WidgetManager/components';
|
|||
import { Inspector } from './Inspector/Inspector';
|
||||
import { DataSourceTypes } from './DataSourceManager/SourceComponents';
|
||||
import { QueryManager, QueryPanel } from './QueryManager';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ManageAppUsers } from './ManageAppUsers';
|
||||
import { ReleaseVersionButton } from './ReleaseVersionButton';
|
||||
import {
|
||||
onComponentOptionChanged,
|
||||
onComponentOptionsChanged,
|
||||
|
|
@ -44,25 +40,19 @@ import config from 'config';
|
|||
import queryString from 'query-string';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { produce, enablePatches, setAutoFreeze, applyPatches } from 'immer';
|
||||
import { AppVersionsManager } from './AppVersionsManager/List';
|
||||
import { SearchBox } from '@/_components/SearchBox';
|
||||
import { createWebsocketConnection } from '@/_helpers/websocketConnection';
|
||||
import Tooltip from 'react-bootstrap/Tooltip';
|
||||
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
|
||||
import RealtimeAvatars from './RealtimeAvatars';
|
||||
import RealtimeCursors from '@/Editor/RealtimeCursors';
|
||||
import { initEditorWalkThrough } from '@/_helpers/createWalkThrough';
|
||||
import { EditorContextWrapper } from './Context/EditorContextWrapper';
|
||||
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 Skeleton from 'react-loading-skeleton';
|
||||
import { GlobalSettings } from './Header/GlobalSettings';
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import Logo from '@assets/images/rocket.svg';
|
||||
import EmptyQueriesIllustration from '@assets/images/icons/no-queries-added.svg';
|
||||
import EditorHeader from './Header';
|
||||
|
||||
setAutoFreeze(false);
|
||||
enablePatches();
|
||||
|
|
@ -1783,117 +1773,34 @@ class EditorComponent extends React.Component {
|
|||
darkMode={this.props.darkMode}
|
||||
/>
|
||||
<EditorContextWrapper>
|
||||
<div className="header">
|
||||
<header className="navbar navbar-expand-md navbar-light d-print-none">
|
||||
<div className="container-xl header-container">
|
||||
<button
|
||||
className="navbar-toggler"
|
||||
type="button"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#navbar-menu"
|
||||
>
|
||||
<span className="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<h1 className="navbar-brand d-none-navbar-horizontal pe-0">
|
||||
<Link to={'/'} data-cy="editor-page-logo">
|
||||
<Logo />
|
||||
</Link>
|
||||
</h1>
|
||||
<GlobalSettings
|
||||
currentState={currentState}
|
||||
globalSettingsChanged={this.globalSettingsChanged}
|
||||
globalSettings={appDefinition.globalSettings}
|
||||
darkMode={this.props.darkMode}
|
||||
toggleAppMaintenance={this.toggleAppMaintenance}
|
||||
is_maintenance_on={this.state.app.is_maintenance_on}
|
||||
/>
|
||||
<EditAppName appId={app.id} appName={app.name} onNameChanged={this.onNameChanged} />
|
||||
<HeaderActions
|
||||
canUndo={this.canUndo}
|
||||
canRedo={this.canRedo}
|
||||
handleUndo={this.handleUndo}
|
||||
handleRedo={this.handleRedo}
|
||||
currentLayout={currentLayout}
|
||||
toggleCurrentLayout={this.toggleCurrentLayout}
|
||||
/>
|
||||
<span
|
||||
className={cx('autosave-indicator', {
|
||||
'autosave-indicator-saving': this.state.isSaving,
|
||||
'text-danger': this.state.saveError,
|
||||
'd-none': this.isVersionReleased(),
|
||||
})}
|
||||
data-cy="autosave-indicator"
|
||||
>
|
||||
{this.state.isSaving
|
||||
? 'Saving...'
|
||||
: this.state.saveError
|
||||
? 'Could not save changes'
|
||||
: 'All changes are saved'}
|
||||
</span>
|
||||
{config.ENABLE_MULTIPLAYER_EDITING && <RealtimeAvatars darkMode={this.props.darkMode} />}
|
||||
{editingVersion && (
|
||||
<AppVersionsManager
|
||||
appId={appId}
|
||||
editingVersion={editingVersion}
|
||||
releasedVersionId={app.current_version_id}
|
||||
setAppDefinitionFromVersion={this.setAppDefinitionFromVersion}
|
||||
showCreateVersionModalPrompt={showCreateVersionModalPrompt}
|
||||
closeCreateVersionModalPrompt={this.closeCreateVersionModalPrompt}
|
||||
/>
|
||||
)}
|
||||
<div className="navbar-nav flex-row order-md-last release-buttons">
|
||||
<div className="nav-item me-1">
|
||||
{app.id && (
|
||||
<ManageAppUsers
|
||||
app={app}
|
||||
slug={slug}
|
||||
darkMode={this.props.darkMode}
|
||||
handleSlugChange={this.handleSlugChange}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="nav-item me-1">
|
||||
<Link
|
||||
title="Preview"
|
||||
to={appVersionPreviewLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
data-cy="preview-link-button"
|
||||
>
|
||||
<svg
|
||||
className="icon cursor-pointer w-100 h-100"
|
||||
width="33"
|
||||
height="33"
|
||||
viewBox="0 0 33 33"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="0.363281" y="0.220703" width="32" height="32" rx="6" fill="#F0F4FF" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10.4712 16.2205C12.1364 18.9742 14.1064 20.2205 16.3646 20.2205C18.6227 20.2205 20.5927 18.9742 22.258 16.2205C20.5927 13.4669 18.6227 12.2205 16.3646 12.2205C14.1064 12.2205 12.1364 13.4669 10.4712 16.2205ZM9.1191 15.8898C10.9694 12.6519 13.3779 10.8872 16.3646 10.8872C19.3513 10.8872 21.7598 12.6519 23.6101 15.8898C23.7272 16.0947 23.7272 16.3464 23.6101 16.5513C21.7598 19.7891 19.3513 21.5539 16.3646 21.5539C13.3779 21.5539 10.9694 19.7891 9.1191 16.5513C9.00197 16.3464 9.00197 16.0947 9.1191 15.8898ZM16.3646 15.5539C15.9964 15.5539 15.6979 15.8524 15.6979 16.2205C15.6979 16.5887 15.9964 16.8872 16.3646 16.8872C16.7328 16.8872 17.0312 16.5887 17.0312 16.2205C17.0312 15.8524 16.7328 15.5539 16.3646 15.5539ZM14.3646 16.2205C14.3646 15.116 15.26 14.2205 16.3646 14.2205C17.4692 14.2205 18.3646 15.116 18.3646 16.2205C18.3646 17.3251 17.4692 18.2205 16.3646 18.2205C15.26 18.2205 14.3646 17.3251 14.3646 16.2205Z"
|
||||
fill="#3E63DD"
|
||||
/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
{app.id && (
|
||||
<ReleaseVersionButton
|
||||
isVersionReleased={this.isVersionReleased()}
|
||||
appId={app.id}
|
||||
appName={app.name}
|
||||
onVersionRelease={this.onVersionRelease}
|
||||
editingVersion={editingVersion}
|
||||
saveEditingVersion={this.saveEditingVersion}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
<EditorHeader
|
||||
darkMode={this.props.darkMode}
|
||||
currentState={currentState}
|
||||
currentLayout={this.state.currentLayout}
|
||||
globalSettingsChanged={this.globalSettingsChanged}
|
||||
appDefinition={appDefinition}
|
||||
toggleAppMaintenance={this.toggleAppMaintenance}
|
||||
editingVersion={editingVersion}
|
||||
showCreateVersionModalPrompt={showCreateVersionModalPrompt}
|
||||
app={app}
|
||||
appVersionPreviewLink={appVersionPreviewLink}
|
||||
slug={slug}
|
||||
appId={appId}
|
||||
canUndo={this.canUndo}
|
||||
canRedo={this.canRedo}
|
||||
handleUndo={this.handleUndo}
|
||||
handleRedo={this.handleRedo}
|
||||
toggleCurrentLayout={this.toggleCurrentLayout}
|
||||
isSaving={this.state.isSaving}
|
||||
saveError={this.state.saveError}
|
||||
isVersionReleased={this.isVersionReleased}
|
||||
onNameChanged={this.onNameChanged}
|
||||
setAppDefinitionFromVersion={this.setAppDefinitionFromVersion}
|
||||
closeCreateVersionModalPrompt={this.closeCreateVersionModalPrompt}
|
||||
handleSlugChange={this.handleSlugChange}
|
||||
onVersionRelease={this.onVersionRelease}
|
||||
saveEditingVersion={this.saveEditingVersion}
|
||||
/>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<div className="sub-section">
|
||||
<LeftSidebar
|
||||
|
|
|
|||
171
frontend/src/Editor/Header/index.js
Normal file
171
frontend/src/Editor/Header/index.js
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import AppLogo from '@/_components/AppLogo';
|
||||
import { GlobalSettings } from './GlobalSettings';
|
||||
import EditAppName from './EditAppName';
|
||||
import HeaderActions from './HeaderActions';
|
||||
import RealtimeAvatars from '../RealtimeAvatars';
|
||||
import { AppVersionsManager } from '../AppVersionsManager/List';
|
||||
import { ManageAppUsers } from '../ManageAppUsers';
|
||||
import { ReleaseVersionButton } from '../ReleaseVersionButton';
|
||||
import cx from 'classnames';
|
||||
import config from 'config';
|
||||
|
||||
export default function EditorHeader({
|
||||
darkMode,
|
||||
currentState,
|
||||
currentLayout,
|
||||
globalSettingsChanged,
|
||||
appDefinition,
|
||||
toggleAppMaintenance,
|
||||
editingVersion,
|
||||
showCreateVersionModalPrompt,
|
||||
app,
|
||||
appVersionPreviewLink,
|
||||
slug,
|
||||
appId,
|
||||
canUndo,
|
||||
canRedo,
|
||||
handleUndo,
|
||||
handleRedo,
|
||||
toggleCurrentLayout,
|
||||
isSaving,
|
||||
saveError,
|
||||
isVersionReleased,
|
||||
onNameChanged,
|
||||
setAppDefinitionFromVersion,
|
||||
closeCreateVersionModalPrompt,
|
||||
handleSlugChange,
|
||||
onVersionRelease,
|
||||
saveEditingVersion,
|
||||
}) {
|
||||
const { is_maintenance_on } = app;
|
||||
|
||||
return (
|
||||
<div className="header">
|
||||
<header className="navbar navbar-expand-md navbar-light d-print-none">
|
||||
<div className="container-xl header-container">
|
||||
<div className="d-flex w-100">
|
||||
<h1 className="navbar-brand d-none-navbar-horizontal pe-0 mt-1">
|
||||
<Link to={'/'} data-cy="editor-page-logo">
|
||||
<AppLogo isLoadingFromHeader={true} />
|
||||
</Link>
|
||||
</h1>
|
||||
<div
|
||||
style={{
|
||||
maxHeight: '45px',
|
||||
}}
|
||||
className="flex-grow-1 row px-3"
|
||||
>
|
||||
<div className="col">
|
||||
<div className="row p-2">
|
||||
<div className="col global-settings-app-wrapper">
|
||||
<GlobalSettings
|
||||
currentState={currentState}
|
||||
globalSettingsChanged={globalSettingsChanged}
|
||||
globalSettings={appDefinition.globalSettings}
|
||||
darkMode={darkMode}
|
||||
toggleAppMaintenance={toggleAppMaintenance}
|
||||
is_maintenance_on={is_maintenance_on}
|
||||
/>
|
||||
<EditAppName appId={app.id} appName={app.name} onNameChanged={onNameChanged} />
|
||||
</div>
|
||||
|
||||
<div className="col d-flex">
|
||||
<HeaderActions
|
||||
canUndo={canUndo}
|
||||
canRedo={canRedo}
|
||||
handleUndo={handleUndo}
|
||||
handleRedo={handleRedo}
|
||||
currentLayout={currentLayout}
|
||||
toggleCurrentLayout={toggleCurrentLayout}
|
||||
/>
|
||||
<div className="my-1 mx-3">
|
||||
<span
|
||||
className={cx('autosave-indicator', {
|
||||
'autosave-indicator-saving': isSaving,
|
||||
'text-danger': saveError,
|
||||
'd-none': isVersionReleased(),
|
||||
})}
|
||||
data-cy="autosave-indicator"
|
||||
>
|
||||
{isSaving ? 'Saving...' : saveError ? 'Could not save changes' : 'Saved changes'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-auto d-flex">
|
||||
<div className="d-flex version-manager-container">
|
||||
{editingVersion && (
|
||||
<AppVersionsManager
|
||||
appId={appId}
|
||||
editingVersion={editingVersion}
|
||||
releasedVersionId={app.current_version_id}
|
||||
setAppDefinitionFromVersion={setAppDefinitionFromVersion}
|
||||
showCreateVersionModalPrompt={showCreateVersionModalPrompt}
|
||||
closeCreateVersionModalPrompt={closeCreateVersionModalPrompt}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{config.ENABLE_MULTIPLAYER_EDITING && (
|
||||
<div className="mx-2 p-2">
|
||||
<RealtimeAvatars />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-1"></div>
|
||||
</div>
|
||||
<div className="d-flex">
|
||||
<div className="navbar-nav flex-row order-md-last release-buttons p-1">
|
||||
<div className="nav-item me-1">
|
||||
{app.id && (
|
||||
<ManageAppUsers app={app} slug={slug} darkMode={darkMode} handleSlugChange={handleSlugChange} />
|
||||
)}
|
||||
</div>
|
||||
<div className="nav-item me-1">
|
||||
<Link
|
||||
title="Preview"
|
||||
to={appVersionPreviewLink}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
data-cy="preview-link-button"
|
||||
>
|
||||
<svg
|
||||
className="icon cursor-pointer w-100 h-100"
|
||||
width="33"
|
||||
height="33"
|
||||
viewBox="0 0 33 33"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="0.363281" y="0.220703" width="32" height="32" rx="6" fill="#F0F4FF" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10.4712 16.2205C12.1364 18.9742 14.1064 20.2205 16.3646 20.2205C18.6227 20.2205 20.5927 18.9742 22.258 16.2205C20.5927 13.4669 18.6227 12.2205 16.3646 12.2205C14.1064 12.2205 12.1364 13.4669 10.4712 16.2205ZM9.1191 15.8898C10.9694 12.6519 13.3779 10.8872 16.3646 10.8872C19.3513 10.8872 21.7598 12.6519 23.6101 15.8898C23.7272 16.0947 23.7272 16.3464 23.6101 16.5513C21.7598 19.7891 19.3513 21.5539 16.3646 21.5539C13.3779 21.5539 10.9694 19.7891 9.1191 16.5513C9.00197 16.3464 9.00197 16.0947 9.1191 15.8898ZM16.3646 15.5539C15.9964 15.5539 15.6979 15.8524 15.6979 16.2205C15.6979 16.5887 15.9964 16.8872 16.3646 16.8872C16.7328 16.8872 17.0312 16.5887 17.0312 16.2205C17.0312 15.8524 16.7328 15.5539 16.3646 15.5539ZM14.3646 16.2205C14.3646 15.116 15.26 14.2205 16.3646 14.2205C17.4692 14.2205 18.3646 15.116 18.3646 16.2205C18.3646 17.3251 17.4692 18.2205 16.3646 18.2205C15.26 18.2205 14.3646 17.3251 14.3646 16.2205Z"
|
||||
fill="#3E63DD"
|
||||
/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
{app.id && (
|
||||
<ReleaseVersionButton
|
||||
isVersionReleased={isVersionReleased()}
|
||||
appId={app.id}
|
||||
appName={app.name}
|
||||
onVersionRelease={onVersionRelease}
|
||||
editingVersion={editingVersion}
|
||||
saveEditingVersion={saveEditingVersion}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ export const LeftSidebarComment = ({ toggleComments, selectedSidebarItem, appVer
|
|||
className={cx(`left-sidebar-item left-sidebar-layout sidebar-comments`, {
|
||||
disabled: !appVersionsId,
|
||||
active: isActive,
|
||||
dark: darkMode,
|
||||
})}
|
||||
onClick={() => {
|
||||
toggleActive(!isActive);
|
||||
|
|
|
|||
22
frontend/src/_components/AppLogo.jsx
Normal file
22
frontend/src/_components/AppLogo.jsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import React from 'react';
|
||||
import Logo from '@assets/images/rocket.svg';
|
||||
|
||||
export default function AppLogo({ isLoadingFromHeader, className }) {
|
||||
const url = window.public_config?.WHITE_LABEL_LOGO;
|
||||
|
||||
return (
|
||||
<>
|
||||
{url ? (
|
||||
<img src={url} height={26} />
|
||||
) : (
|
||||
<>
|
||||
{isLoadingFromHeader ? (
|
||||
<Logo />
|
||||
) : (
|
||||
<img src="assets/images/logo-color.svg" height={26} className={className} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -466,7 +466,11 @@
|
|||
position: fixed !important;
|
||||
top: 0;
|
||||
right: 260px;
|
||||
padding: 5px 0 0 0 !important;
|
||||
border-left: 1px solid #d2ddec;
|
||||
padding: 5px 0 5px 5px !important;
|
||||
}
|
||||
.sidebar-comments.dark {
|
||||
border-color: #324156;
|
||||
}
|
||||
.sidebar-global-settings {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ button {
|
|||
.header-container {
|
||||
max-width: 100%;
|
||||
padding: 0 10px;
|
||||
min-height: 45px;
|
||||
}
|
||||
|
||||
.resizer-select,
|
||||
|
|
@ -4178,6 +4179,7 @@ input[type="text"] {
|
|||
.app-name {
|
||||
width: 200px;
|
||||
left: 84px;
|
||||
top: 6px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
|
@ -4198,9 +4200,6 @@ input[type="text"] {
|
|||
|
||||
.editor-header-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
left: 25%;
|
||||
color: #868aa5;
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
|
|
@ -5349,11 +5348,7 @@ div#driver-page-overlay {
|
|||
}
|
||||
|
||||
.realtime-avatars {
|
||||
position: absolute;
|
||||
min-width: 118px;
|
||||
right: 307px;
|
||||
border-right: 1px solid #E6E8EB;
|
||||
padding: 16px;
|
||||
padding: 0px
|
||||
}
|
||||
|
||||
.widget-style-field-header {
|
||||
|
|
@ -5424,8 +5419,6 @@ div#driver-page-overlay {
|
|||
}
|
||||
|
||||
.autosave-indicator {
|
||||
position: absolute;
|
||||
left: 44%;
|
||||
color: #868aa5;
|
||||
white-space: nowrap;
|
||||
font-weight: 400;
|
||||
|
|
@ -6670,7 +6663,7 @@ tbody {
|
|||
padding: 3px 3px 3px 0px;
|
||||
}
|
||||
|
||||
.editor-center-wrapper {}
|
||||
|
||||
|
||||
.right-bar {
|
||||
height: 100%;
|
||||
|
|
@ -7260,7 +7253,6 @@ tbody {
|
|||
border-right: 1px solid #E6E8EB;
|
||||
padding-right: 12px !important;
|
||||
padding-left: 4px;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
|
|
@ -7398,6 +7390,18 @@ tbody {
|
|||
height: 52px;
|
||||
}
|
||||
|
||||
.release-buttons {
|
||||
height: 45px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.global-settings-app-wrapper {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.version-manager-container {
|
||||
padding: 0.6rem;
|
||||
}
|
||||
// tooljet db fields styles [ query manager ]
|
||||
.tj-db-field-wrapper {
|
||||
.code-hinter-wrapper {
|
||||
|
|
|
|||
Loading…
Reference in a new issue