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

CBIIT / crdc-datahub-ui / 11074479132

27 Sep 2024 04:44PM UTC coverage: 44.982% (+26.5%) from 18.435%
11074479132

Pull #479

github

web-flow
Merge a0867d25a into 3d8b55818
Pull Request #479: 3.0.0 Release

1727 of 4418 branches covered (39.09%)

Branch coverage included in aggregate %.

2612 of 5228 relevant lines covered (49.96%)

128.96 hits per line

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

3.85
/src/components/Header/HeaderTabletAndMobile.tsx
1
import React, { HTMLProps, useEffect, useState } from "react";
2
import { NavLink, Link, useNavigate, useLocation } from "react-router-dom";
3
import { styled } from "@mui/material";
4
import Logo from "./components/LogoMobile";
5
import menuClearIcon from "../../assets/header/Menu_Cancel_Icon.svg";
6
import rightArrowIcon from "../../assets/header/Right_Arrow.svg";
7
import leftArrowIcon from "../../assets/header/Left_Arrow.svg";
8
import { NavBarSublist, navMobileList, navbarSublists } from "../../config/globalHeaderData";
9
import { useAuthContext } from "../Contexts/AuthContext";
10
import GenericAlert from "../GenericAlert";
11
import APITokenDialog from "../../content/users/APITokenDialog";
12
import UploaderToolDialog from "../UploaderToolDialog";
13

14
const HeaderBanner = styled("div")({
2✔
15
  width: "100%",
16
});
17

18
const HeaderContainer = styled("div")({
2✔
19
  margin: "0 auto",
20
  paddingLeft: "16px",
21
  boxShadow: "-0.1px 6px 9px -6px rgba(0, 0, 0, 0.5)",
22
  "& .headerLowerContainer": {
23
    display: "flex",
24
    margin: "16px 0 4px 0",
25
    height: "51px",
26
  },
27
  "& .menuButton": {
28
    width: "89px",
29
    height: "45px",
30
    background: "#1F4671",
31
    borderRadius: "5px",
32
    fontFamily: "Open Sans",
33
    fontWeight: 700,
34
    fontSize: "20px",
35
    lineHeight: "45px",
36
    color: "#FFFFFF",
37
    textAlign: "center",
38
    "&:hover": {
39
      cursor: "pointer",
40
    },
41
  },
42
});
43

44
const NavMobileContainer = styled("div", {
2✔
45
  shouldForwardProp: (prop) => prop !== "display",
2✔
46
})<HTMLProps<HTMLDivElement> & { display: string }>(({ display }) => ({
×
47
  display,
48
  position: "absolute",
49
  left: 0,
50
  top: 0,
51
  height: "100%",
52
  width: "100%",
53
  zIndex: 1200,
54
}));
55

56
const MenuArea = styled("div")({
2✔
57
  height: "100%",
58
  width: "100%",
59
  display: "flex",
60
  "& .menuContainer": {
61
    background: "#ffffff",
62
    width: "300px",
63
    height: "100%",
64
    padding: "21px 16px",
65
  },
66
  "& .greyContainer": {
67
    width: "100%",
68
    height: "100%",
69
    background: "rgba(0,0,0,.2)",
70
  },
71
  "& .closeIcon": {
72
    height: "14px",
73
    marginBottom: "29px",
74
  },
75
  "& .closeIconImg": {
76
    float: "right",
77
    "&:hover": {
78
      cursor: "pointer",
79
    },
80
  },
81
  "& .backButton": {
82
    fontFamily: "Open Sans",
83
    fontWeight: 600,
84
    fontSize: "16px",
85
    lineHeight: "16px",
86
    color: "#007BBD",
87
    paddingLeft: "16px",
88
    background: `url(${leftArrowIcon}) left no-repeat`,
89
    "&:hover": {
90
      cursor: "pointer",
91
    },
92
  },
93
  "& .navMobileContainer": {
94
    padding: "24px 0 0 0",
95
    "& a": {
96
      textDecoration: "none",
97
      color: "#3D4551",
98
    },
99
  },
100
  "& .navMobileItem": {
101
    width: "268px",
102
    padding: "8px 24px 8px 16px",
103
    fontFamily: "Open Sans",
104
    fontWeight: 400,
105
    fontSize: "16px",
106
    lineHeight: "16px",
107
    borderTop: "1px solid #F0F0F0",
108
    borderBottom: "1px solid #F0F0F0",
109
    color: "#3D4551",
110
    "&:hover": {
111
      backgroundColor: "#f9f9f7",
112
    },
113
  },
114
  "& .SubItem": {
115
    paddingLeft: "24px",
116
  },
117
  "& .clickable": {
118
    background: `url(${rightArrowIcon}) 90% no-repeat`,
119
    cursor: "pointer",
120
  },
121
  "& .action": {
122
    cursor: "pointer",
123
  },
124
});
125

