diff --git a/frontend/src/js/common-ui/Time.tsx b/frontend/src/js/common-ui/Time.tsx index 543719f7..6f50aa65 100644 --- a/frontend/src/js/common-ui/Time.tsx +++ b/frontend/src/js/common-ui/Time.tsx @@ -76,7 +76,7 @@ export const ApproximateRelativeDate = ({ className, updateTime }) => { const [updatedTime, setUpdatedTime] = useState(); useEffect(() => { - setUpdatedTime(updatedTime => (updateTime !== updatedTime ? dayjs(updateTime, defaultDateFormat) : updatedTime)); + setUpdatedTime(updatedTime => (updateTime !== updatedTime ? dayjs(updateTime) : updatedTime)); }, [updateTime]); const diff = updatedTime ? Math.abs(updatedTime.diff(dayjs(), 'days')) : 0; diff --git a/frontend/src/js/components/__snapshots__/App.test.tsx.snap b/frontend/src/js/components/__snapshots__/App.test.tsx.snap index 9b68977a..570ff07d 100644 --- a/frontend/src/js/components/__snapshots__/App.test.tsx.snap +++ b/frontend/src/js/components/__snapshots__/App.test.tsx.snap @@ -1144,7 +1144,7 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p margin-right: 8px; } -.emotion-66 { +.emotion-68 { background-color: #f7f7f7; padding: 10px 20px; border-radius: 4px; @@ -1155,61 +1155,61 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p min-height: 70px; } -.emotion-66 .chart-container { +.emotion-68 .chart-container { min-height: 70px; } -.emotion-66 .progress-chart { +.emotion-68 .progress-chart { min-height: 45px; } -.emotion-66 .compact .progress-step, -.emotion-66 .detailed .progress-step { +.emotion-68 .compact .progress-step, +.emotion-68 .detailed .progress-step { min-height: 45px; } -.emotion-66 .progress-step, -.emotion-66 .detailed .progress-step-total { +.emotion-68 .progress-step, +.emotion-68 .detailed .progress-step-total { position: absolute; border-right-style: none; } -.emotion-66 .progress-step-total .progress-bar { +.emotion-68 .progress-step-total .progress-bar { background-color: #d4e9e7; } -.emotion-66 .progress-step-number { +.emotion-68 .progress-step-number { -webkit-align-self: flex-start; -ms-flex-item-align: flex-start; align-self: flex-start; margin-top: -4px; } -.emotion-66.minimal { +.emotion-68.minimal { padding: initial; } -.emotion-66.no-background { +.emotion-68.no-background { background: none; } -.emotion-66.stepped-progress .progress-step-total { +.emotion-68.stepped-progress .progress-step-total { margin-left: -0.25%; width: 100.5%; } -.emotion-66.stepped-progress .progress-step-total .progress-bar { +.emotion-68.stepped-progress .progress-step-total .progress-bar { background-color: #fff; border: 1px solid #a9a9a9; border-radius: 2px; height: 12px; } -.emotion-66.stepped-progress .detailed .progress-step { +.emotion-68.stepped-progress .detailed .progress-step { min-height: 20px; } -.emotion-69 { +.emotion-73 { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; @@ -1220,36 +1220,36 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p max-width: 500px; } -.emotion-69>time { +.emotion-73>time { -webkit-align-self: flex-end; -ms-flex-item-align: flex-end; align-self: flex-end; margin-right: 6px; } -.emotion-71 { +.emotion-75 { background: #fff; border-radius: 4px; padding: 4px; } -.emotion-72 { +.emotion-76 { -webkit-column-gap: 8px; column-gap: 8px; display: grid; grid-template-columns: repeat(auto-fit, 32px); } -.emotion-72>div { +.emotion-76>div { -webkit-column-gap: 4px; column-gap: 4px; } -.emotion-72 .disabled { +.emotion-76 .disabled { opacity: 0.1; } -.emotion-77 { +.emotion-85 { position: fixed; display: grid; bottom: 0; @@ -1354,7 +1354,7 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p - 2 + 3
+
+
+
+ Test +
+
+
+ + + Queued to start + +
+
@@ -1880,6 +1912,123 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p > In Progress +
+
+
+
+ Test +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1895,7 +2044,7 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-9:focus::-ms-input-p
+ +
+
+
+
+ Test +
+
+
+
+
+ +
+ 0 +
+
+
+ +
+ 0 +
+
+
+ +
+ 0 +
+
+
+ +
+ 0 +
+
+
+ +
+ 0 +
+
+
+
+
+
+
`; diff --git a/frontend/src/js/components/dashboard/__snapshots__/Deployments.test.tsx.snap b/frontend/src/js/components/dashboard/__snapshots__/Deployments.test.tsx.snap index 55f3bd47..3b408772 100644 --- a/frontend/src/js/components/dashboard/__snapshots__/Deployments.test.tsx.snap +++ b/frontend/src/js/components/dashboard/__snapshots__/Deployments.test.tsx.snap @@ -206,14 +206,12 @@ exports[`Deployments Component > renders correctly 1`] = ` class="clickable emotion-0" >
-
- r1 -
+
- test deployment + Test
renders correctly 1`] = ` >
+ style="display: contents;" + > +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/js/components/deployments/ProgressChart.test.tsx b/frontend/src/js/components/deployments/ProgressChart.test.tsx index d9e3cc05..9af9a428 100644 --- a/frontend/src/js/components/deployments/ProgressChart.test.tsx +++ b/frontend/src/js/components/deployments/ProgressChart.test.tsx @@ -24,4 +24,10 @@ describe('ProgressChart Component', () => { expect(view).toMatchSnapshot(); expect(view).toEqual(expect.not.stringMatching(undefineds)); }); + it('renders correctly for phases', async () => { + const { baseElement } = render(); + const view = baseElement.firstChild; + expect(view).toMatchSnapshot(); + expect(view).toEqual(expect.not.stringMatching(undefineds)); + }); }); diff --git a/frontend/src/js/components/deployments/ProgressChart.tsx b/frontend/src/js/components/deployments/ProgressChart.tsx index 6d4b5c35..3a3ca2bf 100644 --- a/frontend/src/js/components/deployments/ProgressChart.tsx +++ b/frontend/src/js/components/deployments/ProgressChart.tsx @@ -247,21 +247,19 @@ export const getDeploymentPhasesInfo = deployment => { }; export const ProgressDisplay = ({ className = '', deployment, minimal = false, status }) => { - const [time, setTime] = useState(new Date()); + const [time, setTime] = useState(dayjs()); const timer = useRef(); useEffect(() => { - timer.current = setInterval(updateTime, TIMEOUTS.oneSecond); + timer.current = setInterval(() => setTime(dayjs()), TIMEOUTS.oneSecond); return () => { clearInterval(timer.current); }; }, []); - const updateTime = () => setTime(new Date()); - const { reversedPhases, totalFailureCount, phases, ...remainder } = getDeploymentPhasesInfo(deployment); - const currentPhase = reversedPhases.find(phase => new Date(phase.start_ts) < time) || phases[0]; + const currentPhase = reversedPhases.find(phase => dayjs(phase.start_ts) < time) || phases[0]; const currentPhaseIndex = phases.findIndex(phase => phase.id === currentPhase.id); const nextPhaseStart = phases.length > currentPhaseIndex + 1 ? dayjs(phases[currentPhaseIndex + 1].start_ts) : dayjs(time); @@ -272,8 +270,7 @@ export const ProgressDisplay = ({ className = '', deployment, minimal = false, s ...remainder }); - const momentaryTime = dayjs(time); - const duration = dayjs.duration(nextPhaseStart.diff(momentaryTime)).format('d [days] hh [h] mm [m] ss [s]'); + const duration = dayjs.duration(nextPhaseStart.diff(time)).format('DD [days] HH [h] mm [m] ss [s]'); return ( { afterEach(cleanup); it('renders correctly', async () => { - const ui = ; - const { asFragment, rerender } = render(ui, { preloadedState }); + const ui = ; + const { asFragment, rerender } = render(ui, { + preloadedState: { + ...defaultState, + deployments: { + ...defaultState.deployments, + selectedDeviceIds: [defaultState.deployments.byId.d1.devices.a1.id], + selectionState: { + selectedId: defaultState.deployments.byId.d1.id + } + } + } + }); + act(() => vi.advanceTimersByTime(5000)); + await waitFor(() => rerender(ui)); + const view = prettyDOM(asFragment().childNodes[1], 100000, { highlight: false }) + .replace(/id="mui-[0-9]*"/g, '') + .replace(/aria-labelledby="(mui-[0-9]* *)*"/g, '') + .replace(/\\/g, ''); + expect(view).toMatchSnapshot(); + }); + it('renders correctly for phased inprogress', async () => { + const ui = ; + const { asFragment, rerender } = render(ui, { + preloadedState: { + ...defaultState, + deployments: { + ...defaultState.deployments, + selectedDeviceIds: [defaultState.deployments.byId.d1.devices.a1.id], + selectionState: { + selectedId: defaultState.deployments.byId.d3.id + } + } + } + }); act(() => vi.advanceTimersByTime(5000)); await waitFor(() => rerender(ui)); const view = prettyDOM(asFragment().childNodes[1], 100000, { highlight: false }) diff --git a/frontend/src/js/components/deployments/__snapshots__/Deployments.test.tsx.snap b/frontend/src/js/components/deployments/__snapshots__/Deployments.test.tsx.snap index 8dff85f4..7924c12a 100644 --- a/frontend/src/js/components/deployments/__snapshots__/Deployments.test.tsx.snap +++ b/frontend/src/js/components/deployments/__snapshots__/Deployments.test.tsx.snap @@ -590,7 +590,7 @@ exports[`Deployments Component > renders correctly 1`] = ` margin-right: 8px; } -.emotion-18 { +.emotion-25 { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; @@ -607,22 +607,22 @@ exports[`Deployments Component > renders correctly 1`] = ` font-size: inherit; } -.emotion-18 iconButton { +.emotion-25 iconButton { margin-right: 8px; } -.emotion-22 { +.emotion-29 { border-color: rgba(0, 0, 0, 0.06); background-color: #fdfdfd; color: rgba(10, 10, 11, 0.78); } -.emotion-22 .dashboard-header span { +.emotion-29 .dashboard-header span { background-color: #fdfdfd; color: rgba(10, 10, 11, 0.78); } -.emotion-22 .MuiButtonBase-root { +.emotion-29 .MuiButtonBase-root { color: rgba(10, 10, 11, 0.78); } @@ -744,6 +744,246 @@ exports[`Deployments Component > renders correctly 1`] = `
+
+
+ + Release + +
+
+
+ + Target device(s) + +
+ Test +
+
+
+ + Start time + + + + +
+
+ + End time + + +
+ - +
+
+
+
+ + # devices + +
+ 100 +
+
+
+ + Status + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 failures +
+
+
+
+ Devices in progress +
+
+ + Time until next phase: + + + 21 days 22 h 45 m 09 s + +
+
+
+
+ + +
@@ -888,7 +1128,7 @@ exports[`Deployments Component > renders correctly 1`] = `

renders correctly 1`] = `
+
+
+ + Release + +
+
+
+ + Target device(s) + +
+ Test +
+
+
+ + Start time + + + + +
+
+ + End time + + +
+ - +
+
+
+
+ + # devices + +
+ 100 +
+
+
+ + Status + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 failures +
+
+
+
+ Devices in progress +
+
+ + Time until next phase: + + + 21 days 22 h 45 m 09 s + +
+
+
+
+ + +
@@ -1270,7 +1750,7 @@ exports[`Deployments Component > renders correctly 1`] = `
+
+
+ + Release + +
+
+
+ + Target device(s) + +
+ Test +
+
+
+ + Start time + + + + +
+
+ + End time + + +
+ - +
+
+
+
+ + # devices + +
+ 100 +
+
+
+ + Status + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 failures +
+
+
+
+ Devices in progress +
+
+ + Time until next phase: + + + 21 days 22 h 45 m 09 s + +
+
+
+
+ +
renders correctly 1`] = `
`; + +exports[`ProgressChart Component > renders correctly for phases 1`] = ` +.emotion-0 { + background-color: #f7f7f7; + padding: 10px 20px; + border-radius: 4px; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + min-height: 70px; +} + +.emotion-0 .chart-container { + min-height: 70px; +} + +.emotion-0 .progress-chart { + min-height: 45px; +} + +.emotion-0 .compact .progress-step, +.emotion-0 .detailed .progress-step { + min-height: 45px; +} + +.emotion-0 .progress-step, +.emotion-0 .detailed .progress-step-total { + position: absolute; + border-right-style: none; +} + +.emotion-0 .progress-step-total .progress-bar { + background-color: #d4e9e7; +} + +.emotion-0 .progress-step-number { + -webkit-align-self: flex-start; + -ms-flex-item-align: flex-start; + align-self: flex-start; + margin-top: -4px; +} + +.emotion-0.minimal { + padding: initial; +} + +.emotion-0.no-background { + background: none; +} + +.emotion-0.stepped-progress .progress-step-total { + margin-left: -0.25%; + width: 100.5%; +} + +.emotion-0.stepped-progress .progress-step-total .progress-bar { + background-color: #fff; + border: 1px solid #a9a9a9; + border-radius: 2px; + height: 12px; +} + +.emotion-0.stepped-progress .detailed .progress-step { + min-height: 20px; +} + +.emotion-1 { + display: grid; + grid-template-columns: 2fr 1fr; + grid-column-gap: 16px; +} + +.emotion-1 .progress-chart.detailed { + min-height: 20px; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 failures +
+
+
+
+ Devices in progress +
+
+ + Time until next phase: + + + 21 days 22 h 45 m 09 s + +
+
+
+
+`; diff --git a/frontend/src/js/components/deployments/__snapshots__/Report.test.tsx.snap b/frontend/src/js/components/deployments/__snapshots__/Report.test.tsx.snap index f2bb5975..be06ba8e 100644 --- a/frontend/src/js/components/deployments/__snapshots__/Report.test.tsx.snap +++ b/frontend/src/js/components/deployments/__snapshots__/Report.test.tsx.snap @@ -929,3 +929,1239 @@ Devices that are in the middle of the deployment at the time of abort will finis
" `; + +exports[`DeploymentReport Component > renders correctly for phased inprogress 1`] = ` +" +