mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
* fix: restore reactivity of config settings - move initialization steps to `created()` hook - remove unnecessary `:key` binds - fix comments * refactor: clean up * refactor: clean up * refactor: lint:fix * test(e2e): add regression test and cleanup suite * refactor: consistency is key! * test(fix): fix unit tests, further cleanup
This commit is contained in:
parent
82b1760b0e
commit
6c92e31036
@ -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' });
|
||||
|
||||
@ -41,23 +45,27 @@ test.describe('Flexible Layout', () => {
|
||||
clockObject = await createDomainObjectWithDefaults(page, {
|
||||
type: 'Clock'
|
||||
});
|
||||
|
||||
// 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'
|
||||
});
|
||||
sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(sineWaveObject.name)
|
||||
});
|
||||
clockTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(clockObject.name)
|
||||
});
|
||||
});
|
||||
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({
|
||||
page
|
||||
}) => {
|
||||
const treePane = page.getByRole('tree', {
|
||||
name: 'Main Tree'
|
||||
});
|
||||
const sineWaveGeneratorTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(sineWaveObject.name)
|
||||
});
|
||||
const clockTreeItem = treePane.getByRole('treeitem', {
|
||||
name: new RegExp(clockObject.name)
|
||||
});
|
||||
// Create a Flexible Layout
|
||||
await createDomainObjectWithDefaults(page, {
|
||||
type: 'Flexible Layout'
|
||||
});
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
|
||||
@ -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('changing toolbar settings in edit mode is immediately reflected and persists upon save', async ({
|
||||
page
|
||||
}) => {
|
||||
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
|
||||
}) => {
|
||||
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'
|
||||
});
|
||||
await page.goto(flexibleLayout.url);
|
||||
// Edit Flexible Layout
|
||||
await page.locator('[title="Edit"]').click();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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)
|
||||
});
|
||||
|
@ -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"
|
||||
@ -37,7 +37,7 @@
|
||||
:layout-font-size="item.fontSize"
|
||||
:layout-font="item.font"
|
||||
/>
|
||||
</layout-frame>
|
||||
</LayoutFrame>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -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"
|
||||
@ -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"
|
||||
@ -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"
|
||||
@ -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: {
|
||||
@ -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);
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -75,7 +74,7 @@ export default class FlexibleLayoutViewProvider {
|
||||
component = vNode.componentInstance;
|
||||
_destroy = destroy;
|
||||
},
|
||||
getSelectionContext: function () {
|
||||
getSelectionContext() {
|
||||
return {
|
||||
item: domainObject,
|
||||
addContainer: component.$refs.flexibleLayout.addContainer,
|
||||
@ -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;
|
||||
|
@ -33,6 +33,10 @@ describe('the plugin', function () {
|
||||
let mockComposition;
|
||||
|
||||
const testViewObject = {
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'test-object'
|
||||
},
|
||||
id: 'test-object',
|
||||
type: 'flexible-layout',
|
||||
configuration: {
|
||||
@ -116,6 +120,10 @@ describe('the plugin', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
flexibleLayoutItem = {
|
||||
identifier: {
|
||||
namespace: '',
|
||||
key: 'test-object'
|
||||
},
|
||||
id: 'test-object',
|
||||
type: 'flexible-layout',
|
||||
configuration: {
|
||||
|
Loading…
Reference in New Issue
Block a user