@rh-support/troubleshoot 2.6.308 → 2.6.309

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.
@@ -1 +1 @@
1
- {"version":3,"file":"CaseDetailsManagement.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAkBvD,UAAU,MAAO,SAAQ,gBAAgB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBAmE1D"}
1
+ {"version":3,"file":"CaseDetailsManagement.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseDetailsManagement.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAG5D,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAmBvD,UAAU,MAAO,SAAQ,gBAAgB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,CAAC;IAChC,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAK,EAAE,MAAM,qBA0E1D"}
@@ -5,6 +5,7 @@ import React, { useContext, useState } from 'react';
5
5
  import { useCaseSelector } from '../../../../context/CaseContext';
6
6
  import { OwnerSelector } from '../../../AccountInfo/OwnerSelector';
7
7
  import CaseGroup from '../../../CaseInformation/CaseGroup';
8
+ import CaseLabels from '../../../CaseInformation/CaseLabels';
8
9
  import Fts from '../../../CaseInformation/Fts';
9
10
  // import { Cep } from '../../../CaseManagement/Cep';
10
11
  // import { RHAssociatesSelector } from '../../../CaseManagement/RHAssociatesSelector';
@@ -45,7 +46,11 @@ export default function CaseDetailsManagement(props) {
45
46
  React.createElement(CaseContactPhoneNumberAlert, { isConfirm: true }),
46
47
  canSeeInternalStatus && React.createElement(CaseInternalStatus, null),
47
48
  canSeeSBRGroups && React.createElement(CaseSbrGroups, null),
48
- React.createElement(CaseGroup, null),
49
+ React.createElement(Flex, { direction: { default: 'column', lg: 'row' } },
50
+ React.createElement(FlexItem, { flex: { default: 'flex_1' } },
51
+ React.createElement(CaseGroup, null)),
52
+ React.createElement(FlexItem, { flex: { default: 'flex_1' } },
53
+ React.createElement(CaseLabels, null))),
49
54
  React.createElement(CaseReferenceNumber, null),
50
55
  React.createElement(Fts, { inlineEditable: true }),
51
56
  React.createElement(SFDCUrl, null),
@@ -182,7 +182,7 @@ const CaseComments = React.forwardRef((props, ref) => {
182
182
  .replace(/<\/?ul>/gi, ''));
183
183
  }
184
184
  const commentMarkdown = (markdown) => {
185
- let htmlString = parseCommentMarkdown(markdown, { showButtonForAttachmentLink: true, disableImagePreview: isExportingPDF },
185
+ let htmlString = parseCommentMarkdown(markdown, { showButtonForAttachmentLink: true, disableImagePreview: isExportingPDF, encodeHTMLEntities: false },
186
186
  // @ts-ignore
187
187
  { openLinksInNewTab: true, gfm: true, breaks: true });
188
188
  if (isExportingPDF) {
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export default function CaseLabels(): React.JSX.Element;
3
+ //# sourceMappingURL=CaseLabels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaseLabels.d.ts","sourceRoot":"","sources":["../../../../src/components/CaseInformation/CaseLabels.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAUzD,MAAM,CAAC,OAAO,UAAU,UAAU,sBA6KjC"}
@@ -0,0 +1,98 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Label, MenuToggle, Select, SelectList, SelectOption, Spinner, } from '@patternfly/react-core';
11
+ import { ToastNotification } from '@rh-support/components';
12
+ import { GlobalMetadataStateContext, useCanEditCase } from '@rh-support/react-context';
13
+ import isEqual from 'lodash/isEqual';
14
+ import React, { useContext, useState } from 'react';
15
+ import { Trans, useTranslation } from 'react-i18next';
16
+ import { useCaseSelector } from '../../context/CaseContext';
17
+ import { useCaseLabelLinks } from '../../hooks/useCaseLabelLinkMutations';
18
+ const NUM_VISIBLE_LABELS = 3;
19
+ export default function CaseLabels() {
20
+ const { t } = useTranslation();
21
+ const canEditCase = useCanEditCase();
22
+ const { globalMetadataState: { loggedInUser }, } = useContext(GlobalMetadataStateContext);
23
+ const isOrgAdmin = loggedInUser.data.isOrgAdmin;
24
+ const { caseId, salesforceAccountId } = useCaseSelector((state) => {
25
+ var _a, _b;
26
+ return ({
27
+ caseId: state.caseDetails.id,
28
+ salesforceAccountId: (_b = (_a = state.selectedAccountDetails) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.salesforceAccountId,
29
+ });
30
+ }, isEqual);
31
+ const { availableLabels, assignedLinks, selectedLabelIds, loading, mutating, setAssignedLinks, createLink, deleteLink, } = useCaseLabelLinks(salesforceAccountId, caseId);
32
+ const [isOpen, setIsOpen] = useState(false);
33
+ const handleSelect = (_event, labelId) => __awaiter(this, void 0, void 0, function* () {
34
+ if (!labelId || typeof labelId !== 'string')
35
+ return;
36
+ if (canEditCase.alert())
37
+ return;
38
+ const existingLink = assignedLinks.find((link) => link.labelId === labelId);
39
+ try {
40
+ if (existingLink) {
41
+ yield deleteLink(existingLink.linkId);
42
+ setAssignedLinks((prev) => prev.filter((link) => link.linkId !== existingLink.linkId));
43
+ ToastNotification.addSuccessMessage(t('Label has been removed'));
44
+ }
45
+ else {
46
+ const newId = yield createLink(caseId, labelId);
47
+ if (newId) {
48
+ setAssignedLinks((prev) => [...prev, { linkId: newId, labelId }]);
49
+ }
50
+ ToastNotification.addSuccessMessage(t('Label has been added'));
51
+ }
52
+ }
53
+ catch (_a) {
54
+ ToastNotification.addDangerMessage(t('Failed to update labels'));
55
+ }
56
+ });
57
+ const handleChipRemove = (labelId) => __awaiter(this, void 0, void 0, function* () {
58
+ if (canEditCase.alert())
59
+ return;
60
+ const link = assignedLinks.find((l) => l.labelId === labelId);
61
+ if (!link)
62
+ return;
63
+ try {
64
+ yield deleteLink(link.linkId);
65
+ setAssignedLinks((prev) => prev.filter((l) => l.linkId !== link.linkId));
66
+ ToastNotification.addSuccessMessage(t('Label has been removed'));
67
+ }
68
+ catch (_a) {
69
+ ToastNotification.addDangerMessage(t('Failed to remove label'));
70
+ }
71
+ });
72
+ const selectedLabels = availableLabels.filter((l) => selectedLabelIds.includes(l.id));
73
+ const haltEvent = (e) => e.stopPropagation();
74
+ const toggle = (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: () => setIsOpen((prev) => !prev), isExpanded: isOpen, isDisabled: loading || mutating || !caseId || (!isOrgAdmin && availableLabels.length === 0), isFullWidth: true, style: { height: '36px' } }, loading || mutating ? (React.createElement(Spinner, { size: "md" })) : selectedLabels.length > 0 ? (React.createElement("span", { style: { display: 'flex', gap: '8px', alignItems: 'center', flexWrap: 'nowrap' } },
75
+ selectedLabels.slice(0, NUM_VISIBLE_LABELS).map((label) => (React.createElement(Label, { key: label.id, variant: "outline", onClose: () => handleChipRemove(label.id), closeBtnAriaLabel: t('Remove label {{name}}', { name: label.name }), onClick: haltEvent }, label.name))),
76
+ selectedLabels.length > NUM_VISIBLE_LABELS && (React.createElement("span", { style: {
77
+ color: 'var(--pf-t--global--text--color--link--default)',
78
+ fontSize: '12px',
79
+ whiteSpace: 'nowrap',
80
+ cursor: 'pointer',
81
+ } }, t('{{count}} more', { count: selectedLabels.length - NUM_VISIBLE_LABELS }))))) : availableLabels.length === 0 ? (t('No label assigned')) : (t('Select labels'))));
82
+ if (!caseId)
83
+ return null;
84
+ return (React.createElement("div", { className: "form-group" },
85
+ React.createElement("label", { htmlFor: "case-labels" },
86
+ React.createElement(Trans, null, "Labels")),
87
+ React.createElement(Select, { id: "case-labels", "data-tracking-id": "case-labels", role: "menu", isOpen: isOpen, onSelect: handleSelect, onOpenChange: () => setIsOpen(false), toggle: toggle, shouldFocusFirstItemOnOpen: false, isScrollable: true, popperProps: { direction: 'down', enableFlip: false } },
88
+ React.createElement(SelectList, { id: "case-labels-listbox" }, availableLabels.map((label) => (React.createElement(SelectOption, { key: label.id, value: label.id, hasCheckbox: true, isSelected: selectedLabelIds.includes(label.id) }, label.name))))),
89
+ !loading && availableLabels.length === 0 && (React.createElement("p", { className: "form-instructions" }, isOrgAdmin ? (React.createElement(Trans, null,
90
+ React.createElement("strong", null, "No labels available:"),
91
+ " You haven't created any labels yet.",
92
+ ' ',
93
+ React.createElement("a", { href: "/support/cases/#/manage/case-labels", style: { textDecoration: 'none' }, onClick: () => window.scrollTo(0, 0) }, "Create a label"),
94
+ ' ',
95
+ "to start organizing your cases.")) : (React.createElement(Trans, null,
96
+ React.createElement("strong", null, "No labels available:"),
97
+ " Your organization admin hasn't created any labels yet. Contact them to add labels before you can select one."))))));
98
+ }
@@ -61,7 +61,7 @@ export function mapCaseCommentNode(node) {
61
61
  createdDate: (_t = (_s = node.CreatedDate) === null || _s === void 0 ? void 0 : _s.value) !== null && _t !== void 0 ? _t : '',
62
62
  visibility: visibility !== null && visibility !== void 0 ? visibility : undefined,
63
63
  isPublic: deriveIsPublic(visibility),
64
- contentType: 'plaintext',
64
+ contentType: 'markdown',
65
65
  isDraft: false,
66
66
  publishedDate: '',
67
67
  };
@@ -0,0 +1,21 @@
1
+ export interface LabelOption {
2
+ id: string;
3
+ name: string;
4
+ }
5
+ export interface LabelLink {
6
+ linkId: string;
7
+ labelId: string;
8
+ }
9
+ interface UseCaseLabelLinksResult {
10
+ availableLabels: LabelOption[];
11
+ assignedLinks: LabelLink[];
12
+ selectedLabelIds: string[];
13
+ loading: boolean;
14
+ mutating: boolean;
15
+ setAssignedLinks: React.Dispatch<React.SetStateAction<LabelLink[]>>;
16
+ createLink: (caseId: string, labelId: string) => Promise<string | undefined>;
17
+ deleteLink: (linkId: string) => Promise<void>;
18
+ }
19
+ export declare function useCaseLabelLinks(salesforceAccountId?: string, caseId?: string): UseCaseLabelLinksResult;
20
+ export {};
21
+ //# sourceMappingURL=useCaseLabelLinkMutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCaseLabelLinkMutations.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCaseLabelLinkMutations.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,uBAAuB;IAC7B,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,aAAa,EAAE,SAAS,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACpE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7E,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,wBAAgB,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,uBAAuB,CA6FxG"}
@@ -0,0 +1,84 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { useApolloClient, useMutation } from '@apollo/client/react';
11
+ import { CREATE_CASE_LABEL_LINK, DELETE_CASE_LABEL_LINK, GET_CASE_LABEL_LINKS, GET_CASE_LABELS, } from '@rh-support/utils';
12
+ import { useCallback, useEffect, useState } from 'react';
13
+ export function useCaseLabelLinks(salesforceAccountId, caseId) {
14
+ const client = useApolloClient();
15
+ const [availableLabels, setAvailableLabels] = useState([]);
16
+ const [assignedLinks, setAssignedLinks] = useState([]);
17
+ const [loading, setLoading] = useState(false);
18
+ const fetchData = useCallback(() => __awaiter(this, void 0, void 0, function* () {
19
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
20
+ if (!salesforceAccountId || !caseId)
21
+ return;
22
+ setLoading(true);
23
+ try {
24
+ const [labelsResult, linksResult] = yield Promise.all([
25
+ client.query({
26
+ query: GET_CASE_LABELS,
27
+ variables: { where: { Account__c: { eq: salesforceAccountId } } },
28
+ fetchPolicy: 'network-only',
29
+ }),
30
+ client.query({
31
+ query: GET_CASE_LABEL_LINKS,
32
+ variables: { where: { Case__c: { eq: caseId } } },
33
+ fetchPolicy: 'network-only',
34
+ }),
35
+ ]);
36
+ const labelEdges = (_e = (_d = (_c = (_b = (_a = labelsResult.data) === null || _a === void 0 ? void 0 : _a.redhat_support_uiapi) === null || _b === void 0 ? void 0 : _b.query) === null || _c === void 0 ? void 0 : _c.RedHatSupportCaseLabel__c) === null || _d === void 0 ? void 0 : _d.edges) !== null && _e !== void 0 ? _e : [];
37
+ setAvailableLabels(labelEdges
38
+ .map(({ node }) => { var _a, _b; return ({ id: node.Id, name: (_b = (_a = node.Name) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '' }); })
39
+ .filter((l) => l.id && l.name));
40
+ const linkEdges = (_k = (_j = (_h = (_g = (_f = linksResult.data) === null || _f === void 0 ? void 0 : _f.redhat_support_uiapi) === null || _g === void 0 ? void 0 : _g.query) === null || _h === void 0 ? void 0 : _h.RedHatSupportCaseLabelLink__c) === null || _j === void 0 ? void 0 : _j.edges) !== null && _k !== void 0 ? _k : [];
41
+ setAssignedLinks(linkEdges
42
+ .filter(({ node }) => { var _a; return node.Id && ((_a = node.Label__c) === null || _a === void 0 ? void 0 : _a.value); })
43
+ .map(({ node }) => ({
44
+ linkId: node.Id,
45
+ labelId: node.Label__c.value,
46
+ })));
47
+ }
48
+ catch (_l) {
49
+ setAvailableLabels([]);
50
+ setAssignedLinks([]);
51
+ }
52
+ finally {
53
+ setLoading(false);
54
+ }
55
+ }), [client, salesforceAccountId, caseId]);
56
+ useEffect(() => {
57
+ fetchData();
58
+ }, [fetchData]);
59
+ const [createMutate, { loading: createLoading }] = useMutation(CREATE_CASE_LABEL_LINK);
60
+ const createLink = useCallback((caseSfId, labelId) => __awaiter(this, void 0, void 0, function* () {
61
+ var _a, _b, _c, _d;
62
+ const result = yield createMutate({
63
+ variables: {
64
+ input: { RedHatSupportCaseLabelLink__c: { Case__c: caseSfId, Label__c: labelId } },
65
+ },
66
+ });
67
+ return (_d = (_c = (_b = (_a = result.data) === null || _a === void 0 ? void 0 : _a.redhat_support_uiapi) === null || _b === void 0 ? void 0 : _b.CaseLabelLink__cCreate) === null || _c === void 0 ? void 0 : _c.RedHatSupportRecord) === null || _d === void 0 ? void 0 : _d.Id;
68
+ }), [createMutate]);
69
+ const [deleteMutate, { loading: deleteLoading }] = useMutation(DELETE_CASE_LABEL_LINK);
70
+ const deleteLink = useCallback((linkId) => __awaiter(this, void 0, void 0, function* () {
71
+ yield deleteMutate({ variables: { id: linkId } });
72
+ }), [deleteMutate]);
73
+ const selectedLabelIds = assignedLinks.map((link) => link.labelId);
74
+ return {
75
+ availableLabels,
76
+ assignedLinks,
77
+ selectedLabelIds,
78
+ loading,
79
+ mutating: createLoading || deleteLoading,
80
+ setAssignedLinks,
81
+ createLink,
82
+ deleteLink,
83
+ };
84
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/troubleshoot",
3
- "version": "2.6.308",
3
+ "version": "2.6.309",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org"
@@ -52,11 +52,11 @@
52
52
  "@progress/kendo-licensing": "1.3.5",
53
53
  "@progress/kendo-react-pdf": "^5.16.0",
54
54
  "@redux-devtools/extension": "^3.3.0",
55
- "@rh-support/components": "2.5.189",
56
- "@rh-support/react-context": "2.5.283",
55
+ "@rh-support/components": "2.5.190",
56
+ "@rh-support/react-context": "2.5.284",
57
57
  "@rh-support/types": "2.0.26",
58
- "@rh-support/user-permissions": "2.5.135",
59
- "@rh-support/utils": "2.5.117",
58
+ "@rh-support/user-permissions": "2.5.136",
59
+ "@rh-support/utils": "2.5.118",
60
60
  "@types/react-redux": "^7.1.33",
61
61
  "@types/redux": "^3.6.0",
62
62
  "date-fns": "3.6.0",
@@ -126,5 +126,5 @@
126
126
  "defaults and supports es6-module",
127
127
  "maintained node versions"
128
128
  ],
129
- "gitHead": "8f1387bb291fa73c60cec5251c7cc4c599fd1b5e"
129
+ "gitHead": "9017d17207b6357a27edbab889de8f10696e745b"
130
130
  }