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

CBIIT / crdc-datahub-ui / 11940622675

20 Nov 2024 07:45PM UTC coverage: 55.678% (+1.9%) from 53.816%
11940622675

Pull #538

github

web-flow
Merge 5794cff67 into 85b9e32a0
Pull Request #538: Misc Optimizations

2631 of 5208 branches covered (50.52%)

Branch coverage included in aggregate %.

13 of 20 new or added lines in 4 files covered. (65.0%)

10 existing lines in 1 file now uncovered.

3787 of 6319 relevant lines covered (59.93%)

141.88 hits per line

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

56.58
/src/components/InactivityDialog/InactivityDialog.tsx
1
import React, { useState, useEffect } from "react";
2
import { Button, Dialog, DialogTitle, styled } from "@mui/material";
3
import { useNavigate } from "react-router-dom";
4
import { useSnackbar } from "notistack";
5
import { useAuthContext } from "../Contexts/AuthContext";
6
import { Logger, secondsToMinuteString } from "../../utils";
7
import CloseIcon from "../../assets/icons/close_icon.svg";
8

9
const InactivityWarningDialog = styled(Dialog)({
2✔
10
  "& .MuiDialog-paper": {
11
    width: "550px",
12
    height: "320px",
13
    borderRadius: "8px",
14
    border: "2px solid var(--secondary-one, #0B7F99)",
15
    background: "linear-gradient(0deg, #F2F6FA 0%, #F2F6FA 100%), #2E4D7B",
16
    boxShadow: "0px 4px 45px 0px rgba(0, 0, 0, 0.40)",
17
  },
18
  "& #customized-dialog-title": {
19
    margin: 0,
20
    paddingLeft: "30px",
21
    backgroundColor: "#6D89A2",
22
    color: "#FFFFFF",
23
    fontFamily: "Lato",
24
    fontSize: "20px",
25
    fontWeight: 600,
26
    letterSpacing: 0,
27
  },
28
});
29

30
const InactivityWarningContent = styled("div")({
2✔
31
  margin: "50px auto",
32
  color: "#000000",
33
  fontFamily: "'Nunito', 'Rubik', sans-serif",
34
  fontSize: "17px",
35
  fontWeight: 300,
36
  letterSpacing: 0,
37
  lineHeight: "24px",
38
  "& .buttonWrapper": {
39
    display: "flex",
40
    justifyContent: "center",
41
    alignItems: "center",
42
    textAlign: "center",
43
  },
44
  "& .buttonGroup": {
45
    color: "#FFFFFF",
46
    fontFamily: "Lato",
47
    fontSize: "11px",
48
    lineHeight: "22px",
49
    width: "150px",
50
    border: "1px solid #626262",
51
    marginTop: "30px",
52
    borderRadius: "4px",
53
    fontWeight: 500,
54
  },
55
  "& .extendButton": {
56
    backgroundColor: "#566672 !important",
57
  },
58
  "& .logOutButton": {
59
    marginLeft: "20px",
60
    backgroundColor: "#437BBE !important",
61
  },
62
});
63

64
const SessionTimeoutDialog = styled(Dialog)({
2✔
65
  "& .MuiDialog-paper": {
66
    width: "550px",
67
    height: "320px",
68
    borderRadius: "8px",
69
    border: "2px solid var(--secondary-one, #0B7F99)",
70
    background: "linear-gradient(0deg, #F2F6FA 0%, #F2F6FA 100%), #2E4D7B",
71
    boxShadow: "0px 4px 45px 0px rgba(0, 0, 0, 0.40)",
72
  },
73
  "& .closeIcon": {
74
    cursor: "pointer",
75
    textAlign: "end",
76
  },
77
});
78

79
const SessionTimeoutContent = styled("div")({
2✔
80
  justifyContent: "space-between",
81
  paddingRight: "33px",
82
  paddingLeft: "33px",
83
  paddingTop: "10px",
84
  fontFamily: "lato",
85
  textAlign: "center",
86
  "& .sessionTimeoutTitle": {
87
    fontSize: "25px",
88
    fontWeight: "bold",
89
    paddingBottom: "12px",
90
    color: "#566672",
91
  },
92
  "& .sessionTimeoutMessage": {
93
    fontSize: "17px",
94
    paddingBottom: "14px",
95
  },
96
  "& .buttonWrapper": {
97
    display: "flex",
98
    justifyContent: "center",
99
    alignItems: "center",
100
    textAlign: "center",
101
  },
102
  "& .buttonGroup": {
103
    color: "#FFFFFF",
104
    fontFamily: "Lato",
105
    fontSize: "11px",
106
    lineHeight: "22px",
107
    width: "90px",
108
    border: "1px solid #626262",
109
    marginTop: "30px",
110
    borderRadius: "4px",
111
    fontWeight: 500,
112
  },
113
  "& .closeButton": {
114
    backgroundColor: "#566672 !important",
115
  },
116
  "& .loginButton": {
117
    marginLeft: "20px",
118
    backgroundColor: "#437BBE !important",
119
  },
120
});
121

122
const thresholdTime = 300;
2✔
123

