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

fix(#6942): Toggling FlexibleLayout toolbar options reflects immediately in the view #6943

Merged
merged 8 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
134 changes: 93 additions & 41 deletions e2e/tests/functional/plugins/flexibleLayout/flexibleLayout.e2e.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const {
test.describe('Flexible Layout', () => {
let sineWaveObject;
let clockObject;
let treePane;
let sineWaveGeneratorTreeItem;
let clockTreeItem;
let flexibleLayout;
test.beforeEach(async ({ page }) => {
await page.goto('./', { waitUntil: 'domcontentloaded' });

Expand All @@ -41,23 +45,27 @@ test.describe('Flexible Layout', () => {
clockObject = await createDomainObjectWithDefaults(page, {
type: 'Clock'
});
});
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({
page
}) => {
const treePane = page.getByRole('tree', {

// Create a Flexible Layout
flexibleLayout = await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout'
});

// Define the Sine Wave Generator and Clock tree items
treePane = page.getByRole('tree', {
name: 'Main Tree'
});
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
name: new RegExp(sineWaveObject.name)
});
const clockTreeItem = treePane.getByRole('treeitem', {
clockTreeItem = treePane.getByRole('treeitem', {
name: new RegExp(clockObject.name)
});
// Create a Flexible Layout
await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout'
});
});
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({
page
}) => {
await page.goto(flexibleLayout.url);
// Edit Flexible Layout
await page.locator('[title="Edit"]').click();

Expand All @@ -78,19 +86,79 @@ test.describe('Flexible Layout', () => {
dragWrapper = page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
await expect(dragWrapper).toHaveAttribute('draggable', 'false');
});
test('items in a flexible layout can be removed with object tree context menu when viewing the flexible layout', async ({
test('changing toolbar settings in edit mode is immediately reflected and persists upon save', async ({
page
}) => {
const treePane = page.getByRole('tree', {
name: 'Main Tree'
});
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
name: new RegExp(sineWaveObject.name)
});
// Create a Display Layout
await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout'
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/6942'
});

await page.goto(flexibleLayout.url);

// Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
// Add the Sine Wave Generator and Clock to the Flexible Layout
await sineWaveGeneratorTreeItem.dragTo(page.locator('.c-fl__container.is-empty').first());
await clockTreeItem.dragTo(page.locator('.c-fl__container.is-empty'));

// Click on the first frame to select it
await page.locator('.c-fl-container__frame').first().click();
await expect(page.locator('.c-fl-container__frame > .c-frame').first()).toHaveAttribute(
's-selected',
''
);

// Assert the toolbar is visible
await expect(page.locator('.c-toolbar')).toBeInViewport();

// Assert the layout is in columns orientation
expect(await page.locator('.c-fl--rows').count()).toEqual(0);

// Change the layout to rows orientation
await page.getByTitle('Columns layout').click();

// Assert the layout is in rows orientation
expect(await page.locator('.c-fl--rows').count()).toBeGreaterThan(0);

// Assert the frame of the first item is visible
await expect(page.locator('.c-so-view').first()).not.toHaveClass(/c-so-view--no-frame/);

// Hide the frame of the first item
await page.getByTitle('Frame visible').click();

// Assert the frame is hidden
await expect(page.locator('.c-so-view').first()).toHaveClass(/c-so-view--no-frame/);

// Assert there are 2 containers
expect(await page.locator('.c-fl-container').count()).toEqual(2);

// Add a container
await page.getByTitle('Add Container').click();

// Assert there are 3 containers
expect(await page.locator('.c-fl-container').count()).toEqual(3);

// Save Flexible Layout
await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();

// Nav away and back
await page.goto(sineWaveObject.url);
await page.goto(flexibleLayout.url);

// Wait for the first frame to be visible so we know the layout has loaded
await expect(page.locator('.c-fl-container').nth(0)).toBeInViewport();

// Assert the settings have persisted
expect(await page.locator('.c-fl-container').count()).toEqual(3);
expect(await page.locator('.c-fl--rows').count()).toBeGreaterThan(0);
await expect(page.locator('.c-so-view').first()).toHaveClass(/c-so-view--no-frame/);
});
test('items in a flexible layout can be removed with object tree context menu when viewing the flexible layout', async ({
page
}) => {
await page.goto(flexibleLayout.url);
// Edit Flexible Layout
await page.locator('[title="Edit"]').click();

Expand Down Expand Up @@ -121,17 +189,7 @@ test.describe('Flexible Layout', () => {
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/3117'
});
const treePane = page.getByRole('tree', {
name: 'Main Tree'
});
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
name: new RegExp(sineWaveObject.name)
});

// Create a Flexible Layout
const flexibleLayout = await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout'
});
await page.goto(flexibleLayout.url);
// Edit Flexible Layout
await page.locator('[title="Edit"]').click();

Expand Down Expand Up @@ -167,19 +225,13 @@ test.describe('Flexible Layout', () => {
const exampleImageryObject = await createDomainObjectWithDefaults(page, {
type: 'Example Imagery'
});
// Create a Flexible Layout
await createDomainObjectWithDefaults(page, {
type: 'Flexible Layout'
});
// Edit Display Layout

await page.goto(flexibleLayout.url);
// Edit Flexible Layout
await page.locator('[title="Edit"]').click();

// Expand the 'My Items' folder in the left tree
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').click();
// Add the Sine Wave Generator to the Flexible Layout and save changes
const treePane = page.getByRole('tree', {
name: 'Main Tree'
});
const exampleImageryTreeItem = treePane.getByRole('treeitem', {
name: new RegExp(exampleImageryObject.name)
});
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/displayLayout/components/SubobjectView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
at runtime from the About dialog for additional information.
-->
<template>
<layout-frame
<LayoutFrame
:item="item"
:grid-size="gridSize"
:is-editing="isEditing"
@move="(gridDelta) => $emit('move', gridDelta)"
@endMove="() => $emit('endMove')"
>
<object-frame
<ObjectFrame
v-if="domainObject"
ref="objectFrame"
:domain-object="domainObject"
Expand All @@ -37,7 +37,7 @@
:layout-font-size="item.fontSize"
:layout-font="item.font"
/>
</layout-frame>
</LayoutFrame>
</template>

<script>
Expand Down
36 changes: 15 additions & 21 deletions src/plugins/flexibleLayout/components/flexibleLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
<template v-for="(container, index) in containers" :key="`component-${container.id}`">
<drop-hint
v-if="index === 0 && containers.length > 1"
:key="`hint-top-${container.id}`"
class="c-fl-frame__drop-hint"
:index="-1"
:allow-drop="allowContainerDrop"
Expand All @@ -59,7 +58,6 @@

<resize-handle
v-if="index !== containers.length - 1"
:key="`handle-${container.id}`"
:index="index"
:orientation="rowsLayout ? 'vertical' : 'horizontal'"
:is-editing="isEditing"
Expand All @@ -70,7 +68,6 @@

<drop-hint
v-if="containers.length > 1"
:key="`hint-bottom-${container.id}`"
class="c-fl-frame__drop-hint"
:index="index"
:allow-drop="allowContainerDrop"
Expand Down Expand Up @@ -137,15 +134,16 @@ export default {
ResizeHandle,
DropHint
},
inject: ['openmct', 'objectPath', 'layoutObject'],
inject: ['openmct', 'objectPath', 'domainObject'],
props: {
isEditing: Boolean
},
data() {
return {
domainObject: this.layoutObject,
newFrameLocation: [],
identifierMap: {}
identifierMap: {},
containers: this.domainObject.configuration.containers,
rowsLayout: this.domainObject.configuration.rowsLayout
};
},
computed: {
Expand All @@ -156,22 +154,22 @@ export default {
return 'Columns';
}
},
containers() {
return this.domainObject.configuration.containers;
},
rowsLayout() {
return this.domainObject.configuration.rowsLayout;
},
allContainersAreEmpty() {
return this.containers.every((container) => container.frames.length === 0);
}
},
mounted() {
created() {
this.buildIdentifierMap();
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('remove', this.removeChildObject);
this.composition.on('add', this.addFrame);
this.composition.load();
this.openmct.objects.observe(this.domainObject, 'configuration.containers', (containers) => {
this.containers = containers;
});
this.openmct.objects.observe(this.domainObject, 'configuration.rowsLayout', (rowsLayout) => {
this.rowsLayout = rowsLayout;
});
},
beforeUnmount() {
this.composition.off('remove', this.removeChildObject);
Expand Down Expand Up @@ -211,20 +209,16 @@ export default {
let container = this.containers.filter((c) => c.id === containerId)[0];
let containerIndex = this.containers.indexOf(container);

/*
remove associated domainObjects from composition
*/
// remove associated domainObjects from composition
container.frames.forEach((f) => {
this.removeFromComposition(f.domainObjectIdentifier);
});

this.containers.splice(containerIndex, 1);

/*
add a container when there are no containers in the FL,
to prevent user from not being able to add a frame via
drag and drop.
*/
// add a container when there are no containers in the FL,
// to prevent user from not being able to add a frame via
// drag and drop.
if (this.containers.length === 0) {
this.containers.push(new Container(100));
}
Expand Down
13 changes: 6 additions & 7 deletions src/plugins/flexibleLayout/flexibleLayoutViewProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,16 @@ export default class FlexibleLayoutViewProvider {
let component = null;

return {
show: function (element, isEditing) {
show(element, isEditing) {
const { vNode, destroy } = mount(
{
el: element,
components: {
FlexibleLayoutComponent
},
provide: {
openmct: openmct,
openmct,
objectPath,
layoutObject: domainObject
domainObject
},
data() {
return {
Expand All @@ -75,7 +74,7 @@ export default class FlexibleLayoutViewProvider {
component = vNode.componentInstance;
_destroy = destroy;
},
getSelectionContext: function () {
getSelectionContext() {
return {
item: domainObject,
addContainer: component.$refs.flexibleLayout.addContainer,
Expand All @@ -84,10 +83,10 @@ export default class FlexibleLayoutViewProvider {
type: 'flexible-layout'
};
},
onEditModeChange: function (isEditing) {
onEditModeChange(isEditing) {
component.isEditing = isEditing;
},
destroy: function (element) {
destroy() {
if (_destroy) {
_destroy();
component = null;
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/flexibleLayout/pluginSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ describe('the plugin', function () {
let mockComposition;

const testViewObject = {
identifier: {
namespace: '',
key: 'test-object'
},
id: 'test-object',
type: 'flexible-layout',
configuration: {
Expand Down Expand Up @@ -116,6 +120,10 @@ describe('the plugin', function () {

beforeEach(() => {
flexibleLayoutItem = {
identifier: {
namespace: '',
key: 'test-object'
},
id: 'test-object',
type: 'flexible-layout',
configuration: {
Expand Down