@rh-support/troubleshoot 2.2.18 → 2.2.20
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/lib/esm/components/AccountInfo/OwnerSelector.d.ts.map +1 -1
- package/lib/esm/components/AccountInfo/OwnerSelector.js +2 -2
- package/lib/esm/components/CaseEditView/CaseDetailsTabs.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseDetailsTabs.js +18 -9
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutionsItem.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutionsItem.js +3 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseBugzilla/CaseBugzilla.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseBugzilla/CaseBugzilla.js +11 -7
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.js +13 -18
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseInformation.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseInformation.js +2 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/ProductVersion.js +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.js +2 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.js +3 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseExternalTrackerUpdate.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseExternalTrackerUpdate.js +5 -3
- package/lib/esm/components/CaseEditView/Tabs/CasePrivateNotes/CasePrivateNotes.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CasePrivateNotes/CasePrivateNotes.js +4 -2
- package/lib/esm/components/CaseInformation/ContactPhoneNumber.d.ts.map +1 -1
- package/lib/esm/components/CaseInformation/ContactPhoneNumber.js +11 -17
- package/lib/esm/components/CaseInformation/Description.d.ts.map +1 -1
- package/lib/esm/components/CaseInformation/Description.js +1 -1
- package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/OpenshiftDropdownV4.js +1 -1
- package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.js +1 -1
- package/lib/esm/components/EditDescription/EditDescription.d.ts.map +1 -1
- package/lib/esm/components/EditDescription/EditDescription.js +2 -1
- package/lib/esm/components/ProductSelector/ProductSelector.js +1 -1
- package/lib/esm/components/Recommendations/EARules/EARule.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/EARules/EARule.js +4 -1
- package/lib/esm/components/Recommendations/InsightsRuleInfo.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/InsightsRuleInfo.js +5 -3
- package/lib/esm/components/Recommendations/Recommendations.d.ts +0 -1
- package/lib/esm/components/Recommendations/Recommendations.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/Recommendations.js +0 -4
- package/lib/esm/components/Recommendations/RulesModal.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/RulesModal.js +2 -2
- package/lib/esm/components/SessionRestore/SessionItem.js +4 -4
- package/lib/esm/components/SessionRestore/SessionRestore.d.ts.map +1 -1
- package/lib/esm/components/SessionRestore/SessionRestore.js +4 -4
- package/lib/esm/components/shared/Rule.d.ts.map +1 -1
- package/lib/esm/components/shared/Rule.js +2 -1
- package/lib/esm/components/shared/fileUpload/FileLister.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/FileLister.js +6 -9
- package/lib/esm/components/shared/utils.d.ts.map +1 -1
- package/lib/esm/components/shared/utils.js +1 -4
- package/lib/esm/components/wizardLayout/WizardLayout.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardLayout.js +4 -3
- package/lib/esm/constants/caseDetailsConstants.d.ts +1 -2
- package/lib/esm/constants/caseDetailsConstants.d.ts.map +1 -1
- package/lib/esm/constants/caseDetailsConstants.js +1 -2
- package/lib/esm/reducers/CaseConstNTypes.d.ts +2 -2
- package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
- package/lib/esm/reducers/CaseConstNTypes.js +1 -1
- package/lib/esm/reducers/CaseHelpers.d.ts.map +1 -1
- package/lib/esm/reducers/CaseHelpers.js +2 -0
- package/lib/esm/reducers/CaseReducer.d.ts +4 -2
- package/lib/esm/reducers/CaseReducer.d.ts.map +1 -1
- package/lib/esm/reducers/CaseReducer.js +14 -5
- package/lib/esm/reducers/SessionRestoreReducer.d.ts.map +1 -1
- package/package.json +6 -6
- package/lib/esm/components/Issue/Issue.d.ts +0 -2
- package/lib/esm/components/Issue/Issue.d.ts.map +0 -1
- package/lib/esm/components/Issue/Issue.js +0 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OwnerSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountInfo/OwnerSelector.tsx"],"names":[],"mappings":"AAqCA,UAAU,MAAM;CAAG;AAEnB,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"OwnerSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/AccountInfo/OwnerSelector.tsx"],"names":[],"mappings":"AAqCA,UAAU,MAAM;CAAG;AAEnB,iBAAS,aAAa,CAAC,KAAK,EAAE,MAAM,eA2VnC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -272,11 +272,11 @@ function OwnerSelector(props) {
|
|
|
272
272
|
const showUsersWithSelectedGroupAccess = caseNumber &&
|
|
273
273
|
(selectedCaseGroupUsers.isFetching ||
|
|
274
274
|
(!selectedCaseGroupUsers.isFetching && (selectedCaseGroupUsers.data || []).length > 0));
|
|
275
|
-
return (React.createElement("div", { className: "form-group get-support-owner-wapper" },
|
|
275
|
+
return (React.createElement("div", { className: "form-group get-support-owner-wapper", "data-tracking-id": "get-support-owner" },
|
|
276
276
|
React.createElement("label", { htmlFor: "get-support-owner" },
|
|
277
277
|
React.createElement(Trans, null, "Owner"),
|
|
278
278
|
React.createElement(ValueChangedIcon, { afterLocalChange: afterLocalChange, comparator: ownerComparator, isLocalChange: localOwnerChange, value: selectedOwner.data, getTooltipContent: getChangedValueTooltip(() => CaseValuesToWatch.owner, (v) => v.fullNameCustom) }),
|
|
279
279
|
React.createElement("span", { className: `form-required ${isExportingPDF ? 'hide-in-pdf' : ''}`, "aria-hidden": true }, "*")),
|
|
280
|
-
showUsersWithSelectedGroupAccess ? (React.createElement(Typeahead, { id: "get-support-owner", className: "react-select-custom", clearButton: true, isLoading: selectedCaseGroupUsers.isFetching || isCaseOwnerUpdating, options: usersWithGroupAccess, selected: !isEmpty(selectedOwner.data) ? [selectedOwner.data] : [], onChange: onCustomerContactSelect, labelKey: getHydraContactLabel, placeholder: t(`Search by name or username`), disabled: selectedCaseGroupUsers.isFetching || isCaseOwnerUpdating, renderMenuItemChildren: renderMenuItemChildren
|
|
280
|
+
showUsersWithSelectedGroupAccess ? (React.createElement(Typeahead, { id: "get-support-owner", className: "react-select-custom", clearButton: true, isLoading: selectedCaseGroupUsers.isFetching || isCaseOwnerUpdating, options: usersWithGroupAccess, selected: !isEmpty(selectedOwner.data) ? [selectedOwner.data] : [], onChange: onCustomerContactSelect, labelKey: getHydraContactLabel, placeholder: t(`Search by name or username`), disabled: selectedCaseGroupUsers.isFetching || isCaseOwnerUpdating, renderMenuItemChildren: renderMenuItemChildren })) : (React.createElement(CaseContactsSelectorExternal, { loggedInUserRights: loggedInUserRights.data, selectedAccountNumber: accountNumber, selected: !isEmpty(selectedOwner.data) ? [selectedOwner.data] : [], onChange: onCustomerContactSelect, placeholder: t(`Search by name or username`), clearButton: true, id: "get-support-owner", name: "get-support-owner", className: "react-select-custom", isUpdating: isCaseOwnerUpdating, isInvalid: isNextBtnClickedToShowValidationError && isEmpty(selectedOwner.data) }))));
|
|
281
281
|
}
|
|
282
282
|
export { OwnerSelector };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseDetailsTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/CaseDetailsTabs.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAwBlE,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACnD;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"CaseDetailsTabs.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseEditView/CaseDetailsTabs.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAwBlE,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACnD;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,eA+M5C"}
|
|
@@ -105,14 +105,23 @@ export function CaseDetailsTabs(props) {
|
|
|
105
105
|
};
|
|
106
106
|
const isTabVisibleInPdfExport = (tab) => tab.title === CaseDetailsTabsEnum.DISCUSSION && pdfOption === 'Reduced' ? false : true;
|
|
107
107
|
return (React.createElement("div", { className: "case-details-tabs", ref: props.tabdRef },
|
|
108
|
-
React.createElement(Tabs, { className: isExportingPDF ? 'hide-in-pdf' : '', activeKey: getActiveTabKey(), component: TabsComponent.nav, onSelect: handleTabClick }, tabsToRender.map((tab, index) => (React.createElement(Tab, { eventKey: index, tabContentRef: tab.ref, tabContentId: tab.key, key: tab.title, href: `#${props.basePath}/${tab.routePath}`, "data-tracking-id": tab['data-tracking-id'], title: React.createElement(TabTitleText, null,
|
|
108
|
+
React.createElement(Tabs, { className: isExportingPDF ? 'hide-in-pdf' : '', activeKey: getActiveTabKey(), component: TabsComponent.nav, onSelect: handleTabClick, role: "region", "aria-label": t('Case details tabs') }, tabsToRender.map((tab, index) => (React.createElement(Tab, { eventKey: index, tabContentRef: tab.ref, tabContentId: tab.key, key: tab.title, href: `#${props.basePath}/${tab.routePath}`, "data-tracking-id": tab['data-tracking-id'], title: React.createElement(TabTitleText, null,
|
|
109
109
|
React.createElement(Trans, null, tab.title)) })))),
|
|
110
|
-
React.createElement("div", { className: "case-details-tabs-content pf-u-pt-xl" }, tabsToRender.map((tab, index) =>
|
|
111
|
-
React.createElement(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
React.createElement(
|
|
116
|
-
React.createElement(
|
|
117
|
-
|
|
110
|
+
React.createElement("div", { className: "case-details-tabs-content pf-u-pt-xl" }, tabsToRender.map((tab, index) => {
|
|
111
|
+
return index === getActiveTabKey() && !isExportingPDF ? (React.createElement(TabContent, { eventKey: index, key: tab.key, id: tab.key, ref: tab.ref, "aria-label": tab.title, hidden: isExportingPDF ? !isTabVisibleInPdfExport(tab) : index !== getActiveTabKey() },
|
|
112
|
+
React.createElement(ErrorBoundary, { errorMsgInfo: {
|
|
113
|
+
message: t(`There was an error loading case ${tab.key}`),
|
|
114
|
+
} },
|
|
115
|
+
React.createElement(Suspense, { fallback: React.createElement(LoadingIndicator, { size: "sm" }) },
|
|
116
|
+
React.createElement(TextContent, { className: "show-in-pdf pf-u-mt-md" },
|
|
117
|
+
React.createElement(Text, { component: TextVariants.h2 }, tab.title)),
|
|
118
|
+
tab.component)))) : isExportingPDF ? (React.createElement(TabContent, { eventKey: index, key: tab.key, id: tab.key, ref: tab.ref, "aria-label": tab.title, hidden: isExportingPDF ? !isTabVisibleInPdfExport(tab) : index !== getActiveTabKey() },
|
|
119
|
+
React.createElement(ErrorBoundary, { errorMsgInfo: {
|
|
120
|
+
message: t(`There was an error loading case ${tab.key}`),
|
|
121
|
+
} },
|
|
122
|
+
React.createElement(Suspense, { fallback: React.createElement(LoadingIndicator, { size: "sm" }) },
|
|
123
|
+
React.createElement(TextContent, { className: "show-in-pdf pf-u-mt-md" },
|
|
124
|
+
React.createElement(Text, { component: TextVariants.h2 }, tab.title)),
|
|
125
|
+
tab.component)))) : (React.createElement(React.Fragment, null));
|
|
126
|
+
}))));
|
|
118
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseSolutionsItem.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseEditView/CaseSolutions/CaseSolutionsItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseSolutionsItem.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseEditView/CaseSolutions/CaseSolutionsItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAS5E,UAAU,MAAM;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,8BAA8B,CAAC;IAC/C,YAAY,EAAE,GAAG,CAAC;IAClB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,8BAA+B,SAAQ,OAAO,CAAC,iBAAiB,CAAC;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,eA4C9C"}
|
|
@@ -3,6 +3,7 @@ import LinkIcon from '@patternfly/react-icons/dist/js/icons/link-icon';
|
|
|
3
3
|
import ThumbTackIcon from '@patternfly/react-icons/dist/js/icons/thumb-tack-icon';
|
|
4
4
|
import { LoadingIndicator } from '@rh-support/components';
|
|
5
5
|
import { cleanupMarkDown, decodeMarkTag, truncate } from '@rh-support/utils';
|
|
6
|
+
import DOMPurify from 'dompurify';
|
|
6
7
|
import React from 'react';
|
|
7
8
|
export function CaseSolutionsItem(props) {
|
|
8
9
|
const maxTitleLength = 150;
|
|
@@ -15,9 +16,9 @@ export function CaseSolutionsItem(props) {
|
|
|
15
16
|
!isLoading && props.showPin && React.createElement(ThumbTackIcon, { className: "pinned-resource" }),
|
|
16
17
|
!isLoading && props.showLink && React.createElement(LinkIcon, null)),
|
|
17
18
|
React.createElement("a", { href: props.recommendation.resourceViewURI, "data-tracking-id": `case-resource-${props.type}-link-${props.index}`, target: "_blank", rel: "noopener noreferrer", dangerouslySetInnerHTML: {
|
|
18
|
-
__html: truncate(decodeMarkTag(props.recommendation.title || ''), maxTitleLength),
|
|
19
|
+
__html: DOMPurify.sanitize(truncate(decodeMarkTag(props.recommendation.title || ''), maxTitleLength)),
|
|
19
20
|
} })),
|
|
20
21
|
React.createElement("div", { className: "result-body", dangerouslySetInnerHTML: {
|
|
21
|
-
__html: truncate(cleanupMarkDown(decodeMarkTag(props.recommendation.solutionAbstract || '')), maxAbstractLength),
|
|
22
|
+
__html: DOMPurify.sanitize(truncate(cleanupMarkDown(decodeMarkTag(props.recommendation.solutionAbstract || '')), maxAbstractLength)),
|
|
22
23
|
} })));
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseBugzilla.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseBugzilla/CaseBugzilla.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CaseBugzilla.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseBugzilla/CaseBugzilla.tsx"],"names":[],"mappings":"AAQA,UAAU,MAAM;CAAG;AAEnB,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,KAAK,EAAE,MAAM,eAmDjD"}
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
import isEqual from 'lodash/isEqual';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useContext } from 'react';
|
|
3
3
|
import { Trans } from 'react-i18next';
|
|
4
4
|
import { useCaseSelector } from '../../../../context/CaseContext';
|
|
5
|
+
import { PDFContext } from '../../PDFContainer';
|
|
5
6
|
export default function CaseBugzilla(props) {
|
|
6
7
|
const bugzillas = useCaseSelector((state) => state.caseDetails.bugzillas, isEqual);
|
|
8
|
+
const { isExportingPDF } = useContext(PDFContext);
|
|
7
9
|
const bugzillaRow = (bugzilla) => (React.createElement("tr", { key: bugzilla.bugzillaNumber },
|
|
8
|
-
React.createElement("
|
|
10
|
+
React.createElement("td", { id: `th-bug${bugzilla.bugzillaNumber}`, headers: "th-bug-number" },
|
|
9
11
|
React.createElement("a", { href: bugzilla.bugzillaLink, target: "_blank", rel: "noopener noreferrer" }, bugzilla.bugzillaNumber)),
|
|
10
12
|
React.createElement("td", { headers: `th-bug${bugzilla.bugzillaNumber} th-bug-summary` }, bugzilla.summary)));
|
|
11
13
|
const bugzillasList = (bugzillas) => {
|
|
12
|
-
return (React.createElement("table", { className: "table table-naked table-hover table-respond" },
|
|
14
|
+
return (React.createElement("table", { className: "table table-naked table-hover table-respond", style: { fontFamily: isExportingPDF ? 'DejaVu Sans' : '' } },
|
|
13
15
|
React.createElement("thead", null,
|
|
14
16
|
React.createElement("tr", null,
|
|
15
|
-
React.createElement("
|
|
16
|
-
React.createElement(
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
React.createElement("td", { id: "th-bug-number" },
|
|
18
|
+
React.createElement("strong", null,
|
|
19
|
+
React.createElement(Trans, null, "Request number"))),
|
|
20
|
+
React.createElement("td", { id: "th-bug-summary" },
|
|
21
|
+
React.createElement("strong", null,
|
|
22
|
+
React.createElement(Trans, null, "Summary"))))),
|
|
19
23
|
React.createElement("tbody", null, bugzillas.map((item) => bugzillaRow(item)))));
|
|
20
24
|
};
|
|
21
25
|
return (React.createElement(React.Fragment, null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CaseContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseContactPhoneNumber.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,sBAAsB,gBA4OrC"}
|
|
@@ -17,11 +17,10 @@ import isEmpty from 'lodash/isEmpty';
|
|
|
17
17
|
import isEqual from 'lodash/isEqual';
|
|
18
18
|
import React, { useContext, useEffect, useState } from 'react';
|
|
19
19
|
import { Trans, useTranslation } from 'react-i18next';
|
|
20
|
-
import { PHONE_INSTRUCTION, PHONE_IS_NOT_VALID,
|
|
20
|
+
import { PHONE_INSTRUCTION, PHONE_IS_NOT_VALID, PHONE_NO_CHAR_ERROR } from '../../../../constants/caseDetailsConstants';
|
|
21
21
|
import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
|
|
22
22
|
import { useCaseUpdateErrorMessage } from '../../../../hooks/useCaseUpdateErrorMessage';
|
|
23
|
-
import {
|
|
24
|
-
import { updateCaseDetails } from '../../../../reducers/CaseReducer';
|
|
23
|
+
import { setCaseState, updateCaseDetails } from '../../../../reducers/CaseReducer';
|
|
25
24
|
import { ContactPhoneNumberPopOver } from '../../../CaseInformation/ContactPhoneNumberPopOver';
|
|
26
25
|
import { trimAndReplacePlus } from '../../../shared/utils';
|
|
27
26
|
import { PDFContext } from '../../PDFContainer';
|
|
@@ -43,6 +42,7 @@ export function CaseContactPhoneNumber() {
|
|
|
43
42
|
const [invalid, setInvalid] = useState(false);
|
|
44
43
|
const [isSaveClicked, setIsSavedClicked] = useState(false);
|
|
45
44
|
const [isShowOldPhone, setIsShowOldPhone] = useState(false);
|
|
45
|
+
const [phoneLength, setPhoneLength] = useState(localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length);
|
|
46
46
|
const caseDispatch = useCaseDispatch();
|
|
47
47
|
const caseUpdateError = useCaseUpdateErrorMessage();
|
|
48
48
|
const { t } = useTranslation();
|
|
@@ -51,6 +51,7 @@ export function CaseContactPhoneNumber() {
|
|
|
51
51
|
const onPhoneChange = (fullPhone) => __awaiter(this, void 0, void 0, function* () {
|
|
52
52
|
if (canEditCase.alert())
|
|
53
53
|
return;
|
|
54
|
+
setCaseState(caseDispatch, { isPhoneLengthInvalid: (fullPhone === null || fullPhone === void 0 ? void 0 : fullPhone.length) < phoneLength });
|
|
54
55
|
setLocalFullPhoneState(fullPhone);
|
|
55
56
|
});
|
|
56
57
|
const onCountryCodeChange = (countryCode) => {
|
|
@@ -60,11 +61,11 @@ export function CaseContactPhoneNumber() {
|
|
|
60
61
|
};
|
|
61
62
|
const onSave = () => __awaiter(this, void 0, void 0, function* () {
|
|
62
63
|
setIsSavedClicked(true);
|
|
63
|
-
if (isPhoneLineEmpty || isPhoneNumberInvalid)
|
|
64
|
+
if (isPhoneLineEmpty || isPhoneNumberInvalid || (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) < phoneLength)
|
|
64
65
|
return;
|
|
65
66
|
setCasePhoneUpdating(true);
|
|
66
67
|
const phoneLine = localFullPhoneState
|
|
67
|
-
.substring(localCountryCodeState.length, localFullPhoneState.length)
|
|
68
|
+
.substring(localCountryCodeState.length, localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length)
|
|
68
69
|
.trim();
|
|
69
70
|
const countryCode = localCountryCodeState.trim();
|
|
70
71
|
try {
|
|
@@ -112,14 +113,11 @@ export function CaseContactPhoneNumber() {
|
|
|
112
113
|
caseUpdateError.showError(e, t(`Phone number failed to update`));
|
|
113
114
|
}
|
|
114
115
|
});
|
|
115
|
-
const maxLengthErrorMessage = t('Phone number cannot be more than {{limit}} digits.', {
|
|
116
|
-
limit: PHONE_LIMIT,
|
|
117
|
-
});
|
|
118
116
|
const isPhoneNeedsReview = contactSSOName === loggedInUser.data.ssoUsername && suppliedPhoneNumberVerified === 'Deferred';
|
|
119
117
|
// To check if country code is given but phone number empty
|
|
120
118
|
const isPhoneLineEmpty = !isEmpty(localFullPhoneState) && isEmpty(localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.replace(localCountryCodeState, ''));
|
|
121
119
|
const isPhoneNumberInvalid = isEmpty(localCountryCodeState) && !isEmpty(localFullPhoneState);
|
|
122
|
-
const isPhoneNumberValid = (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length)
|
|
120
|
+
const isPhoneNumberValid = isSaveClicked && (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) < phoneLength
|
|
123
121
|
? ValidatedOptions.error
|
|
124
122
|
: isPhoneNeedsReview
|
|
125
123
|
? ValidatedOptions.warning
|
|
@@ -152,25 +150,22 @@ export function CaseContactPhoneNumber() {
|
|
|
152
150
|
React.createElement(Trans, null, "Case owner's phone number"),
|
|
153
151
|
!isExportingPDF ? ContactPhoneNumberPopOver() : ''),
|
|
154
152
|
React.createElement(InputGroupText, { variant: InputGroupTextVariant.plain },
|
|
155
|
-
React.createElement(PhoneInput, { phoneValue: localFullPhoneState, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, isDisabled: isCasePhoneUpdating || isCaseOwnerUpdating, isLoading: isCasePhoneUpdating, "data-tracking-id": "case-details-page-supplied-phone", invalid: invalid, setInvalid: setInvalid }),
|
|
156
|
-
React.createElement("button", { className: "btn btn-app btn-link pf-u-ml-sm", type: "button", "data-tracking-id": "case-details-page-supplied-phone-save", onClick: () => onSave(), disabled:
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
React.createElement(PhoneInput, { phoneValue: localFullPhoneState, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, isDisabled: isCasePhoneUpdating || isCaseOwnerUpdating, isLoading: isCasePhoneUpdating, "data-tracking-id": "case-details-page-supplied-phone", invalid: invalid, setInvalid: setInvalid, phoneLength: phoneLength, setPhoneLength: setPhoneLength }),
|
|
154
|
+
React.createElement("button", { className: "btn btn-app btn-link pf-u-ml-sm", type: "button", "data-tracking-id": "case-details-page-supplied-phone-save", onClick: () => onSave(), disabled: localFullPhoneState === phoneCountryCode + ' ' + phoneAreaCodePrefixLineNumber ||
|
|
155
|
+
(isSaveClicked &&
|
|
156
|
+
(isPhoneLineEmpty || isPhoneNumberInvalid || (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) < phoneLength)), style: { display: isExportingPDF ? 'none' : '' } },
|
|
159
157
|
React.createElement(CheckIcon, null)),
|
|
160
158
|
React.createElement("button", { className: "btn btn-app btn-link", type: "button", onClick: onClear, "data-tracking-id": "case-details-page-supplied-phone-cancel", style: { display: isExportingPDF ? 'none' : '' }, disabled: isEmpty(localFullPhoneState) },
|
|
161
159
|
React.createElement(TimesIcon, { color: "#6A6E73" }))),
|
|
162
160
|
!invalid &&
|
|
163
|
-
(localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) <
|
|
161
|
+
!(isSaveClicked && (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) < phoneLength) &&
|
|
164
162
|
!(isPhoneLineEmpty && isSaveClicked) &&
|
|
165
163
|
!(isSaveClicked && isPhoneNumberInvalid) &&
|
|
166
164
|
!isShowOldPhone && (React.createElement("p", { className: "form-instructions" },
|
|
167
165
|
React.createElement(Trans, null, PHONE_INSTRUCTION))),
|
|
168
166
|
invalid && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
169
167
|
React.createElement(Trans, null, PHONE_NO_CHAR_ERROR))),
|
|
170
|
-
(localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length)
|
|
171
|
-
isSaveClicked && isPhoneLineEmpty && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
172
|
-
React.createElement(Trans, null, PHONE_LINE_CANNOT_BE_EMPTY))),
|
|
173
|
-
isSaveClicked && isPhoneNumberInvalid && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
168
|
+
isSaveClicked && (isPhoneNumberInvalid || (localFullPhoneState === null || localFullPhoneState === void 0 ? void 0 : localFullPhoneState.length) < phoneLength) && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
174
169
|
React.createElement(Trans, null, PHONE_IS_NOT_VALID))),
|
|
175
170
|
isShowOldPhone && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
176
171
|
React.createElement(Trans, null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseInformation.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseInformation.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseInformation.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseInformation.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAgB5D,UAAU,MAAO,SAAQ,gBAAgB;CAAG;AAE5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,eAqE5C"}
|
|
@@ -3,6 +3,7 @@ import { MoreOrLess } from '@rh-support/components';
|
|
|
3
3
|
import { useGlobalStateContext } from '@rh-support/react-context';
|
|
4
4
|
import { ability, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
5
5
|
import { PreviousCaseTypes } from '@rh-support/utils';
|
|
6
|
+
import DOMPurify from 'dompurify';
|
|
6
7
|
import isEqual from 'lodash/isEqual';
|
|
7
8
|
import React from 'react';
|
|
8
9
|
import { Trans } from 'react-i18next';
|
|
@@ -33,7 +34,7 @@ export function CaseInformation(props) {
|
|
|
33
34
|
text = encodeAngularBrackets(text);
|
|
34
35
|
text = linkifyWithCaseIDs(text);
|
|
35
36
|
text = linkifyBZIDs(text);
|
|
36
|
-
return { __html: text };
|
|
37
|
+
return { __html: DOMPurify.sanitize(text) };
|
|
37
38
|
};
|
|
38
39
|
const canEditDescription = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_DESCRIPTION);
|
|
39
40
|
const hasCluster = isClusterIdEnabledForProduct(product, (_a = allProducts.data) === null || _a === void 0 ? void 0 : _a.productsResult);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductVersion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/ProductVersion.tsx"],"names":[],"mappings":"AA6BA,UAAU,MAAM;IACZ,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACvC;AAYD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ProductVersion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/ProductVersion.tsx"],"names":[],"mappings":"AA6BA,UAAU,MAAM;IACZ,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACvC;AAYD,iBAAS,eAAe,CAAC,KAAK,EAAE,MAAM,eAoRrC;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -221,6 +221,6 @@ function ProductNVersion(props) {
|
|
|
221
221
|
React.createElement("div", { className: "version-selector-wrapper" },
|
|
222
222
|
React.createElement("label", { htmlFor: "version-dropdown" },
|
|
223
223
|
React.createElement(Trans, null, "Version")),
|
|
224
|
-
React.createElement(Dropdown, { className: "open-case-version", id: "version-dropdown", selectedItem: toOption(selectedVersionLocal), list: versionsList, title: t(`Select a version`), isInValid: checkIfVersionIsInvalid, disabled: isVersionUpdating || (allProducts.isFetching && !allProducts.isError), onChange: onVersionChange, isLoadingList: isVersionUpdating, "data-tracking-id": "case-details-version-selector" }))))));
|
|
224
|
+
React.createElement(Dropdown, { className: "open-case-version", id: "version-dropdown", placeholder: t(`Select a version`), selectedItem: toOption(selectedVersionLocal), list: versionsList, title: t(`Select a version`), isInValid: checkIfVersionIsInvalid, disabled: isVersionUpdating || (allProducts.isFetching && !allProducts.isError), onChange: onVersionChange, isLoadingList: isVersionUpdating, "data-tracking-id": "case-details-version-selector" }))))));
|
|
225
225
|
}
|
|
226
226
|
export default ProductNVersion;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseChat.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseChat.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseChat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;IAChB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,QAAA,MAAM,QAAQ,4EAiDZ,CAAC;AACH,eAAe,QAAQ,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { formatDateTime } from '@rh-support/utils';
|
|
2
|
+
import DOMPurify from 'dompurify';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { Trans } from 'react-i18next';
|
|
4
5
|
import { DiscussionType } from '../../../../reducers/CaseDiscussionTabReducer';
|
|
@@ -7,7 +8,7 @@ import { JumpAndCopyLink } from './JumpAndCopyLink';
|
|
|
7
8
|
const CaseChat = React.forwardRef((props, ref) => {
|
|
8
9
|
const { caseNumber } = props;
|
|
9
10
|
const sanetize = (html) => {
|
|
10
|
-
return { __html: html };
|
|
11
|
+
return { __html: DOMPurify.sanitize(html) };
|
|
11
12
|
};
|
|
12
13
|
const onJumpToComment = (chatId) => () => props.showJumpToComment && props.onJumpToComment && props.onJumpToComment(chatId);
|
|
13
14
|
return (React.createElement("section", { className: `prevent-split support-comment ${ref ? 'selected-case-comment' : ''}`, id: props.chat.id, ref: ref },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseComments.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseComments.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseComments.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AA8BvE,OAAO,KAA+B,MAAM,OAAO,CAAC;AAQpD,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,kBAAkB,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChH;AAED,QAAA,MAAM,YAAY,4EAqThB,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -20,6 +20,7 @@ import UserCircleIcon from '@patternfly/react-icons/dist/js/icons/user-circle-ic
|
|
|
20
20
|
import { EditorMode, LoadingIndicator, ToastNotification } from '@rh-support/components';
|
|
21
21
|
import { AbilityContext, CaseDetailsFields, CaseDiscussionFields, resourceActions, resources, } from '@rh-support/user-permissions';
|
|
22
22
|
import { formatDateTime, linkifyLinks } from '@rh-support/utils';
|
|
23
|
+
import DOMPurify from 'dompurify';
|
|
23
24
|
import isEmpty from 'lodash/isEmpty';
|
|
24
25
|
import React, { useContext, useState } from 'react';
|
|
25
26
|
import { Trans, useTranslation } from 'react-i18next';
|
|
@@ -127,11 +128,11 @@ const CaseComments = React.forwardRef((props, ref) => {
|
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
130
|
const commentText = (text) => {
|
|
130
|
-
return { __html: text };
|
|
131
|
+
return { __html: DOMPurify.sanitize(text) };
|
|
131
132
|
};
|
|
132
133
|
const commentMarkdown = (markdown) => {
|
|
133
134
|
const htmlString = parseCommentMarkdown(markdown, { showButtonForAttachmentLink: true }, { openLinksInNewTab: true, gfm: true, breaks: true });
|
|
134
|
-
return { __html: htmlString };
|
|
135
|
+
return { __html: DOMPurify.sanitize(htmlString) };
|
|
135
136
|
};
|
|
136
137
|
const onCommentAreaClick = (e) => {
|
|
137
138
|
let { event } = e.target['dataset'];
|
package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseExternalTrackerUpdate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseExternalTrackerUpdate.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseExternalTrackerUpdate.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseExternalTrackerUpdate.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseExternalTrackerUpdate.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AAOjF,OAAO,KAAqB,MAAM,OAAO,CAAC;AAO1C,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,sBAAsB,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,IAAI,CAAC;CACzD;AAID,QAAA,MAAM,yBAAyB,4EAuF7B,CAAC;AAEH,eAAe,yBAAyB,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { markdownToHTML } from '@cee-eng/ui-toolkit';
|
|
|
2
2
|
import TopologyIcon from '@patternfly/react-icons/dist/js/icons/topology-icon';
|
|
3
3
|
import { AbilityContext, CaseDiscussionFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
4
4
|
import { formatDateTime } from '@rh-support/utils';
|
|
5
|
+
import DOMPurify from 'dompurify';
|
|
5
6
|
import includes from 'lodash/includes';
|
|
6
7
|
import React, { useContext } from 'react';
|
|
7
8
|
import { Trans } from 'react-i18next';
|
|
@@ -13,8 +14,9 @@ const CaseExternalTrackerUpdate = React.forwardRef((props, ref) => {
|
|
|
13
14
|
const { caseNumber } = props;
|
|
14
15
|
const ability = useContext(AbilityContext);
|
|
15
16
|
const canSeePrivateComments = ability.can(resourceActions.PATCH, resources.CASE_COMMENTS, CaseDiscussionFields.VIEW_PRIVATE_COMMENT);
|
|
16
|
-
const
|
|
17
|
-
|
|
17
|
+
const sanitize = (markdown) => {
|
|
18
|
+
const htmlString = markdownToHTML(markdown, { openLinksInNewTab: true });
|
|
19
|
+
return { __html: DOMPurify.sanitize(htmlString) };
|
|
18
20
|
};
|
|
19
21
|
const onJumpToComment = (externalTrackerId) => () => props.showJumpToComment && props.onJumpToComment && props.onJumpToComment(externalTrackerId);
|
|
20
22
|
// To check and set if a comment is private or not
|
|
@@ -30,7 +32,7 @@ const CaseExternalTrackerUpdate = React.forwardRef((props, ref) => {
|
|
|
30
32
|
React.createElement("time", null, formatDateTime(props.trackerUpdate.createdDate))),
|
|
31
33
|
React.createElement("div", { className: "comment-body" },
|
|
32
34
|
props.trackerUpdate.originatingSystem,
|
|
33
|
-
React.createElement("pre", { className: "push-top-narrow", dangerouslySetInnerHTML:
|
|
35
|
+
React.createElement("pre", { className: "push-top-narrow", dangerouslySetInnerHTML: sanitize(props.trackerUpdate.body) })),
|
|
34
36
|
React.createElement("footer", null,
|
|
35
37
|
isPrivateUpdate() && (React.createElement("div", { className: "comment-note" },
|
|
36
38
|
React.createElement(Trans, null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CasePrivateNotes.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CasePrivateNotes/CasePrivateNotes.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CasePrivateNotes.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CasePrivateNotes/CasePrivateNotes.tsx"],"names":[],"mappings":"AAcA,QAAA,MAAM,YAAY;;CAEjB,CAAC;AAEF,aAAK,YAAY,GAAG,OAAO,YAAY,CAAC;AAExC,UAAU,MAAO,SAAQ,YAAY;CAAG;AAExC,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,eAuGtC;kBAvGQ,gBAAgB;;;;;AA0GzB,eAAe,gBAAgB,CAAC"}
|
|
@@ -17,6 +17,7 @@ import { Trans, useTranslation } from 'react-i18next';
|
|
|
17
17
|
import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
|
|
18
18
|
import { useCaseUpdateErrorMessage } from '../../../../hooks/useCaseUpdateErrorMessage';
|
|
19
19
|
import { updateCaseDetails } from '../../../../reducers/CaseReducer';
|
|
20
|
+
import { PDFContext } from '../../PDFContainer';
|
|
20
21
|
const defaultProps = {
|
|
21
22
|
caseNumber: undefined,
|
|
22
23
|
};
|
|
@@ -30,6 +31,7 @@ function CasePrivateNotes(props) {
|
|
|
30
31
|
const [notesState, setNotes] = useState(notes);
|
|
31
32
|
const [formIsDirty, setFormIsDirty] = useState(false);
|
|
32
33
|
const [isUpdating, setIsUpdating] = useState(false);
|
|
34
|
+
const { isExportingPDF } = useContext(PDFContext);
|
|
33
35
|
const canEditCase = useCanEditCase();
|
|
34
36
|
useEffect(() => {
|
|
35
37
|
if (notes !== notesState) {
|
|
@@ -77,11 +79,11 @@ function CasePrivateNotes(props) {
|
|
|
77
79
|
canUpdatePrivateNotes && (React.createElement("form", null,
|
|
78
80
|
React.createElement(TextAreaResizable, { className: "form-control", style: { minHeight: '200px' }, id: "rha-case-notes", disabled: isUpdating, maxLength: 255, name: "notes", value: notesState, onChange: onChange }),
|
|
79
81
|
React.createElement("div", { className: "pf-u-mt-md" },
|
|
80
|
-
React.createElement("button", { className:
|
|
82
|
+
React.createElement("button", { className: `btn btn-app btn-primary ${isExportingPDF ? 'hide-in-pdf' : ''}`, onClick: updateCase, disabled: isPrivateNotesEmpty || isUpdating || !formIsDirty },
|
|
81
83
|
React.createElement(Trans, null, "Update"),
|
|
82
84
|
" ",
|
|
83
85
|
React.createElement(LoadingIndicator, { show: isUpdating, isInline: true })),
|
|
84
|
-
React.createElement("button", { className:
|
|
86
|
+
React.createElement("button", { className: `btn btn-app btn-link ${isExportingPDF ? 'hide-in-pdf' : ''}`, onClick: discardNotes, disabled: isUpdating || !formIsDirty },
|
|
85
87
|
React.createElement(Trans, null, "Discard Changes"))))),
|
|
86
88
|
React.createElement("p", { className: "pf-u-mt-xl" },
|
|
87
89
|
React.createElement(Trans, null, "Please note, contents of this field are not visible to Red Hat Support professionals."))));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/ContactPhoneNumber.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ContactPhoneNumber.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/ContactPhoneNumber.tsx"],"names":[],"mappings":"AAiBA,wBAAgB,kBAAkB,gBAqJjC"}
|
|
@@ -5,12 +5,11 @@ import { ability, CaseListFields, resourceActions, resources } from '@rh-support
|
|
|
5
5
|
import isEmpty from 'lodash/isEmpty';
|
|
6
6
|
import isEqual from 'lodash/isEqual';
|
|
7
7
|
import React, { useContext, useEffect, useState } from 'react';
|
|
8
|
-
import { Trans
|
|
9
|
-
import { PHONE_INSTRUCTION, PHONE_IS_NOT_VALID,
|
|
8
|
+
import { Trans } from 'react-i18next';
|
|
9
|
+
import { PHONE_INSTRUCTION, PHONE_IS_NOT_VALID, PHONE_NO_CHAR_ERROR } from '../../constants/caseDetailsConstants';
|
|
10
10
|
import { useCaseDispatch, useCaseSelector } from '../../context/CaseContext';
|
|
11
11
|
import { RouteContext } from '../../context/RouteContext';
|
|
12
|
-
import {
|
|
13
|
-
import { setCaseDetails } from '../../reducers/CaseReducer';
|
|
12
|
+
import { setCaseDetails, setCaseState } from '../../reducers/CaseReducer';
|
|
14
13
|
import { trimAndReplacePlus } from '../shared/utils';
|
|
15
14
|
import { ContactPhoneNumberPopOver } from './ContactPhoneNumberPopOver';
|
|
16
15
|
export function ContactPhoneNumber() {
|
|
@@ -24,10 +23,9 @@ export function ContactPhoneNumber() {
|
|
|
24
23
|
const { globalMetadataState: { loggedInUser }, } = useContext(GlobalMetadataStateContext);
|
|
25
24
|
const [invalid, setInvalid] = useState(false);
|
|
26
25
|
const [localFullPhone, setLocalFullPhone] = useState(phoneCountryCode + ' ' + phoneAreaCodePrefixLineNumber);
|
|
26
|
+
const [phoneLength, setPhoneLength] = useState(localFullPhone === null || localFullPhone === void 0 ? void 0 : localFullPhone.length);
|
|
27
27
|
const canChangeAccountInfo = ability.can(resourceActions.PATCH, resources.CASE_CREATE, CaseListFields.ACCOUNT_AND_OWNER);
|
|
28
|
-
const getPhone = () => phoneCountryCode + ' ' + phoneAreaCodePrefixLineNumber;
|
|
29
28
|
const caseDispatch = useCaseDispatch();
|
|
30
|
-
const { t } = useTranslation();
|
|
31
29
|
const onPhoneChange = (fullPhone) => {
|
|
32
30
|
setLocalFullPhone(fullPhone);
|
|
33
31
|
if (isEmpty(fullPhone)) {
|
|
@@ -41,14 +39,11 @@ export function ContactPhoneNumber() {
|
|
|
41
39
|
const onCountryCodeChange = (phoneCountryCode) => {
|
|
42
40
|
setCaseDetails(caseDispatch, { phoneCountryCode });
|
|
43
41
|
};
|
|
44
|
-
const maxLengthErrorMessage = t('Phone number cannot be more than {{limit}} digits.', {
|
|
45
|
-
limit: PHONE_LIMIT,
|
|
46
|
-
});
|
|
47
42
|
const isPhoneNumberInvalid = isEmpty(trimAndReplacePlus(phoneCountryCode)) && !isEmpty(phoneAreaCodePrefixLineNumber.trim());
|
|
48
43
|
// To check if country code is given but phone number empty
|
|
49
44
|
const isPhoneNumberEmpty = !isEmpty(trimAndReplacePlus(phoneCountryCode)) &&
|
|
50
45
|
isEmpty(phoneAreaCodePrefixLineNumber === null || phoneAreaCodePrefixLineNumber === void 0 ? void 0 : phoneAreaCodePrefixLineNumber.replace(phoneCountryCode, ''));
|
|
51
|
-
const isPhoneNumberValid =
|
|
46
|
+
const isPhoneNumberValid = isNextBtnClickedToShowValidationError && (localFullPhone === null || localFullPhone === void 0 ? void 0 : localFullPhone.length) < phoneLength
|
|
52
47
|
? ValidatedOptions.error
|
|
53
48
|
: severity === "1 (Urgent)" /* SEV_1 */ && isEmpty(suppliedPhoneNumberVerified)
|
|
54
49
|
? ValidatedOptions.warning
|
|
@@ -88,23 +83,22 @@ export function ContactPhoneNumber() {
|
|
|
88
83
|
else if (!isEmpty(localFullPhone) && !localFullPhone.startsWith('+')) {
|
|
89
84
|
setLocalFullPhone('+' + localFullPhone.replace(' ', ''));
|
|
90
85
|
}
|
|
86
|
+
setCaseState(caseDispatch, { isPhoneLengthInvalid: (localFullPhone === null || localFullPhone === void 0 ? void 0 : localFullPhone.length) < phoneLength });
|
|
91
87
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
92
88
|
}, [localFullPhone]);
|
|
93
89
|
return (React.createElement("div", { className: "form-group", style: { minWidth: '200px' } },
|
|
94
90
|
React.createElement("label", null,
|
|
95
91
|
React.createElement(Trans, null, "Case owner's phone number"),
|
|
96
92
|
ContactPhoneNumberPopOver()),
|
|
97
|
-
React.createElement(PhoneInput, { phoneValue: localFullPhone, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, invalid: invalid, setInvalid: setInvalid }),
|
|
93
|
+
React.createElement(PhoneInput, { phoneValue: localFullPhone, onPhoneValueChange: onPhoneChange, onCountryCodeChange: onCountryCodeChange, validations: isPhoneNumberValid, invalid: invalid, setInvalid: setInvalid, phoneLength: phoneLength, setPhoneLength: setPhoneLength }),
|
|
98
94
|
!invalid &&
|
|
99
|
-
getPhone().length < PHONE_LIMIT &&
|
|
100
95
|
!(isPhoneNumberEmpty && isNextBtnClickedToShowValidationError) &&
|
|
101
|
-
!(isNextBtnClickedToShowValidationError &&
|
|
96
|
+
!(isNextBtnClickedToShowValidationError &&
|
|
97
|
+
(isPhoneNumberInvalid || (localFullPhone === null || localFullPhone === void 0 ? void 0 : localFullPhone.length) < phoneLength)) && (React.createElement("p", { className: "form-instructions" },
|
|
102
98
|
React.createElement(Trans, null, PHONE_INSTRUCTION))),
|
|
103
99
|
invalid && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
104
100
|
React.createElement(Trans, null, PHONE_NO_CHAR_ERROR))),
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
React.createElement(Trans, null, PHONE_LINE_CANNOT_BE_EMPTY))),
|
|
108
|
-
isNextBtnClickedToShowValidationError && isPhoneNumberInvalid && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
101
|
+
isNextBtnClickedToShowValidationError &&
|
|
102
|
+
(isPhoneNumberInvalid || (localFullPhone === null || localFullPhone === void 0 ? void 0 : localFullPhone.length) < phoneLength) && (React.createElement("p", { className: "form-instructions form-invalid" },
|
|
109
103
|
React.createElement(Trans, null, PHONE_IS_NOT_VALID)))));
|
|
110
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Description.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/Description.tsx"],"names":[],"mappings":"AAkBA,UAAU,MAAM;IACZ,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"Description.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/Description.tsx"],"names":[],"mappings":"AAkBA,UAAU,MAAM;IACZ,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,KAAK,EAAE,MAAM,eAyGhD"}
|
|
@@ -47,7 +47,7 @@ export default function Description(props) {
|
|
|
47
47
|
isKT1Required && (React.createElement("span", { className: "form-required", "aria-hidden": true }, "*"))), labelProps: { htmlFor: 'get-support-ktQ1-issue' }, content: issue, allowInlineEdit: !!props.inlineEditable, hideSaveCancel: !!props.hideSaveCancel, initialIsEditing: isEmpty(issue), usePreformattedTag: true, saveOnBlur: true },
|
|
48
48
|
React.createElement(TextArea, { id: "get-support-ktQ1-issue", name: "get-support-ktQ1-issue", className: `form-control${isDescriptionInvalid(issue) || (isNextBtnClickedToShowValidationError && isEmpty(issue))
|
|
49
49
|
? ' form-invalid'
|
|
50
|
-
: ''}`, "aria-invalid": (issue === null || issue === void 0 ? void 0 : issue.length) > CASE_DEATILS_ISSUE_LIMIT ? 'true' : 'false', "aria-required": isKT1Required, isRequired: isKT1Required, value: issue, isDisabled: isEmpty(issue) && hasLargeCaseDescription && !setIssueTextAreaFocused, onChange: onKTQ1IssueChange, onFocus: onKTQ1IssueFocusChange, onBlur: onKTQ1IssueFocusChange, "data-tracking-id": "get-support-ktQ1-issue", placeholder: t('Please enter an elaborate description') }),
|
|
50
|
+
: ''}`, "aria-invalid": (issue === null || issue === void 0 ? void 0 : issue.length) > CASE_DEATILS_ISSUE_LIMIT ? 'true' : 'false', "aria-required": isKT1Required, isRequired: isKT1Required, value: issue, isDisabled: isEmpty(issue) && hasLargeCaseDescription && !setIssueTextAreaFocused, onChange: onKTQ1IssueChange, onFocus: onKTQ1IssueFocusChange, onBlur: onKTQ1IssueFocusChange, "data-tracking-id": "get-support-ktQ1-issue", placeholder: t('Please enter an elaborate description'), rows: 5 }),
|
|
51
51
|
React.createElement("p", { className: "form-instructions", "data-tracking-id": "large-20k-warning-ktQ1-environment" }, `${(issue === null || issue === void 0 ? void 0 : issue.length) > CASE_DEATILS_ISSUE_LIMIT
|
|
52
52
|
? `Description cannot be more than ${CASE_DEATILS_ISSUE_LIMIT} characters`
|
|
53
53
|
: ''}`),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenshiftDropdownV4.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseManagement/OpenshiftDropdownV4.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAG5E,OAAO,EAAE,gBAAgB,EAAuB,MAAM,0BAA0B,CAAC;AAWjF,UAAU,MAAO,SAAQ,gBAAgB;IACrC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iCAAiC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAuBD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"OpenshiftDropdownV4.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseManagement/OpenshiftDropdownV4.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAG5E,OAAO,EAAE,gBAAgB,EAAuB,MAAM,0BAA0B,CAAC;AAWjF,UAAU,MAAO,SAAQ,gBAAgB;IACrC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iCAAiC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAuBD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,eAqXzC;kBArXQ,mBAAmB;;;AAwX5B,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
|
|
@@ -100,7 +100,7 @@ function OpenshiftDropdownV4(props) {
|
|
|
100
100
|
React.createElement(SelectOption, { key: 'show-hide-archived-clusters', inputId: "check-box" },
|
|
101
101
|
React.createElement(Checkbox, { label: t('Show archived clusters'), key: "show-archived-clusters", "aria-label": t('Show archived clusters'), id: "show-archived-clusters", "data-tracking-id": "show-hide-archived-clusters", isChecked: showArchivedClusters, className: "archived-clusters-checkbox" })),
|
|
102
102
|
React.createElement(Divider, { component: "div", key: 'cluster-id-options-divider-e' }),
|
|
103
|
-
React.createElement(SelectOption, { key: 'dont-have-id', value: createState('dont-have-id', t("I don't have my Cluster ID")) }),
|
|
103
|
+
React.createElement(SelectOption, { key: 'dont-have-id', value: createState('dont-have-id', t("I don't have my Cluster ID")), "data-tracking-id": "dont-have-cluster-id" }),
|
|
104
104
|
...(props.isV3
|
|
105
105
|
? [
|
|
106
106
|
React.createElement(SelectOption, { key: 'v3-cluster', value: createState('v3-cluster', t('The case is for a v3 cluster')) }),
|
|
@@ -270,7 +270,7 @@ function CaseContactSelector(props) {
|
|
|
270
270
|
" is not listed under your account. You can always",
|
|
271
271
|
' ',
|
|
272
272
|
React.createElement(Button, { variant: "link", isInline: true, component: "span", onClick: onAddEmailToAccountBtnClick }, "add them at the account level"))))),
|
|
273
|
-
caseNumber && showAddWatchButton() && (React.createElement(Button, { variant: "secondary", onClick: addCurrentUser, type: "button", "data-tracking-id": "case-add-me-watcher" },
|
|
273
|
+
caseNumber && showAddWatchButton() && !isExportingPDF && (React.createElement(Button, { variant: "secondary", onClick: addCurrentUser, type: "button", "data-tracking-id": "case-add-me-watcher" },
|
|
274
274
|
React.createElement(Trans, null, "Add me as a watcher"))),
|
|
275
275
|
caseNumber && showRemoveWatchButton() && (React.createElement("div", { ref: toolTipRef, className: "remove-me-as-watcher pf-u-display-inline-block" }, isCurrentUserCaseContact ? (React.createElement(React.Fragment, null,
|
|
276
276
|
React.createElement(Tooltip, { trigger: 'mouseenter focus', reference: toolTipRef, position: TooltipPosition.top, content: React.createElement(Trans, null, "You are case contact and therefore you cannot be removed as watcher") }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditDescription.d.ts","sourceRoot":"","sources":["../../../../src/components/EditDescription/EditDescription.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EditDescription.d.ts","sourceRoot":"","sources":["../../../../src/components/EditDescription/EditDescription.tsx"],"names":[],"mappings":"AAeA,UAAU,MAAM;IACZ,cAAc,EAAE,OAAO,CAAC;CAC3B;AAUD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,MAAM,eAuEpD"}
|
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import { kase } from '@cee-eng/hydrajs';
|
|
11
11
|
import { encodeAngularBrackets, linkifyBZIDs, linkifyWithCaseIDs } from '@cee-eng/ui-toolkit';
|
|
12
12
|
import { InlineEdit, LoadingIndicator, TextAreaAutosize, ToastNotification } from '@rh-support/components';
|
|
13
|
+
import DOMPurify from 'dompurify';
|
|
13
14
|
import isEqual from 'lodash/isEqual';
|
|
14
15
|
import React, { useContext, useState } from 'react';
|
|
15
16
|
import { Trans, useTranslation } from 'react-i18next';
|
|
@@ -22,7 +23,7 @@ const linkifiedDescription = (text) => {
|
|
|
22
23
|
text = encodeAngularBrackets(text);
|
|
23
24
|
text = linkifyWithCaseIDs(text);
|
|
24
25
|
text = linkifyBZIDs(text);
|
|
25
|
-
return text;
|
|
26
|
+
return DOMPurify.sanitize(text);
|
|
26
27
|
};
|
|
27
28
|
export default function EditDescription(props) {
|
|
28
29
|
const { t } = useTranslation();
|
|
@@ -52,5 +52,5 @@ export default function ProductSelector(props) {
|
|
|
52
52
|
React.createElement(EARuleWidget, null)),
|
|
53
53
|
React.createElement("div", { className: "suggestions-result-section" },
|
|
54
54
|
React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading recommendations') } }, !isEmpty(version) && (React.createElement("div", { className: "common-suggestions" },
|
|
55
|
-
React.createElement(Recommendations,
|
|
55
|
+
React.createElement(Recommendations, null)))))))));
|
|
56
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EARule.d.ts","sourceRoot":"","sources":["../../../../../src/components/Recommendations/EARules/EARule.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EARule.d.ts","sourceRoot":"","sources":["../../../../../src/components/Recommendations/EARules/EARule.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAM1C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,UAAU,cAAc;IACpB,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;CAClG;AAGD,eAAO,MAAM,aAAa,+BAGxB,CAAC;AAEH,wBAAgB,gBAAgB,mBAM/B;AACD,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;;CAAA,eAmCxC;AAED,iBAAS,WAAW,gBAGnB;AAED,iBAAS,iBAAiB,gBA0BzB;AAED,iBAAS,aAAa,CAAC,EAAE,SAA6B,EAAE,SAAc,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,eA2BnH;AAED,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC"}
|