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

mendersoftware / gui / 897326496

pending completion
897326496

Pull #3752

gitlab-ci

mzedel
chore(e2e): made use of shared timeout & login checking values to remove code duplication

Signed-off-by: Manuel Zedel <manuel.zedel@northern.tech>
Pull Request #3752: chore(e2e-tests): slightly simplified log in test + separated log out test

4395 of 6392 branches covered (68.76%)

8060 of 9780 relevant lines covered (82.41%)

126.17 hits per line

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

92.86
/src/js/components/uploads.js
1
// Copyright 2022 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, { useCallback, useState } from 'react';
15
import { connect } from 'react-redux';
16

17
import { Cancel as CancelIcon } from '@mui/icons-material';
18
import { Drawer, IconButton, LinearProgress, Tooltip, drawerClasses } from '@mui/material';
19
import { makeStyles } from 'tss-react/mui';
20

21
import pluralize from 'pluralize';
22

23
import { cancelFileUpload } from '../actions/releaseActions';
24
import { FileSize } from '../helpers';
25

26
const useStyles = makeStyles()(theme => ({
52✔
27
  progress: {
28
    backgroundColor: theme.palette.grey[600],
29
    gridColumn: 1,
30
    margin: '15px 0'
31
  },
32
  drawer: {
33
    [`.${drawerClasses.paper}`]: {
34
      maxWidth: 'initial'
35
    }
36
  },
37
  progressBarContainer: {
38
    position: 'fixed',
39
    display: 'grid',
40
    bottom: 0,
41
    gridTemplateRows: 'min-content',
42
    height: 'max-content',
43
    padding: `0 ${theme.spacing(2)}px`,
44
    overflow: 'hidden',
45
    width: '100%',
46
    zIindex: 10000,
47
    transition: 'all 0.2s ease-in-out'
48
  },
49
  progressContainer: {
50
    backgroundColor: theme.palette.background.default,
51
    borderColor: theme.palette.grey[300],
52
    color: theme.palette.grey[600],
53
    display: 'grid',
54
    gridTemplateRows: '30px 30px',
55
    gridTemplateColumns: '1fr 60px',
56
    columnGap: theme.spacing(2),
57
    ['> .MuiIconButton-root']: {
58
      gridColumn: 2,
59
      gridRowStart: 1,
60
      gridRowEnd: 2,
61
      height: 60
62
    }
63
  }
64
}));
65

66
const UploadProgressBar = ({ cancelFileUpload, classes, upload, uploadId }) => {
3✔
67
  const { name, size, uploadProgress } = upload;
1✔
68
  const onCancelClick = useCallback(() => cancelFileUpload(uploadId), [uploadId]);
1✔
69
  return (
1✔
70
    <div className={classes.progressContainer}>
71
      <div className="info flexbox centered">
72
        {Math.round(uploadProgress)}% - {name} (<FileSize fileSize={size} />)
73
      </div>
74
      <LinearProgress className={classes.progress} variant="determinate" value={uploadProgress} />
75
      <Tooltip title="Abort" placement="top">
76
        <IconButton onClick={onCancelClick} size="large">
77
          <CancelIcon />
78
        </IconButton>
79
      </Tooltip>
80
    </div>
81
  );
82
};
83

84
const Uploads = ({ cancelFileUpload, uploads }) => {
3✔
85
  const [isHovering, setIsHovering] = useState(false);
53✔
86
  const { classes } = useStyles();
53✔
87

88
  const isUploading = !!Object.keys(uploads).length;
53✔
89
  const uploadProgress = Object.values(uploads).reduce((accu, item, currentIndex, items) => {
53✔
90
    accu += item.uploadProgress;
2✔
91
    if (currentIndex === items.length - 1) {
2!
92
      return accu / (currentIndex + 1);
2✔
93
    }
94
    return accu;
×
95
  }, 0);
96

97
  const onClose = () => setIsHovering(false);
53✔
98
  const onMouseOver = () => setIsHovering(true);
53✔
99

100
  return (
53✔
101
    <div className={classes.progressBarContainer} onMouseEnter={onMouseOver}>
102
      {isUploading && !isHovering && <LinearProgress className={classes.progress} variant="determinate" value={uploadProgress} />}
56✔
103
      <Drawer anchor="bottom" className={classes.drawer} open={isUploading && isHovering} onClose={onClose}>
55✔
104
        <h3>{pluralize('Upload', Object.keys(uploads).length)} in progress</h3>
105
        {Object.entries(uploads).map(([uploadId, upload]) => (
106
          <UploadProgressBar cancelFileUpload={cancelFileUpload} classes={classes} key={uploadId} upload={upload} uploadId={uploadId} />
2✔
107
        ))}
108
      </Drawer>
109
    </div>
110
  );
111
};
112

113
const actionCreators = { cancelFileUpload };
3✔
114

115
const mapStateToProps = state => {
3✔
116
  return {
447✔
117
    uploads: state.app.uploadsById
118
  };
119
};
120

121
export default connect(mapStateToProps, actionCreators)(Uploads);
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