added bottom panel with resize functionality (#3149)

* added bottom panel with resize functionality

* merge conflicts fixed

Co-authored-by: Ivan Hrynevytskyi <ivan.hrynevytskyi@IHRYNEVYTSKYIL.local>
This commit is contained in:
Ivan Hrynevytskyi (FE-underwriting) 2022-06-23 12:33:58 +03:00 committed by GitHub
parent 5d758284be
commit e71d39d59e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 31 deletions

View file

@ -2,7 +2,7 @@
&.x6-graph-scroller-pannable[data-panning='false'] {
cursor: default;
}
width: calc(100vw - var(--activity-editor-width) - var(--activity-picker-width)) !important;
width: calc(100vw - var(--workflow-editor-width) - var(--activity-picker-width)) !important;
}
.x6-widget-selection-box {

View file

@ -1,6 +1,11 @@
.panel-state-closed {
.panel-state-collapsed {
.panel {
&.panel {
&-position-bottom {
right: var(--workflow-editor-width);
left: var(--activity-picker-width);
}
&panel-position-top {
width: 0;

View file

@ -45,10 +45,13 @@ export class Panel {
resize = (e: MouseEvent) => {
if (this.position === PanelPosition.Right) {
applyResize({ position: PanelPosition.Right, width: document.body.clientWidth - e.pageX });
applyResize({ position: PanelPosition.Right, size: document.body.clientWidth - e.pageX });
}
if (this.position === PanelPosition.Left) {
applyResize({ position: PanelPosition.Left, width: e.pageX });
applyResize({ position: PanelPosition.Left, size: e.pageX });
}
if (this.position === PanelPosition.Bottom) {
applyResize({ position: PanelPosition.Bottom, size: document.body.offsetHeight - e.pageY });
}
};
@ -67,6 +70,7 @@ export class Panel {
const containerClassMap = [];
containerClassMap[PanelPosition.Left] = 'panel-position-left left-0 top-0 bottom-0 border-r';
containerClassMap[PanelPosition.Top] = 'panel-position-top left-0 top-0 right-0 border-b';
containerClassMap[PanelPosition.Bottom] = 'panel-position-bottom h-0 bottom-0 border-t';
containerClassMap[PanelPosition.Right] = 'panel-position-right right-0 top-0 bottom-0 border-l';
const containerCssClass = containerClassMap[position];
@ -78,14 +82,17 @@ export class Panel {
const toggleCssClass = toggleClassMap[position];
const dragBarClass = position === PanelPosition.Left ? 'right-0' : 'left-0';
const dragBarClassMap = {
[PanelPosition.Left]: 'right-0 h-full cursor-col-resize w-1',
[PanelPosition.Right]: 'left-0 h-full cursor-col-resize w-1',
[PanelPosition.Bottom]: 'top-0 w-full cursor-row-resize h-1',
};
const dragBarClass = dragBarClassMap[this.position];
return (
<Host class={`panel absolute bg-white z-10 ${containerCssClass} ${stateClass}`}>
<div
class={`absolute h-full opacity-0 cursor-col-resize w-1 bg-blue-400 transition ease-in-out duration-300 hover:opacity-100 z-10 ${dragBarClass}`}
onMouseDown={this.onDragBarMouseDown}
/>
<div class={`absolute opacity-0 bg-blue-400 transition ease-in-out duration-300 hover:opacity-100 z-10 ${dragBarClass}`} onMouseDown={this.onDragBarMouseDown} />
<div class="panel-content-container">
<slot />
</div>

View file

@ -4,33 +4,36 @@ type ApplyResizeParams = {
position: PanelPosition;
isDefault?: boolean;
isHide?: boolean;
width?: number;
size?: number;
};
const positionToLocalStorage = {
[PanelPosition.Right]: 'LS/rightPanelWidth',
[PanelPosition.Left]: 'LS/leftPanelWidth',
[PanelPosition.Bottom]: 'LS/bottomPanelWidth',
};
const positionToCssVariable = {
[PanelPosition.Right]: '--activity-editor-width',
[PanelPosition.Right]: '--workflow-editor-width',
[PanelPosition.Left]: '--activity-picker-width',
[PanelPosition.Bottom]: '--activity-editor-height',
};
const positionToDefaultWidth = {
const positionToDefaultSize = {
[PanelPosition.Right]: 580,
[PanelPosition.Left]: 300,
[PanelPosition.Bottom]: 200,
};
function getPanelDefaultWidth(position: PanelPosition) {
return localStorage.getItem(positionToLocalStorage[position]) || positionToDefaultWidth[position];
function getPanelDefaultSize(position: PanelPosition) {
return localStorage.getItem(positionToLocalStorage[position]) || positionToDefaultSize[position];
}
function updatePanelDefaultWidth(position: PanelPosition, width: number) {
return localStorage.setItem(positionToLocalStorage[position], width.toString());
function updatePanelDefaultSize(position: PanelPosition, size: number) {
return localStorage.setItem(positionToLocalStorage[position], size.toString());
}
export function applyResize({ position, isDefault, isHide, width }: ApplyResizeParams) {
export function applyResize({ position, isDefault, isHide, size }: ApplyResizeParams) {
const root = document.querySelector<HTMLElement>(':root');
if (isHide) {
@ -39,11 +42,11 @@ export function applyResize({ position, isDefault, isHide, width }: ApplyResizeP
}
if (isDefault) {
root.style.setProperty(positionToCssVariable[position], `${getPanelDefaultWidth(position)}px`);
root.style.setProperty(positionToCssVariable[position], `${getPanelDefaultSize(position)}px`);
return;
}
root.style.setProperty(positionToCssVariable[position], `${width}px`);
updatePanelDefaultWidth(position, width);
root.style.setProperty(positionToCssVariable[position], `${size}px`);
updatePanelDefaultSize(position, size);
return;
}

View file

@ -1,29 +1,37 @@
:root {
--activity-editor-width: 580px;
--workflow-editor-width: 580px;
--activity-picker-width: 300px;
--activity-editor-height: 200px;
}
elsa-canvas {
left: var(--activity-picker-width);
top: 54px;
right: var(--activity-editor-width);
bottom: 0;
right: var(--workflow-editor-width);
bottom: var(--activity-editor-height);
}
.elsa-panel-toolbar {
left: var(--activity-picker-width);
right: var(--activity-editor-width);
right: var(--workflow-editor-width);
}
elsa-panel.panel-state-expanded.elsa-activity-picker-container {
width: var(--activity-picker-width);
}
elsa-panel.panel-state-expanded.elsa-activity-editor-container {
width: var(--activity-editor-width);
elsa-panel.panel-state-expanded.elsa-workflow-editor-container {
width: var(--workflow-editor-width);
right: 0;
left: unset;
}
elsa-panel.panel-state-expanded.elsa-activity-editor-container {
height: var(--activity-editor-height);
right: var(--workflow-editor-width);
left: var(--activity-picker-width);
bottom: 0;
}
elsa-workflow-navigator {
top: 70px;
position: absolute;
@ -53,3 +61,15 @@ elsa-workflow-navigator {
right: 0;
}
}
.activity-editor-closed {
.activity-editor-container {
display: none;
}
elsa-canvas {
bottom: 0;
}
}

View file

@ -215,14 +215,20 @@ export class WorkflowDefinitionEditor {
onDragOver={this.onDragOver}
onDrop={this.onDrop}/>
<elsa-panel
class="elsa-activity-editor-container"
class="elsa-workflow-editor-container"
position={PanelPosition.Right}
onExpandedStateChanged={e => this.onActivityEditorPanelStateChanged(e.detail)}>
onExpandedStateChanged={e => this.onWorkflowEditorPanelStateChanged(e.detail)}>
<div class="object-editor-container">
{this.renderSelectedObject()}
</div>
</elsa-panel>
<elsa-panel
class="elsa-activity-editor-container"
position={PanelPosition.Bottom}
onExpandedStateChanged={e => this.onActivityEditorPanelStateChanged(e.detail)}>
<div class="activity-editor-container">
</div>
</elsa-panel>
</div>
// </WorkflowEditorTunnel.Provider>
);
@ -307,7 +313,8 @@ export class WorkflowDefinitionEditor {
};
private onActivityPickerPanelStateChanged = async (e: PanelStateChangedArgs) => await this.updateContainerLayout('activity-picker-closed', e.expanded)
private onActivityEditorPanelStateChanged = async (e: PanelStateChangedArgs) => await this.updateContainerLayout('object-editor-closed', e.expanded)
private onWorkflowEditorPanelStateChanged = async (e: PanelStateChangedArgs) => await this.updateContainerLayout('object-editor-closed', e.expanded)
private onActivityEditorPanelStateChanged = async (e: PanelStateChangedArgs) => await this.updateContainerLayout('activity-editor-closed', e.expanded)
private onDragOver = (e: DragEvent) => {
e.preventDefault();

View file

@ -59,6 +59,14 @@
@apply absolute py-4 bg-gray-50 border border-gray-400 text-gray-400 rounded-r z-10;
}
.panel-toggle-bottom {
top: -42px;
left: 50%;
transform: translateX(-50%) rotate(270deg);
@apply absolute py-4 bg-gray-50 border border-gray-400 text-gray-400 rounded-r z-10;
}
/* Forms */
label {
@apply block text-sm font-medium text-gray-700;
@ -137,3 +145,7 @@ tbody tr td:first-child {
.pager-chevron.right {
@apply rounded-r-md -ml-px;
}
body {
min-height: 100vh;
}