qpp-style 9.16.9 → 9.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.husky/pre-commit +5 -0
  2. package/components/Alert/Alert.stories.js +1 -1
  3. package/components/Alert/index.js +8 -1
  4. package/components/GovBanner/index.js +65 -57
  5. package/components/Header/HeaderContainer.jsx +1 -1
  6. package/components/Header/HeaderMenuItem.jsx +13 -6
  7. package/components/Modal/Modal.jsx +1 -1
  8. package/components/SideNav/AnimationGroup/AnimationGroup.jsx +2 -2
  9. package/components/SideNav/Content/LevelOneContent.jsx +121 -156
  10. package/components/SideNav/Content/SelectRole/index.js +79 -0
  11. package/components/SideNav/Content/SelectRole/utils.js +120 -0
  12. package/components/SideNav/Details/PracticeDetails.jsx +1 -1
  13. package/components/SideNav/Links/NavLinkDrawer.jsx +1 -1
  14. package/components/SideNav/Links/NavLinkInline.jsx +6 -1
  15. package/components/SideNav/UI/SideNavUI.jsx +7 -3
  16. package/components/SideNav/helpers.js +213 -0
  17. package/components/Tabs/Tab.js +1 -1
  18. package/components/Tabs/TabPanel.js +8 -1
  19. package/components/Tabs/index.js +46 -41
  20. package/components/TextInput/index.js +1 -1
  21. package/components/hooks/useGetConfig.js +1 -0
  22. package/dist/browser.js +1 -1
  23. package/dist/browser.js.LICENSE.txt +10 -1
  24. package/dist/browser.js.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.LICENSE.txt +10 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/react/index.js +1 -1
  29. package/dist/react/index.js.LICENSE.txt +9 -0
  30. package/dist/react/index.js.map +1 -1
  31. package/images/icons/svg/arrow-down.svg +3 -1
  32. package/images/icons/svg/arrow-up.svg +3 -0
  33. package/lib/SvgComponents.jsx +15 -0
  34. package/package.json +10 -8
  35. package/storybook-static/favicon.ico +0 -0
  36. package/styles/qppds/components/_dropdown.scss +1 -0
  37. package/styles/qppds/components/_sidebar.scss +1 -0
  38. package/styles/qppds/components/sidebar/_links.scss +14 -1
  39. package/styles/qppds/components/sidebar/_select-role-dropdown.scss +21 -0
  40. package/styles/qppds/components/sidebar/_select-role.scss +13 -0
  41. package/coverage/clover.xml +0 -1294
  42. package/coverage/coverage-final.json +0 -70
  43. package/coverage/lcov-report/base.css +0 -224
  44. package/coverage/lcov-report/block-navigation.js +0 -87
  45. package/coverage/lcov-report/favicon.png +0 -0
  46. package/coverage/lcov-report/index.html +0 -461
  47. package/coverage/lcov-report/prettify.css +0 -1
  48. package/coverage/lcov-report/prettify.js +0 -2
  49. package/coverage/lcov-report/react/components/Accordion/index.html +0 -116
  50. package/coverage/lcov-report/react/components/Accordion/index.jsx.html +0 -364
  51. package/coverage/lcov-report/react/components/Button/index.html +0 -116
  52. package/coverage/lcov-report/react/components/Button/index.js.html +0 -355
  53. package/coverage/lcov-report/react/components/Error/Collapsible.jsx.html +0 -349
  54. package/coverage/lcov-report/react/components/Error/ErrorUI.jsx.html +0 -178
  55. package/coverage/lcov-report/react/components/Error/error.js.html +0 -163
  56. package/coverage/lcov-report/react/components/Error/index.html +0 -146
  57. package/coverage/lcov-report/react/components/Footer/FooterUI.jsx.html +0 -880
  58. package/coverage/lcov-report/react/components/Footer/LegacyFooterUI.jsx.html +0 -667
  59. package/coverage/lcov-report/react/components/Footer/SocialLinks.jsx.html +0 -265
  60. package/coverage/lcov-report/react/components/Footer/Subscribe.jsx.html +0 -187
  61. package/coverage/lcov-report/react/components/Footer/footer.js.html +0 -175
  62. package/coverage/lcov-report/react/components/Footer/index.html +0 -176
  63. package/coverage/lcov-report/react/components/GovBanner/index.html +0 -116
  64. package/coverage/lcov-report/react/components/GovBanner/index.js.html +0 -409
  65. package/coverage/lcov-report/react/components/Header/HeaderAccountMenu.jsx.html +0 -592
  66. package/coverage/lcov-report/react/components/Header/HeaderCancel.jsx.html +0 -133
  67. package/coverage/lcov-report/react/components/Header/HeaderContainer.jsx.html +0 -280
  68. package/coverage/lcov-report/react/components/Header/HeaderLogo.jsx.html +0 -211
  69. package/coverage/lcov-report/react/components/Header/HeaderMenuButton.js.html +0 -235
  70. package/coverage/lcov-report/react/components/Header/HeaderMenuItem.jsx.html +0 -781
  71. package/coverage/lcov-report/react/components/Header/HeaderMenuLink.js.html +0 -235
  72. package/coverage/lcov-report/react/components/Header/HeaderMenuSignOutButton.js.html +0 -271
  73. package/coverage/lcov-report/react/components/Header/HeaderMobileButton.js.html +0 -196
  74. package/coverage/lcov-report/react/components/Header/HeaderUI.jsx.html +0 -586
  75. package/coverage/lcov-report/react/components/Header/HelpIcon.jsx.html +0 -181
  76. package/coverage/lcov-report/react/components/Header/ImpersonatorBanner.jsx.html +0 -331
  77. package/coverage/lcov-report/react/components/Header/NavigationButtonIcon.jsx.html +0 -166
  78. package/coverage/lcov-report/react/components/Header/header.js.html +0 -205
  79. package/coverage/lcov-report/react/components/Header/hooks.js.html +0 -241
  80. package/coverage/lcov-report/react/components/Header/index.html +0 -341
  81. package/coverage/lcov-report/react/components/Header/utag-helpers.js.html +0 -112
  82. package/coverage/lcov-report/react/components/Infotip/Infotip.jsx.html +0 -310
  83. package/coverage/lcov-report/react/components/Infotip/InfotipIcon.jsx.html +0 -208
  84. package/coverage/lcov-report/react/components/Infotip/index.html +0 -146
  85. package/coverage/lcov-report/react/components/Infotip/index.js.html +0 -94
  86. package/coverage/lcov-report/react/components/Modal/LegacyModal.jsx.html +0 -301
  87. package/coverage/lcov-report/react/components/Modal/Modal.jsx.html +0 -505
  88. package/coverage/lcov-report/react/components/Modal/index.html +0 -146
  89. package/coverage/lcov-report/react/components/Modal/index.jsx.html +0 -151
  90. package/coverage/lcov-report/react/components/NotificationBanner/index.html +0 -116
  91. package/coverage/lcov-report/react/components/NotificationBanner/index.js.html +0 -880
  92. package/coverage/lcov-report/react/components/SanitizedContent/index.html +0 -116
  93. package/coverage/lcov-report/react/components/SanitizedContent/index.jsx.html +0 -685
  94. package/coverage/lcov-report/react/components/SessionDialog/index.html +0 -116
  95. package/coverage/lcov-report/react/components/SessionDialog/sessionDialog.js.html +0 -163
  96. package/coverage/lcov-report/react/components/SessionDialogUI.jsx.html +0 -868
  97. package/coverage/lcov-report/react/components/SideNav/AnimationGroup/AnimationGroup.jsx.html +0 -166
  98. package/coverage/lcov-report/react/components/SideNav/AnimationGroup/index.html +0 -116
  99. package/coverage/lcov-report/react/components/SideNav/Chart/ScoreChart.jsx.html +0 -889
  100. package/coverage/lcov-report/react/components/SideNav/Chart/index.html +0 -131
  101. package/coverage/lcov-report/react/components/SideNav/Chart/index.js.html +0 -94
  102. package/coverage/lcov-report/react/components/SideNav/Content/LevelOneContent.jsx.html +0 -709
  103. package/coverage/lcov-report/react/components/SideNav/Content/LevelTwoContent.jsx.html +0 -733
  104. package/coverage/lcov-report/react/components/SideNav/Content/index.html +0 -146
  105. package/coverage/lcov-report/react/components/SideNav/Content/index.js.html +0 -97
  106. package/coverage/lcov-report/react/components/SideNav/Details/IndividualDetails.jsx.html +0 -139
  107. package/coverage/lcov-report/react/components/SideNav/Details/PracticeDetails.jsx.html +0 -220
  108. package/coverage/lcov-report/react/components/SideNav/Details/index.html +0 -146
  109. package/coverage/lcov-report/react/components/SideNav/Details/index.js.html +0 -97
  110. package/coverage/lcov-report/react/components/SideNav/Links/CmsSwitchLink.jsx.html +0 -208
  111. package/coverage/lcov-report/react/components/SideNav/Links/NavItemInline.jsx.html +0 -247
  112. package/coverage/lcov-report/react/components/SideNav/Links/NavLinkContainer.jsx.html +0 -199
  113. package/coverage/lcov-report/react/components/SideNav/Links/NavLinkDrawer.jsx.html +0 -883
  114. package/coverage/lcov-report/react/components/SideNav/Links/NavLinkInline.jsx.html +0 -406
  115. package/coverage/lcov-report/react/components/SideNav/Links/NavLinkToggle.jsx.html +0 -187
  116. package/coverage/lcov-report/react/components/SideNav/Links/index.html +0 -206
  117. package/coverage/lcov-report/react/components/SideNav/Links/index.js.html +0 -124
  118. package/coverage/lcov-report/react/components/SideNav/UI/SideNavUI.jsx.html +0 -1087
  119. package/coverage/lcov-report/react/components/SideNav/UI/index.html +0 -131
  120. package/coverage/lcov-report/react/components/SideNav/UI/index.js.html +0 -94
  121. package/coverage/lcov-report/react/components/SideNav/helpers.js.html +0 -238
  122. package/coverage/lcov-report/react/components/SideNav/index.html +0 -131
  123. package/coverage/lcov-report/react/components/SideNav/index.js.html +0 -244
  124. package/coverage/lcov-report/react/components/Tooltip/Tooltip.jsx.html +0 -349
  125. package/coverage/lcov-report/react/components/Tooltip/index.html +0 -146
  126. package/coverage/lcov-report/react/components/Tooltip/index.js.html +0 -94
  127. package/coverage/lcov-report/react/components/Tooltip/position.js.html +0 -289
  128. package/coverage/lcov-report/react/components/hooks/index.html +0 -116
  129. package/coverage/lcov-report/react/components/hooks/useGetConfig.js.html +0 -307
  130. package/coverage/lcov-report/react/components/index.html +0 -116
  131. package/coverage/lcov-report/react/index.html +0 -116
  132. package/coverage/lcov-report/react/index.js.html +0 -178
  133. package/coverage/lcov-report/react/lib/Chevron.jsx.html +0 -181
  134. package/coverage/lcov-report/react/lib/SvgComponents.jsx.html +0 -1702
  135. package/coverage/lcov-report/react/lib/index.html +0 -146
  136. package/coverage/lcov-report/react/lib/svg-definitions.svg.html +0 -460
  137. package/coverage/lcov-report/react/session/index.html +0 -161
  138. package/coverage/lcov-report/react/session/index.js.html +0 -100
  139. package/coverage/lcov-report/react/session/logout.js.html +0 -307
  140. package/coverage/lcov-report/react/session/refresh.js.html +0 -232
  141. package/coverage/lcov-report/react/session/ttl.js.html +0 -196
  142. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  143. package/coverage/lcov-report/sorter.js +0 -196
  144. package/coverage/lcov.info +0 -2924
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ cd react
5
+ npm run precommit
@@ -11,7 +11,7 @@ export const Default = () => (
11
11
  <div className="qpp-u-padding--16">
12
12
  <h1 className="h3">Information</h1>
13
13
  <Alert
14
- title='Information Alert'
14
+ title="Information Alert"
15
15
  description="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi imperdiet consequat ex ut vestibulum. Sed vel erat aliquet arcu eleifend gravida."
16
16
  />
17
17
  <h2 className="h3">Warning</h2>
@@ -1,7 +1,14 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
- const Alert = ({ title, children, description, variant, className, ...rest }) => {
4
+ const Alert = ({
5
+ title,
6
+ children,
7
+ description,
8
+ variant,
9
+ className,
10
+ ...rest
11
+ }) => {
5
12
  const HeadingComponent = title?.headingLevel || 'h2';
6
13
  return (
7
14
  <div
@@ -1,95 +1,103 @@
1
- import React, { useState } from 'react'
1
+ import React, { useState } from 'react';
2
2
 
3
3
  const GovBanner = () => {
4
- const [hideContent, setHideContent] = useState(true)
4
+ const [hideContent, setHideContent] = useState(true);
5
5
 
6
6
  return (
7
- <section className='qpp-c-gov-banner' aria-label='Official government website'>
8
- <div className='qpp-c-gov-banner__expand-wrap'>
9
- <header
10
- className={ `qpp-c-gov-banner__header ${!hideContent ? 'qpp-c-gov-banner__header--expanded' : ''}` }
7
+ <section
8
+ className="qpp-c-gov-banner"
9
+ aria-label="Official government website"
10
+ >
11
+ <div className="qpp-c-gov-banner__expand-wrap">
12
+ <header
13
+ className={`qpp-c-gov-banner__header ${
14
+ !hideContent ? 'qpp-c-gov-banner__header--expanded' : ''
15
+ }`}
11
16
  >
12
- <div className='qpp-c-gov-banner__inner'>
13
- <div className='qpp-c-gov-banner__header-col1'>
17
+ <div className="qpp-c-gov-banner__inner">
18
+ <div className="qpp-c-gov-banner__header-col1">
14
19
  <img
15
- className='qpp-c-gov-banner__header-flag'
16
- src='/images/us_flag_small.png'
17
- alt='U.S. flag'
20
+ className="qpp-c-gov-banner__header-flag"
21
+ src="/images/us_flag_small.png"
22
+ alt="U.S. flag"
18
23
  />
19
24
  </div>
20
- <div className='qpp-c-gov-banner__header-col2'>
21
- <p className='qpp-c-gov-banner__header-text'>
25
+ <div className="qpp-c-gov-banner__header-col2">
26
+ <p className="qpp-c-gov-banner__header-text">
22
27
  An official website of the United States government
23
28
  </p>
24
- <p className='qpp-c-gov-banner__header-action' aria-hidden='true'>
25
- <span className='qpp-c-gov-banner__header-action-text qpp-c-button qpp-c-button--text'>Here’s how you know</span><span className='qpp-c-gov-banner__header-action-icon qpp-c-button qpp-c-button--text'></span>
29
+ <p className="qpp-c-gov-banner__header-action" aria-hidden="true">
30
+ <span className="qpp-c-gov-banner__header-action-text qpp-c-button qpp-c-button--text">
31
+ Here’s how you know
32
+ </span>
33
+ <span className="qpp-c-gov-banner__header-action-icon qpp-c-button qpp-c-button--text"></span>
26
34
  </p>
27
35
  </div>
28
36
  <button
29
- className='qpp-c-gov-banner__button qpp-c-button qpp-c-button--icon-after qpp-c-button--text'
30
- aria-expanded={ !hideContent }
31
- aria-controls='qpp-gov-banner-content'
32
- onClick={ () => setHideContent(!hideContent) }
37
+ className="qpp-c-gov-banner__button qpp-c-button qpp-c-button--icon-after qpp-c-button--text"
38
+ aria-expanded={!hideContent}
39
+ aria-controls="qpp-gov-banner-content"
40
+ onClick={() => setHideContent(!hideContent)}
33
41
  >
34
- <span className='qpp-c-gov-banner__button-text'>Here’s how you know</span>
42
+ <span className="qpp-c-gov-banner__button-text">
43
+ Here’s how you know
44
+ </span>
35
45
  </button>
36
46
  </div>
37
47
  </header>
38
48
  <div
39
- className='qpp-c-gov-banner__content'
40
- id='qpp-gov-banner-content'
41
- hidden={ hideContent }
49
+ className="qpp-c-gov-banner__content"
50
+ id="qpp-gov-banner-content"
51
+ hidden={hideContent}
42
52
  >
43
- <div className='qpp-u-display--flex qpp-u-flex-direction--column qpp-u-xs-flex-direction--row qpp-u-flex-gap--24'>
44
- <div className='qpp-c-gov-banner__guidance'>
53
+ <div className="qpp-u-display--flex qpp-u-flex-direction--column qpp-u-xs-flex-direction--row qpp-u-flex-gap--24">
54
+ <div className="qpp-c-gov-banner__guidance">
45
55
  <img
46
- className='qpp-c-gov-banner__icon'
47
- src='/images/icon-dot-gov.svg'
48
- role='img'
49
- alt=''
50
- aria-hidden='true'
56
+ className="qpp-c-gov-banner__icon"
57
+ src="/images/icon-dot-gov.svg"
58
+ role="img"
59
+ alt=""
60
+ aria-hidden="true"
51
61
  />
52
62
  <div>
53
63
  <p>
54
64
  <strong> Official websites use .gov </strong>
55
- <br />
56
- A <strong>.gov</strong> website belongs to an official
65
+ <br />A <strong>.gov</strong> website belongs to an official
57
66
  government organization in the United States.
58
67
  </p>
59
68
  </div>
60
69
  </div>
61
- <div className='qpp-c-gov-banner__guidance'>
70
+ <div className="qpp-c-gov-banner__guidance">
62
71
  <img
63
- className='qpp-c-gov-banner__icon'
64
- src='/images/icon-https.svg'
65
- role='img'
66
- alt=''
67
- aria-hidden='true'
72
+ className="qpp-c-gov-banner__icon"
73
+ src="/images/icon-https.svg"
74
+ role="img"
75
+ alt=""
76
+ aria-hidden="true"
68
77
  />
69
78
  <div>
70
79
  <p>
71
80
  <strong> Secure .gov websites use HTTPS </strong>
72
- <br />
73
- A <strong>lock</strong> (
74
- <span className='icon-lock'>
81
+ <br />A <strong>lock</strong> (
82
+ <span className="icon-lock">
75
83
  <svg
76
- xmlns='http://www.w3.org/2000/svg'
77
- width='52'
78
- height='64'
79
- viewBox='0 0 52 64'
80
- className='qpp-c-gov-banner__lock-image '
81
- role='img'
82
- aria-labelledby='banner-lock-title-default banner-lock-description-default'
83
- focusable='false'
84
+ xmlns="http://www.w3.org/2000/svg"
85
+ width="52"
86
+ height="64"
87
+ viewBox="0 0 52 64"
88
+ className="qpp-c-gov-banner__lock-image "
89
+ role="img"
90
+ aria-labelledby="banner-lock-title-default banner-lock-description-default"
91
+ focusable="false"
84
92
  >
85
- <title id='banner-lock-title-default'>Lock</title>
86
- <desc id='banner-lock-description-default'>
93
+ <title id="banner-lock-title-default">Lock</title>
94
+ <desc id="banner-lock-description-default">
87
95
  A locked padlock
88
96
  </desc>
89
97
  <path
90
- fill='#000000'
91
- fillRule='evenodd'
92
- d='M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z'
98
+ fill="#000000"
99
+ fillRule="evenodd"
100
+ d="M26 0c10.493 0 19 8.507 19 19v9h3a4 4 0 0 1 4 4v28a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V32a4 4 0 0 1 4-4h3v-9C7 8.507 15.507 0 26 0zm0 8c-5.979 0-10.843 4.77-10.996 10.712L15 19v9h22v-9c0-6.075-4.925-11-11-11z"
93
101
  />
94
102
  </svg>
95
103
  </span>
@@ -103,7 +111,7 @@ const GovBanner = () => {
103
111
  </div>
104
112
  </div>
105
113
  </section>
106
- )
107
- }
114
+ );
115
+ };
108
116
 
109
- export default GovBanner
117
+ export default GovBanner;
@@ -40,7 +40,7 @@ const HeaderContainer = ({
40
40
  </a>
41
41
  )}
42
42
  <GovBanner />
43
- {!isIESupportPage && <NotificationBanner />}
43
+ {!isIESupportPage && <NotificationBanner />}
44
44
  <header id="top" className={showCancelButton ? 'show-cancel-button' : ''}>
45
45
  <HeaderLogo />
46
46
  {children}
@@ -77,7 +77,7 @@ const HeaderMenuItem = ({
77
77
  ) {
78
78
  return;
79
79
  }
80
- setOpenMobileSubMenu('')
80
+ setOpenMobileSubMenu('');
81
81
  closeMenus();
82
82
  };
83
83
  document.addEventListener('mousedown', listener);
@@ -85,10 +85,10 @@ const HeaderMenuItem = ({
85
85
  }, [menuRef]);
86
86
 
87
87
  useEffect(() => {
88
- if (!isMobileMenuExpanded || !isOpen){
89
- setOpenMobileSubMenu('')
88
+ if (!isMobileMenuExpanded || !isOpen) {
89
+ setOpenMobileSubMenu('');
90
90
  }
91
- }, [isMobileMenuExpanded, isOpen])
91
+ }, [isMobileMenuExpanded, isOpen]);
92
92
 
93
93
  return (
94
94
  <li
@@ -148,7 +148,11 @@ const HeaderMenuItem = ({
148
148
  <li
149
149
  onClick={handleClick}
150
150
  key={`item-link-${item.name}`}
151
- className={isSubLink ? 'nav-link-li sublink' : 'nav-link-li'}
151
+ className={
152
+ isSubLink
153
+ ? 'nav-link-li sublink'
154
+ : 'nav-link-li'
155
+ }
152
156
  >
153
157
  <SubMenuComponent
154
158
  href={item.href}
@@ -170,7 +174,10 @@ const HeaderMenuItem = ({
170
174
  >
171
175
  <Accordion
172
176
  title={c.heading}
173
- isOpen={isMobileMenuExpanded && openMobileSubMenu === c.heading}
177
+ isOpen={
178
+ isMobileMenuExpanded &&
179
+ openMobileSubMenu === c.heading
180
+ }
174
181
  >
175
182
  <ul>
176
183
  {c.items.map((item) => {
@@ -72,7 +72,7 @@ const Modal = ({
72
72
  id="modal-body"
73
73
  className="qpp-c-modal__body"
74
74
  ref={contentRef}
75
- tabIndex={overflowSeparator ? "0" : undefined}
75
+ tabIndex={overflowSeparator ? '0' : undefined}
76
76
  >
77
77
  {children}
78
78
  </div>
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
 
4
4
  const hasDarkerBackground = (darkerBackground) => {
5
5
  return darkerBackground ? 'background-highlight' : '';
6
- }
6
+ };
7
7
 
8
8
  const AnimationGroup = ({ display, className, children, darkerBackground }) => {
9
9
  return (
@@ -21,7 +21,7 @@ AnimationGroup.propTypes = {
21
21
  children: PropTypes.node,
22
22
  className: PropTypes.string,
23
23
  display: PropTypes.bool,
24
- darkerBackground: PropTypes.bool
24
+ darkerBackground: PropTypes.bool,
25
25
  };
26
26
 
27
27
  export default AnimationGroup;
@@ -1,74 +1,30 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import cookie from 'cookie';
4
4
  import jwtDecode from 'jwt-decode';
5
-
5
+ import { EyeIcon } from '../../../lib/SvgComponents';
6
6
  import { NavLinkContainer, NavLinkInline, NavLinkDrawer } from '../Links';
7
7
  import AnimationGroup from '../AnimationGroup/AnimationGroup';
8
8
  import defaultContent from '../UI/default-content';
9
9
  import {
10
- AccountHomeIcon,
11
- DashboardIcon,
12
- FacilityBasedPreviewIcon,
13
- HardshipIcon,
14
- HelpSupportIcon,
15
- ManageUsersIcon,
16
- MyApplicationsIcon,
17
- MyTestDataIcon,
18
- PaymentIcon,
19
- PhysicianCompareIcon,
20
- StarIcon,
21
- TargetIcon,
22
- IndividualReporting,
23
- } from '../../../lib/SvgComponents';
24
- import {
25
- dashboardUrl,
26
- facilityBasedPreviewBaseUrl,
27
- feedbackUrl,
28
- manageUrl,
29
- physicianCompareUrl,
30
- reportsPortalUrl,
31
- submissionsUrl,
10
+ loadUserPermissions,
11
+ getUrlConditionMap,
12
+ isMultiRoleUser,
13
+ isReviewerOrSelfNomRole,
14
+ getIcon,
15
+ isImpersonating,
16
+ isImpersonationLink,
32
17
  } from '../helpers';
33
-
34
- const getIcon = (url) =>
35
- ({
36
- [dashboardUrl]: DashboardIcon,
37
- [feedbackUrl]: StarIcon,
38
- [manageUrl]: ManageUsersIcon,
39
- [physicianCompareUrl]: PhysicianCompareIcon,
40
- [reportsPortalUrl]: HardshipIcon,
41
- [submissionsUrl]: AccountHomeIcon,
42
- [facilityBasedPreviewBaseUrl]: FacilityBasedPreviewIcon,
43
- '/developers': HelpSupportIcon,
44
- '/resources/help-and-support': HelpSupportIcon,
45
- '/user/apm-incentive-payments': PaymentIcon,
46
- '/user/applications': MyApplicationsIcon,
47
- '/user/exception/#/landing': HardshipIcon,
48
- '/user/targeted-review/#/landing': TargetIcon,
49
- '/user/test-data': MyTestDataIcon,
50
- '/user/self-nomination/#/landing': IndividualReporting,
51
- '/user/reviewers': DashboardIcon,
52
- '/reviewer/exception': HardshipIcon,
53
- '/reviewer/targeted-review': TargetIcon,
54
- '/self-nomination': IndividualReporting,
55
- }[url] || null);
18
+ import SelectRole from './SelectRole';
56
19
 
57
20
  const LevelOneContent = ({
58
21
  isExpanded,
59
22
  config: { linkCallback, useTooltips } = {},
60
23
  levelOneContent,
61
24
  }) => {
62
- let {
63
- qpp_has_authorizations,
64
- user_has_apm_payments,
65
- qpp_is_dev_pre,
66
- qpp_ehr_authorized,
67
- qpp_has_non_registry_authorizations,
68
- qpp_auth_token,
69
- qpp_cms_internal_authorized,
70
- qpp_can_impersonate,
71
- } = cookie.parse(document.cookie);
25
+ let { qpp_is_dev_pre, qpp_auth_token } = cookie.parse(document.cookie);
26
+
27
+ const [selectedRole, setSelectedRole] = useState('');
72
28
 
73
29
  let name = '';
74
30
  if (qpp_auth_token) {
@@ -76,111 +32,114 @@ const LevelOneContent = ({
76
32
  name = `${firstName} ${lastName}`;
77
33
  }
78
34
 
79
- const canImpersonate = qpp_can_impersonate === 'true';
80
- const hasAuthorizations = qpp_has_authorizations === 'true';
81
- const hasApmPayments = user_has_apm_payments === 'true';
82
- const isDevPre = qpp_is_dev_pre === 'true';
83
- const internalReviewerNames = JSON.parse(
84
- qpp_cms_internal_authorized || 'null'
85
- );
86
- const ehrAuthorized = qpp_ehr_authorized === 'true';
87
- const hasNonRegistryAuthorizations =
88
- qpp_has_non_registry_authorizations === 'true';
35
+ const permissions = loadUserPermissions(document.cookie, selectedRole);
36
+ const { internalReviewerNames } = permissions;
37
+
38
+ const hasMultipleRoles = isMultiRoleUser(document.cookie);
89
39
 
90
40
  const linkClass = isExpanded ? 'link-inline' : 'link-collapsed';
91
- let content = isDevPre ? levelOneContent?.devPre : levelOneContent?.default;
92
- if (
93
- (internalReviewerNames || []).some(
94
- (name) =>
95
- name === 'QPP Self-Nomination' ||
96
- name === 'QPP Targeted Review & Exceptions'
97
- )
98
- ) {
99
- content =
100
- levelOneContent?.internalReviewers || defaultContent.internalReviewers;
41
+
42
+ const isDevPre = qpp_is_dev_pre === 'true';
43
+
44
+ let content;
45
+ content = isDevPre ? levelOneContent?.devPre : levelOneContent?.default;
46
+
47
+ if (!hasMultipleRoles) {
48
+ if (internalReviewerNames?.some(isReviewerOrSelfNomRole)) {
49
+ content =
50
+ levelOneContent?.internalReviewers || defaultContent.internalReviewers;
51
+ }
52
+ } else {
53
+ if (selectedRole === 'Reviewer') {
54
+ content =
55
+ levelOneContent?.internalReviewers || defaultContent.internalReviewers;
56
+ }
101
57
  }
102
58
 
103
59
  // Mapping side nav link urls to the conditions that determine their inclusion in the side nav
104
- const urlConditionMap = {
105
- [dashboardUrl]: hasAuthorizations,
106
- [feedbackUrl]: hasAuthorizations,
107
- '/user/apm-incentive-payments': hasApmPayments,
108
- [physicianCompareUrl]: hasNonRegistryAuthorizations,
109
- [reportsPortalUrl]: hasAuthorizations,
110
- [facilityBasedPreviewBaseUrl]: hasAuthorizations,
111
- '/user/helpdesk-viewing-tool': canImpersonate,
112
-
113
- '/reviewer/exception': (internalReviewerNames || []).includes(
114
- 'QPP Targeted Review & Exceptions'
115
- ),
116
- '/reviewer/targeted-review': (internalReviewerNames || []).includes(
117
- 'QPP Targeted Review & Exceptions'
118
- ),
119
- '/self-nomination': (internalReviewerNames || []).includes(
120
- 'QPP Self-Nomination'
121
- ),
122
-
123
- // dev pre
124
- '/user/applications': ehrAuthorized,
125
- '/user/test-data': ehrAuthorized,
126
- };
127
-
128
- const navLinks = content.reduce((acc, link) => {
129
- const { url, label, className, listOfLinks, ...rest } = link;
130
-
131
- // Any links failing the corresponding condition in the urlConditionMap are skipped
132
- if (url in urlConditionMap && !urlConditionMap[url]) {
60
+ const urlConditionMap = getUrlConditionMap(permissions);
61
+
62
+ const navLinks = content
63
+ // Filter out Exception & Targeted Review links for Helpdesk Viewer when not impersonating
64
+ .filter((link) => {
65
+ const isHelpdeskRoleNotImpersonating =
66
+ selectedRole === 'Helpdesk Viewer' && !isImpersonating(document.cookie);
67
+ if (isHelpdeskRoleNotImpersonating) {
68
+ return (
69
+ link.url !== '/user/exception/#/landing' &&
70
+ link.url !== '/user/targeted-review/#/landing'
71
+ );
72
+ }
73
+ return link;
74
+ })
75
+ .reduce((acc, link) => {
76
+ const { url, label, className, listOfLinks, ...rest } = link;
77
+
78
+ // Any links failing the corresponding condition in the urlConditionMap are skipped
79
+ if (url in urlConditionMap && !urlConditionMap[url]) {
80
+ return acc;
81
+ }
82
+
83
+ const IconComponent = getIcon(url);
84
+ const Icon = IconComponent ? <IconComponent /> : null;
85
+ const sharedProps = {
86
+ url,
87
+ label,
88
+ linkCallback,
89
+ className: className ? `${linkClass} ${className}` : linkClass,
90
+ };
91
+
92
+ if (isImpersonating(document.cookie)) {
93
+ sharedProps.className = `${sharedProps.className} includes-read-only`;
94
+ }
95
+
96
+ const { pathname, hash } = window.location;
97
+ const filteredListOfLinks = (listOfLinks || []).filter((sublink) => {
98
+ return !(
99
+ sublink.url in urlConditionMap && !urlConditionMap[sublink.url]
100
+ );
101
+ });
102
+ if (
103
+ filteredListOfLinks?.length > 0 &&
104
+ (pathname === url ||
105
+ filteredListOfLinks.some(
106
+ (sublink) =>
107
+ pathname === sublink.url || `${pathname}${hash}` === sublink.url
108
+ ))
109
+ ) {
110
+ acc.push(
111
+ <NavLinkDrawer
112
+ key={`nav-drawer-${url}-${label}`}
113
+ leftIcon={Icon}
114
+ listOfLinks={filteredListOfLinks}
115
+ isExpanded={isExpanded}
116
+ staticDrawer={false}
117
+ openByDefault
118
+ isAlwaysOpen
119
+ {...sharedProps}
120
+ {...rest}
121
+ />
122
+ );
123
+ } else {
124
+ // Check if link is associated with the impersonated user not the Helpdesk Viewer user
125
+ const impersonationLink = isImpersonationLink(document.cookie, label);
126
+ acc.push(
127
+ <NavLinkInline
128
+ key={`nav-link-${url}-${label}`}
129
+ icon={Icon}
130
+ className={impersonationLink ? 'read-only-link' : ''}
131
+ {...(impersonationLink
132
+ ? { rightIcon: <EyeIcon classes="read-only-icon" /> }
133
+ : null)}
134
+ useTooltips={useTooltips}
135
+ showLabel={isExpanded}
136
+ {...sharedProps}
137
+ {...rest}
138
+ />
139
+ );
140
+ }
133
141
  return acc;
134
- }
135
-
136
- const IconComponent = getIcon(url);
137
- const Icon = IconComponent ? <IconComponent /> : null;
138
- const sharedProps = {
139
- url,
140
- label,
141
- linkCallback,
142
- className: className ? `${linkClass} ${className}` : linkClass,
143
- };
144
-
145
- const { pathname, hash } = window.location;
146
- const filteredListOfLinks = (listOfLinks || []).filter((sublink) => {
147
- return !(sublink.url in urlConditionMap && !urlConditionMap[sublink.url]);
148
- });
149
- if (
150
- filteredListOfLinks?.length > 0 &&
151
- (pathname === url ||
152
- filteredListOfLinks.some(
153
- (sublink) =>
154
- pathname === sublink.url || `${pathname}${hash}` === sublink.url
155
- ))
156
- ) {
157
- acc.push(
158
- <NavLinkDrawer
159
- key={`nav-drawer-${url}-${label}`}
160
- leftIcon={Icon}
161
- listOfLinks={filteredListOfLinks}
162
- isExpanded={isExpanded}
163
- staticDrawer={false}
164
- openByDefault
165
- isAlwaysOpen
166
- {...sharedProps}
167
- {...rest}
168
- />
169
- );
170
- } else {
171
- acc.push(
172
- <NavLinkInline
173
- key={`nav-link-${url}-${label}`}
174
- icon={Icon}
175
- useTooltips={useTooltips}
176
- showLabel={isExpanded}
177
- {...sharedProps}
178
- {...rest}
179
- />
180
- );
181
- }
182
- return acc;
183
- }, []);
142
+ }, []);
184
143
 
185
144
  return (
186
145
  <div className="sidebar-content">
@@ -188,6 +147,12 @@ const LevelOneContent = ({
188
147
  <h1 className="label">{name}</h1>
189
148
  </AnimationGroup>
190
149
  <div className="level-one-nav animation-flat">
150
+ {hasMultipleRoles && (
151
+ <SelectRole
152
+ selectedRole={selectedRole}
153
+ setSelectedRole={setSelectedRole}
154
+ />
155
+ )}
191
156
  <NavLinkContainer listOfLinks={navLinks} />
192
157
  </div>
193
158
  </div>