Fix nested Flexible Layout direction problem (#7637)

* Closes #7635
- More specific approach to CSS class application for column vs. row layouts.
- Added layout direction CSS classing to `c-fl-container__frames-holder`.
- Switched toolbar icon and titling for better parity with
'toggle' approach used elsewhere.
- Cleaned up duped property def in mixin.

* Addressing PR change requests
- Updated e2e test.
- New computed properties for layout direction.
- CSS code cleanup.

* fix selector in test

* fix more bad selectors

* fix changed title

---------

Co-authored-by: David Tsay <david.e.tsay@nasa.gov>
This commit is contained in:
Charles Hacskaylo 2024-04-18 16:38:11 -07:00 committed by GitHub
parent 5a06b51c5a
commit a961d7e3bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 39 additions and 39 deletions

View File

@ -78,8 +78,8 @@ test.describe('Flexible Layout', () => {
// Expand the 'My Items' folder in the left tree // Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click(); await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
// Add the Sine Wave Generator and Clock to the Flexible Layout // Add the Sine Wave Generator and Clock to the Flexible Layout
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first()); await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl-container.is-empty').first());
await clockTreeItem.dragTo(page.locator('.c-fl__container.is-empty')); await clockTreeItem.dragTo(page.locator('.c-fl-container.is-empty'));
// Check that panes can be dragged while Flexible Layout is in Edit mode // Check that panes can be dragged while Flexible Layout is in Edit mode
let dragWrapper = page let dragWrapper = page
.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper') .locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper')
@ -105,8 +105,8 @@ test.describe('Flexible Layout', () => {
// Expand the 'My Items' folder in the left tree // Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click(); await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
// Add the Sine Wave Generator and Clock to the Flexible Layout // Add the Sine Wave Generator and Clock to the Flexible Layout
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first()); await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl-container.is-empty').first());
await clockTreeItem.dragTo(page.locator('.c-fl__container.is-empty')); await clockTreeItem.dragTo(page.locator('.c-fl-container.is-empty'));
// Click on the first frame to select it // Click on the first frame to select it
await page.locator('.c-fl-container__frame').first().click(); await page.locator('.c-fl-container__frame').first().click();
@ -122,7 +122,7 @@ test.describe('Flexible Layout', () => {
expect(await page.locator('.c-fl--rows').count()).toEqual(0); expect(await page.locator('.c-fl--rows').count()).toEqual(0);
// Change the layout to rows orientation // Change the layout to rows orientation
await page.getByTitle('Columns layout').click(); await page.getByTitle('Switch to rows layout').click();
// Assert the layout is in rows orientation // Assert the layout is in rows orientation
expect(await page.locator('.c-fl--rows').count()).toBeGreaterThan(0); expect(await page.locator('.c-fl--rows').count()).toBeGreaterThan(0);
@ -171,7 +171,7 @@ test.describe('Flexible Layout', () => {
// Expand the 'My Items' folder in the left tree // Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click(); await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
// Add the Sine Wave Generator to the Flexible Layout and save changes // Add the Sine Wave Generator to the Flexible Layout and save changes
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first()); await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl-container.is-empty').first());
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
@ -202,7 +202,7 @@ test.describe('Flexible Layout', () => {
// Expand the 'My Items' folder in the left tree // Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click(); await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
// Add the Sine Wave Generator to the Flexible Layout and save changes // Add the Sine Wave Generator to the Flexible Layout and save changes
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first()); await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl-container.is-empty').first());
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
@ -242,7 +242,7 @@ test.describe('Flexible Layout', () => {
name: new RegExp(exampleImageryObject.name) name: new RegExp(exampleImageryObject.name)
}); });
// Add the Sine Wave Generator to the Flexible Layout and save changes // Add the Sine Wave Generator to the Flexible Layout and save changes
await exampleImageryTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first()); await exampleImageryTreeItem.dragTo(page.locator('.c-fl-container.is-empty').first());
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
@ -309,9 +309,9 @@ test.describe('Flexible Layout Toolbar Actions @localStorage', () => {
await page.getByRole('columnheader', { name: 'Container Handle 1' }).click(); await page.getByRole('columnheader', { name: 'Container Handle 1' }).click();
const flexRows = page.getByLabel('Flexible Layout Row'); const flexRows = page.getByLabel('Flexible Layout Row');
expect(await flexRows.count()).toEqual(0); expect(await flexRows.count()).toEqual(0);
await page.getByTitle('Columns layout').click(); await page.getByTitle('Switch to rows layout').click();
expect(await flexRows.count()).toEqual(1); expect(await flexRows.count()).toEqual(1);
await page.getByTitle('Rows layout').click(); await page.getByTitle('Switch to columns layout').click();
expect(await flexRows.count()).toEqual(0); expect(await flexRows.count()).toEqual(0);
}); });
}); });

