mirror of
https://github.com/nasa/openmct.git
synced 2025-01-30 08:04:03 +00:00
[Mobile] Center Confirmation Dialog Texts (#7492)
* Make overlay messages centered * Fix changes so that only dialogs and not forms are affected * Fix buttons such that they are right-aligned * Reduce to one worker for stability * Add test to cover new capabilities * lint fixes * Closes #7343 - Fixed an oversight that caused the top of form dialogs to be scrolled out of view by default. - Fixed approach to vertical centering for `-fit` type confirmation dialogs. - Reduced size of confirmation dialog icons. - Smoke tested in Chrome mobile emulator in a large variety of mobile viewport sizes and orientations. * Closes #7343 - Removes extra margin unintentionally added to `l-overlay-large`. --------- Co-authored-by: John Hill <john.c.hill@nasa.gov> Co-authored-by: Charles Hacskaylo <charles.f.hacskaylo@nasa.gov>
This commit is contained in:
parent
e449fd0eda
commit
73eead6b72
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import { devices } from '@playwright/test';
|
import { devices } from '@playwright/test';
|
||||||
const MAX_FAILURES = 5;
|
const MAX_FAILURES = 5;
|
||||||
const NUM_WORKERS = 2;
|
|
||||||
|
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
@ -20,7 +19,8 @@ const config = {
|
|||||||
reuseExistingServer: true //This was originally disabled to prevent differences in local debugging vs. CI. However, it significantly speeds up local debugging.
|
reuseExistingServer: true //This was originally disabled to prevent differences in local debugging vs. CI. However, it significantly speeds up local debugging.
|
||||||
},
|
},
|
||||||
maxFailures: MAX_FAILURES, //Limits failures to 5 to reduce CI Waste
|
maxFailures: MAX_FAILURES, //Limits failures to 5 to reduce CI Waste
|
||||||
workers: NUM_WORKERS, //Limit to 2 for CircleCI Agent
|
workers: 1, //Limit to 1 due to resource constraints similar to https://github.com/percy/cli/discussions/1067
|
||||||
|
|
||||||
use: {
|
use: {
|
||||||
baseURL: 'http://localhost:8080/',
|
baseURL: 'http://localhost:8080/',
|
||||||
headless: true,
|
headless: true,
|
||||||
|
@ -34,20 +34,16 @@ Make no assumptions about the order that elements appear in the DOM.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { expect, test } from '../../pluginFixtures.js';
|
import { expect, test } from '../../pluginFixtures.js';
|
||||||
|
|
||||||
test('Verify that My Items Tree appears @mobile', async ({ page, openmctConfig }) => {
|
test('Verify that My Items Tree appears @mobile', async ({ page, openmctConfig }) => {
|
||||||
const { myItemsFolderName } = openmctConfig;
|
const { myItemsFolderName } = openmctConfig;
|
||||||
//Go to baseURL
|
//Go to baseURL
|
||||||
await page.goto('./');
|
await page.goto('./');
|
||||||
|
|
||||||
//My Items to be visible
|
//My Items to be visible
|
||||||
await expect(page.getByRole('treeitem', { name: `${myItemsFolderName}` })).toBeVisible();
|
await expect(page.getByRole('treeitem', { name: `${myItemsFolderName}` })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Verify that user can search @mobile', async ({ page }) => {
|
test('Verify that user can search @mobile', async ({ page }) => {
|
||||||
//For now, this test is going to be hardcoded against './test-data/display_layout_with_child_layouts.json'
|
//For now, this test is going to be hardcoded against './test-data/display_layout_with_child_layouts.json'
|
||||||
await page.goto('./');
|
await page.goto('./');
|
||||||
|
|
||||||
await page.getByRole('searchbox', { name: 'Search Input' }).click();
|
await page.getByRole('searchbox', { name: 'Search Input' }).click();
|
||||||
await page.getByRole('searchbox', { name: 'Search Input' }).fill('Parent Display Layout');
|
await page.getByRole('searchbox', { name: 'Search Input' }).fill('Parent Display Layout');
|
||||||
//Search Results appear in search modal
|
//Search Results appear in search modal
|
||||||
@ -57,3 +53,23 @@ test('Verify that user can search @mobile', async ({ page }) => {
|
|||||||
await page.getByTitle('Collapse Browse Pane').click();
|
await page.getByTitle('Collapse Browse Pane').click();
|
||||||
await expect(page.getByRole('main').getByText('Parent Display Layout')).toBeVisible();
|
await expect(page.getByRole('main').getByText('Parent Display Layout')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
test('Remove Object and confirmation dialog @mobile', async ({ page }) => {
|
||||||
|
await page.goto('./');
|
||||||
|
await page.getByRole('searchbox', { name: 'Search Input' }).click();
|
||||||
|
await page.getByRole('searchbox', { name: 'Search Input' }).fill('Parent Display Layout');
|
||||||
|
//Search Results appear in search modal
|
||||||
|
//Clicking on the search result takes you to the object
|
||||||
|
await page.getByLabel('Object Results').getByText('Parent Display Layout').click();
|
||||||
|
await page.getByTitle('Collapse Browse Pane').click();
|
||||||
|
await expect(page.getByRole('main').getByText('Parent Display Layout')).toBeVisible();
|
||||||
|
//Verify both objects are in view
|
||||||
|
await expect(await page.getByLabel('Child Layout 1 Layout')).toBeVisible();
|
||||||
|
await expect(await page.getByLabel('Child Layout 2 Layout')).toBeVisible();
|
||||||
|
//Remove First Object to bring up confirmation dialog
|
||||||
|
await page.getByLabel('View menu items').nth(1).click();
|
||||||
|
await page.getByLabel('Remove').click();
|
||||||
|
await page.getByRole('button', { name: 'OK' }).click();
|
||||||
|
//Verify that the object is removed
|
||||||
|
await expect(await page.getByLabel('Child Layout 1 Layout')).toBeVisible();
|
||||||
|
expect(await page.getByLabel('Child Layout 2 Layout').count()).toBe(0);
|
||||||
|
});
|
||||||
|
@ -29,27 +29,29 @@
|
|||||||
class="c-click-icon c-overlay__close-button icon-x"
|
class="c-click-icon c-overlay__close-button icon-x"
|
||||||
@click.stop="destroy"
|
@click.stop="destroy"
|
||||||
></button>
|
></button>
|
||||||
<div
|
<div class="c-overlay__content-wrapper">
|
||||||
ref="element"
|
<div
|
||||||
class="c-overlay__contents js-notebook-snapshot-item-wrapper"
|
ref="element"
|
||||||
tabindex="0"
|
class="c-overlay__contents js-notebook-snapshot-item-wrapper"
|
||||||
aria-modal="true"
|
|
||||||
aria-label="Overlay"
|
|
||||||
role="dialog"
|
|
||||||
></div>
|
|
||||||
<div v-if="buttons" class="c-overlay__button-bar">
|
|
||||||
<button
|
|
||||||
v-for="(button, index) in buttons"
|
|
||||||
ref="buttons"
|
|
||||||
:key="index"
|
|
||||||
class="c-button js-overlay__button"
|
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
:class="{ 'c-button--major': focusIndex === index }"
|
aria-modal="true"
|
||||||
@focus="focusIndex = index"
|
aria-label="Overlay"
|
||||||
@click="buttonClickHandler(button.callback)"
|
role="dialog"
|
||||||
>
|
></div>
|
||||||
{{ button.label }}
|
<div v-if="buttons" class="c-overlay__button-bar">
|
||||||
</button>
|
<button
|
||||||
|
v-for="(button, index) in buttons"
|
||||||
|
ref="buttons"
|
||||||
|
:key="index"
|
||||||
|
class="c-button js-overlay__button"
|
||||||
|
tabindex="0"
|
||||||
|
:class="{ 'c-button--major': focusIndex === index }"
|
||||||
|
@focus="focusIndex = index"
|
||||||
|
@click="buttonClickHandler(button.callback)"
|
||||||
|
>
|
||||||
|
{{ button.label }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
&__icon {
|
&__icon {
|
||||||
// Holds a background SVG graphic
|
// Holds a background SVG graphic
|
||||||
$s: 80px;
|
$s: 50px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
min-width: $s;
|
min-width: $s;
|
||||||
min-height: $s;
|
min-height: $s;
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
z-index: 70;
|
z-index: 70;
|
||||||
|
|
||||||
&__blocker {
|
&__blocker {
|
||||||
display: none; // Mobile-first
|
// Mobile-first: use the blocker to create a full look to dialogs
|
||||||
|
@include abs();
|
||||||
|
background: $colorBodyBg;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__outer {
|
&__outer {
|
||||||
@ -27,7 +29,13 @@
|
|||||||
background: $colorBodyBg;
|
background: $colorBodyBg;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: $overlayInnerMargin;
|
|
||||||
|
body.mobile .l-overlay-fit & {
|
||||||
|
// Vertically center small dialogs in mobile
|
||||||
|
top: 50%;
|
||||||
|
bottom: auto;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__close-button {
|
&__close-button {
|
||||||
@ -39,12 +47,32 @@
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $interiorMargin;
|
||||||
|
|
||||||
|
body.desktop & {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-overlay-fit &,
|
||||||
|
.l-overlay-dialog & {
|
||||||
|
margin: $overlayInnerMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__contents {
|
&__contents {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
outline: none;
|
outline: none;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
body.mobile & {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__top-bar {
|
&__top-bar {
|
||||||
@ -78,6 +106,10 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-top: $interiorMargin;
|
margin-top: $interiorMargin;
|
||||||
|
body.mobile & {
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
> * + * {
|
> * + * {
|
||||||
margin-left: $interiorMargin;
|
margin-left: $interiorMargin;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user