124
const InactivityDialog = () => {
2✔
125
  const navigate = useNavigate();
8✔
126
  const { enqueueSnackbar } = useSnackbar();
8✔
127
  const { isLoggedIn, logout } = useAuthContext();
8✔
128

129
  const [warning, setWarning] = useState<boolean>(false);
8✔
130
  const [timedOut, setTimedOut] = useState<boolean>(false);
8✔
131
  const [timeLeft, setTimeLeft] = useState<number>(thresholdTime);
8✔
132

133
  const extendSession = async () => {
8✔
134
    try {
×
NEW
135
      const res = await fetch(`${window.origin}/api/authn/authenticated`, {
×
136
        method: "POST",
137
        headers: {
138
          Accept: "application/json",
139
          "Content-Type": "application/json",
140
        },
141
      })
142
        .then((response) => response.json())
×
143
        .catch(() => {});
144

145
      if (res.status) {
×
146
        setWarning(false);
×
147
      }
148
    } catch (e) {
NEW
149
      Logger.error("Error in extending session", e);
×
150
    }
151
  };
152

153
  const handleExtendSession = () => {
8✔
154
    extendSession();
×
155
  };
156

157
  const handleSignOutNoBanner = async () => {
8✔
158
    const logoutStatus = await logout();
2✔
159
    if (logoutStatus) {
2!
160
      navigate("/");
2✔
161
      setWarning(false);
2✔
162
    }
163
  };
164

165
  const handleSignOut = async () => {
8✔
NEW
166
    const logoutStatus = await logout();
×
167
    if (logoutStatus) {
×
168
      navigate("/");
×
169
      setWarning(false);
×
NEW
170
      enqueueSnackbar("You have been logged out.", { variant: "default" });
×
171
    }
172
  };
173

174
  const loadData = async () => {
8✔
175
    try {
6✔
176
      const res = await fetch(`${window.origin}/api/authn/session-ttl`);
6✔
177
      const data = await res.json();
4✔
178
      const { ttl } = data;
4✔
179
      if (ttl <= 0) {
4✔
180
        // If user did not select any option and timed out in BE.
181
        handleSignOutNoBanner();
2✔
182
        setTimedOut(true);
2✔
183
      } else if (ttl > 0 && ttl <= thresholdTime) {
2!
184
        setTimeLeft(ttl);
×
185
        setWarning(true);
×
186
      }
187
    } catch (e) {
NEW
188
      Logger.error("Error in fetching session ttl", e);
×
189
    }
190
  };
191

192
  useEffect(() => {
8✔
193
    let ID: NodeJS.Timer;
194
    if (isLoggedIn) {
6!
195
      ID = setInterval(loadData, 10 * 1000);
6✔
196
    } else {
NEW
197
      clearInterval(ID);
×
198
    }
199

200
    return () => clearInterval(ID);
6✔
201
  }, [isLoggedIn]);
202

203
  return (
8✔
204
    <>
205
      <InactivityWarningDialog open={warning}>
206
        <DialogTitle id="customized-dialog-title">Session Timeout Warning</DialogTitle>
207
        <InactivityWarningContent>
208
          This session is about to expire due to inactivity.
209
          <br />
210
          You will be logged out in
211
          {` ${secondsToMinuteString(timeLeft)} `}
212
          minutes.
213
          <br />
214
          Please elect to extend this session or logout.
215
          <div className="buttonWrapper">
216
            <Button
217
              variant="contained"
218
              className="buttonGroup extendButton"
219
              onClick={handleExtendSession}
220
              disableElevation={false}
221
            >
222
              EXTEND SESSION
223
            </Button>
224
            <Button
225
              variant="contained"
226
              className="buttonGroup logOutButton"
227
              onClick={handleSignOut}
228
              disableElevation={false}
229
            >
230
              LOGOUT
231
            </Button>
232
          </div>
233
        </InactivityWarningContent>
234
      </InactivityWarningDialog>
235
      <SessionTimeoutDialog open={timedOut}>
236
        <DialogTitle>
237
          <div
238
            role="button"
239
            className="closeIcon"
240
            onClick={() => setTimedOut(false)}
×
241
            tabIndex={0}
242
            onKeyDown={(e) => {
243
              if (e.key === "Enter") {
×
244
                setTimedOut(false);
×
245
              }
246
            }}
247
          >
248
            <img style={{ height: 10, marginBottom: 2 }} src={CloseIcon} alt="close icon" />
249
          </div>
250
        </DialogTitle>
251
        <SessionTimeoutContent>
252
          <div className="sessionTimeoutTitle">Your session has expired.</div>
253
          <br />
254
          <div className="sessionTimeoutMessage">Please login again to continue working.</div>
255
          <div className="buttonWrapper">
256
            <Button
257
              variant="contained"
258
              className="buttonGroup closeButton"
259
              onClick={() => setTimedOut(false)}
×
260
              disableElevation={false}
261
            >
262
              CLOSE
263
            </Button>
264
            <Button
265
              variant="contained"
266
              className="buttonGroup loginButton"
267
              onClick={() => {
268
                setTimedOut(false);
×
269
                navigate("login");
×
270
              }}
271
              disableElevation={false}
272
            >
273
              LOGIN
274
            </Button>
275
          </div>
276
        </SessionTimeoutContent>
277
      </SessionTimeoutDialog>
278
    </>
279
  );
280
};
281

282
export default InactivityDialog;
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