126
const Header = () => {
2✔
127
  const [navMobileDisplay, setNavMobileDisplay] = useState("none");
×
128
  const [openAPITokenDialog, setOpenAPITokenDialog] = useState<boolean>(false);
×
129
  const [uploaderToolOpen, setUploaderToolOpen] = useState<boolean>(false);
×
130
  const navMobileListHookResult = useState<NavBarSublist[]>(navMobileList);
×
131
  const navbarMobileList: NavBarSublist[] = navMobileListHookResult[0];
×
132
  const setNavbarMobileList = navMobileListHookResult[1];
×
133
  const [showLogoutAlert, setShowLogoutAlert] = useState<boolean>(false);
×
134
  const [restorePath, setRestorePath] = useState<string | null>(null);
×
135

136
  const authData = useAuthContext();
×
137
  const displayName = authData?.user?.firstName || "N/A";
×
138
  const navigate = useNavigate();
×
139
  const location = useLocation();
×
140

141
  const handleLogout = async () => {
×
142
    const logoutStatus = await authData.logout?.();
×
143
    if (logoutStatus) {
×
144
      navigate("/");
×
145
      setShowLogoutAlert(true);
×
146
      setTimeout(() => setShowLogoutAlert(false), 10000);
×
147
    }
148
  };
149

150
  navbarSublists[displayName] = [
×
151
    {
152
      name: "User Profile",
153
      link: `/profile/${authData?.user?._id}`,
154
      id: "navbar-dropdown-item-user-profile",
155
      className: "navMobileSubItem",
156
    },
157
    {
158
      name: "Uploader CLI Tool",
159
      onClick: () => setUploaderToolOpen(true),
×
160
      id: "navbar-dropdown-item-uploader-tool",
161
      className: "navMobileSubItem action",
162
    },
163
    {
164
      name: "Logout",
165
      link: "/logout",
166
      id: "navbar-dropdown-item-logout",
167
      className: "navMobileSubItem",
168
    },
169
  ];
170

171
  if (authData?.user?.role === "Admin" || authData?.user?.role === "Organization Owner") {
×
172
    navbarSublists[displayName].splice(1, 0, {
×
173
      name: "Manage Users",
174
      link: "/users",
175
      id: "navbar-dropdown-item-user-manage",
176
      className: "navMobileSubItem",
177
    });
178
  }
179
  if (authData?.user?.role === "Admin") {
×
180
    navbarSublists[displayName].splice(1, 0, {
×
181
      name: "Manage Organizations",
182
      link: "/organizations",
183
      id: "navbar-dropdown-item-user-manage",
184
      className: "navMobileSubItem",
185
    });
186
  }
187
  if (authData?.user?.role === "Submitter" || authData?.user?.role === "Organization Owner") {
×
188
    navbarSublists[displayName].splice(1, 0, {
×
189
      name: "API Token",
190
      onClick: () => setOpenAPITokenDialog(true),
×
191
      id: "navbar-dropdown-item-api-token",
192
      className: "navMobileSubItem action",
193
    });
194
  }
195

196
  const clickNavItem = (e) => {
×
197
    const clickTitle = e.target.innerText;
×
198
    setNavbarMobileList(navbarSublists[clickTitle]);
×
199
  };
200

201
  useEffect(() => {
×
202
    if (!location?.pathname || location?.pathname === "/") {
×
203
      setRestorePath(null);
×
204
      return;
×
205
    }
206

207
    setRestorePath(location?.pathname);
×
208
  }, [location]);
209

210
  return (
×
211
    <>
212
      <GenericAlert open={showLogoutAlert}>
213
        <span>You have been logged out.</span>
214
      </GenericAlert>
215
      <HeaderBanner>
216
        <HeaderContainer>
217
          <Logo />
218
          <div className="headerLowerContainer">
219
            <div
220
              role="button"
221
              id="header-navbar-open-menu-button"
222
              tabIndex={0}
223
              className="menuButton"
224
              onKeyDown={(e) => {
225
                if (e.key === "Enter") {
×
226
                  setNavMobileDisplay("block");
×
227
                }
228
              }}
229
              onClick={() => setNavMobileDisplay("block")}
×
230
            >
231
              Menu
232
            </div>
233
          </div>
234
        </HeaderContainer>
235
      </HeaderBanner>
236
      <NavMobileContainer display={navMobileDisplay}>
237
        <MenuArea>
238
          <div className="menuContainer">
239
            <div
240
              role="button"
241
              id="navbar-close-navbar-button"
242
              tabIndex={0}
243
              className="closeIcon"
244
              onKeyDown={(e) => {
245
                if (e.key === "Enter") {
×
246
                  setNavMobileDisplay("none");
×
247
                }
248
              }}
249
              onClick={() => setNavMobileDisplay("none")}
×
250
            >
251
              <img className="closeIconImg" src={menuClearIcon} alt="menuClearButton" />
252
            </div>
253
            {navbarMobileList !== navMobileList && (
×
254
              <div
255
                role="button"
256
                id="navbar-back-to-main-menu-button"
257
                tabIndex={0}
258
                className="backButton"
259
                onKeyDown={(e) => {
260
                  if (e.key === "Enter") {
×
261
                    setNavbarMobileList(navMobileList);
×
262
                  }
263
                }}
264
                onClick={() => setNavbarMobileList(navMobileList)}
×
265
              >
266
                Main Menu
267
              </div>
268
            )}
269
            <div className="navMobileContainer">
270
              {navbarMobileList.map((navMobileItem, idx) => {
271
                const mobilekey = `mobile_${idx}`;
×
272
                return (
×
273
                  <React.Fragment key={mobilekey}>
274
                    {navMobileItem.className === "navMobileItem" && (
×
275
                      <NavLink
276
                        id={navMobileItem.id}
277
                        to={navMobileItem.link}
278
                        target={navMobileItem.link.startsWith("https://") ? "_blank" : "_self"}
×
279
                        onClick={() => setNavMobileDisplay("none")}
×
280
                      >
281
                        <div className="navMobileItem">{navMobileItem.name}</div>
282
                      </NavLink>
283
                    )}
284
                    {navMobileItem.className === "navMobileItem clickable" && (
×
285
                      <div
286
                        id={navMobileItem.id}
287
                        role="button"
288
                        tabIndex={0}
289
                        className="navMobileItem clickable"
290
                        onKeyDown={(e) => {
291
                          if (e.key === "Enter") {
×
292
                            clickNavItem(e);
×
293
                          }
294
                        }}
295
                        onClick={clickNavItem}
296
                      >
297
                        {navMobileItem.name}
298
                      </div>
299
                    )}
300
                    {navMobileItem.className === "navMobileSubItem action" &&
×
301
                      typeof navMobileItem.onClick === "function" && (
302
                        <div
303
                          id={navMobileItem.id}
304
                          role="button"
305
                          tabIndex={0}
306
                          className="navMobileItem SubItem action"
307
                          onKeyDown={(e) => {
308
                            if (e.key === "Enter") {
×
309
                              navMobileItem.onClick();
×
310
                            }
311
                          }}
312
                          onClick={() => navMobileItem.onClick()}
×
313
                        >
314
                          {navMobileItem.name}
315
                        </div>
316
                      )}
317
                    {navMobileItem.className === "navMobileSubItem" && (
×
318
                      <Link
319
                        id={navMobileItem.id}
320
                        to={navMobileItem.link}
321
                        target={
322
                          navMobileItem.link.startsWith("https://") ||
×
323
                          navMobileItem.link.endsWith(".pdf")
324
                            ? "_blank"
325
                            : "_self"
326
                        }
327
                      >
328
                        <div
329
                          role="button"
330
                          tabIndex={0}
331
                          className="navMobileItem SubItem"
332
                          onKeyDown={(e) => {
333
                            if (e.key === "Enter") {
×
334
                              setNavMobileDisplay("none");
×
335
                              if (navMobileItem.name === "Logout") {
×
336
                                handleLogout();
×
337
                                setNavbarMobileList(navMobileList);
×
338
                              }
339
                            }
340
                          }}
341
                          onClick={() => {
342
                            setNavMobileDisplay("none");
×
343
                            if (navMobileItem.name === "Logout") {
×
344
                              handleLogout();
×
345
                              setNavbarMobileList(navMobileList);
×
346
                            }
347
                          }}
348
                        >
349
                          {navMobileItem.name}
350
                        </div>
351
                      </Link>
352
                    )}
353
                    {navMobileItem.className === "navMobileSubTitle" && (
×
354
                      <div className="navMobileItem">{navMobileItem.name}</div>
355
                    )}
356
                  </React.Fragment>
357
                );
358
              })}
359
              {/* eslint-disable-next-line no-nested-ternary */}
360
              {navbarMobileList === navMobileList ? (
×
361
                authData.isLoggedIn ? (
×
362
                  <div
363
                    id="navbar-dropdown-name"
364
                    role="button"
365
                    tabIndex={0}
366
                    className="navMobileItem clickable"
367
                    onKeyDown={(e) => {
368
                      if (e.key === "Enter") {
×
369
                        clickNavItem(e);
×
370
                      }
371
                    }}
372
                    onClick={clickNavItem}
373
                  >
374
                    {displayName}
375
                  </div>
376
                ) : (
377
                  <Link
378
                    id="navbar-link-login"
379
                    to="/login"
380
                    state={{ redirectURLOnLoginSuccess: restorePath }}
381
                  >
382
                    <div
383
                      role="button"
384
                      tabIndex={0}
385
                      className="navMobileItem"
386
                      onKeyDown={(e) => {
387
                        if (e.key === "Enter") {
×
388
                          setNavMobileDisplay("none");
×
389
                        }
390
                      }}
391
                      onClick={() => setNavMobileDisplay("none")}
×
392
                    >
393
                      Login
394
                    </div>
395
                  </Link>
396
                )
397
              ) : null}
398
            </div>
399
          </div>
400
          <div
401
            role="button"
402
            id="navbar-close-navbar-grey-section"
403
            tabIndex={0}
404
            className="greyContainer"
405
            onKeyDown={(e) => {
406
              if (e.key === "Enter") {
×
407
                setNavMobileDisplay("none");
×
408
              }
409
            }}
410
            onClick={() => setNavMobileDisplay("none")}
×
411
            aria-label="greyContainer"
412
          />
413
        </MenuArea>
414
        <APITokenDialog open={openAPITokenDialog} onClose={() => setOpenAPITokenDialog(false)} />
×
415
        <UploaderToolDialog open={uploaderToolOpen} onClose={() => setUploaderToolOpen(false)} />
×
416
      </NavMobileContainer>
417
    </>
418
  );
419
};
420

421
export default Header;
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

© 2026 Coveralls, Inc