qpp-style 2.0.2-sm.3 → 2.0.3-sm.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.
- package/components/Footer/FooterUI.jsx +2 -3
- package/components/Header/ImpersonatorBanner.jsx +1 -2
- package/components/Infotip/Infotip.jsx +3 -7
- package/components/Infotip/InfotipContent.jsx +46 -0
- package/components/Search/index.js +2 -2
- package/components/SideNav/Content/LevelTwoContent.jsx +216 -0
- package/components/SideNav/Content/index.js +2 -1
- package/components/SideNav/Links/NavLinkInline.jsx +4 -2
- package/components/SideNav/UI/SideNavUI.jsx +59 -19
- package/components/SideNav/helpers.js +39 -0
- package/components/SideNav/index.js +0 -2
- package/components/Tabs/TabPanel.js +2 -38
- package/components/Tabs/Tabs.js +73 -0
- package/components/index.js +3 -5
- package/dist/browser.js +1 -1
- package/dist/browser.js.LICENSE.txt +0 -39
- package/dist/browser.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +0 -39
- package/dist/index.js.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.LICENSE.txt +8 -50
- package/dist/react/index.js.map +1 -1
- package/images/icons/svg/block.svg +5 -0
- package/images/icons/svg/check-circle.svg +5 -0
- package/lib/SvgComponents.jsx +120 -0
- package/package.json +6 -10
- package/session/logout.js +3 -0
- package/styles/qppds/components/_footer.scss +2 -2
- package/test/components/HeaderUI.test.js +1 -1
- package/test/components/Infotip.test.js +17 -11
- package/components/Accordion/Accordion.stories.js +0 -20
- package/components/Alert/Alert.stories.js +0 -61
- package/components/Details/Details.stories.js +0 -63
- package/components/DropdownButton/DropdownButton.stories.js +0 -127
- package/components/SideNav/UI/utils.js +0 -0
- package/components/Tabs/Tab.js +0 -26
- package/components/Tabs/index.js +0 -100
- package/components/Tooltip/Tooltip.jsx +0 -88
- package/components/Tooltip/Tooltip.stories.js +0 -80
- package/components/Tooltip/index.js +0 -3
- package/components/Tooltip/position.js +0 -68
- package/test/components/Tooltip.test.js +0 -147
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
|
|
3
|
-
|
|
4
2
|
import InfoTip from '../Infotip/Infotip';
|
|
5
3
|
import Subscribe from './Subscribe';
|
|
6
4
|
import SocialLinks from './SocialLinks';
|
|
7
5
|
import pjson from '../../package.json';
|
|
6
|
+
import { OpenInNewIcon } from '../../lib/SvgComponents';
|
|
8
7
|
|
|
9
8
|
const infoTipLabel =
|
|
10
9
|
'When dialing 711, you will automatically be connected to a TRS Communications Assistant who will relay your conversation to the help desk agent with strict confidentiality.';
|
|
@@ -126,7 +125,7 @@ const FooterUI = () => (
|
|
|
126
125
|
rel="noopener noreferrer"
|
|
127
126
|
>
|
|
128
127
|
<strong>Create or Track a QPP Service Center Ticket</strong>
|
|
129
|
-
<OpenInNewIcon
|
|
128
|
+
<OpenInNewIcon className="ccsq-link-icon" />
|
|
130
129
|
</a>
|
|
131
130
|
</h3>
|
|
132
131
|
</div>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import cookie from 'cookie';
|
|
3
3
|
import axios from 'axios';
|
|
4
|
-
import CloseIcon from '
|
|
5
|
-
|
|
4
|
+
import { CloseIcon } from '../../lib/SvgComponents';
|
|
6
5
|
import { TextButton } from '../Button';
|
|
7
6
|
import {
|
|
8
7
|
deleteImpersonatedUser,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import
|
|
3
|
+
import InfotipContent from './InfotipContent';
|
|
4
4
|
import InfotipIcon from './InfotipIcon';
|
|
5
5
|
|
|
6
6
|
const BUTTON_SIZE = '16px';
|
|
@@ -16,10 +16,6 @@ const buttonStyle = {
|
|
|
16
16
|
userSelect: 'none',
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
// Use basic touch handlers for mobile "tap-to-open" ui. Mobile touch
|
|
20
|
-
// is currently not supported by @reach/tooltip; this may change in future.
|
|
21
|
-
// Leverages @reach/tooltip "focus" behavior to open tooltip on tap,
|
|
22
|
-
// and close tooltip on second tap or loss of focus.
|
|
23
19
|
// TODO: We may want to improve this by tracking touch positions to ensure
|
|
24
20
|
// that a 'touchend' event must be reasonably close to the tooltip target.
|
|
25
21
|
const touchHandlers = {
|
|
@@ -41,7 +37,7 @@ const touchHandlers = {
|
|
|
41
37
|
* Tooltip with styled information icon
|
|
42
38
|
*/
|
|
43
39
|
const Infotip = ({ ariaLabel, label, lightIcon, ...props }) => (
|
|
44
|
-
<
|
|
40
|
+
<InfotipContent label={label} {...props}>
|
|
45
41
|
<button
|
|
46
42
|
type="button"
|
|
47
43
|
aria-label={ariaLabel}
|
|
@@ -56,7 +52,7 @@ const Infotip = ({ ariaLabel, label, lightIcon, ...props }) => (
|
|
|
56
52
|
style={{ float: 'left' }}
|
|
57
53
|
/>
|
|
58
54
|
</button>
|
|
59
|
-
</
|
|
55
|
+
</InfotipContent>
|
|
60
56
|
);
|
|
61
57
|
|
|
62
58
|
Infotip.propTypes = {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import {
|
|
4
|
+
Tooltip as TooltipAriaKit,
|
|
5
|
+
TooltipAnchor,
|
|
6
|
+
TooltipArrow,
|
|
7
|
+
useTooltipState,
|
|
8
|
+
} from 'ariakit/tooltip';
|
|
9
|
+
|
|
10
|
+
const TEXT_COLOR = '#FFF';
|
|
11
|
+
const BACKGROUND_COLOR = '#333';
|
|
12
|
+
|
|
13
|
+
const InfotipContent = ({ children, label }) => {
|
|
14
|
+
const tooltip = useTooltipState();
|
|
15
|
+
|
|
16
|
+
const cssStyles = {
|
|
17
|
+
maxWidth: '300px',
|
|
18
|
+
padding: '8px',
|
|
19
|
+
borderRadius: '4px',
|
|
20
|
+
fontSize: '0.9rem',
|
|
21
|
+
backgroundColor: BACKGROUND_COLOR,
|
|
22
|
+
color: TEXT_COLOR,
|
|
23
|
+
};
|
|
24
|
+
return (
|
|
25
|
+
<>
|
|
26
|
+
<TooltipAnchor as={'span'} state={tooltip} className="tooltip-anchor">
|
|
27
|
+
{children}
|
|
28
|
+
</TooltipAnchor>
|
|
29
|
+
<TooltipAriaKit
|
|
30
|
+
state={tooltip}
|
|
31
|
+
className="tooltip-content"
|
|
32
|
+
style={cssStyles}
|
|
33
|
+
>
|
|
34
|
+
{label}
|
|
35
|
+
<TooltipArrow />
|
|
36
|
+
</TooltipAriaKit>
|
|
37
|
+
</>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
InfotipContent.propTypes = {
|
|
42
|
+
children: PropTypes.node.isRequired,
|
|
43
|
+
label: PropTypes.node.isRequired,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default InfotipContent;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import SearchIcon from '
|
|
3
|
+
import { SearchIcon } from '../../lib/SvgComponents';
|
|
4
4
|
|
|
5
5
|
const Search = ({
|
|
6
6
|
id,
|
|
@@ -55,7 +55,7 @@ const Search = ({
|
|
|
55
55
|
className="qpp-c-search__submit qpp-c-button qpp-c-button--text"
|
|
56
56
|
>
|
|
57
57
|
<span className="qpp-u-visually-hidden">Search</span>
|
|
58
|
-
<SearchIcon
|
|
58
|
+
<SearchIcon viewBox="0 0 45 50" />
|
|
59
59
|
</button>
|
|
60
60
|
</div>
|
|
61
61
|
</form>
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
NavLinkContainer,
|
|
4
|
+
NavLinkInline,
|
|
5
|
+
NavLinkDrawer,
|
|
6
|
+
NavItemInline,
|
|
7
|
+
} from '../Links';
|
|
8
|
+
import AnimationGroup from '../AnimationGroup/AnimationGroup';
|
|
9
|
+
import { PracticeDetails } from '../Details';
|
|
10
|
+
import { ScoreChart } from '../Chart';
|
|
11
|
+
import PropTypes from 'prop-types';
|
|
12
|
+
import {
|
|
13
|
+
AccountHomeIcon,
|
|
14
|
+
DashboardIcon,
|
|
15
|
+
StarIcon,
|
|
16
|
+
CliniciansIcon,
|
|
17
|
+
ScoreIncrease,
|
|
18
|
+
TooltipIcon,
|
|
19
|
+
} from '../../../lib/SvgComponents.jsx';
|
|
20
|
+
import {
|
|
21
|
+
submissionsUrl,
|
|
22
|
+
manageUrl,
|
|
23
|
+
dashboardUrl,
|
|
24
|
+
performanceFeedbackUrl,
|
|
25
|
+
} from '../helpers';
|
|
26
|
+
|
|
27
|
+
const PAST_REPORTING_YEARS = ['2017', '2018'];
|
|
28
|
+
|
|
29
|
+
const LevelTwoContent = ({
|
|
30
|
+
isExpanded,
|
|
31
|
+
chartData,
|
|
32
|
+
showReportingLinks,
|
|
33
|
+
config: {
|
|
34
|
+
chartActive = true,
|
|
35
|
+
openDrawersByDefault,
|
|
36
|
+
linkCallback,
|
|
37
|
+
updateTime,
|
|
38
|
+
practiceId,
|
|
39
|
+
practiceName,
|
|
40
|
+
practiceTin,
|
|
41
|
+
apmEntityId,
|
|
42
|
+
isConnectedUsersPage,
|
|
43
|
+
vgId,
|
|
44
|
+
roleAbbr,
|
|
45
|
+
performanceYear,
|
|
46
|
+
finalFeedbackOpen,
|
|
47
|
+
isApmPaymentDetailsPage,
|
|
48
|
+
useTooltips,
|
|
49
|
+
cpcPlusId,
|
|
50
|
+
pcfId,
|
|
51
|
+
} = {},
|
|
52
|
+
}) => {
|
|
53
|
+
const linkClass = isExpanded ? 'link-inline' : 'link-collapsed';
|
|
54
|
+
let links = [];
|
|
55
|
+
|
|
56
|
+
if (isApmPaymentDetailsPage) {
|
|
57
|
+
const apmDetailsUrl = '/user/apm-incentive-payments/(.*)/practice-details';
|
|
58
|
+
links.push(
|
|
59
|
+
<NavItemInline
|
|
60
|
+
icon={<CliniciansIcon />}
|
|
61
|
+
className={linkClass}
|
|
62
|
+
label="Payment Details"
|
|
63
|
+
urlExpressionToMatch={apmDetailsUrl}
|
|
64
|
+
showLabel={isExpanded}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
} else {
|
|
68
|
+
const linkLabel = isConnectedUsersPage
|
|
69
|
+
? 'Connected Users'
|
|
70
|
+
: 'Eligibility & Reporting';
|
|
71
|
+
let items = [];
|
|
72
|
+
|
|
73
|
+
const practiceUrlSegment =
|
|
74
|
+
performanceYear === '2017' || performanceYear === '2018' || !roleAbbr
|
|
75
|
+
? practiceId
|
|
76
|
+
: practiceId + '_' + roleAbbr;
|
|
77
|
+
|
|
78
|
+
if (showReportingLinks && !apmEntityId) {
|
|
79
|
+
items = [
|
|
80
|
+
{
|
|
81
|
+
url: `${submissionsUrl}/reporting/${practiceUrlSegment}/overview`,
|
|
82
|
+
label: vgId ? 'Virtual Group Reporting' : 'Group Reporting Overview',
|
|
83
|
+
items: [
|
|
84
|
+
{
|
|
85
|
+
url: `${submissionsUrl}/reporting/${practiceUrlSegment}/quality`,
|
|
86
|
+
label: 'Quality Measures',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
url: `${submissionsUrl}/reporting/${practiceUrlSegment}/aci`,
|
|
90
|
+
label: 'Promoting Interoperability',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
url: `${submissionsUrl}/reporting/${practiceUrlSegment}/ia`,
|
|
94
|
+
label: 'Improvement Activities',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
links.push(
|
|
101
|
+
<NavLinkDrawer
|
|
102
|
+
key="connected-clinicians-link"
|
|
103
|
+
isAlwaysOpen
|
|
104
|
+
url={
|
|
105
|
+
!isConnectedUsersPage
|
|
106
|
+
? `${dashboardUrl}`
|
|
107
|
+
: `${manageUrl}/${practiceId}/connected-users`
|
|
108
|
+
}
|
|
109
|
+
isExpanded={isExpanded}
|
|
110
|
+
openByDefault={openDrawersByDefault}
|
|
111
|
+
leftIcon={<DashboardIcon />}
|
|
112
|
+
className={linkClass}
|
|
113
|
+
label={linkLabel}
|
|
114
|
+
linkCallback={linkCallback}
|
|
115
|
+
listOfLinks={
|
|
116
|
+
!isConnectedUsersPage && [
|
|
117
|
+
{
|
|
118
|
+
label: vgId
|
|
119
|
+
? 'Virtual Group Details & Participants'
|
|
120
|
+
: apmEntityId
|
|
121
|
+
? 'APM Entity Details & Participants'
|
|
122
|
+
: 'Practice Details & Clinicians',
|
|
123
|
+
items: items,
|
|
124
|
+
},
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
disabled={isConnectedUsersPage ? true : false}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
if (
|
|
131
|
+
(apmEntityId && performanceYear === '2018' && finalFeedbackOpen) ||
|
|
132
|
+
(!apmEntityId &&
|
|
133
|
+
!vgId &&
|
|
134
|
+
!isConnectedUsersPage &&
|
|
135
|
+
PAST_REPORTING_YEARS.indexOf(performanceYear) >= 0)
|
|
136
|
+
) {
|
|
137
|
+
links.push(
|
|
138
|
+
<NavLinkInline
|
|
139
|
+
key="performance-feedback-link"
|
|
140
|
+
icon={<StarIcon />}
|
|
141
|
+
className={linkClass}
|
|
142
|
+
url={performanceFeedbackUrl(
|
|
143
|
+
finalFeedbackOpen && performanceYear === '2018'
|
|
144
|
+
? performanceYear
|
|
145
|
+
: '2017'
|
|
146
|
+
)}
|
|
147
|
+
label="Performance Feedback"
|
|
148
|
+
linkCallback={linkCallback}
|
|
149
|
+
showLabel={isExpanded}
|
|
150
|
+
useTooltips={useTooltips}
|
|
151
|
+
/>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<div className="sidebar-content">
|
|
158
|
+
<AnimationGroup display={isExpanded}>
|
|
159
|
+
<NavLinkInline
|
|
160
|
+
icon={<AccountHomeIcon />}
|
|
161
|
+
url={submissionsUrl}
|
|
162
|
+
label="Account Home"
|
|
163
|
+
showLabel={isExpanded}
|
|
164
|
+
className="account-home-link"
|
|
165
|
+
linkCallback={linkCallback}
|
|
166
|
+
useTooltips={useTooltips}
|
|
167
|
+
/>
|
|
168
|
+
<hr />
|
|
169
|
+
</AnimationGroup>
|
|
170
|
+
<AnimationGroup display={isExpanded} className={'details'}>
|
|
171
|
+
<PracticeDetails
|
|
172
|
+
practiceName={practiceName}
|
|
173
|
+
{...(!practiceTin ? {} : { practiceTin })}
|
|
174
|
+
{...(!apmEntityId ? {} : { apmEntityId })}
|
|
175
|
+
{...(!vgId ? {} : { vgId })}
|
|
176
|
+
{...(!cpcPlusId ? {} : { cpcPlusId })}
|
|
177
|
+
{...(!pcfId ? {} : { pcfId })}
|
|
178
|
+
/>
|
|
179
|
+
<hr />
|
|
180
|
+
</AnimationGroup>
|
|
181
|
+
<div className="level-two-nav animation-flat">
|
|
182
|
+
<NavLinkContainer listOfLinks={links} />
|
|
183
|
+
<AnimationGroup display={isExpanded && chartActive} className="chart">
|
|
184
|
+
<div>
|
|
185
|
+
<hr />
|
|
186
|
+
<div className="chart-title">
|
|
187
|
+
<p className="title">Final Group Score</p>
|
|
188
|
+
<p className="disclaimer">
|
|
189
|
+
<svg className="left-icon" aria-hidden="true">
|
|
190
|
+
<ScoreIncrease />
|
|
191
|
+
</svg>
|
|
192
|
+
Score may increase
|
|
193
|
+
<svg className="right-icon" aria-hidden="true">
|
|
194
|
+
<TooltipIcon />
|
|
195
|
+
</svg>
|
|
196
|
+
</p>
|
|
197
|
+
{updateTime && (
|
|
198
|
+
<p className="timestamp">Last update at {updateTime}</p>
|
|
199
|
+
)}
|
|
200
|
+
</div>
|
|
201
|
+
<ScoreChart chartData={chartData} linkCallback={linkCallback} />
|
|
202
|
+
</div>
|
|
203
|
+
</AnimationGroup>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
LevelTwoContent.propTypes = {
|
|
210
|
+
isExpanded: PropTypes.bool,
|
|
211
|
+
config: PropTypes.object,
|
|
212
|
+
chartData: PropTypes.object,
|
|
213
|
+
showReportingLinks: PropTypes.bool,
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export default LevelTwoContent;
|
|
@@ -14,6 +14,7 @@ const NavLinkInline = ({
|
|
|
14
14
|
showLabel,
|
|
15
15
|
linkCallback,
|
|
16
16
|
disabled,
|
|
17
|
+
useTooltips,
|
|
17
18
|
target,
|
|
18
19
|
}) => {
|
|
19
20
|
const localUrl = urlExpressionToMatch || url;
|
|
@@ -25,12 +26,12 @@ const NavLinkInline = ({
|
|
|
25
26
|
const tooltipRef = React.useRef();
|
|
26
27
|
|
|
27
28
|
React.useEffect(() => {
|
|
28
|
-
if (!showLabel && svgRef.current) {
|
|
29
|
+
if (!showLabel && useTooltips && svgRef.current) {
|
|
29
30
|
const existingMouseenter = svgRef.current.onmouseover;
|
|
30
31
|
const existingMouseout = svgRef.current.onmouseout;
|
|
31
32
|
|
|
32
33
|
svgRef.current.onmouseover = () => {
|
|
33
|
-
if (tooltipRef.current) {
|
|
34
|
+
if (tooltipRef.current && useTooltips) {
|
|
34
35
|
const svgOffset = svgRef.current.getBoundingClientRect();
|
|
35
36
|
tooltipRef.current.style.top = `${svgOffset.top - 5}px`;
|
|
36
37
|
tooltipRef.current.style.display = 'block';
|
|
@@ -104,6 +105,7 @@ NavLinkInline.propTypes = {
|
|
|
104
105
|
showLabel: PropTypes.bool,
|
|
105
106
|
linkCallback: PropTypes.func,
|
|
106
107
|
disabled: PropTypes.bool,
|
|
108
|
+
useTooltips: PropTypes.bool,
|
|
107
109
|
target: PropTypes.string,
|
|
108
110
|
};
|
|
109
111
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { useState, useRef } from 'react';
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
|
+
import { sideNavExpandedStorage } from '../helpers';
|
|
4
5
|
import { withGetConfig } from '../../hooks/useGetConfig';
|
|
5
|
-
import { LevelOneContent } from '../Content';
|
|
6
|
+
import { LevelOneContent, LevelTwoContent } from '../Content';
|
|
6
7
|
import {
|
|
7
8
|
NavLinkContainer,
|
|
8
9
|
NavLinkInline,
|
|
@@ -18,20 +19,28 @@ import CmsSwitchLink from '../Links/CmsSwitchLink';
|
|
|
18
19
|
import defaultContent from './default-content';
|
|
19
20
|
|
|
20
21
|
const SideNavUI = ({
|
|
22
|
+
chartData,
|
|
21
23
|
config,
|
|
24
|
+
currentLevel,
|
|
22
25
|
isAltStyle,
|
|
23
|
-
isExpanded,
|
|
24
26
|
items,
|
|
25
27
|
onCollapsed,
|
|
26
28
|
onExpanded,
|
|
27
29
|
performanceYear,
|
|
30
|
+
showReportingLinks,
|
|
28
31
|
result,
|
|
29
32
|
}) => {
|
|
30
|
-
|
|
33
|
+
// Use localStorage value to set init state, default to true
|
|
34
|
+
const [isExpandedState, setIsExpandedState] = useState(
|
|
35
|
+
sideNavExpandedStorage.setDefault()
|
|
36
|
+
);
|
|
37
|
+
const [itemsState, setItemsState] = useState(items);
|
|
38
|
+
const [currentLevelState, setCurrentLevelState] = useState(currentLevel);
|
|
31
39
|
|
|
32
40
|
const collapseRef = useRef(null);
|
|
33
41
|
|
|
34
42
|
const expand = () => {
|
|
43
|
+
sideNavExpandedStorage.toggle();
|
|
35
44
|
setIsExpandedState(true);
|
|
36
45
|
if (onExpanded) {
|
|
37
46
|
onExpanded();
|
|
@@ -39,6 +48,7 @@ const SideNavUI = ({
|
|
|
39
48
|
};
|
|
40
49
|
|
|
41
50
|
const collapse = () => {
|
|
51
|
+
sideNavExpandedStorage.toggle();
|
|
42
52
|
setIsExpandedState(false);
|
|
43
53
|
if (onCollapsed) {
|
|
44
54
|
onCollapsed();
|
|
@@ -49,8 +59,30 @@ const SideNavUI = ({
|
|
|
49
59
|
isExpandedState ? collapse() : expand();
|
|
50
60
|
};
|
|
51
61
|
|
|
62
|
+
const getLevelContent = () => {
|
|
63
|
+
return (
|
|
64
|
+
{
|
|
65
|
+
2: (
|
|
66
|
+
<LevelTwoContent
|
|
67
|
+
showReportingLinks={showReportingLinks}
|
|
68
|
+
isExpanded={isExpandedState}
|
|
69
|
+
chartData={chartData}
|
|
70
|
+
config={config}
|
|
71
|
+
/>
|
|
72
|
+
),
|
|
73
|
+
}[currentLevelState] || (
|
|
74
|
+
<LevelOneContent
|
|
75
|
+
levelOneContent={result?.content}
|
|
76
|
+
isExpanded={isExpandedState}
|
|
77
|
+
config={config}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
52
83
|
const getDynamicContent = (contentItems, className, recursionId) => {
|
|
53
|
-
const { openDrawersByDefault, linkActiveFunc, linkCallback } =
|
|
84
|
+
const { openDrawersByDefault, linkActiveFunc, linkCallback, useTooltips } =
|
|
85
|
+
config;
|
|
54
86
|
let linkClass = isExpandedState ? 'link-inline' : 'link-collapsed';
|
|
55
87
|
const containerRecursionId = recursionId || 0;
|
|
56
88
|
|
|
@@ -90,6 +122,7 @@ const SideNavUI = ({
|
|
|
90
122
|
label={item.label}
|
|
91
123
|
linkCallback={linkCallback}
|
|
92
124
|
showLabel={true}
|
|
125
|
+
useTooltips={useTooltips}
|
|
93
126
|
/>
|
|
94
127
|
</AnimationGroup>
|
|
95
128
|
),
|
|
@@ -102,6 +135,7 @@ const SideNavUI = ({
|
|
|
102
135
|
label={item.label}
|
|
103
136
|
linkCallback={linkCallback}
|
|
104
137
|
showLabel={true}
|
|
138
|
+
useTooltips={useTooltips}
|
|
105
139
|
/>
|
|
106
140
|
</AnimationGroup>
|
|
107
141
|
),
|
|
@@ -191,6 +225,7 @@ const SideNavUI = ({
|
|
|
191
225
|
linkCallback={linkCallback}
|
|
192
226
|
showLabel={isExpandedState}
|
|
193
227
|
disabled={item.disabled}
|
|
228
|
+
useTooltips={useTooltips}
|
|
194
229
|
target={item.target}
|
|
195
230
|
/>
|
|
196
231
|
)
|
|
@@ -214,18 +249,25 @@ const SideNavUI = ({
|
|
|
214
249
|
}
|
|
215
250
|
};
|
|
216
251
|
|
|
217
|
-
const content =
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
252
|
+
const content = itemsState
|
|
253
|
+
? getDynamicContent(
|
|
254
|
+
itemsState,
|
|
255
|
+
'sidebar-content' + (isAltStyle ? ' alt-style' : '')
|
|
256
|
+
)
|
|
257
|
+
: getLevelContent();
|
|
258
|
+
|
|
259
|
+
// Set side nav expanded state in localStorage on initial render
|
|
260
|
+
useEffect(() => {
|
|
261
|
+
sideNavExpandedStorage.init();
|
|
262
|
+
}, []);
|
|
263
|
+
|
|
264
|
+
useEffect(() => {
|
|
265
|
+
setCurrentLevelState(currentLevel);
|
|
266
|
+
}, [currentLevel]);
|
|
267
|
+
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
setItemsState(items);
|
|
270
|
+
}, [items]);
|
|
229
271
|
|
|
230
272
|
return (
|
|
231
273
|
<aside
|
|
@@ -248,7 +290,6 @@ const SideNavUI = ({
|
|
|
248
290
|
|
|
249
291
|
SideNavUI.propTypes = {
|
|
250
292
|
currentLevel: PropTypes.number,
|
|
251
|
-
isExpanded: PropTypes.bool,
|
|
252
293
|
onExpanded: PropTypes.func,
|
|
253
294
|
onCollapsed: PropTypes.func,
|
|
254
295
|
chartData: PropTypes.object,
|
|
@@ -270,7 +311,6 @@ SideNavUI.propTypes = {
|
|
|
270
311
|
|
|
271
312
|
SideNavUI.defaultProps = {
|
|
272
313
|
currentLevel: 1,
|
|
273
|
-
isExpanded: true,
|
|
274
314
|
onExpanded: () => {},
|
|
275
315
|
onCollapsed: () => {},
|
|
276
316
|
chartData: {},
|
|
@@ -328,6 +328,44 @@ const isImpersonationLink = (docCookie, linkLabel) => {
|
|
|
328
328
|
return !helpdeskLinks.includes(linkLabel);
|
|
329
329
|
};
|
|
330
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Set SideNav expanded state as qpp_side_nav_expanded in localStorage
|
|
333
|
+
*/
|
|
334
|
+
const sideNavExpandedStorage = {
|
|
335
|
+
isNullOrUndefined: function () {
|
|
336
|
+
const sideNavExpandedValue = localStorage.getItem('qpp_side_nav_expanded');
|
|
337
|
+
return sideNavExpandedValue === null || sideNavExpandedValue === undefined;
|
|
338
|
+
},
|
|
339
|
+
init: function () {
|
|
340
|
+
if (this.isNullOrUndefined()) {
|
|
341
|
+
localStorage.setItem('qpp_side_nav_expanded', true);
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
toggle: function () {
|
|
345
|
+
const isSideNavExpanded = JSON.parse(
|
|
346
|
+
localStorage.getItem('qpp_side_nav_expanded')
|
|
347
|
+
);
|
|
348
|
+
if (!isSideNavExpanded) {
|
|
349
|
+
localStorage.setItem('qpp_side_nav_expanded', true);
|
|
350
|
+
} else {
|
|
351
|
+
localStorage.setItem('qpp_side_nav_expanded', false);
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
get: function () {
|
|
355
|
+
return JSON.parse(localStorage.getItem('qpp_side_nav_expanded'));
|
|
356
|
+
},
|
|
357
|
+
remove: function () {
|
|
358
|
+
localStorage.removeItem('qpp_side_nav_expanded');
|
|
359
|
+
},
|
|
360
|
+
setDefault: function () {
|
|
361
|
+
let defaultValue = true;
|
|
362
|
+
if (!this.isNullOrUndefined()) {
|
|
363
|
+
defaultValue = this.get();
|
|
364
|
+
}
|
|
365
|
+
return defaultValue;
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
|
|
331
369
|
module.exports = {
|
|
332
370
|
submissionsUrl,
|
|
333
371
|
dashboardUrl,
|
|
@@ -348,4 +386,5 @@ module.exports = {
|
|
|
348
386
|
isImpersonating,
|
|
349
387
|
isImpersonationLink,
|
|
350
388
|
loadSideNavContent,
|
|
389
|
+
sideNavExpandedStorage,
|
|
351
390
|
};
|
|
@@ -5,7 +5,6 @@ import { SideNavUI } from './UI';
|
|
|
5
5
|
const SideNav = (options = {}) => {
|
|
6
6
|
const {
|
|
7
7
|
rootElement,
|
|
8
|
-
isExpanded,
|
|
9
8
|
onExpanded,
|
|
10
9
|
onCollapsed,
|
|
11
10
|
chartData,
|
|
@@ -26,7 +25,6 @@ const SideNav = (options = {}) => {
|
|
|
26
25
|
|
|
27
26
|
const { expand, collapse } = render(
|
|
28
27
|
<SideNavUI
|
|
29
|
-
isExpanded={isExpanded}
|
|
30
28
|
onExpanded={onExpanded}
|
|
31
29
|
onCollapsed={onCollapsed}
|
|
32
30
|
chartData={chartData}
|
|
@@ -1,41 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const TabPanel = ({
|
|
5
|
-
children,
|
|
6
|
-
value,
|
|
7
|
-
id,
|
|
8
|
-
index,
|
|
9
|
-
className,
|
|
10
|
-
disabled,
|
|
11
|
-
}) => {
|
|
12
|
-
const classes = ['qpp-c-tabs__panel', className].filter(Boolean).join(' ');
|
|
13
|
-
return (
|
|
14
|
-
<div
|
|
15
|
-
role="tabpanel"
|
|
16
|
-
id={id}
|
|
17
|
-
aria-hidden={value !== index}
|
|
18
|
-
aria-labelledby={`qpp-c-tabs__item--${id}`}
|
|
19
|
-
aria-disabled={disabled}
|
|
20
|
-
className={classes}
|
|
21
|
-
>
|
|
22
|
-
{value === index && children}
|
|
23
|
-
</div>
|
|
24
|
-
);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
TabPanel.propTypes = {
|
|
28
|
-
children: PropTypes.node,
|
|
29
|
-
className: PropTypes.string,
|
|
30
|
-
index: PropTypes.number.isRequired,
|
|
31
|
-
id: PropTypes.string,
|
|
32
|
-
value: PropTypes.number.isRequired,
|
|
33
|
-
disabled: PropTypes.bool,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
TabPanel.defaultProps = {
|
|
37
|
-
index: 0,
|
|
38
|
-
value: 0,
|
|
1
|
+
const TabPanel = ({ children }) => {
|
|
2
|
+
return children;
|
|
39
3
|
};
|
|
40
4
|
|
|
41
5
|
export default TabPanel;
|