View File

@ -265,8 +265,8 @@ test.describe('Verify tooltips', () => {
name: 'Test Flexible Layout' name: 'Test Flexible Layout'
}); });
await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.c-fl__container >> nth=0'); await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.c-fl-container >> nth=0');
await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-fl__container >> nth=1'); await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-fl-container >> nth=1');
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();

View File

@ -45,7 +45,7 @@
@object-drop-to="moveOrCreateNewFrame" @object-drop-to="moveOrCreateNewFrame"
/> />
<div role="row" class="c-fl-container__frames-holder"> <div role="row" class="c-fl-container__frames-holder" :class="flexLayoutCssClass">
<template v-for="(frame, i) in frames" :key="frame.id"> <template v-for="(frame, i) in frames" :key="frame.id">
<frame-component <frame-component
class="c-fl-container__frame" class="c-fl-container__frame"
@ -118,6 +118,9 @@ export default {
}, },
emits: ['new-frame', 'move-frame', 'persist'], emits: ['new-frame', 'move-frame', 'persist'],
computed: { computed: {
flexLayoutCssClass() {
return this.rowsLayout ? '--layout-rows' : '--layout-cols';
},
frames() { frames() {
return this.container.frames; return this.container.frames;
}, },

View File

@ -30,10 +30,8 @@
<div <div
class="c-fl__container-holder u-style-receiver js-style-receiver" class="c-fl__container-holder u-style-receiver js-style-receiver"
:class="{ :class="flexLayoutCssClass"
'c-fl--rows': rowsLayout === true :aria-label="`Flexible Layout ${rowsLayout ? 'Rows' : 'Columns'}`"
}"
:aria-label="`Flexible Layout ${rowsLayout ? 'Row' : 'Column'}`"
> >
<template v-for="(container, index) in containers" :key="`component-${container.id}`"> <template v-for="(container, index) in containers" :key="`component-${container.id}`">
<drop-hint <drop-hint
@ -45,7 +43,6 @@
/> />
<container-component <container-component
class="c-fl__container"
:index="index" :index="index"
:container="container" :container="container"
:rows-layout="rowsLayout" :rows-layout="rowsLayout"
@ -148,15 +145,11 @@ export default {
}; };
}, },
computed: { computed: {
layoutDirectionStr() {
if (this.rowsLayout) {
return 'Rows';
} else {
return 'Columns';
}
},
allContainersAreEmpty() { allContainersAreEmpty() {
return this.containers.every((container) => container.frames.length === 0); return this.containers.every((container) => container.frames.length === 0);
},
flexLayoutCssClass() {
return this.rowsLayout ? 'c-fl--rows' : 'c-fl--cols';
} }
}, },
created() { created() {

View File

@ -7,7 +7,6 @@
$majorOffset: 35%; $majorOffset: 35%;
content: ''; content: '';
display: block; display: block;
position: absolute;
@include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir); @include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir);
@if $dir == 'x' { @if $dir == 'x' {
top: $minorOffset; top: $minorOffset;
@ -35,18 +34,15 @@
flex: 1 1 100%; // Must be 100% to work flex: 1 1 100%; // Must be 100% to work
overflow: auto; overflow: auto;
// Columns by default // Controls layout of c-fl__container(s)
flex-direction: row; &[class*='--cols'] {
> * + * { flex-direction: row;
margin-left: 1px; column-gap: 1px;
} }
&[class*='--rows'] { &[class*='--rows'] {
flex-direction: column; flex-direction: column;
> * + * { row-gap: 1px;
margin-left: 0;
margin-top: 1px;
}
} }
} }
@ -119,10 +115,18 @@
&__frames-holder { &__frames-holder {
display: flex; display: flex;
flex: 1 1 100%; // Must be 100% to work flex: 1 1 100%; // Must be 100% to work
flex-direction: column; // Default flex-direction: row; // Default
align-content: stretch; align-content: stretch;
align-items: stretch; align-items: stretch;
overflow: hidden; // This sucks, but doing in the short-term overflow: hidden; // This sucks, but doing in the short-term
&.--layout-cols {
flex-direction: column !important;
}
&.--layout-rows {
flex-direction: row !important;
}
} }
.is-editing & { .is-editing & {

View File

@ -61,13 +61,13 @@ function ToolbarProvider(openmct) {
options: [ options: [
{ {
value: true, value: true,
icon: 'icon-columns', icon: 'icon-rows',
title: 'Columns layout' title: 'Switch to rows layout'
}, },
{ {
value: false, value: false,
icon: 'icon-rows', icon: 'icon-columns',
title: 'Rows layout' title: 'Switch to columns layout'
} }
] ]
}; };