@rh-support/troubleshoot 2.4.5-beta.1 → 2.4.5-beta.3
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/CaseEditView/CaseDetailsTabs.js +2 -2
- package/lib/esm/components/CaseEditView/CaseOverview/CaseType.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseOverview/CaseType.js +4 -18
- package/lib/esm/components/CaseEditView/CaseOverview/index.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseOverview/index.js +2 -2
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/CaseSolutions/CaseSolutions.js +2 -4
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseInternalStatus.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDetails/CaseInternalStatus.js +1 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +4 -6
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CommentSearch.js +2 -3
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +1 -4
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.css +21 -95
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.js +137 -269
- package/lib/esm/components/CaseInformation/Fts.d.ts.map +1 -1
- package/lib/esm/components/CaseInformation/Fts.js +5 -6
- package/lib/esm/components/CaseManagement/Cep.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/Cep.js +2 -3
- package/lib/esm/components/CaseManagement/RHAssociatesSelector.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/RHAssociatesSelector.js +5 -11
- package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.d.ts.map +1 -1
- package/lib/esm/components/CaseManagement/SendNotifications/CaseContactSelector.js +5 -11
- package/lib/esm/components/Cve/CveItem.d.ts +8 -0
- package/lib/esm/components/Cve/CveItem.d.ts.map +1 -0
- package/lib/esm/components/Cve/CveItem.js +81 -0
- package/lib/esm/components/Cve/CveModal.d.ts +3 -0
- package/lib/esm/components/Cve/CveModal.d.ts.map +1 -0
- package/lib/esm/components/Cve/CveModal.js +40 -0
- package/lib/esm/components/Cve/CvePanel.d.ts +7 -0
- package/lib/esm/components/Cve/CvePanel.d.ts.map +1 -0
- package/lib/esm/components/Cve/CvePanel.js +23 -0
- package/lib/esm/components/Cve/CveSidebar.d.ts +3 -0
- package/lib/esm/components/Cve/CveSidebar.d.ts.map +1 -0
- package/lib/esm/components/Cve/CveSidebar.js +24 -0
- package/lib/esm/components/ProductSelector/ProductSelector.d.ts.map +1 -1
- package/lib/esm/components/ProductSelector/ProductSelector.js +4 -0
- package/lib/esm/components/Recommendations/AsideResults.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/AsideResults.js +2 -4
- package/lib/esm/components/Recommendations/EARules/EARule.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/EARules/EARule.js +2 -0
- package/lib/esm/components/Recommendations/EARules/EARuleInfoInline.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/EARules/EARuleInfoInline.js +2 -2
- package/lib/esm/components/Recommendations/Recommendations.d.ts.map +1 -1
- package/lib/esm/components/Recommendations/Recommendations.js +22 -24
- package/lib/esm/components/Recommendations/RecommendationsLoader.d.ts +3 -0
- package/lib/esm/components/Recommendations/RecommendationsLoader.d.ts.map +1 -0
- package/lib/esm/components/Recommendations/RecommendationsLoader.js +11 -0
- package/lib/esm/components/SubmitCase/SubmitCase.js +3 -3
- package/lib/esm/components/Suggestions/TopContent.d.ts.map +1 -1
- package/lib/esm/components/Suggestions/TopContent.js +4 -1
- package/lib/esm/components/shared/fileUpload/fileSelectors/WidgetFileSelector.d.ts +2 -2
- package/lib/esm/components/shared/fileUpload/fileSelectors/WidgetFileSelector.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/fileSelectors/WidgetFileSelector.js +1 -10
- package/lib/esm/components/wizardLayout/WizardAside.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardAside.js +5 -1
- package/lib/esm/components/wizardLayout/WizardLayout.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardLayout.js +1 -4
- package/lib/esm/components/wizardLayout/WizardMain.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardMain.js +0 -5
- package/lib/esm/components/wizardLayout/WizardNavigation.d.ts.map +1 -1
- package/lib/esm/components/wizardLayout/WizardNavigation.js +3 -7
- package/lib/esm/hooks/useFetchCVEData.d.ts +5 -0
- package/lib/esm/hooks/useFetchCVEData.d.ts.map +1 -0
- package/lib/esm/hooks/useFetchCVEData.js +101 -0
- package/lib/esm/models/caseCreationWorkflows.d.ts +25 -0
- package/lib/esm/models/caseCreationWorkflows.d.ts.map +1 -0
- package/lib/esm/models/caseCreationWorkflows.js +1 -0
- package/lib/esm/reducers/CaseConstNTypes.d.ts +3 -0
- package/lib/esm/reducers/CaseConstNTypes.d.ts.map +1 -1
- package/lib/esm/reducers/CaseConstNTypes.js +2 -0
- package/lib/esm/scss/_main.scss +20 -2
- package/lib/esm/scss/_pf-overrides.scss +0 -6
- package/lib/esm/utils/caseUtils.d.ts +6 -0
- package/lib/esm/utils/caseUtils.d.ts.map +1 -1
- package/lib/esm/utils/caseUtils.js +15 -0
- package/package.json +11 -11
|
@@ -11,7 +11,6 @@ import { Button, Tooltip, TooltipPosition } from '@patternfly/react-core';
|
|
|
11
11
|
import { ToastNotification } from '@rh-support/components';
|
|
12
12
|
import { GlobalMetadataStateContext } from '@rh-support/react-context';
|
|
13
13
|
import { AbilityContext, CaseListFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
14
|
-
import { dtmTrackEventCaseStepEncountered } from '@rh-support/utils';
|
|
15
14
|
import differenceBy from 'lodash/differenceBy';
|
|
16
15
|
import filter from 'lodash/filter';
|
|
17
16
|
import find from 'lodash/find';
|
|
@@ -32,13 +31,11 @@ function RHAssociatesSelector(props) {
|
|
|
32
31
|
const [isRHAssociatesUpdating, setIsRHAssociatesUpdating] = useState(false);
|
|
33
32
|
const ability = useContext(AbilityContext);
|
|
34
33
|
const { isExportingPDF } = useContext(PDFContext);
|
|
35
|
-
const { caseNumber, contactSsoUsername,
|
|
34
|
+
const { caseNumber, contactSsoUsername, selectedOwner, selectedNotificationContacts } = useCaseSelector((state) => ({
|
|
36
35
|
caseNumber: state.caseDetails.caseNumber,
|
|
37
36
|
contactSsoUsername: state.caseDetails.contactSSOName,
|
|
38
37
|
selectedOwner: state.selectedOwner,
|
|
39
38
|
selectedNotificationContacts: state.selectedNotificationContacts,
|
|
40
|
-
product: state.caseDetails.product,
|
|
41
|
-
version: state.caseDetails.version,
|
|
42
39
|
}), isEqual);
|
|
43
40
|
const caseDispatch = useCaseDispatch();
|
|
44
41
|
const onRhAssociateAdded = (addedUsers) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -67,7 +64,7 @@ function RHAssociatesSelector(props) {
|
|
|
67
64
|
ToastNotification.addDangerMessage(t(`Red Hat associate failed to get removed`));
|
|
68
65
|
}
|
|
69
66
|
});
|
|
70
|
-
const onNotifiedUserChange = (
|
|
67
|
+
const onNotifiedUserChange = (selectedContacts) => __awaiter(this, void 0, void 0, function* () {
|
|
71
68
|
const toAdd = filter(differenceBy(selectedContacts, selectedNotificationContacts, 'ssoUsername'), (item) => item.ssoUsername !== contactSsoUsername);
|
|
72
69
|
const toRemove = filter(differenceBy(selectedNotificationContacts, selectedContacts, 'ssoUsername'), (item) => item.isInternal && item.ssoUsername !== contactSsoUsername);
|
|
73
70
|
let newContacts = [];
|
|
@@ -75,9 +72,6 @@ function RHAssociatesSelector(props) {
|
|
|
75
72
|
newContacts = [...selectedNotificationContacts, ...toAdd];
|
|
76
73
|
if (!isEmpty(caseNumber)) {
|
|
77
74
|
yield onRhAssociateAdded(toAdd);
|
|
78
|
-
if (throwTrackEventOnAdd) {
|
|
79
|
-
dtmTrackEventCaseStepEncountered('follow', caseNumber, product, version);
|
|
80
|
-
}
|
|
81
75
|
}
|
|
82
76
|
}
|
|
83
77
|
else if ((toRemove || []).length > 0) {
|
|
@@ -96,9 +90,9 @@ function RHAssociatesSelector(props) {
|
|
|
96
90
|
!isCurrentUserSelectedInternalNotifiedUser();
|
|
97
91
|
const showRemoveWatchButton = () => (loggedInUserRights.data.isInternal() && isCurrentUserSelectedInternalNotifiedUser()) ||
|
|
98
92
|
contactSsoUsername === loggedInUser.data.ssoUsername;
|
|
99
|
-
const addCurrentUser = () =>
|
|
100
|
-
onNotifiedUserChange([Object.assign(Object.assign({}, loggedInUser.data), { accountNumber: loggedInUserRights.data.getAccountNumber() })]
|
|
101
|
-
}
|
|
93
|
+
const addCurrentUser = () => {
|
|
94
|
+
onNotifiedUserChange([Object.assign(Object.assign({}, loggedInUser.data), { accountNumber: loggedInUserRights.data.getAccountNumber() })]);
|
|
95
|
+
};
|
|
102
96
|
const removeCurrentUser = () => {
|
|
103
97
|
if (isCurrentUserSelectedInternalNotifiedUser()) {
|
|
104
98
|
onNotifiedUserChange(filter(selectedNotificationContacts, (contact) => contact.ssoUsername !== loggedInUser.data.ssoUsername));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseContactSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseManagement/SendNotifications/CaseContactSelector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CaseContactSelector.d.ts","sourceRoot":"","sources":["../../../../../src/components/CaseManagement/SendNotifications/CaseContactSelector.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAgBvE,MAAM,WAAW,MAAM;CAAG;AAG1B,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,qBAmbzC;AAED,eAAe,mBAAmB,CAAC"}
|
|
@@ -11,7 +11,6 @@ import { Button, Tooltip, TooltipPosition } from '@patternfly/react-core';
|
|
|
11
11
|
import { CaseContactsSelectorExternal, getHydraContactLabel, PromisifyModal, ToastNotification, usePrevious, } from '@rh-support/components';
|
|
12
12
|
import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
|
|
13
13
|
import { AbilityContext, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
14
|
-
import { dtmTrackEventCaseStepEncountered } from '@rh-support/utils';
|
|
15
14
|
import differenceBy from 'lodash/differenceBy';
|
|
16
15
|
import filter from 'lodash/filter';
|
|
17
16
|
import find from 'lodash/find';
|
|
@@ -35,7 +34,7 @@ function CaseContactSelector(props) {
|
|
|
35
34
|
const canSeeEmailNotifications = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS);
|
|
36
35
|
const [isAssociatesUpdating, setIsAssociatesUpdating] = useState(false);
|
|
37
36
|
const { t } = useTranslation();
|
|
38
|
-
const { accountNumber, caseNumber, contactSsoUsername, selectedNotificationContacts, selectedOwner, customEmailsList,
|
|
37
|
+
const { accountNumber, caseNumber, contactSsoUsername, selectedNotificationContacts, selectedOwner, customEmailsList, selectedCaseGroupUsers, ownersCaseGroups, groupNumber, createdById, } = useCaseSelector((state) => ({
|
|
39
38
|
accountNumber: state.caseDetails.accountNumberRef,
|
|
40
39
|
caseNumber: state.caseDetails.caseNumber,
|
|
41
40
|
contactSsoUsername: state.caseDetails.contactSSOName,
|
|
@@ -46,8 +45,6 @@ function CaseContactSelector(props) {
|
|
|
46
45
|
groupNumber: state.caseDetails.groupNumber,
|
|
47
46
|
ownersCaseGroups: state.ownersCaseGroups,
|
|
48
47
|
createdById: state.caseDetails.createdById,
|
|
49
|
-
product: state.caseDetails.product,
|
|
50
|
-
version: state.caseDetails.version,
|
|
51
48
|
}), isEqual);
|
|
52
49
|
const caseDispatch = useCaseDispatch();
|
|
53
50
|
const { addCustomEmail, canAddCustomEmail, hideCustomEmails, deleteCustomEmail, isUpdatingCustomEmails, isEmailValid, showAddEmailToAccountModal, } = useCustomEmails({
|
|
@@ -188,7 +185,7 @@ function CaseContactSelector(props) {
|
|
|
188
185
|
}
|
|
189
186
|
return hasGroupAccess;
|
|
190
187
|
});
|
|
191
|
-
const onNotifiedUserChange = (...args_1) => __awaiter(this, [...args_1], void 0, function* (selectedContacts = []
|
|
188
|
+
const onNotifiedUserChange = (...args_1) => __awaiter(this, [...args_1], void 0, function* (selectedContacts = []) {
|
|
192
189
|
// check if selection changed
|
|
193
190
|
const alreadySelected = [
|
|
194
191
|
...customEmailsList.data,
|
|
@@ -202,9 +199,6 @@ function CaseContactSelector(props) {
|
|
|
202
199
|
const selectedCustomEmails = remove(allSelectedContacts, (item) => item.customOption || item.emailAddress).map((item) => item.label || item.emailAddress || item.ssoUsername);
|
|
203
200
|
yield processCustomEmails(selectedCustomEmails);
|
|
204
201
|
yield processCaseContacts(allSelectedContacts);
|
|
205
|
-
if (throwTrackEvent) {
|
|
206
|
-
dtmTrackEventCaseStepEncountered('follow', caseNumber, product, version);
|
|
207
|
-
}
|
|
208
202
|
});
|
|
209
203
|
/** Reset all non-internal selectedNotificationContacts when selected account number changes */
|
|
210
204
|
useEffect(() => {
|
|
@@ -220,9 +214,9 @@ function CaseContactSelector(props) {
|
|
|
220
214
|
!isCurrentUserSelectedExternalNotifiedUser();
|
|
221
215
|
const showRemoveWatchButton = () => loggedInUserRights.data.isExternal() &&
|
|
222
216
|
(isCurrentUserSelectedExternalNotifiedUser() || isCurrentUserCaseContact);
|
|
223
|
-
const addCurrentUser = () =>
|
|
224
|
-
onNotifiedUserChange([...selectedNotificationContacts, ...customEmailsList.data, loggedInUser.data]
|
|
225
|
-
}
|
|
217
|
+
const addCurrentUser = () => {
|
|
218
|
+
onNotifiedUserChange([...selectedNotificationContacts, ...customEmailsList.data, loggedInUser.data]);
|
|
219
|
+
};
|
|
226
220
|
const removeCurrentUser = () => {
|
|
227
221
|
if (isCurrentUserSelectedExternalNotifiedUser()) {
|
|
228
222
|
onNotifiedUserChange([
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ICVEWorkflowRecommendation } from '../../models/caseCreationWorkflows';
|
|
3
|
+
interface IProp {
|
|
4
|
+
cve: ICVEWorkflowRecommendation;
|
|
5
|
+
}
|
|
6
|
+
export declare const CveItem: (props: IProp) => React.JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=CveItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CveItem.d.ts","sourceRoot":"","sources":["../../../../src/components/Cve/CveItem.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAEhF,UAAU,KAAK;IACX,GAAG,EAAE,0BAA0B,CAAC;CACnC;AAID,eAAO,MAAM,OAAO,UAAW,KAAK,sBAqInC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Button, Flex, FlexItem, Label, LabelGroup, Text, TextVariants } from '@patternfly/react-core';
|
|
2
|
+
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
|
|
3
|
+
import StarIcon from '@patternfly/react-icons/dist/esm/icons/star-icon';
|
|
4
|
+
import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';
|
|
5
|
+
import { format } from 'date-fns';
|
|
6
|
+
import DOMPurify from 'dompurify';
|
|
7
|
+
import isEmpty from 'lodash/isEmpty';
|
|
8
|
+
import map from 'lodash/map';
|
|
9
|
+
import slice from 'lodash/slice';
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { Trans } from 'react-i18next';
|
|
12
|
+
const sanitize = (html) => ({ __html: DOMPurify.sanitize(html) });
|
|
13
|
+
export const CveItem = (props) => {
|
|
14
|
+
const { cve } = props;
|
|
15
|
+
const renderDate = () => (React.createElement("div", { className: "pf-v5-u-disabled-color-100" },
|
|
16
|
+
React.createElement(Trans, null, "Public on"),
|
|
17
|
+
" - ",
|
|
18
|
+
format(cve === null || cve === void 0 ? void 0 : cve.publicDate, 'MMM dd, yyyy')));
|
|
19
|
+
const renderLabels = () => (React.createElement(LabelGroup, { defaultIsOpen: true, numLabels: 10 },
|
|
20
|
+
React.createElement(Label, { color: "green", isCompact: true, icon: React.createElement(StarIcon, null) },
|
|
21
|
+
React.createElement(Trans, null, "Exact match")),
|
|
22
|
+
React.createElement(Label, { color: cve.severity === 'Critical'
|
|
23
|
+
? 'red'
|
|
24
|
+
: cve.severity === 'Important'
|
|
25
|
+
? 'orange'
|
|
26
|
+
: cve.severity === 'Moderate'
|
|
27
|
+
? 'gold'
|
|
28
|
+
: undefined, isCompact: true }, cve.severity),
|
|
29
|
+
!isEmpty(cve.errataData) && (React.createElement(Label, { color: "blue", isCompact: true },
|
|
30
|
+
React.createElement(Trans, null, "Fixed"))),
|
|
31
|
+
!isEmpty(cve.mitigation) && (React.createElement(Label, { isCompact: true },
|
|
32
|
+
React.createElement(Trans, null, "Mitigation available")))));
|
|
33
|
+
const displayErrataTable = () => {
|
|
34
|
+
if (isEmpty(cve === null || cve === void 0 ? void 0 : cve.errataData)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return (React.createElement(Table, { "aria-label": "Errata table", variant: 'compact' },
|
|
38
|
+
React.createElement(Thead, null,
|
|
39
|
+
React.createElement(Tr, null,
|
|
40
|
+
React.createElement(Th, { width: 30 },
|
|
41
|
+
React.createElement(Trans, null, "Errata link")),
|
|
42
|
+
React.createElement(Th, null,
|
|
43
|
+
React.createElement(Trans, null, "Component")),
|
|
44
|
+
React.createElement(Th, { width: 30 },
|
|
45
|
+
React.createElement(Trans, null, "Status")))),
|
|
46
|
+
React.createElement(Tbody, null, map(slice(cve.errataData, 0, 3), (errata, index) => {
|
|
47
|
+
var _a, _b, _c;
|
|
48
|
+
return (React.createElement(Tr, Object.assign({ key: (_a = errata === null || errata === void 0 ? void 0 : errata.advisory) === null || _a === void 0 ? void 0 : _a.name }, (index % 2 === 0 && { isStriped: true })),
|
|
49
|
+
React.createElement(Td, null,
|
|
50
|
+
React.createElement(Text, { component: TextVariants.a, href: (_b = errata === null || errata === void 0 ? void 0 : errata.advisory) === null || _b === void 0 ? void 0 : _b.url, target: "_blank", ouiaSafe: true, "data-tracking-id": "errata-link" }, (_c = errata === null || errata === void 0 ? void 0 : errata.advisory) === null || _c === void 0 ? void 0 :
|
|
51
|
+
_c.name,
|
|
52
|
+
React.createElement(ExternalLinkAltIcon, { className: "pf-v5-u-ml-sm" }))),
|
|
53
|
+
React.createElement(Td, null, errata === null || errata === void 0 ? void 0 : errata.package),
|
|
54
|
+
React.createElement(Td, null,
|
|
55
|
+
React.createElement(Trans, null, errata === null || errata === void 0 ? void 0 : errata.state))));
|
|
56
|
+
}))));
|
|
57
|
+
};
|
|
58
|
+
const displayDescription = () => {
|
|
59
|
+
var _a;
|
|
60
|
+
if (isEmpty(cve === null || cve === void 0 ? void 0 : cve.mitigation) && ((_a = cve === null || cve === void 0 ? void 0 : cve.errataData) === null || _a === void 0 ? void 0 : _a.length) === 0) {
|
|
61
|
+
return (React.createElement("p", { className: "pf-v5-u-mt-md" }, "for this CVE mitigation and fix is not available, for more details, go to CVE page."));
|
|
62
|
+
}
|
|
63
|
+
const MAX_DESCRIPTION_LENGTH = 300;
|
|
64
|
+
const description = !isEmpty(cve === null || cve === void 0 ? void 0 : cve.mitigation) ? cve === null || cve === void 0 ? void 0 : cve.mitigation : cve === null || cve === void 0 ? void 0 : cve.details;
|
|
65
|
+
if (!description)
|
|
66
|
+
return '';
|
|
67
|
+
const trimmedDescription = description.length <= MAX_DESCRIPTION_LENGTH
|
|
68
|
+
? description
|
|
69
|
+
: description.slice(0, MAX_DESCRIPTION_LENGTH).trim() + '...';
|
|
70
|
+
return React.createElement("p", { className: "pf-v5-u-mt-md", dangerouslySetInnerHTML: sanitize(trimmedDescription) });
|
|
71
|
+
};
|
|
72
|
+
return (React.createElement("p", null,
|
|
73
|
+
React.createElement(Flex, null,
|
|
74
|
+
React.createElement(FlexItem, { spacer: { default: 'spacerXs' } }, renderLabels()),
|
|
75
|
+
React.createElement(FlexItem, null, renderDate())),
|
|
76
|
+
displayErrataTable(),
|
|
77
|
+
displayDescription(),
|
|
78
|
+
(cve === null || cve === void 0 ? void 0 : cve.cveLink) && (React.createElement(Button, { variant: "primary", className: "pf-v5-u-my-md", "data-tracking-id": "go-to-CVE-button", component: "a", href: cve.cveLink, target: "_blank", rel: "noopener noreferrer" },
|
|
79
|
+
React.createElement(Trans, null, "Go to CVE"),
|
|
80
|
+
React.createElement(ExternalLinkAltIcon, { className: "pf-v5-u-ml-sm" })))));
|
|
81
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CveModal.d.ts","sourceRoot":"","sources":["../../../../src/components/Cve/CveModal.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,eAAO,MAAM,QAAQ,yBAuDpB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Badge, Button, Flex, FlexItem, Modal, ModalVariant } from '@patternfly/react-core';
|
|
2
|
+
import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
|
|
3
|
+
import { getAccessHostname } from '@rh-support/utils';
|
|
4
|
+
import isEqual from 'lodash/isEqual';
|
|
5
|
+
import join from 'lodash/join';
|
|
6
|
+
import map from 'lodash/map';
|
|
7
|
+
import size from 'lodash/size';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { Trans } from 'react-i18next';
|
|
10
|
+
import { useCaseDispatch, useCaseSelector } from '../../context/CaseContext';
|
|
11
|
+
import { setCaseState } from '../../reducers/CaseReducer';
|
|
12
|
+
import { CvePanel } from './CvePanel';
|
|
13
|
+
export const CveModal = () => {
|
|
14
|
+
const caseDispatch = useCaseDispatch();
|
|
15
|
+
const { cveWorkflowRecommendation, isCveModalOpened } = useCaseSelector((state) => ({
|
|
16
|
+
cveWorkflowRecommendation: state.cveWorkflowRecommendation,
|
|
17
|
+
isCveModalOpened: state.isCveModalOpened,
|
|
18
|
+
}), isEqual);
|
|
19
|
+
const handleModalToggle = () => {
|
|
20
|
+
setCaseState(caseDispatch, { isCveModalOpened: !isCveModalOpened });
|
|
21
|
+
};
|
|
22
|
+
const handleEscapePress = (event) => {
|
|
23
|
+
// prevent the default escape key behavior
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
};
|
|
26
|
+
const generateCveCheckerUrl = () => {
|
|
27
|
+
const cveTitles = join(map(cveWorkflowRecommendation, 'title'), ',');
|
|
28
|
+
return `https://${getAccessHostname()}/labs/cvechecker/?id=${cveTitles}`;
|
|
29
|
+
};
|
|
30
|
+
return (React.createElement(Modal, { variant: ModalVariant.medium, title: React.createElement(Flex, { alignItems: { default: 'alignItemsCenter' } },
|
|
31
|
+
React.createElement(FlexItem, { spacer: { default: 'spacerSm' } },
|
|
32
|
+
React.createElement(Trans, null, "Handpicked for this CVEs")),
|
|
33
|
+
React.createElement(Badge, { isRead: true }, size(cveWorkflowRecommendation))), isOpen: isCveModalOpened, onClose: handleModalToggle, titleIconVariant: "info", disableFocusTrap: true, onEscapePress: handleEscapePress, actions: [
|
|
34
|
+
React.createElement(Button, { key: "cve-checker-link", "data-tracking-id": "cve-checker-link", target: "_blank", variant: "secondary", isInline: true, component: "a", href: generateCveCheckerUrl() },
|
|
35
|
+
React.createElement(Trans, null, "Red Hat CVE Checker"),
|
|
36
|
+
" ",
|
|
37
|
+
React.createElement(ExternalLinkAltIcon, { className: "pf-v5-u-ml-sm" })),
|
|
38
|
+
] },
|
|
39
|
+
React.createElement(CvePanel, null)));
|
|
40
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CvePanel.d.ts","sourceRoot":"","sources":["../../../../src/components/Cve/CvePanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAMxC,UAAU,MAAM;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,QAAQ,UAAW,MAAM,sBAyCrC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionToggle } from '@patternfly/react-core';
|
|
2
|
+
import isEqual from 'lodash/isEqual';
|
|
3
|
+
import map from 'lodash/map';
|
|
4
|
+
import slice from 'lodash/slice';
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
import { useCaseSelector } from '../../context/CaseContext';
|
|
7
|
+
import { CveItem } from './CveItem';
|
|
8
|
+
export const CvePanel = (props) => {
|
|
9
|
+
var _a;
|
|
10
|
+
const { cveWorkflowRecommendation } = useCaseSelector((state) => ({
|
|
11
|
+
cveWorkflowRecommendation: state.cveWorkflowRecommendation,
|
|
12
|
+
}), isEqual);
|
|
13
|
+
const [expanded, setExpanded] = useState(((_a = cveWorkflowRecommendation === null || cveWorkflowRecommendation === void 0 ? void 0 : cveWorkflowRecommendation[0]) === null || _a === void 0 ? void 0 : _a.title) || '');
|
|
14
|
+
const handleToggle = (id) => setExpanded(id === expanded ? '' : id);
|
|
15
|
+
const renderAccordionItem = (cve, index) => {
|
|
16
|
+
const isExpanded = expanded === (cve === null || cve === void 0 ? void 0 : cve.title);
|
|
17
|
+
return (React.createElement(AccordionItem, { key: `cve-item-${index}` },
|
|
18
|
+
React.createElement(AccordionToggle, { onClick: () => handleToggle(cve.title), isExpanded: isExpanded, id: `cve-toggle-${index}`, "data-tracking-id": "cve-accordion-toggle" }, cve.title),
|
|
19
|
+
React.createElement(AccordionContent, { id: `cve-content-${index}`, isHidden: !isExpanded },
|
|
20
|
+
React.createElement(CveItem, { cve: cve }))));
|
|
21
|
+
};
|
|
22
|
+
return (React.createElement(Accordion, { isBordered: true, displaySize: 'default', asDefinitionList: false, className: `${props.className ? props.className : ''}` }, map(slice(cveWorkflowRecommendation, 0, 4), renderAccordionItem)));
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CveSidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/Cve/CveSidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,eAAO,MAAM,UAAU,yBAyBtB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Badge } from '@patternfly/react-core';
|
|
2
|
+
import isEmpty from 'lodash/isEmpty';
|
|
3
|
+
import isEqual from 'lodash/isEqual';
|
|
4
|
+
import size from 'lodash/size';
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { Trans } from 'react-i18next';
|
|
7
|
+
import { useCaseSelector } from '../../context/CaseContext';
|
|
8
|
+
import { CvePanel } from './CvePanel';
|
|
9
|
+
export const CveSidebar = () => {
|
|
10
|
+
const { cveWorkflowRecommendation } = useCaseSelector((state) => ({
|
|
11
|
+
cveWorkflowRecommendation: state.cveWorkflowRecommendation,
|
|
12
|
+
}), isEqual);
|
|
13
|
+
if (isEmpty(cveWorkflowRecommendation)) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return (React.createElement(React.Fragment, null,
|
|
17
|
+
React.createElement("div", { className: "card card-white card-support file-diag pf-v5-u-mb-md" },
|
|
18
|
+
React.createElement("h3", { className: "card-heading popular-solutions green-card-heading" },
|
|
19
|
+
React.createElement("span", { className: "pf-v5-u-mr-sm" },
|
|
20
|
+
React.createElement(Trans, null, "Handpicked for this CVEs")),
|
|
21
|
+
React.createElement(Badge, { isRead: true }, size(cveWorkflowRecommendation))),
|
|
22
|
+
React.createElement("div", { className: "card-body" },
|
|
23
|
+
React.createElement(CvePanel, null)))));
|
|
24
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/ProductSelector/ProductSelector.tsx"],"names":[],"mappings":"AAKA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProductSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/ProductSelector/ProductSelector.tsx"],"names":[],"mappings":"AAKA,OAAO,KAA6B,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAOlE,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACzE,gCAAgC,EAAE,OAAO,CAAC;IAC1C,aAAa,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CAChE;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,MAAM,qBAwFpD"}
|
|
@@ -7,6 +7,8 @@ import React, { useContext, useRef } from 'react';
|
|
|
7
7
|
import { Trans, useTranslation } from 'react-i18next';
|
|
8
8
|
import { useCaseSelector } from '../../context/CaseContext';
|
|
9
9
|
import { RouteContext } from '../../context/RouteContext';
|
|
10
|
+
import { useFetchCVEData } from '../../hooks/useFetchCVEData';
|
|
11
|
+
import { CveModal } from '../Cve/CveModal';
|
|
10
12
|
import { EARuleWidget } from '../Recommendations/EARules/EARuleWidget';
|
|
11
13
|
import Recommendations from '../Recommendations/Recommendations';
|
|
12
14
|
import { AllProductsSelector } from './AllProductsSelector';
|
|
@@ -20,6 +22,7 @@ import { ProductSelectorLoader } from './ProductSelectorLoader';
|
|
|
20
22
|
* @param props
|
|
21
23
|
*/
|
|
22
24
|
export default function ProductSelector(props) {
|
|
25
|
+
const { cveRecommendation } = useFetchCVEData();
|
|
23
26
|
const { t } = useTranslation();
|
|
24
27
|
const { globalMetadataState: { allProducts }, } = useContext(GlobalMetadataStateContext);
|
|
25
28
|
const { product, version } = useCaseSelector((state) => ({
|
|
@@ -38,6 +41,7 @@ export default function ProductSelector(props) {
|
|
|
38
41
|
React.createElement(AlertMessage, { variant: AlertType.DANGER, className: "pf-v5-u-mt-lg", title: t('There was an error loading products.'), show: allProducts.isError }),
|
|
39
42
|
!allProducts.isFetching && !allProducts.isError && (React.createElement(React.Fragment, null,
|
|
40
43
|
React.createElement("form", null,
|
|
44
|
+
(cveRecommendation === null || cveRecommendation === void 0 ? void 0 : cveRecommendation.length) !== 0 && React.createElement(CveModal, null),
|
|
41
45
|
React.createElement(AllProductsSelector, { routeProps: props.routeProps, checkEntitledProduct: isCaseCreate ? true : false, ref: productSelectorRef, isOnSummaryPage: true }),
|
|
42
46
|
product === 'Subscription Watch' && (React.createElement(Alert, { isInline: true, variant: AlertVariant.warning, title: React.createElement(Trans, null,
|
|
43
47
|
' ',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AsideResults.d.ts","sourceRoot":"","sources":["../../../../src/components/Recommendations/AsideResults.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AsideResults.d.ts","sourceRoot":"","sources":["../../../../src/components/Recommendations/AsideResults.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAE7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AASvD,OAAO,EAAE,eAAe,EAAsC,MAAM,iCAAiC,CAAC;AAUtG,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,qBAyLzC"}
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { pcm, search } from '@cee-eng/hydrajs';
|
|
11
11
|
import { useDebounce } from '@rh-support/components';
|
|
12
|
-
import { computeRecommendationAbstract, computeRecommendationTitle, convertObjToEncodedQueryParams,
|
|
12
|
+
import { computeRecommendationAbstract, computeRecommendationTitle, convertObjToEncodedQueryParams, getSolrParams, getTrimmedCharacters, PreviousCaseTypes, replaceHighlightingData, } from '@rh-support/utils';
|
|
13
13
|
import isEmpty from 'lodash/isEmpty';
|
|
14
14
|
import isEqual from 'lodash/isEqual';
|
|
15
15
|
import React, { useContext, useEffect, useRef } from 'react';
|
|
@@ -117,9 +117,7 @@ export function AsideResults(props) {
|
|
|
117
117
|
const onResourceClick = (doc, index) => (event) => {
|
|
118
118
|
if (isSelectedAccounntSecureSupport)
|
|
119
119
|
return;
|
|
120
|
-
const rank = index + 1 + PAGE_SIZE * ((recommendationState.currentPage || 1) - 1);
|
|
121
120
|
createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.RECOMMENDATIONS_ASIDE, [getSessResFromRec(doc, SessionResourceVisibility.VISITED, index + 1)], payload);
|
|
122
|
-
dtmTrackEventRecommendationListingItemClicked(window.location.href, activeSection, 'middle', doc.id, rank, doc.allTitle, doc.view_uri, 'Recommendation Aside', 'Live troubleshooting powered by OpenShift AI');
|
|
123
121
|
};
|
|
124
122
|
useEffect(() => {
|
|
125
123
|
if (isSelectedAccounntSecureSupport)
|
|
@@ -131,7 +129,7 @@ export function AsideResults(props) {
|
|
|
131
129
|
if (!canShowSideRecommendations())
|
|
132
130
|
return React.createElement(React.Fragment, null);
|
|
133
131
|
return (React.createElement("div", { className: `card card-white card-support top-recommendations ${props.className ? props.className : ''}` },
|
|
134
|
-
React.createElement("h3", { className: "card-heading popular-solutions green-card-heading" }, isIdea ?
|
|
132
|
+
React.createElement("h3", { className: "card-heading popular-solutions green-card-heading" }, isIdea ? React.createElement(Trans, null, "Search recommendations") : React.createElement(Trans, null, "Articles recommended by OpenShift AI")),
|
|
135
133
|
React.createElement("div", { className: "card-body" },
|
|
136
134
|
React.createElement("ul", { className: "list-flat" }, recommendationState.sideRecommendation.map((doc, index) => {
|
|
137
135
|
var _a, _b;
|
|
@@ -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":"AAKA,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,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,KAAK,IAAI,CAAC;CAClH;AAGD,eAAO,MAAM,aAAa,+BAGxB,CAAC;AAEH,wBAAgB,gBAAgB,mBAM/B;AACD,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;;;;CAAA,qBAqClD;AAED,iBAAS,WAAW,sBAGnB;AAED,iBAAS,iBAAiB,sBA0BzB;AAED,iBAAS,aAAa,CAAC,EAAE,SAA6B,EAAE,SAAc,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,qBA2BnH;AAED,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
import { pcm } from '@cee-eng/hydrajs';
|
|
3
|
+
import { dtmTrackEventCaseStartStopped } from '@rh-support/utils';
|
|
3
4
|
import DOMPurify from 'dompurify';
|
|
4
5
|
import isEqual from 'lodash/isEqual';
|
|
5
6
|
import React, { useContext } from 'react';
|
|
@@ -30,6 +31,7 @@ export function EARule({ children, rule, ruleRank }) {
|
|
|
30
31
|
const sessionRestoreDispatch = useContext(SessionRestoreDispatchContext);
|
|
31
32
|
const onCtaClick = (link, title) => () => {
|
|
32
33
|
createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.EDMOUND_ABOTT, [getSessResFromEA(link, SessionResourceVisibility.VISITED, ruleRank, rule.rule_id)], JSON.stringify({ product, version, summary }));
|
|
34
|
+
dtmTrackEventCaseStartStopped(`insight rule button click: ${title}`, undefined, `${product}|${version}`);
|
|
33
35
|
};
|
|
34
36
|
return (React.createElement(EARuleContext.Provider, { value: {
|
|
35
37
|
rule,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EARuleInfoInline.d.ts","sourceRoot":"","sources":["../../../../../src/components/Recommendations/EARules/EARuleInfoInline.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EARuleInfoInline.d.ts","sourceRoot":"","sources":["../../../../../src/components/Recommendations/EARules/EARuleInfoInline.tsx"],"names":[],"mappings":"AAeA,OAAO,KAA0C,MAAM,OAAO,CAAC;AAM/D,OAAO,EAAE,aAAa,EAAkD,MAAM,gCAAgC,CAAC;AAO/G,UAAU,MAAM;IACZ,OAAO,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,OAAY,EAAE,EAAE,MAAM,qBAiKxD"}
|
|
@@ -14,7 +14,7 @@ import CloseIcon from '@patternfly/react-icons/dist/js/icons/close-icon';
|
|
|
14
14
|
import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
|
|
15
15
|
import { PaginationCompact, useFetch } from '@rh-support/components';
|
|
16
16
|
import { GlobalMetadataStateContext } from '@rh-support/react-context';
|
|
17
|
-
import { getResTypeFromUrl, getStyleVariantColor, StyleVariants } from '@rh-support/utils';
|
|
17
|
+
import { dtmTrackEventCaseStartStopped, getResTypeFromUrl, getStyleVariantColor, StyleVariants, } from '@rh-support/utils';
|
|
18
18
|
import isEqual from 'lodash/isEqual';
|
|
19
19
|
import some from 'lodash/some';
|
|
20
20
|
import React, { useContext, useEffect, useState } from 'react';
|
|
@@ -102,7 +102,7 @@ export function EARuleInfoInline({ eaRules = [] }) {
|
|
|
102
102
|
React.createElement(EARuleTitle, null))),
|
|
103
103
|
React.createElement("div", { className: "pf-v5-c-alert__action" },
|
|
104
104
|
React.createElement(Button, { style: { fontSize: 15 }, variant: ButtonVariant.link, "data-tracking-id": "se-recommended-asa-ignore", type: "button", onClick: onIgnoreBtnClick }, validEARulesLength > 1 ? React.createElement(Trans, null, "Skip") : React.createElement(CloseIcon, null))),
|
|
105
|
-
React.createElement("div", { className: "pf-v5-c-alert__description" },
|
|
105
|
+
React.createElement("div", { className: "pf-v5-c-alert__description", onClick: () => dtmTrackEventCaseStartStopped('insight rule description click', undefined, `${product}|${version}`) },
|
|
106
106
|
React.createElement(EARuleDescription, null)),
|
|
107
107
|
React.createElement("div", { className: "pf-v5-c-alert__action-group pf-v5-u-display-flex" },
|
|
108
108
|
React.createElement(EARuleArticle, { className: "pf-v5-u-align-self-center pf-v5-u-mr-sm", linkTitle: "View details" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Recommendations.d.ts","sourceRoot":"","sources":["../../../../src/components/Recommendations/Recommendations.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAelE,OAAO,EAAoB,eAAe,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"Recommendations.d.ts","sourceRoot":"","sources":["../../../../src/components/Recommendations/Recommendations.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAelE,OAAO,EAAoB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAYpF,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACzE,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,aAAa,EAAE,GAAG,CAAC;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,MAAM,qBAoSpD"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { pcm } from '@cee-eng/hydrajs';
|
|
2
|
-
import { Label, Pagination, PaginationVariant } from '@patternfly/react-core';
|
|
3
|
-
import
|
|
2
|
+
import { Label, Pagination, PaginationVariant, Spinner } from '@patternfly/react-core';
|
|
3
|
+
import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
|
|
4
|
+
import { useDebounce, usePrevious } from '@rh-support/components';
|
|
4
5
|
import { useGlobalStateContext } from '@rh-support/react-context';
|
|
5
|
-
import { computeRecommendationAbstract, computeRecommendationTitle,
|
|
6
|
+
import { computeRecommendationAbstract, computeRecommendationTitle, dtmTrackEventCaseStartStopped, formatDate, } from '@rh-support/utils';
|
|
6
7
|
import differenceBy from 'lodash/differenceBy';
|
|
7
8
|
import isEmpty from 'lodash/isEmpty';
|
|
8
9
|
import isEqual from 'lodash/isEqual';
|
|
@@ -20,6 +21,7 @@ import { fetchRecommendations, fetchWatsonXRecommendations, RecommendationsConst
|
|
|
20
21
|
import { AppRouteSections } from '../../reducers/RouteConstNTypes';
|
|
21
22
|
import { createOrUpdateSessionResources, getSessResFromRec, getSessResFromRecs, } from '../../reducers/SessionRestoreReducer';
|
|
22
23
|
import RouteUtils from '../../utils/routeUtils';
|
|
24
|
+
import { RecommendationsLoader } from './RecommendationsLoader';
|
|
23
25
|
import { WatsonxAiIcon } from './WatsonxAiIcon';
|
|
24
26
|
const { SessionResourceSource, SessionResourceVisibility } = pcm.preCase.session;
|
|
25
27
|
export default function Recommendations(props) {
|
|
@@ -121,18 +123,6 @@ export default function Recommendations(props) {
|
|
|
121
123
|
setCaseRecommendations(caseDispatch, recommendationState.visibleDocs, caseResourceLinks);
|
|
122
124
|
}
|
|
123
125
|
createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.RECOMMENDATIONS, getSessResFromRecs(recommendationState.visibleDocs, SessionResourceVisibility.PRESENTED, pageSize || DEFAULTPAGESIZE, recommendationState.currentPage || 1), JSON.stringify(payload));
|
|
124
|
-
const listing = recommendationState.visibleDocs.map((doc, i) => ({
|
|
125
|
-
content: {
|
|
126
|
-
contentID: doc.id,
|
|
127
|
-
contentPosition: i + 1,
|
|
128
|
-
contentTitle: doc.publishedTitle,
|
|
129
|
-
contentUrl: doc.view_uri,
|
|
130
|
-
displayFeature: 'Troubleshooting',
|
|
131
|
-
displayFeatureTitle: '',
|
|
132
|
-
},
|
|
133
|
-
isDisplayed: true,
|
|
134
|
-
}));
|
|
135
|
-
dtmTrackEventRecommendationListingDisplayed('middle', activeSection, listing, recommendationState.numFound);
|
|
136
126
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
137
127
|
}, [caseDispatch, recommendationState.visibleDocs, activeSessionId]);
|
|
138
128
|
useEffect(() => {
|
|
@@ -157,17 +147,25 @@ export default function Recommendations(props) {
|
|
|
157
147
|
setCurrentPage(recommendationDispatch, 1);
|
|
158
148
|
};
|
|
159
149
|
const onResourceClick = (doc, index) => (event) => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.RECOMMENDATIONS, [
|
|
151
|
+
getSessResFromRec(doc, SessionResourceVisibility.VISITED, index + 1 + (pageSize || DEFAULTPAGESIZE) * ((recommendationState.currentPage || 1) - 1)),
|
|
152
|
+
], JSON.stringify(payload));
|
|
153
|
+
dtmTrackEventCaseStartStopped('recommendation click', caseNumber, `${product}|${version}`);
|
|
163
154
|
};
|
|
164
155
|
return (React.createElement(React.Fragment, null,
|
|
165
|
-
React.createElement(LoadingDots, { className: "recommendation-loading-dots", show: recommendationState.isLoadingRecommendations && !isEmpty(summary) && !isEmpty(issue) }),
|
|
166
156
|
React.createElement("div", { className: "recommendation-list pf-v5-u-pt-md", ref: props.resultsRowRef },
|
|
167
|
-
recommendationState.visibleDocs.length !== 0 && (React.createElement(Label, {
|
|
168
|
-
React.createElement(
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
(recommendationState.visibleDocs.length !== 0 || recommendationState.isLoadingRecommendations) && (React.createElement(Label, { id: "DeepPurpleColorAILabel", className: "pf-v5-u-mb-md" },
|
|
158
|
+
recommendationState.isLoadingRecommendations ? (React.createElement(React.Fragment, null,
|
|
159
|
+
React.createElement(Spinner, { size: "sm", className: "pf-v5-u-mr-xs" }),
|
|
160
|
+
' ',
|
|
161
|
+
React.createElement(Trans, null, "Recommending articles using OpenShift AI"))) : (React.createElement(React.Fragment, null,
|
|
162
|
+
React.createElement(WatsonxAiIcon, { fillColor: "#FFFFFF", className: "pf-v5-u-mr-xs" }),
|
|
163
|
+
' ',
|
|
164
|
+
React.createElement(Trans, null, "Articles recommended by OpenShift AI"))),
|
|
165
|
+
' ',
|
|
166
|
+
React.createElement(InfoCircleIcon, { color: "white" }))),
|
|
167
|
+
recommendationState.isLoadingRecommendations ? ( // as much as it pains me to add these <br /> the pf docs has it this way
|
|
168
|
+
React.createElement(RecommendationsLoader, null)) : (React.createElement("ul", { className: "list-flat" }, map(recommendationState.visibleDocs, (doc, i) => {
|
|
171
169
|
var _a, _b;
|
|
172
170
|
return (React.createElement("li", { className: "result", key: doc.id },
|
|
173
171
|
React.createElement("header", { className: "result-header" },
|
|
@@ -180,7 +178,7 @@ export default function Recommendations(props) {
|
|
|
180
178
|
React.createElement("span", { className: "list-separator" }, "\u2013"),
|
|
181
179
|
React.createElement("time", { className: "moment_date meta", title: doc.lastModifiedDate.toString() }, formatDate(doc.lastModifiedDate)))),
|
|
182
180
|
React.createElement("p", { className: "result-body", dangerouslySetInnerHTML: computeRecommendationAbstract(doc, 300) })));
|
|
183
|
-
})),
|
|
181
|
+
}))),
|
|
184
182
|
recommendationState.numFound !== 0 && recommendationState.numFound > DEFAULTPAGESIZE && (React.createElement("div", { className: "pagination-footer" },
|
|
185
183
|
React.createElement(Pagination, { className: "push-top", itemCount: (_c = (_b = recommendationState.allDocs) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0, perPage: recPageSize, page: recommendationState.currentPage, variant: PaginationVariant.bottom, onSetPage: pageChanged, dropDirection: "up", onPerPageSelect: onPageSizeChanged })))),
|
|
186
184
|
recommendationState.visibleDocs.length === 0 &&
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecommendationsLoader.d.ts","sourceRoot":"","sources":["../../../../src/components/Recommendations/RecommendationsLoader.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,qBAAqB,yBAejC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Skeleton } from '@patternfly/react-core';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export const RecommendationsLoader = () => {
|
|
4
|
+
return (React.createElement("div", { className: "pf-v5-u-mt-md" }, [...Array(5)].map((_, i) => (React.createElement(React.Fragment, { key: `recommendation-loading-${i}` },
|
|
5
|
+
React.createElement(Skeleton, { height: "20px", width: "100%" }),
|
|
6
|
+
React.createElement("br", null),
|
|
7
|
+
React.createElement(Skeleton, { height: "45px", width: "100%" }),
|
|
8
|
+
React.createElement("br", null),
|
|
9
|
+
React.createElement("br", null),
|
|
10
|
+
React.createElement("br", null))))));
|
|
11
|
+
};
|
|
@@ -168,11 +168,11 @@ export default function SubmitCase(props) {
|
|
|
168
168
|
React.createElement("div", { className: "submit-case-header-container" },
|
|
169
169
|
React.createElement("p", { className: "kicker kicker-sm pf-v5-u-mb-sm" }, !isEmpty(RouteUtils.seBasePath) &&
|
|
170
170
|
!isUploadingAttachment(attachmentState.caseFiles.selectedLocalFiles) ? (React.createElement(React.Fragment, null,
|
|
171
|
-
React.createElement("div", { className: "submit-page-title pf-v5-u-mb-lg" },
|
|
171
|
+
React.createElement("div", { role: "alert", className: "submit-page-title pf-v5-u-mb-lg" },
|
|
172
172
|
React.createElement(Icon, { className: "submit-case-check-icon pf-v5-u-mt-sm", size: "lg" },
|
|
173
173
|
React.createElement(CheckCircleIcon, null)),
|
|
174
174
|
' ',
|
|
175
|
-
React.createElement(Text, {
|
|
175
|
+
React.createElement(Text, { className: "pf-v5-u-mb-0", component: TextVariants.h1 },
|
|
176
176
|
React.createElement(Trans, null, "We've added your case to our queue"))),
|
|
177
177
|
React.createElement("div", { className: "pf-v5-u-mt-sm" },
|
|
178
178
|
React.createElement(Trans, null, "Case number:"),
|
|
@@ -184,7 +184,7 @@ export default function SubmitCase(props) {
|
|
|
184
184
|
React.createElement(Icon, { size: "lg", className: "submit-case-check-icon" },
|
|
185
185
|
React.createElement(CheckCircleIcon, null)),
|
|
186
186
|
' ',
|
|
187
|
-
React.createElement(Text, {
|
|
187
|
+
React.createElement(Text, { component: TextVariants.h1 },
|
|
188
188
|
React.createElement(Trans, null, "We\u2019ve added your case to our queue"))),
|
|
189
189
|
React.createElement(React.Fragment, null,
|
|
190
190
|
React.createElement(Trans, null, "Case number: "),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopContent.d.ts","sourceRoot":"","sources":["../../../../src/components/Suggestions/TopContent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;
|
|
1
|
+
{"version":3,"file":"TopContent.d.ts","sourceRoot":"","sources":["../../../../src/components/Suggestions/TopContent.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2DAA2D,CAAC;AAKxF,OAAO,KAAmB,MAAM,OAAO,CAAC;AASxC,UAAU,MAAM;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,KAAK,EAAE,MAAM,qBAiJ/C"}
|