• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / gui / 1057188406

01 Nov 2023 04:24AM UTC coverage: 82.824% (-17.1%) from 99.964%
1057188406

Pull #4134

gitlab-ci

web-flow
chore: Bump uuid from 9.0.0 to 9.0.1

Bumps [uuid](https://github.com/uuidjs/uuid) from 9.0.0 to 9.0.1.
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.0...v9.0.1)

---
updated-dependencies:
- dependency-name: uuid
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #4134: chore: Bump uuid from 9.0.0 to 9.0.1

4349 of 6284 branches covered (0.0%)

8313 of 10037 relevant lines covered (82.82%)

200.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.88
/src/js/components/deployments/deployment-report/rolloutschedule.js
1
// Copyright 2021 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14
import React from 'react';
15

16
import { ArrowForward } from '@mui/icons-material';
17
import { Chip } from '@mui/material';
18
import { makeStyles } from 'tss-react/mui';
19

20
import moment from 'moment';
21
import momentDurationFormatSetup from 'moment-duration-format';
22
import pluralize from 'pluralize';
23

24
import { DEPLOYMENT_STATES } from '../../../constants/deploymentConstants';
25
import { formatTime, getPhaseDeviceCount, getRemainderPercent } from '../../../helpers';
26
import { TwoColumnData } from '../../common/configurationobject';
27
import LinedHeader from '../../common/lined-header';
28
import Time from '../../common/time';
29
import { getPhaseStartTime } from '../createdeployment';
30
import { ProgressChartComponent, getDeploymentPhasesInfo, getDisplayablePhases } from '../progressChart';
31
import { defaultColumnDataProps } from '../report';
32
import PhaseProgress from './phaseprogress';
33

34
const useStyles = makeStyles()(theme => ({
11✔
35
  currentPhaseInfo: { backgroundColor: theme.palette.grey[400] },
36
  phaseInfo: { maxWidth: maxPhaseWidth, borderRadius: 5, paddingTop: theme.spacing(), paddingBottom: theme.spacing(3) },
37
  phaseIndex: { alignSelf: 'flex-start', margin: theme.spacing(2), marginLeft: theme.spacing(2.5) },
38
  phasesOverviewArrow: { marginLeft: theme.spacing(4), marginRight: theme.spacing(4) }
39
}));
40

41
momentDurationFormatSetup(moment);
11✔
42

43
const maxPhaseWidth = 270;
11✔
44

45
const PhaseLabel = ({ index }) => <div className="capitalized progress-step-number muted">Phase {index + 1}</div>;
11✔
46

47
export const RolloutSchedule = ({ deployment, headerClass, innerRef, onAbort, onUpdateControlChange }) => {
11✔
48
  const { classes } = useStyles();
4✔
49
  const now = moment();
4✔
50
  const { created: creationTime = now.toISOString(), filter, finished, status, update_control_map } = deployment;
4!
51

52
  const { phases, reversedPhases, totalDeviceCount, ...remainder } = getDeploymentPhasesInfo(deployment);
4✔
53

54
  const start_time = phases[0].start_ts || creationTime;
4!
55
  const currentPhase = reversedPhases.find(phase => now.isAfter(phase.start_ts)) || phases[0];
4!
56
  const currentPhaseIndex = phases.findIndex(phase => phase.id === currentPhase.id);
4✔
57
  const currentPhaseStartTime = getPhaseStartTime(phases, currentPhaseIndex, start_time);
4✔
58
  let currentPhaseTime = 'N/A';
4✔
59
  if (now.isSameOrAfter(currentPhaseStartTime)) {
4!
60
    currentPhaseTime = currentPhaseIndex + 1;
4✔
61
  }
62
  const endTime = finished ? <Time value={formatTime(finished)} /> : filter ? 'N/A' : '-';
4!
63

64
  const displayablePhases = getDisplayablePhases({ currentPhase, phases, totalDeviceCount, ...remainder });
4✔
65
  return (
4✔
66
    <>
67
      <LinedHeader className={`margin-top-large ${headerClass}`} heading="Schedule details" innerRef={innerRef} />
68
      {phases.length > 1 || !update_control_map ? (
12!
69
        <>
70
          <div className="flexbox">
71
            <TwoColumnData
72
              {...defaultColumnDataProps}
73
              config={{
74
                'Start time': <Time value={formatTime(creationTime)} />,
75
                'Current phase': currentPhaseTime
76
              }}
77
            />
78
            <ArrowForward className={classes.phasesOverviewArrow} />
79
            <TwoColumnData {...defaultColumnDataProps} config={{ 'End time': endTime }} />
80
          </div>
81
          <ProgressChartComponent className="margin-top no-background" phases={displayablePhases} PhaseLabel={PhaseLabel} />
82
        </>
83
      ) : (
84
        <PhaseProgress deployment={deployment} onAbort={onAbort} onUpdateControlChange={onUpdateControlChange} />
85
      )}
86
      <div className="deployment-phases-report margin-top margin-bottom" style={{ gridTemplateColumns: `repeat(auto-fit, ${maxPhaseWidth}px)` }}>
87
        {phases.map((phase, index) => {
88
          phase.batch_size = phase.batch_size || getRemainderPercent(phases);
4!
89
          const deviceCount = getPhaseDeviceCount(totalDeviceCount, phase.batch_size, phase.batch_size, index === phases.length - 1);
4✔
90
          const deviceCountText = !filter ? ` (${deviceCount} ${pluralize('device', deviceCount)})` : '';
4!
91
          const startTime = phase.start_ts ?? getPhaseStartTime(phases, index, start_time);
4!
92
          const phaseObject = {
4✔
93
            'Start time': <Time value={startTime} />,
94
            'Batch size': <div className="muted">{`${phase.batch_size}%${deviceCountText}`}</div>
95
          };
96
          let phaseTitle = status !== DEPLOYMENT_STATES.scheduled ? <div className="muted">Complete</div> : null;
4!
97
          let isCurrentPhase = false;
4✔
98
          if (now.isBefore(startTime)) {
4!
99
            const duration = moment.duration(moment(startTime).diff(now));
×
100
            phaseTitle = <div>{`Begins in ${duration.format('d [days] hh [h] mm [m]')}`}</div>;
×
101
          } else if (status === DEPLOYMENT_STATES.inprogress && phase.id === currentPhase.id) {
4!
102
            phaseTitle = <div className="muted">Current phase</div>;
×
103
            isCurrentPhase = true;
×
104
          }
105
          return (
4✔
106
            <div className={`flexbox column centered ${classes.phaseInfo} ${isCurrentPhase ? classes.currentPhaseInfo : ''}`} key={startTime}>
4!
107
              {phaseTitle}
108
              <Chip className={classes.phaseIndex} size="small" label={`Phase ${index + 1}`} />
109
              <TwoColumnData {...defaultColumnDataProps} style={{ ...defaultColumnDataProps.style, alignSelf: 'initial' }} config={phaseObject} />
110
            </div>
111
          );
112
        })}
113
      </div>
114
    </>
115
  );
116
};
117

118
export default RolloutSchedule;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc