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

mendersoftware / gui / 1113439055

19 Dec 2023 09:01PM UTC coverage: 82.752% (-17.2%) from 99.964%
1113439055

Pull #4258

gitlab-ci

mender-test-bot
chore: Types update

Signed-off-by: Mender Test Bot <mender@northern.tech>
Pull Request #4258: chore: Types update

4326 of 6319 branches covered (0.0%)

8348 of 10088 relevant lines covered (82.75%)

189.39 hits per line

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

91.43
/src/js/components/dashboard/deployments.js
1
// Copyright 2015 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, useEffect, useRef, useState } from 'react';
15
import { useDispatch, useSelector } from 'react-redux';
16
import { Link } from 'react-router-dom';
17

18
import { setSnackbar } from '../../actions/appActions';
19
import { getDeploymentsByStatus } from '../../actions/deploymentActions';
20
import { DEPLOYMENT_ROUTES, DEPLOYMENT_STATES, deploymentDisplayStates } from '../../constants/deploymentConstants';
21
import { onboardingSteps } from '../../constants/onboardingConstants';
22
import { DEPLOYMENT_CUTOFF, getDevicesById, getIdAttribute, getOnboardingState, getRecentDeployments, getUserCapabilities } from '../../selectors';
23
import { getOnboardingComponentFor } from '../../utils/onboardingmanager';
24
import useWindowSize from '../../utils/resizehook';
25
import { clearAllRetryTimers, setRetryTimer } from '../../utils/retrytimer';
26
import Loader from '../common/loader';
27
import { BaseDeploymentsWidget, CompletedDeployments } from './widgets/deployments';
28
import RedirectionWidget from './widgets/redirectionwidget';
29

30
const refreshDeploymentsLength = 30000;
4✔
31

32
// we need to exclude the scheduled state here as the os version is not able to process these and would prevent the dashboard from loading
33
const stateMap = {
4✔
34
  [DEPLOYMENT_STATES.pending]: BaseDeploymentsWidget,
35
  [DEPLOYMENT_STATES.inprogress]: BaseDeploymentsWidget,
36
  [DEPLOYMENT_STATES.finished]: CompletedDeployments
37
};
38

39
export const Deployments = ({ className = '', clickHandle }) => {
4✔
40
  const dispatch = useDispatch();
419✔
41
  const setSnackbarDispatched = useCallback(message => dispatch(setSnackbar(message)), [dispatch]);
419✔
42
  const { canDeploy } = useSelector(getUserCapabilities);
419✔
43
  const { total: deploymentsCount, ...deployments } = useSelector(getRecentDeployments);
419✔
44
  const onboardingState = useSelector(getOnboardingState);
419✔
45
  const devicesById = useSelector(getDevicesById);
419✔
46
  const idAttribute = useSelector(getIdAttribute);
419✔
47
  const [loading, setLoading] = useState(!deploymentsCount);
419✔
48
  // eslint-disable-next-line no-unused-vars
49
  const size = useWindowSize();
419✔
50
  const deploymentsRef = useRef();
419✔
51
  const timer = useRef();
419✔
52

53
  const getDeployments = useCallback(
419✔
54
    () =>
55
      Promise.all(Object.keys(stateMap).map(status => dispatch(getDeploymentsByStatus(status, 1, DEPLOYMENT_CUTOFF))))
207✔
56
        .catch(err => setRetryTimer(err, 'deployments', `Couldn't load deployments.`, refreshDeploymentsLength, setSnackbarDispatched))
×
57
        .finally(() => setLoading(false)),
68✔
58
    [dispatch, setSnackbarDispatched]
59
  );
60

61
  useEffect(() => {
419✔
62
    clearAllRetryTimers(setSnackbarDispatched);
7✔
63
    clearInterval(timer.current);
7✔
64
    timer.current = setInterval(getDeployments, refreshDeploymentsLength);
7✔
65
    getDeployments();
7✔
66
    return () => {
7✔
67
      clearInterval(timer.current);
7✔
68
      clearAllRetryTimers(setSnackbarDispatched);
7✔
69
    };
70
  }, [getDeployments, setSnackbarDispatched]);
71

72
  let onboardingComponent;
73
  if (deploymentsRef.current) {
419✔
74
    const anchor = {
412✔
75
      top: deploymentsRef.current.offsetTop + deploymentsRef.current.offsetHeight,
76
      left: deploymentsRef.current.offsetLeft + deploymentsRef.current.offsetWidth / 2
77
    };
78
    onboardingComponent = getOnboardingComponentFor(onboardingSteps.DEPLOYMENTS_PAST_COMPLETED, onboardingState, { anchor });
412✔
79
  }
80
  return (
419✔
81
    <div className={`${className} deployments`}>
82
      {loading ? (
419!
83
        <Loader show={loading} fade={true} />
84
      ) : (
85
        <div className="dashboard flexbox column" ref={deploymentsRef} style={{ gridTemplateColumns: '1fr', rowGap: 10 }}>
86
          <h4 className={`${deploymentsCount ? 'margin-bottom-none' : 'margin-top-none'} margin-left-small`}>
419!
87
            {deploymentsCount ? 'Recent deployments' : 'Deployments'}
419!
88
          </h4>
89
          {deploymentsCount ? (
419!
90
            <>
91
              {Object.entries(stateMap).reduce((accu, [key, Component]) => {
92
                if (!deployments[key]) {
1,257!
93
                  return accu;
×
94
                }
95
                accu.push(
1,257✔
96
                  <React.Fragment key={key}>
97
                    <h5 className="margin-bottom-none">{deploymentDisplayStates[key]}</h5>
98
                    <Component deployments={deployments[key]} devicesById={devicesById} idAttribute={idAttribute} state={key} onClick={clickHandle} />
99
                  </React.Fragment>
100
                );
101
                return accu;
1,257✔
102
              }, [])}
103
              <Link className="margin-top" to="/deployments">
104
                See all deployments
105
              </Link>
106
            </>
107
          ) : (
108
            canDeploy && (
×
109
              <RedirectionWidget
110
                content="Create a new deployment to update a group of devices"
111
                onClick={() => clickHandle({ route: `${DEPLOYMENT_ROUTES.active.route}?open=true` })}
×
112
              />
113
            )
114
          )}
115
        </div>
116
      )}
117
      {onboardingComponent}
118
    </div>
119
  );
120
};
121

122
export default Deployments;
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