mirror of
https://github.com/nasa/openmct.git
synced 2025-06-19 07:38:15 +00:00
[Mobile] Make Time Conductor Usable Again (#7515)
* Initial changes to refactor Time Conductor * Finish refactor using grid-template * Finish total refactor of Time Conductor * Initial mobile changes * Fix TC on mobile by changing grid template * Fix more mobile stuff * Add ellipsize to TC popup options and rearrange popup inputs and labels * Small final changes so TC is adaptive to extreme cases * Add e2e mobile test --------- Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
committed by
GitHub
parent
ab49f3f3a1
commit
87ba9fcbc0
@ -34,27 +34,46 @@ 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 }) => {
|
|
||||||
const { myItemsFolderName } = openmctConfig;
|
test.describe('Smoke tests for @mobile', () => {
|
||||||
//Go to baseURL
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto('./');
|
|
||||||
//My Items to be visible
|
|
||||||
await expect(page.getByRole('treeitem', { name: `${myItemsFolderName}` })).toBeVisible();
|
|
||||||
});
|
|
||||||
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('./');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Verify that My Items Tree appears @mobile', async ({ page }) => {
|
||||||
|
//My Items to be visible
|
||||||
|
await expect(page.getByRole('treeitem', { name: 'My Items' })).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Verify that user can search @mobile', async ({ page }) => {
|
||||||
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
|
||||||
await expect(page.getByLabel('Object Results').getByText('Parent Display Layout')).toBeVisible();
|
await expect(
|
||||||
|
page.getByLabel('Object Results').getByText('Parent Display Layout')
|
||||||
|
).toBeVisible();
|
||||||
//Clicking on the search result takes you to the object
|
//Clicking on the search result takes you to the object
|
||||||
await page.getByLabel('Object Results').getByText('Parent Display Layout').click();
|
await page.getByLabel('Object Results').getByText('Parent Display Layout').click();
|
||||||
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('./');
|
test('Verify that user can change time conductor @mobile', async ({ page }) => {
|
||||||
|
//Collapse Browse Pane to get more Time Conductor space
|
||||||
|
await page.getByLabel('Collapse Browse Pane').click();
|
||||||
|
//Open Time Conductor and change to Real Time Mode and set offset hour by 1 hour
|
||||||
|
// Disabling line because we're intentionally obscuring the text
|
||||||
|
// eslint-disable-next-line playwright/no-force-option
|
||||||
|
await page.getByLabel('Time Conductor Mode').click({ force: true });
|
||||||
|
await page.getByLabel('Time Conductor Mode Menu').click();
|
||||||
|
await page.getByLabel('Real-Time').click();
|
||||||
|
await page.getByLabel('Start offset hours').fill('01');
|
||||||
|
await page.getByLabel('Submit time offsets').click();
|
||||||
|
await expect(page.getByLabel('Start offset: 01:30:00')).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Remove Object and confirmation dialog @mobile', async ({ page }) => {
|
||||||
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
|
||||||
@ -72,4 +91,5 @@ test('Remove Object and confirmation dialog @mobile', async ({ page }) => {
|
|||||||
//Verify that the object is removed
|
//Verify that the object is removed
|
||||||
await expect(await page.getByLabel('Child Layout 1 Layout')).toBeVisible();
|
await expect(await page.getByLabel('Child Layout 1 Layout')).toBeVisible();
|
||||||
expect(await page.getByLabel('Child Layout 2 Layout').count()).toBe(0);
|
expect(await page.getByLabel('Child Layout 2 Layout').count()).toBe(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<form ref="fixedDeltaInput">
|
<form ref="fixedDeltaInput">
|
||||||
<div class="c-tc-input-popup__input-grid">
|
<div class="c-tc-input-popup__input-grid">
|
||||||
<div class="pr-time-label"><em>Start</em> Date</div>
|
<div class="pr-time-label pr-time-label-start-date"><em>Start</em> Date</div>
|
||||||
<div class="pr-time-label">Time</div>
|
<div class="pr-time-label pr-time-label-start-time">Time</div>
|
||||||
<div class="pr-time-label"></div>
|
<div class="pr-time-label pr-time-label-end-date"><em>End</em> Date</div>
|
||||||
<div class="pr-time-label"><em>End</em> Date</div>
|
<div class="pr-time-label pr-time-label-end-time">Time</div>
|
||||||
<div class="pr-time-label">Time</div>
|
|
||||||
<div class="pr-time-label"></div>
|
|
||||||
|
|
||||||
<div class="pr-time-input pr-time-input--date pr-time-input--input-and-button">
|
<div
|
||||||
|
class="pr-time-input pr-time-input--date pr-time-input--input-and-button pr-time-input-start-date"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
ref="startDate"
|
ref="startDate"
|
||||||
v-model="formattedBounds.start"
|
v-model="formattedBounds.start"
|
||||||
@ -28,7 +28,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pr-time-input pr-time-input--time">
|
<div class="pr-time-input pr-time-input--time pr-time-input-start-time">
|
||||||
<input
|
<input
|
||||||
ref="startTime"
|
ref="startTime"
|
||||||
v-model="formattedBounds.startTime"
|
v-model="formattedBounds.startTime"
|
||||||
@ -43,7 +43,9 @@
|
|||||||
|
|
||||||
<div class="pr-time-input pr-time-input__start-end-sep icon-arrows-right-left"></div>
|
<div class="pr-time-input pr-time-input__start-end-sep icon-arrows-right-left"></div>
|
||||||
|
|
||||||
<div class="pr-time-input pr-time-input--date pr-time-input--input-and-button">
|
<div
|
||||||
|
class="pr-time-input pr-time-input--date pr-time-input--input-and-button pr-time-input-end-date"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
ref="endDate"
|
ref="endDate"
|
||||||
v-model="formattedBounds.end"
|
v-model="formattedBounds.end"
|
||||||
@ -63,7 +65,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pr-time-input pr-time-input--time">
|
<div class="pr-time-input pr-time-input--time pr-time-input-end-time">
|
||||||
<input
|
<input
|
||||||
ref="endTime"
|
ref="endTime"
|
||||||
v-model="formattedBounds.endTime"
|
v-model="formattedBounds.endTime"
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<form ref="deltaInput">
|
<form ref="deltaInput">
|
||||||
<div class="c-tc-input-popup__input-grid">
|
<div class="c-tc-input-popup__input-grid">
|
||||||
<div class="pr-time-label icon-minus">Hrs</div>
|
<div class="pr-time-label icon-minus pr-time-label-minus-hrs">Hrs</div>
|
||||||
<div class="pr-time-label">Mins</div>
|
<div class="pr-time-label pr-time-label-minus-mins">Mins</div>
|
||||||
<div class="pr-time-label">Secs</div>
|
<div class="pr-time-label pr-time-label-minus-secs">Secs</div>
|
||||||
<div class="pr-time-label"></div>
|
<div class="pr-time-label icon-plus pr-time-label-plus-hrs">Hrs</div>
|
||||||
<div class="pr-time-label icon-plus">Hrs</div>
|
<div class="pr-time-label pr-time-label-plus-mins">Mins</div>
|
||||||
<div class="pr-time-label">Mins</div>
|
<div class="pr-time-label pr-time-label-plus-secs">Secs</div>
|
||||||
<div class="pr-time-label">Secs</div>
|
|
||||||
<div class="pr-time-label"></div>
|
|
||||||
|
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-minus-hrs">
|
||||||
<input
|
<input
|
||||||
ref="startInputHrs"
|
ref="startInputHrs"
|
||||||
v-model="startInputHrs"
|
v-model="startInputHrs"
|
||||||
@ -29,7 +27,7 @@
|
|||||||
/>
|
/>
|
||||||
<b>:</b>
|
<b>:</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-minus-mins">
|
||||||
<input
|
<input
|
||||||
ref="startInputMins"
|
ref="startInputMins"
|
||||||
v-model="startInputMins"
|
v-model="startInputMins"
|
||||||
@ -48,7 +46,7 @@
|
|||||||
/>
|
/>
|
||||||
<b>:</b>
|
<b>:</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-minus-secs">
|
||||||
<input
|
<input
|
||||||
ref="startInputSecs"
|
ref="startInputSecs"
|
||||||
v-model="startInputSecs"
|
v-model="startInputSecs"
|
||||||
@ -69,7 +67,7 @@
|
|||||||
|
|
||||||
<div class="pr-time-input pr-time-input__start-end-sep icon-arrows-right-left"></div>
|
<div class="pr-time-input pr-time-input__start-end-sep icon-arrows-right-left"></div>
|
||||||
|
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-plus-hrs">
|
||||||
<input
|
<input
|
||||||
ref="endInputHrs"
|
ref="endInputHrs"
|
||||||
v-model="endInputHrs"
|
v-model="endInputHrs"
|
||||||
@ -88,7 +86,7 @@
|
|||||||
/>
|
/>
|
||||||
<b>:</b>
|
<b>:</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-plus-mins">
|
||||||
<input
|
<input
|
||||||
ref="endInputMins"
|
ref="endInputMins"
|
||||||
v-model="endInputMins"
|
v-model="endInputMins"
|
||||||
@ -106,7 +104,7 @@
|
|||||||
/>
|
/>
|
||||||
<b>:</b>
|
<b>:</b>
|
||||||
</div>
|
</div>
|
||||||
<div class="pr-time-input">
|
<div class="pr-time-input pr-time-input-plus-secs">
|
||||||
<input
|
<input
|
||||||
ref="endInputSecs"
|
ref="endInputSecs"
|
||||||
v-model="endInputSecs"
|
v-model="endInputSecs"
|
||||||
|
@ -604,23 +604,170 @@
|
|||||||
padding: cButtonPadding($compact: true);
|
padding: cButtonPadding($compact: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.pr-time{
|
||||||
|
// FIXED TIME MODE
|
||||||
|
&-label-start-date{
|
||||||
|
grid-area: sDate;
|
||||||
|
}
|
||||||
|
&-label-start-time{
|
||||||
|
grid-area: sTime;
|
||||||
|
}
|
||||||
|
&-input-start-date{
|
||||||
|
grid-area: sDateInput;
|
||||||
|
}
|
||||||
|
&-input-start-time{
|
||||||
|
grid-area: sTimeInput;
|
||||||
|
}
|
||||||
|
&-label-end-date{
|
||||||
|
grid-area: eDate;
|
||||||
|
}
|
||||||
|
&-label-end-time{
|
||||||
|
grid-area: eTime;
|
||||||
|
|
||||||
|
}
|
||||||
|
&-input-end-date{
|
||||||
|
grid-area: eDateInput;
|
||||||
|
}
|
||||||
|
&-input-end-time{
|
||||||
|
grid-area: eTimeInput;
|
||||||
|
}
|
||||||
|
&-label-blank-grid{
|
||||||
|
grid-area: blank;
|
||||||
|
}
|
||||||
|
|
||||||
|
//REAL TIME MODE
|
||||||
|
&-label-minus-hrs{
|
||||||
|
grid-area: labelMinusHrs;
|
||||||
|
}
|
||||||
|
&-label-minus-mins{
|
||||||
|
grid-area: labelMinusMins;
|
||||||
|
}
|
||||||
|
&-label-minus-secs{
|
||||||
|
grid-area: labelMinusSecs;
|
||||||
|
}
|
||||||
|
&-label-plus-hrs{
|
||||||
|
grid-area: labelPlusHrs;
|
||||||
|
}
|
||||||
|
&-label-plus-mins{
|
||||||
|
grid-area: labelPlusMins;
|
||||||
|
}
|
||||||
|
&-label-plus-secs{
|
||||||
|
grid-area: labelPlusSecs;
|
||||||
|
}
|
||||||
|
&-input-minus-hrs{
|
||||||
|
grid-area: inputMinusHrs;
|
||||||
|
}
|
||||||
|
&-input-minus-mins{
|
||||||
|
grid-area: inputMinusMins;
|
||||||
|
}
|
||||||
|
&-input-minus-secs{
|
||||||
|
grid-area: inputMinusSecs;
|
||||||
|
}
|
||||||
|
&-input-plus-hrs{
|
||||||
|
grid-area: inputPlusHrs;
|
||||||
|
}
|
||||||
|
&-input-plus-mins{
|
||||||
|
grid-area: inputPlusMins;
|
||||||
|
}
|
||||||
|
&-input-plus-secs{
|
||||||
|
grid-area: inputPlusSecs;
|
||||||
|
}
|
||||||
|
// USED FOR BOTH
|
||||||
|
&-label-blank-grid{
|
||||||
|
grid-area: empty;
|
||||||
|
}
|
||||||
|
&-input__start-end-sep{
|
||||||
|
grid-area: arrowIcon;
|
||||||
|
}
|
||||||
|
&-input--buttons{
|
||||||
|
grid-area: buttons;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&--fixed-mode {
|
&--fixed-mode {
|
||||||
.c-tc-input-popup__input-grid {
|
.c-tc-input-popup__input-grid {
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 2fr;
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 2fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"sDate sTime . eDate eTime ."
|
||||||
|
"sDateInput sTimeInput arrowIcon eDateInput eTimeInput buttons";
|
||||||
}
|
}
|
||||||
|
@include phonePortrait(){
|
||||||
|
.c-tc-input-popup__input-grid {
|
||||||
|
grid-template-columns: repeat(2, max-content) 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"sDate sTime ."
|
||||||
|
"sDateInput sTimeInput ."
|
||||||
|
"eDate eTime ."
|
||||||
|
"eDateInput eTimeInput buttons";
|
||||||
|
padding: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&--realtime-mode {
|
&--realtime-mode {
|
||||||
.c-tc-input-popup__input-grid {
|
.c-tc-input-popup__input-grid {
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 2fr;
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 2fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"labelMinusHrs labelMinusMins labelMinusSecs . labelPlusHrs labelPlusMins labelPlusSecs ."
|
||||||
|
"inputMinusHrs inputMinusMins inputMinusSecs arrowIcon inputPlusHrs inputPlusMins inputPlusSecs buttons";
|
||||||
|
}
|
||||||
|
@include phonePortrait(){
|
||||||
|
.c-tc-input-popup__input-grid {
|
||||||
|
grid-template-columns: repeat(3, max-content) 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"labelMinusHrs labelMinusMins labelMinusSecs ."
|
||||||
|
"inputMinusHrs inputMinusMins inputMinusSecs ."
|
||||||
|
"labelPlusHrs labelPlusMins labelPlusSecs ."
|
||||||
|
"inputPlusHrs inputPlusMins inputPlusSecs buttons";
|
||||||
|
padding: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__input-grid {
|
&__input-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-column-gap: 3px;
|
|
||||||
grid-row-gap: $interiorMargin;
|
grid-row-gap: $interiorMargin;
|
||||||
|
grid-column-gap: $interiorMarginSm;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@include phonePortrait(){ // Additional styling for mobile portrait.
|
||||||
|
.c-tc-input-popup{
|
||||||
|
width: 100%;
|
||||||
|
&__options{
|
||||||
|
> * {
|
||||||
|
overflow: hidden;
|
||||||
|
[class*= 'ctrl-wrapper']{
|
||||||
|
[class*='--menu'] {
|
||||||
|
width: 100%;
|
||||||
|
[class*='__label'] {
|
||||||
|
@include ellipsize();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-time-input-end-time, .pr-time-input-start-time{
|
||||||
|
> * {
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pr-time-input--buttons{
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.pr-time-input__start-end-sep{
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.pr-time-input__start-end-sep{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.pr-time-input-start-date, .pr-time-input-end-date{
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user