Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2137 Resize Right Flyout using drag #2224

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
24fc35e
#2137 Resize Right Flyout using drag
srikant-ch5 Oct 24, 2024
4672b3d
Fix eslint
srikant-ch5 Oct 24, 2024
b960ffe
Enable resize using drag and change classname in properties-main - reset
srikant-ch5 Oct 25, 2024
c186d1a
Resolve toolbar move issue in cc right flyout
srikant-ch5 Oct 25, 2024
26c4ca5
Include right flyout width in redux
srikant-ch5 Oct 25, 2024
c3fce9e
Fix lint issue
srikant-ch5 Oct 25, 2024
56c93d1
Merge branch 'main' into resize-rightflyout
srikant-ch5 Oct 30, 2024
9a0e490
Update Right Flyout logic as per Bottom Panel
srikant-ch5 Nov 6, 2024
7ca8ccd
Merge branch 'main' into resize-rightflyout
srikant-ch5 Nov 6, 2024
004c49f
Reset Right Flyout Min width and Default width to 320
srikant-ch5 Nov 6, 2024
0071ea1
Split bottom-panel test to test with rightFlyout open
srikant-ch5 Nov 6, 2024
216f59d
Merge branch 'main' into resize-rightflyout
srikant-ch5 Nov 7, 2024
2da678d
Add Cypress Tests for Right Flyout Drag
srikant-ch5 Nov 7, 2024
ba94e30
Include isRightFlyoutOpen condition in panels
srikant-ch5 Nov 7, 2024
09bb046
Fix Rightflyout failing jest test case
srikant-ch5 Nov 7, 2024
7b16e8b
move css code of right-flyout-panel
srikant-ch5 Nov 7, 2024
e757c09
Merge branch 'main' into resize-rightflyout
srikant-ch5 Nov 8, 2024
c381e6c
Include Right Flyout Drag Feature Flag
srikant-ch5 Nov 8, 2024
d92e6db
Include force true in moveRightFlyoutDivider to resolve build test ca…
srikant-ch5 Nov 8, 2024
f31a076
Include Feature flag description in docs and include a function for e…
srikant-ch5 Nov 11, 2024
eea68de
Merge branch 'main' into resize-rightflyout
srikant-ch5 Nov 11, 2024
7268860
Include a comment in change in common-canvas-test.js for showRightFly…
srikant-ch5 Nov 11, 2024
60a9f5d
Update wdth to wd, include default value for right flyout as 0 and mi…
srikant-ch5 Nov 12, 2024
e4b80c6
Fix right-flyout functional test for default width=0
srikant-ch5 Nov 12, 2024
6336f85
Update naming and minor changes
srikant-ch5 Nov 12, 2024
13024aa
Update naming to rightFlyoutIsOpen
srikant-ch5 Nov 12, 2024
536d6fc
Hide Resize button if the flyout is dragged
srikant-ch5 Nov 15, 2024
4dcabc9
Merge remote-tracking branch 'upstream/main' into resize-rightflyout
srikant-ch5 Nov 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ describe("CommonCanvas renders correctly", () => {
const config = {};
const canvasParams = { showRightFlyout: false };
const wrapper = createCommonCanvas(config, canvasController, canvasParams);
expect(wrapper.find(CommonCanvasRightFlyout)).to.have.length(1);
// When showRightFlyout is false then Right Flyout should not be visible
expect(wrapper.find(CommonCanvasRightFlyout)).to.have.length(0);
expect(canvasController.isRightFlyoutOpen() === false).to.be.true;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,10 @@ export default class CanvasController {
this.objectModel.setBottomPanelHeight(ht);
}

setRightPanelWidth(wdth) {
this.objectModel.setRightPanelWidth(wdth);
}
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved

isTopPanelOpen() {
return this.getObjectModel().isTopPanelOpen();
}
Expand Down
9 changes: 8 additions & 1 deletion canvas_modules/common-canvas/src/common-canvas/cc-panels.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class CommonCanvasPanels extends React.Component {
return false;
}

// Returns true if the right flyout should be displayed.
isRightPanelOpen() {
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
return this.props.rightFlyoutIsOpen;
}

// Returns a JSX object for the contents of the left panel. If the application
// sets enablePaletteLayout to None this indicates the app wamts its own content
// to go into the left panel provided by leftFlyoutContent provided to <CommonCanvas>
Expand All @@ -138,7 +143,8 @@ class CommonCanvasPanels extends React.Component {
containingDivId={this.props.containingDivId}
/>
);
const rightFlyout = (<CommonCanvasRightFlyout />);
const rightFlyoutOpen = this.isRightPanelOpen();
const rightFlyout = rightFlyoutOpen ? (<CommonCanvasRightFlyout containingDivId={this.props.containingDivId} canvasController={this.props.canvasController} />) : null;
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
const leftFlyoutIsOpen = this.isLeftPanelOpen();
const leftFlyout = leftFlyoutIsOpen ? this.generateLeftFlyout() : null;

Expand Down Expand Up @@ -288,6 +294,7 @@ const mapStateToProps = (state, ownProps) => ({
enableNarrowPalette: state.canvasconfig.enableNarrowPalette,
enableLeftFlyoutUnderToolbar: state.canvasconfig.enableLeftFlyoutUnderToolbar,
enableRightFlyoutUnderToolbar: state.canvasconfig.enableRightFlyoutUnderToolbar,
enableRightFlyoutDragToResize: state.canvasconfig.enableRightFlyoutDragToResize,
toolbarIsOpen: (state.canvasconfig.enableToolbarLayout !== PALETTE_LAYOUT_NONE),
paletteIsOpen: state.palette.isOpen,
topPanelIsOpen: state.toppanel.isOpen,
Expand Down
82 changes: 78 additions & 4 deletions canvas_modules/common-canvas/src/common-canvas/cc-right-flyout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,90 @@ import { connect } from "react-redux";
import PropTypes from "prop-types";
import Logger from "../logging/canvas-logger.js";

const MAX_WIDTH_EXTEND_PERCENT = 0.7; // Should cover atmost 70% of available width
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
const MIN_WIDTH = 300;
class CommonCanvasRightFlyout extends React.Component {
constructor(props) {
super(props);

this.logger = new Logger("CC-RightFlyout");

this.onMouseUp = this.onMouseUp.bind(this);
this.onMouseDown = this.onMouseDown.bind(this);
this.onMouseMoveX = this.onMouseMoveX.bind(this);

this.getRightFlyoutResizeContent = this.getRightFlyoutResizeContent.bind(this);
}

onMouseDown(e) {
if (e.button === 0) {
document.addEventListener("mousemove", this.onMouseMoveX, true);
document.addEventListener("mouseup", this.onMouseUp, true);
this.posX = e.clientX;
// Prevent panel contents being dragged in the test harness (which can
// happen even though draggable is false for the contents!)
e.preventDefault();
}
}

onMouseUp() {
document.removeEventListener("mousemove", this.onMouseMoveX, true);
document.removeEventListener("mouseup", this.onMouseUp, true);
}

onMouseMoveX(e) {
if (e.clientX) {
const diff = e.clientX - this.posX;
const wth = this.props.panelWidth - diff;
this.props.canvasController.setRightPanelWidth(this.limitWidth(wth));
this.posX = e.clientX;
}
}

// Returns content to enable/disable resize based on feature flag.
getRightFlyoutResizeContent() {
let resizeContent = null;

if (this.props.enableRightFlyoutDragToResize) {
resizeContent = (<div className="right-flyout-drag" onMouseDown={this.onMouseDown} />);
}

return resizeContent;
}

// Returns a new width for right panel limited by the need to enforce
// a minimum and maximum width
limitWidth(wth) {
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
const canvasContainer = document.getElementById(this.props.containingDivId);
let width = wth;

if (canvasContainer) {
// Max Width should be 70% of the total available width (canvas + rightflyout)
const canvasWidth = canvasContainer.getBoundingClientRect().width;
const maxWidth = (canvasWidth + this.props.panelWidth) * MAX_WIDTH_EXTEND_PERCENT;
width = Math.min(Math.max(width, MIN_WIDTH), maxWidth);
}

return width;
}

render() {
this.logger.log("render");

tomlyn marked this conversation as resolved.
Show resolved Hide resolved
let rightFlyout = <div />; // For no content, return empty <div> so grid siziing for parent <div> work correctly.
const rightFlyoutDragContent = this.getRightFlyoutResizeContent();

if (this.props.content && this.props.isOpen) {
const widthPx = this.limitWidth(this.props.panelWidth) + "px";
const rfClass = this.props.enableRightFlyoutUnderToolbar
? "right-flyout-panel under-toolbar"
: "right-flyout-panel";
rightFlyout = (
<div className={rfClass}>
{this.props.content}
<div className="right-flyout-container" style={{ width: widthPx }} >
{rightFlyoutDragContent}
<div className={rfClass}>
{this.props.content}
</div>
</div>
);
}
Expand All @@ -46,16 +112,24 @@ class CommonCanvasRightFlyout extends React.Component {
}

CommonCanvasRightFlyout.propTypes = {
// Provided by Common Canvas
canvasController: PropTypes.object,
containingDivId: PropTypes.string,

// Provided by Redux
isOpen: PropTypes.bool,
content: PropTypes.object,
enableRightFlyoutUnderToolbar: PropTypes.bool
enableRightFlyoutUnderToolbar: PropTypes.bool,
enableRightFlyoutDragToResize: PropTypes.bool,
panelWidth: PropTypes.number
};

const mapStateToProps = (state, ownProps) => ({
isOpen: state.rightflyout.isOpen,
content: state.rightflyout.content,
enableRightFlyoutUnderToolbar: state.canvasconfig.enableRightFlyoutUnderToolbar
enableRightFlyoutUnderToolbar: state.canvasconfig.enableRightFlyoutUnderToolbar,
enableRightFlyoutDragToResize: state.canvasconfig.enableRightFlyoutDragToResize,
panelWidth: state.rightflyout.panelWidth
});

export default connect(mapStateToProps)(CommonCanvasRightFlyout);
25 changes: 25 additions & 0 deletions canvas_modules/common-canvas/src/common-canvas/common-canvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,43 @@ $panel-border-color: $border-subtle-01;
position: relative; // This allows the State Tag to have positio: absolute
}

.right-flyout-container {
display: flex;
border-left: $panel-border-width solid $panel-border-color;
min-height: fit-content;
min-width: fit-content;
}

.left-flyout-panel,
.right-flyout-panel {
// This combination of height and min-height enable scrolling in the child panel,
// I believe this is because it sets a specific height on the CSS grid cell,
// so the contents of the panel can adjust themselves to the height accordingly.
height: 0;
min-height: 100%;
}

// Allow content in child to expand on drag using flex
.right-flyout-panel {
min-width: fit-content;
display: flex;
flex: 1;
user-select: none; /* Prevent elements from being selectable */
background-color: $layer-01;
}

.right-flyout-drag {
cursor: ew-resize;
flex: 0 0 0.5px;
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
border: $panel-border-color;
background: $layer-01;
transition: all 0.2s ease-in;
&:hover {
flex: 0 0 $spacing-01;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for - is it necessary? I took it out and the right flyout seems to size OK. If this is needed to get Common Properties to display correctly? If so it ought to be part of the Common Properties CSS, not here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated above to include spacing-01 in right-flyout-drag.

But the problem with above spacing is that when a common properties Accordion is highlighted on click there is a small gap between right flyout left border and common properties.
Screenshot 2024-11-12 at 10 15 53 PM

I tried to resolve this using common properties css but this is visible in canvas so initially I set the width to 0.5px so that the gap isn't visible and on hover it will take up 1px width to match with bottom panel, but I have reverted it now and kept spacing-01 for the right-flyout-drag.

Screen.Recording.2024-11-12.at.10.42.51.PM.mov

Copy link
Member

@tomlyn tomlyn Nov 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are concerned about the visual appearance of the UI after you've implemented a change you should be asking @Analuisa-Del-Rivero1 for her decision on how she wants it to appear. Unfortunately your video doesn't show what it looks like with the accordion highlighting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW It's probably best to ask question to Ana in the issue to keep all the design information discussion together in one place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you could do a video (or two?) that shows both approaches and what the accordion looks like in each case and explain to her about the difficulty in hovering over the drag area ... and see what she decides.

background: $button-tertiary;
}
}

.bottom-panel {
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import TitleEditor from "./../components/title-editor";
import classNames from "classnames";

import { injectIntl } from "react-intl";
import styles from "./properties-main-widths.scss";
import styles from "./properties-main-widths.module.scss";

const FLYOUT_WIDTH_SMALL = parseInt(styles.flyoutWidthSmall, 10);
const FLYOUT_WIDTH_MEDIUM = parseInt(styles.flyoutWidthMedium, 10);
Expand All @@ -53,6 +53,12 @@ class PropertiesMain extends React.Component {
if (this.props.propertiesInfo.initialEditorSize) {
this.propertiesController.setEditorSize(this.props.propertiesInfo.initialEditorSize);
}
this.flyoutWidth = {
small: FLYOUT_WIDTH_SMALL,
medium: FLYOUT_WIDTH_MEDIUM,
large: FLYOUT_WIDTH_LARGE,
max: FLYOUT_WIDTH_MAX
};
this.propertiesController.setCustomControls(props.customControls);
this.propertiesController.setConditionOps(props.customConditionOps);
this.propertiesController.setLight(props.light);
Expand Down Expand Up @@ -96,6 +102,7 @@ class PropertiesMain extends React.Component {
this._getResizeButton = this._getResizeButton.bind(this);
this._isResizeButtonRequired = this._isResizeButtonRequired.bind(this);
this.onBlur = this.onBlur.bind(this);
this.updateRightFlyoutWidth = this.updateRightFlyoutWidth.bind(this);
}

componentDidMount() {
Expand Down Expand Up @@ -420,11 +427,19 @@ class PropertiesMain extends React.Component {
this.setState({ showPropertiesButtons: state });
}

updateRightFlyoutWidth(size) {
const element = document.querySelector(".common-canvas .right-flyout-container");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is creating a dependency from Common Properties on Common Canvas. You could discuss with @matthoward366 @nmgokhale and @caritaou but I don't think we should be doing that. Common Properties and Common Canvas should remained decoupled, so each can always be used independently of the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmgokhale Would appreciate your feedback on above I can see similar common properties dependancy on common canvas over here

Without enforcing width to right-flyout in properties it will look something like below, where the properties content width is set as per custom classnames but flyout width is not reset.

Screenshot 2024-11-12 at 10 52 49 PM

if (element) {
element.style.width = `${this.flyoutWidth[size]}px`;
}
}

updateEditorSize(newEditorSize) {
this.setState({
editorSize: newEditorSize
});
this.propertiesController.setEditorSize(newEditorSize);
this.updateRightFlyoutWidth(newEditorSize);
}

resize() {
Expand Down Expand Up @@ -589,21 +604,24 @@ class PropertiesMain extends React.Component {
"properties-light-disabled": !this.props.light
},
propertiesSizeClassname);

return (
<Provider store={this.propertiesController.getStore()}>
<aside
aria-label={PropertyUtils.formatMessage(this.props.intl, MESSAGE_KEYS.PROPERTIES_LABEL, { label: propertiesLabel })}
role="complementary"
ref={ (ref) => (this.commonProperties = ref) }
className={className}
onBlur={this.onBlur}
style={overrideStyle}
>
{propertiesTitle}
{propertiesDialog}
{buttonsContainer}
</aside>
{resizeBtn}
<div className="properties-right-flyout-container">
<aside
aria-label={PropertyUtils.formatMessage(this.props.intl, MESSAGE_KEYS.PROPERTIES_LABEL, { label: propertiesLabel })}
role="complementary"
ref={ (ref) => (this.commonProperties = ref) }
className={className}
onBlur={this.onBlur}
style={overrideStyle}
>
{propertiesTitle}
{propertiesDialog}
{buttonsContainer}
</aside>
{resizeBtn}
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
</div>
</Provider>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@
* limitations under the License.
*/

@import "./properties-main-widths.scss";
@import "./properties-main-widths.module.scss";
$properties-modal-buttons-height: $spacing-10;
$properties-resize-button-size: $spacing-06;

.properties-right-flyout-container {
display: flex;
flex: 1;
flex-direction: column;
}

.properties-right-flyout {
// Set the font explicitly to 14px to shrink them across the entire properties editor
display: flex;
min-width: 100%;
min-height: 100%;
flex: 1;
font-size: 14px;
width: 0;
height: 100%;
overflow: hidden;
border-left: 1px solid $layer-accent-01;
outline: none;
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export default class ConfigUtils {
enableDropZoneOnExternalDrag: false,
enableLeftFlyoutUnderToolbar: false,
enableRightFlyoutUnderToolbar: false,
enableRightFlyoutDragToResize: false,
enablePanIntoViewOnOpen: false,
enableZoomIntoSubFlows: false,
enableBrowserEditMenu: true,
Expand Down
4 changes: 4 additions & 0 deletions canvas_modules/common-canvas/src/object-model/object-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,10 @@ export default class ObjectModel {
return this.store.isRightFlyoutOpen();
}

setRightPanelWidth(wdth) {
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
srikant-ch5 marked this conversation as resolved.
Show resolved Hide resolved
this.store.dispatch({ type: "SET_RIGHT_FLYOUT_CONFIG", data: { config: { panelWidth: wdth } } });
}

// ---------------------------------------------------------------------------
// Bottom panel methods
// ---------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class CanavasStore {
texttoolbar: { isOpen: false },
contextmenu: { isOpen: false, menuDef: [], source: {} },
leftflyout: {},
rightflyout: {},
rightflyout: { panelWidth: 300 },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR we didn't have a default width -- right? So the behavior was that the right-flyout panel would size to fit the content of the JSX the app placed into it. I don't think we can change that behavior because we will upset existing applications that are using the right-flyout.

For example, the Flows sample application has a behavior where right-flyout is opened when the user double clicks on a node. However with your PR the right-flyout is visible (but empty) with its default width even before the user double clicks a node. Like this:

image

I believe this is because Common Properties is deciding whether it is open or closed. When closed it is returning an empty (null) JSX. Previously, this would have caused Common Canvas to add an empty <div> for the right-flyout to the DOM however your PR is now adding the <div> which is empty but with a default width of 300.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have updated this to rightflyout: { panelWidth: 0 } would that be ok because in cc-right-flyout it is causing issue without default width set in store.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current right-flyout behavior allows an application to add some content into the right-flyout and it stretches to accommodate that content. (Remember applications can put whatever content they like into the right-flyout. They don't necessarily have to put Common Properties in there.)

So we need to make sure that function still works. Does that still work if we set the size to 0?

bottompanel: { panelHeight: 393 },
toppanel: { }
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ export default (state = {}, action) => {
switch (action.type) {
case "SET_RIGHT_FLYOUT_CONFIG": {
if (action.data.config) {
return {
content: action.data.config.content,
isOpen: action.data.config.isOpen };
return Object.assign({}, state, action.data.config);
}
return state;
}
Expand Down
2 changes: 2 additions & 0 deletions canvas_modules/harness/cypress/e2e/canvas/bottom-panel.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ describe("Testing bottom panel", function() {
// Test bottom panel does not exceed max-size successfully
cy.moveBottomPanelDivider(50);
cy.verifyBottomPanelHeight(650);
});

it("Testing bottom panel max height with rightFlyout open", function() {
// Test bottom panel does not exceed max-size successfully with the right flyout open
cy.setCanvasConfig({ "selectedShowRightFlyout": true });
cy.moveBottomPanelDivider(50);
Expand Down
Loading