@rh-support/troubleshoot 2.7.42 → 2.7.44
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/Tabs/CaseDiscussion/CaseDiscussion.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.js +38 -2
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseDiscussion/PostComment.js +13 -0
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.css +6 -8
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.d.ts.map +1 -1
- package/lib/esm/components/CaseEditView/Tabs/CaseHistory/Timeline.js +1 -2
- package/lib/esm/components/SubmitCase/SubmitCase.d.ts.map +1 -1
- package/lib/esm/components/SubmitCase/SubmitCase.js +2 -0
- package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts +2 -0
- package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/reducer/AttachmentHelper.js +36 -4
- package/lib/esm/components/shared/fileUpload/reducer/FileStatusHelper.js +1 -1
- package/lib/esm/components/shared/fileUpload/useFileUploader.d.ts.map +1 -1
- package/lib/esm/components/shared/fileUpload/useFileUploader.js +14 -2
- package/lib/esm/context/CaseDiscussionTabContext.d.ts.map +1 -1
- package/lib/esm/hooks/useCaseUpdateErrorMessage.d.ts +2 -1
- package/lib/esm/hooks/useCaseUpdateErrorMessage.d.ts.map +1 -1
- package/lib/esm/hooks/useCaseUpdateErrorMessage.js +2 -4
- package/lib/esm/hooks/useInProgressAttachmentPoll.d.ts +14 -0
- package/lib/esm/hooks/useInProgressAttachmentPoll.d.ts.map +1 -0
- package/lib/esm/hooks/useInProgressAttachmentPoll.js +82 -0
- package/lib/esm/hooks/useS3Upload.js +1 -1
- package/lib/esm/hooks/useSyncServerAttachments.d.ts +4 -0
- package/lib/esm/hooks/useSyncServerAttachments.d.ts.map +1 -0
- package/lib/esm/hooks/useSyncServerAttachments.js +165 -0
- package/lib/esm/hooks/useUploadingContentVersionSfIds.d.ts +13 -0
- package/lib/esm/hooks/useUploadingContentVersionSfIds.d.ts.map +1 -0
- package/lib/esm/hooks/useUploadingContentVersionSfIds.js +121 -0
- package/lib/esm/hooks/useWarnBeforeUnloadOnUpload.d.ts +2 -0
- package/lib/esm/hooks/useWarnBeforeUnloadOnUpload.d.ts.map +1 -0
- package/lib/esm/hooks/useWarnBeforeUnloadOnUpload.js +63 -0
- package/lib/esm/reducers/CaseDetailsPageReducer.d.ts.map +1 -1
- package/lib/esm/utils/caseHistoryUtils.d.ts +1 -1
- package/lib/esm/utils/caseHistoryUtils.d.ts.map +1 -1
- package/lib/esm/utils/caseHistoryUtils.js +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAwBvE,OAAO,KAA0F,MAAM,OAAO,CAAC;AA4C/G,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBAg6BnD"}
|
|
@@ -12,7 +12,7 @@ import { Alert, Button, MenuToggle, Select, SelectList, SelectOption } from '@pa
|
|
|
12
12
|
import { AlertMessage, AlertType, ErrorBoundary, LoadingIndicator, ToastNotification } from '@rh-support/components';
|
|
13
13
|
import { useGlobalStateContext } from '@rh-support/react-context';
|
|
14
14
|
import { AbilityContext, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
|
|
15
|
-
import { downloadCaseAttachment, dtmTrackEventCaseStepEncountered, getApiResourceObject, getDropdownBtnPlaceholder, getUrlParsedParams, scrollIntoView, } from '@rh-support/utils';
|
|
15
|
+
import { downloadCaseAttachment, dtmTrackEventCaseStepEncountered, fetchCaseAttachmentsViaGraphQL, getApiResourceObject, getDropdownBtnPlaceholder, getUrlParsedParams, isAttachmentUploadComplete, scrollIntoView, } from '@rh-support/utils';
|
|
16
16
|
import cloneDeep from 'lodash/cloneDeep';
|
|
17
17
|
import filter from 'lodash/filter';
|
|
18
18
|
import findIndex from 'lodash/findIndex';
|
|
@@ -28,6 +28,7 @@ import { AutoSizer, CellMeasurer, CellMeasurerCache, List, WindowScroller } from
|
|
|
28
28
|
import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
|
|
29
29
|
import { useCaseDetailsPageDispatchContext, useCaseDetailsPageStateContext, } from '../../../../context/CaseDetailsPageContext';
|
|
30
30
|
import { useCaseDiscussionTabDispatchContext, useCaseDiscussionTabStateContext, } from '../../../../context/CaseDiscussionTabContext';
|
|
31
|
+
import { useInProgressAttachmentPoll } from '../../../../hooks/useInProgressAttachmentPoll';
|
|
31
32
|
import { CaseDetailsConstants } from '../../../../reducers/CaseDetailsPageReducer';
|
|
32
33
|
import { clearReplyingTo, commputeFeedback, computeFeedbackReason, discussionSortOrderConst, DiscussionType, setDiscussions, setFilter, setReplyingTo, setSort, updateAttachment, updateAttacmentsAfterRemoval, updateDiscussionStateAttachments, } from '../../../../reducers/CaseDiscussionTabReducer';
|
|
33
34
|
import { setCaseState } from '../../../../reducers/CaseReducer';
|
|
@@ -58,8 +59,42 @@ export default function CaseDiscussion(props) {
|
|
|
58
59
|
const dispatchCaseDetailsHydraAttachments = useCaseDetailsPageDispatchContext();
|
|
59
60
|
const caseDispatch = useCaseDispatch();
|
|
60
61
|
const apolloClient = useApolloClient();
|
|
62
|
+
useInProgressAttachmentPoll({
|
|
63
|
+
apolloClient: apolloClient,
|
|
64
|
+
caseNumber: props.caseNumber,
|
|
65
|
+
caseSalesforceId,
|
|
66
|
+
caseAttachmentHydra,
|
|
67
|
+
dispatchCaseDetails: dispatchCaseDetailsHydraAttachments,
|
|
68
|
+
});
|
|
61
69
|
const ability = useContext(AbilityContext);
|
|
62
70
|
const canSeeAttachments = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEE_ATTACHMENTS);
|
|
71
|
+
// Discussion unmounts when switching tabs (e.g. Management). Refetch attachments on remount
|
|
72
|
+
// so In Progress uploads created while away show up without a full page refresh.
|
|
73
|
+
// Silent refresh — do not clear existing list (avoids UI flash).
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!canSeeAttachments || !caseSalesforceId)
|
|
76
|
+
return;
|
|
77
|
+
let cancelled = false;
|
|
78
|
+
(() => __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
try {
|
|
80
|
+
const fresh = yield fetchCaseAttachmentsViaGraphQL(apolloClient, props.caseNumber, caseSalesforceId);
|
|
81
|
+
if (!cancelled) {
|
|
82
|
+
dispatchCaseDetailsHydraAttachments({
|
|
83
|
+
type: CaseDetailsConstants.updateState,
|
|
84
|
+
payload: { caseAttachmentHydra: getApiResourceObject(fresh) },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (_a) {
|
|
89
|
+
// Keep existing list on transient errors
|
|
90
|
+
}
|
|
91
|
+
}))();
|
|
92
|
+
return () => {
|
|
93
|
+
cancelled = true;
|
|
94
|
+
};
|
|
95
|
+
// Only on mount / case change — intentional
|
|
96
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
97
|
+
}, [props.caseNumber, caseSalesforceId, canSeeAttachments]);
|
|
63
98
|
const { caseNumber } = props;
|
|
64
99
|
const activeElementId = useRef(null);
|
|
65
100
|
const listRef = React.useRef(null);
|
|
@@ -118,7 +153,8 @@ export default function CaseDiscussion(props) {
|
|
|
118
153
|
});
|
|
119
154
|
let allAttachments = canSeeAttachments
|
|
120
155
|
? (caseAttachmentHydra.data || [])
|
|
121
|
-
.filter((attachment) => (attachment === null || attachment === void 0 ? void 0 : attachment.lastModifiedDate) || (attachment === null || attachment === void 0 ? void 0 : attachment.createdDate))
|
|
156
|
+
.filter((attachment) => ((attachment === null || attachment === void 0 ? void 0 : attachment.lastModifiedDate) || (attachment === null || attachment === void 0 ? void 0 : attachment.createdDate)) &&
|
|
157
|
+
isAttachmentUploadComplete(attachment))
|
|
122
158
|
.map((attachment) => ({
|
|
123
159
|
item: Object.assign(Object.assign({}, attachment), { lastModifiedDate: attachment.lastModifiedDate || attachment.createdDate }),
|
|
124
160
|
last_modified_date: (attachment.lastModifiedDate || attachment.createdDate),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAwE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PostComment.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/PostComment.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAW7F,OAAO,EAAE,WAAW,EAAE,MAAM,+CAA+C,CAAC;AAmB5E,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,qBAicxC"}
|
|
@@ -21,8 +21,12 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
|
|
|
21
21
|
import { useDropzone } from 'react-dropzone';
|
|
22
22
|
import { Trans, useTranslation } from 'react-i18next';
|
|
23
23
|
import { useCaseDispatch, useCaseSelector } from '../../../../context/CaseContext';
|
|
24
|
+
import { useCaseDetailsPageStateContext } from '../../../../context/CaseDetailsPageContext';
|
|
24
25
|
import { useCreateCaseComment } from '../../../../hooks/useCaseComments';
|
|
25
26
|
import { useS3Upload } from '../../../../hooks/useS3Upload';
|
|
27
|
+
import { useSyncServerAttachments } from '../../../../hooks/useSyncServerAttachments';
|
|
28
|
+
import { useUploadingContentVersionSfIds } from '../../../../hooks/useUploadingContentVersionSfIds';
|
|
29
|
+
import { useWarnBeforeUnloadOnUpload } from '../../../../hooks/useWarnBeforeUnloadOnUpload';
|
|
26
30
|
import { checkForCaseStatusToggleOnAttachOrComment } from '../../../../reducers/CaseReducer';
|
|
27
31
|
import { AttachmentDispatchContext, AttachmentStateContext, hasAbortedOrFailedAttachments, hasQueuedAttachmentUploads, hasSomeSelectedFiles, isUploadingAttachment, resetAttachment, } from '../../../shared/fileUpload';
|
|
28
32
|
import FileSelectorButton from '../../../shared/fileUpload/fileSelectors/FileSelectorButton';
|
|
@@ -40,6 +44,8 @@ export function PostComment(props) {
|
|
|
40
44
|
const { createComment, loading: isPostingComment } = useCreateCaseComment();
|
|
41
45
|
const dispatchToAttachmentReducer = useContext(AttachmentDispatchContext);
|
|
42
46
|
const { attachmentState } = useContext(AttachmentStateContext);
|
|
47
|
+
const { caseDetailsPageState: { caseAttachmentHydra }, } = useCaseDetailsPageStateContext();
|
|
48
|
+
useSyncServerAttachments(caseNumber, caseAttachmentHydra);
|
|
43
49
|
const isUploadingAttachmentPrevious = useRef(false);
|
|
44
50
|
const batchSuccessCountRef = useRef(0);
|
|
45
51
|
const isUploadingAttachments = isUploadingAttachment(attachmentState.caseFiles.selectedLocalFiles);
|
|
@@ -105,6 +111,13 @@ export function PostComment(props) {
|
|
|
105
111
|
existingCaseDetails: state.caseDetails,
|
|
106
112
|
}), isEqual);
|
|
107
113
|
const apolloClient = useApolloClient();
|
|
114
|
+
const contentVersionSfIds = useUploadingContentVersionSfIds({
|
|
115
|
+
caseNumber,
|
|
116
|
+
selectedLocalFiles: attachmentState.caseFiles.selectedLocalFiles,
|
|
117
|
+
apolloClient: apolloClient,
|
|
118
|
+
serverAttachments: caseAttachmentHydra.data,
|
|
119
|
+
});
|
|
120
|
+
useWarnBeforeUnloadOnUpload(isUploadingAttachments || hasQueuedUploads, contentVersionSfIds);
|
|
108
121
|
const { uploadFile: uploadImageFile } = useS3Upload(caseNumber, apolloClient, caseSalesforceId);
|
|
109
122
|
const onImageUpload = useCallback((file) => __awaiter(this, void 0, void 0, function* () {
|
|
110
123
|
const attachmentId = yield uploadImageFile({ file });
|
|
@@ -220,16 +220,14 @@
|
|
|
220
220
|
background-color: #316dc1;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
.timeline-avatar-internal {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
border-style: solid;
|
|
223
|
+
.timeline-avatar.timeline-avatar-internal {
|
|
224
|
+
--pf-v6-c-avatar--BorderColor: #ee0000;
|
|
225
|
+
--pf-v6-c-avatar--BorderWidth: 2px;
|
|
227
226
|
}
|
|
228
227
|
|
|
229
|
-
.timeline-avatar-customer {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
border-style: solid;
|
|
228
|
+
.timeline-avatar.timeline-avatar-customer {
|
|
229
|
+
--pf-v6-c-avatar--BorderColor: #316dc1;
|
|
230
|
+
--pf-v6-c-avatar--BorderWidth: 2px;
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
.contentTimeline {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAsBxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7F,OAAO,EAAE,KAAK,kBAAkB,EAA0C,MAAM,iCAAiC,CAAC;AAElH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AACD,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;
|
|
1
|
+
{"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAsBxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D,OAAO,KAAK,EAAwB,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAE7F,OAAO,EAAE,KAAK,kBAAkB,EAA0C,MAAM,iCAAiC,CAAC;AAElH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AACD,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAiID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,kBAAkB,GAAG,IAAI,GAAG,SAAS,KAAG,MAU/E,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kCAAkC,GAAI,aAAa;IAC5D,YAAY,EAAE,gBAAgB,EAAE,CAAC;CACpC,KAAG,iBAAiB,EAoDpB,CAAC;AAEF,UAAU,cAAc;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAED,QAAA,MAAM,QAAQ,GAAI,8CAA8C,cAAc,sBAgU7E,CAAC;AAEF,eAAe,QAAQ,CAAC"}
|
|
@@ -9,7 +9,7 @@ import isEmpty from 'lodash/isEmpty';
|
|
|
9
9
|
import React, { useEffect, useRef, useState } from 'react';
|
|
10
10
|
import { Trans, useTranslation } from 'react-i18next';
|
|
11
11
|
import { useCaseHistory } from '../../../../hooks/useCaseHistory';
|
|
12
|
-
import { getFieldDisplayName } from '../../../../utils/caseHistoryUtils';
|
|
12
|
+
import { DEFAULT_AVATAR_SRC, getFieldDisplayName } from '../../../../utils/caseHistoryUtils';
|
|
13
13
|
import { applyPostProcessing, handleFieldChange } from '../../../../utils/TimelineUtils';
|
|
14
14
|
const CustomHighlighter = ({ search, children, highlightDate, }) => {
|
|
15
15
|
const createHighlight = (text) => React.createElement("mark", { className: "timeline-highlight" }, text);
|
|
@@ -45,7 +45,6 @@ const TimelineEvent = ({ date, text, side, user, useAvatar, searchValue, highlig
|
|
|
45
45
|
text && (React.createElement("p", { className: `content-time-${side}-history` },
|
|
46
46
|
React.createElement(CustomHighlighter, { search: searchValue || '' }, text))))));
|
|
47
47
|
};
|
|
48
|
-
const DEFAULT_AVATAR_SRC = 'https://www.patternfly.org/images/668560cd.svg';
|
|
49
48
|
const TimelineNode = React.forwardRef(({ leftEvent, rightEvent, user, useAvatar, photoUrl, searchValue, highlightDate }, ref) => {
|
|
50
49
|
const [imgSrc, setImgSrc] = useState(photoUrl || DEFAULT_AVATAR_SRC);
|
|
51
50
|
return (React.createElement("div", { className: "timeline-node", role: "region", "aria-label": "Timeline node" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubmitCase.d.ts","sourceRoot":"","sources":["../../../../src/components/SubmitCase/SubmitCase.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,OAAO,EAAQ,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"SubmitCase.d.ts","sourceRoot":"","sources":["../../../../src/components/SubmitCase/SubmitCase.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAErD,OAAO,EAAQ,mBAAmB,EAAe,MAAM,kBAAkB,CAAC;AAS1E,OAAO,EAAqB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAWrF,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;CACpD;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,KAAK,EAAE,MAAM,qBAgZ/C"}
|
|
@@ -14,6 +14,7 @@ import { useCaseDispatch, useCaseSelector } from '../../context/CaseContext';
|
|
|
14
14
|
import { ClusterRecommendationsContext } from '../../context/ClusterRecommendationsContext';
|
|
15
15
|
import { RulesStateContext } from '../../context/RulesContext';
|
|
16
16
|
import { TCStateContext } from '../../context/TopContentContext';
|
|
17
|
+
import { useWarnBeforeUnloadOnUpload } from '../../hooks/useWarnBeforeUnloadOnUpload';
|
|
17
18
|
import { getIrtForSLAAndSeverity } from '../../reducers/CaseHelpers';
|
|
18
19
|
import { setCaseState } from '../../reducers/CaseReducer';
|
|
19
20
|
import RouteUtils from '../../utils/routeUtils';
|
|
@@ -48,6 +49,7 @@ export default function SubmitCase(props) {
|
|
|
48
49
|
const { rulesState } = useContext(RulesStateContext);
|
|
49
50
|
const { clusterRecommendationsState: { clusterRecommendations }, } = useContext(ClusterRecommendationsContext);
|
|
50
51
|
const { attachmentState } = useContext(AttachmentStateContext);
|
|
52
|
+
useWarnBeforeUnloadOnUpload(isUploadingAttachment(attachmentState.caseFiles.selectedLocalFiles));
|
|
51
53
|
const { globalMetadataState: { loggedInUser }, } = useContext(GlobalMetadataStateContext);
|
|
52
54
|
const getBusinessHours = useFetch(publicApi.businessHours.getBusinessHours);
|
|
53
55
|
const { t } = useTranslation();
|
|
@@ -37,6 +37,8 @@ export declare const hasQueuedAttachmentUploads: (selectedLocalFiles: IFileLocal
|
|
|
37
37
|
export declare const hasAbortedOrFailedAttachments: (selectedLocalFiles: IFileLocal[]) => boolean;
|
|
38
38
|
/** True when at least one non-deleted file remains in the upload queue (UI visibility). */
|
|
39
39
|
export declare const hasSomeSelectedFiles: (selectedLocalFiles: IFileLocal[]) => boolean;
|
|
40
|
+
/** Abort a background S3 upload by attachment UUID (if one is still in-flight). */
|
|
41
|
+
export declare const abortBackgroundUpload: (attachmentId: string) => boolean;
|
|
40
42
|
export declare const clearUploadRuntimeState: () => void;
|
|
41
43
|
export declare const isUploadingAttachment: (selectedLocalFiles: IFileLocal[]) => boolean;
|
|
42
44
|
export declare const isAnalysingAnyAttachment: (selectedLocalFiles: IFileLocal[]) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AttachmentHelper.d.ts","sourceRoot":"","sources":["../../../../../../src/components/shared/fileUpload/reducer/AttachmentHelper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oDAAoD,CAAC;AAC3F,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AAEvF,OAAO,EACH,iBAAiB,EAWpB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACH,uBAAuB,EAEvB,6BAA6B,EAK7B,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,eAAe,EAMf,qBAAqB,EACxB,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,MAAM,GACd,6BAA6B,6BAA6B,EAAE,aAAa,OAAO,EAAE,mBAAiB,MACnG,eAAe,IAAI,EAAE,SAkDrB,CAAC;AAiBN,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,uDAAwD,CAAC;AAC5G,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,oDAAqD,CAAC;AACtG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,mDAAoD,CAAC;AACpG,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,2DAA4D,CAAC;AACpH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,wDAAyD,CAAC;AAC9G,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,wDAAyD,CAAC;AAC9G,eAAO,MAAM,uBAAuB,GAAI,QAAQ,MAAM,kGACiC,CAAC;AACxF,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,mDAAoD,CAAC;AACxG,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,0DAA2D,CAAC;AAChH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,uDAAwD,CAAC;AAC1G,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,iDAAkD,CAAC;AAEhG,eAAO,MAAM,oBAAoB,GAAI,QAAQ,MAAM,yDAA0D,CAAC;AAC9G,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,wDAAyD,CAAC;AACxG,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,uDAAwD,CAAC;AAC1G,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,qDAAsD,CAAC;AACtG,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,sDAAuD,CAAC;AAExG,eAAO,MAAM,iBAAiB,GAAI,QAAQ,MAAM,uGAAsE,CAAC;AACvH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,+NAC0E,CAAC;AACrH,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,yIAAoE,CAAC;AACpH,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,qGAAgE,CAAC;AAC9G,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,4CAA6C,CAAC;AAC5F,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,4CAA6C,CAAC;AAE1F,eAAO,MAAM,0BAA0B,GAAI,oBAAoB,UAAU,EAAE,YACmC,CAAC;AAC/G,eAAO,MAAM,0BAA0B,GAAI,oBAAoB,UAAU,EAAE,YACyC,CAAC;AACrH,eAAO,MAAM,4BAA4B,GAAI,oBAAoB,UAAU,EAAE,YASxE,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GAAI,oBAAoB,UAAU,EAAE,YAWtE,CAAC;AAEN,wFAAwF;AACxF,eAAO,MAAM,6BAA6B,GAAI,oBAAoB,UAAU,EAAE,YAQzE,CAAC;AAEN,2FAA2F;AAC3F,eAAO,MAAM,oBAAoB,GAAI,oBAAoB,UAAU,EAAE,YACuC,CAAC;
|
|
1
|
+
{"version":3,"file":"AttachmentHelper.d.ts","sourceRoot":"","sources":["../../../../../../src/components/shared/fileUpload/reducer/AttachmentHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -118,11 +118,23 @@ const MAX_CONCURRENT_SESSION_UPLOADS = 3;
|
|
|
118
118
|
const SESSION_UPLOAD_MAX_ATTEMPTS = 2;
|
|
119
119
|
const SESSION_UPLOAD_RETRY_DELAY_MS = 500;
|
|
120
120
|
const activeUploadLockKeys = new Set();
|
|
121
|
+
const backgroundAbortControllers = new Map();
|
|
122
|
+
/** Abort a background S3 upload by attachment UUID (if one is still in-flight). */
|
|
123
|
+
export const abortBackgroundUpload = (attachmentId) => {
|
|
124
|
+
const abort = backgroundAbortControllers.get(attachmentId);
|
|
125
|
+
if (abort) {
|
|
126
|
+
abort();
|
|
127
|
+
backgroundAbortControllers.delete(attachmentId);
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
};
|
|
121
132
|
const sessionUploadQueues = new Map();
|
|
122
133
|
const buildUploadLockKey = (idToUploadTo, localFile) => `${idToUploadTo}:${localFile.name}:${localFile.size}:${localFile.lastModified}`;
|
|
123
134
|
export const clearUploadRuntimeState = () => {
|
|
124
135
|
activeUploadLockKeys.clear();
|
|
125
136
|
sessionUploadQueues.clear();
|
|
137
|
+
backgroundAbortControllers.clear();
|
|
126
138
|
};
|
|
127
139
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
128
140
|
const acquireSessionUploadSlot = (sessionId) => new Promise((resolve) => {
|
|
@@ -199,11 +211,16 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
199
211
|
}
|
|
200
212
|
const startEligibleUpload = (index) => {
|
|
201
213
|
const localFile = caseFiles.selectedLocalFiles[index];
|
|
214
|
+
const originalFile = caseFiles.selectedOriginalFiles[index];
|
|
215
|
+
// Skip rows without real file bytes (e.g. server-restored In Progress placeholders)
|
|
216
|
+
if (!originalFile || originalFile.size === 0) {
|
|
217
|
+
return Promise.resolve();
|
|
218
|
+
}
|
|
202
219
|
return uploadFile({
|
|
203
220
|
dispatch,
|
|
204
221
|
idToUploadTo,
|
|
205
222
|
localFile,
|
|
206
|
-
originalFile
|
|
223
|
+
originalFile,
|
|
207
224
|
index,
|
|
208
225
|
needsAnalyzing,
|
|
209
226
|
isSessionId,
|
|
@@ -327,6 +344,9 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
327
344
|
uploadStatus: UploadStatusConstants.aborted,
|
|
328
345
|
};
|
|
329
346
|
abortUpload === null || abortUpload === void 0 ? void 0 : abortUpload();
|
|
347
|
+
// Clean up cross-mount abort registry
|
|
348
|
+
if (localFile.attachmentId)
|
|
349
|
+
backgroundAbortControllers.delete(localFile.attachmentId);
|
|
330
350
|
updateUploadMetadata(dispatch, abortedFileIndex, abortPayload);
|
|
331
351
|
};
|
|
332
352
|
// Register abort handler immediately so Cancel works before first progress tick
|
|
@@ -360,6 +380,10 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
360
380
|
abort();
|
|
361
381
|
return;
|
|
362
382
|
}
|
|
383
|
+
// Register in module-level map so a remounted component can still abort this XHR
|
|
384
|
+
if (localFile.attachmentId) {
|
|
385
|
+
backgroundAbortControllers.set(localFile.attachmentId, abort);
|
|
386
|
+
}
|
|
363
387
|
updateUploadMetadata(dispatch, index, {
|
|
364
388
|
uploadStatus: UploadStatusConstants.uploadingOnCase,
|
|
365
389
|
onAbort,
|
|
@@ -379,6 +403,9 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
379
403
|
}
|
|
380
404
|
: undefined, (initAttachmentId) => {
|
|
381
405
|
updateAttachmentIdForFile(dispatch, initAttachmentId, index);
|
|
406
|
+
if (abortUpload) {
|
|
407
|
+
backgroundAbortControllers.set(initAttachmentId, abortUpload);
|
|
408
|
+
}
|
|
382
409
|
}, localFile.description);
|
|
383
410
|
if (userAborted) {
|
|
384
411
|
return;
|
|
@@ -393,10 +420,12 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
393
420
|
}
|
|
394
421
|
}
|
|
395
422
|
attachmentId && updateAttachmentIdForFile(dispatch, attachmentId, index);
|
|
423
|
+
if (attachmentId) {
|
|
424
|
+
backgroundAbortControllers.delete(attachmentId);
|
|
425
|
+
}
|
|
396
426
|
if (!isSessionId && attachmentId) {
|
|
397
|
-
// Hide from upload queue without shifting indices of in-flight siblings, then refresh discussion
|
|
398
427
|
updateUploadMetadata(dispatch, index, {
|
|
399
|
-
uploadStatus: UploadStatusConstants.
|
|
428
|
+
uploadStatus: UploadStatusConstants.uploadedOnCase,
|
|
400
429
|
uploadErrorMessage: '',
|
|
401
430
|
percentUploaded: 100,
|
|
402
431
|
onAbort: undefined,
|
|
@@ -448,14 +477,17 @@ needsAnalyzing = false, isSessionId = false, slowUploadConfig = {}, apolloClient
|
|
|
448
477
|
}
|
|
449
478
|
updateUploadMetadata(dispatch, index, uploadErrorPayload);
|
|
450
479
|
//mark ContentVersion as Failed in SCT so it does not stay "In Progress".
|
|
480
|
+
// Persist backend failure reason on ContentVersion.Description
|
|
451
481
|
if (!isSessionId && attachmentIdFromError && apolloClient && caseSalesforceId) {
|
|
452
|
-
void markCaseAttachmentUploadFailed(apolloClient, idToUploadTo, attachmentIdFromError);
|
|
482
|
+
void markCaseAttachmentUploadFailed(apolloClient, idToUploadTo, attachmentIdFromError, error.message);
|
|
453
483
|
}
|
|
454
484
|
}
|
|
455
485
|
}
|
|
456
486
|
finally {
|
|
457
487
|
releaseSessionUploadSlot === null || releaseSessionUploadSlot === void 0 ? void 0 : releaseSessionUploadSlot();
|
|
458
488
|
activeUploadLockKeys.delete(uploadLockKey);
|
|
489
|
+
if (localFile.attachmentId)
|
|
490
|
+
backgroundAbortControllers.delete(localFile.attachmentId);
|
|
459
491
|
}
|
|
460
492
|
});
|
|
461
493
|
export function doSosReportAnalysisForAllFiles(dispatch, idToUploadTo, localFiles, isSessionId) {
|
|
@@ -11,7 +11,7 @@ export class FileStatusHelper {
|
|
|
11
11
|
return this.uploadStatus === UploadStatusConstants.uploadingOnSession;
|
|
12
12
|
}
|
|
13
13
|
isUploadingOnCase() {
|
|
14
|
-
return this.uploadStatus === UploadStatusConstants.
|
|
14
|
+
return this.uploadStatus === UploadStatusConstants.uploadingOnCase;
|
|
15
15
|
}
|
|
16
16
|
isVerifyingSessionUpload() {
|
|
17
17
|
return this.uploadStatus === UploadStatusConstants.verifyingSessionUpload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFileUploader.d.ts","sourceRoot":"","sources":["../../../../../src/components/shared/fileUpload/useFileUploader.tsx"],"names":[],"mappings":"AAcA,OAAO,KAA8D,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useFileUploader.d.ts","sourceRoot":"","sources":["../../../../../src/components/shared/fileUpload/useFileUploader.tsx"],"names":[],"mappings":"AAcA,OAAO,KAA8D,MAAM,OAAO,CAAC;AAiBnF,OAAO,EACH,UAAU,EAKb,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAKnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,wBAAwB;gCA8JjB,MAAM;gCAYA,UAAU,mBAAmB,MAAM,WAAW,UAAU;oCAOpD,MAAM,QAAQ,UAAU;wBAxGzD,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC;4BAmK3B,MAAM;kCAzEN,MAAM;EAiHhD"}
|
|
@@ -18,7 +18,7 @@ import { SessionRestoreDispatchContext, SessionRestoreStateContext } from '../..
|
|
|
18
18
|
import { SESSION_REFERRER_URL_LIMIT } from '../../../reducers/CaseConstNTypes';
|
|
19
19
|
import { getSessionDetailsFromCase } from '../../../reducers/CaseHelpers';
|
|
20
20
|
import { createSession } from '../../../reducers/SessionRestoreReducer';
|
|
21
|
-
import { doSosReportAnalysisForFile, hasSomeSelectedFiles, isAnalysingAnyAttachment, isUploadedSuccessfully, isUploadingAttachment, updateUploadMetadata, uploadAllFiles, uploadFile, } from './reducer/AttachmentHelper';
|
|
21
|
+
import { doSosReportAnalysisForFile, hasSomeSelectedFiles, isAnalysingAnyAttachment, isFileDeleted, isUploadedSuccessfully, isUploadingAttachment, updateUploadMetadata, uploadAllFiles, uploadFile, } from './reducer/AttachmentHelper';
|
|
22
22
|
import { onFileEdit, onFileRemove, resetAttachment, UploadStatusConstants, } from './reducer/AttachmentReducer';
|
|
23
23
|
import { AttachmentDispatchContext, AttachmentStateContext } from './reducer/AttachmentReducerContext';
|
|
24
24
|
/** Wait for staggered onDrop dispatches before auto-uploading. */
|
|
@@ -196,12 +196,24 @@ export function useFileUploader(props) {
|
|
|
196
196
|
}
|
|
197
197
|
});
|
|
198
198
|
const onUploadFile = (fileIndex) => __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
const originalFile = attachmentState.caseFiles.selectedOriginalFiles[fileIndex];
|
|
200
|
+
if (!originalFile || originalFile.size === 0) {
|
|
201
|
+
updateUploadMetadata(dispatch, fileIndex, {
|
|
202
|
+
uploadStatus: UploadStatusConstants.deleted,
|
|
203
|
+
onAbort: undefined,
|
|
204
|
+
});
|
|
205
|
+
const remaining = attachmentState.caseFiles.selectedLocalFiles.filter((f, i) => i !== fileIndex && !isFileDeleted(f.uploadProgress.uploadStatus));
|
|
206
|
+
if (remaining.length === 0) {
|
|
207
|
+
resetAttachment(dispatch);
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
199
211
|
yield resolveCaseSalesforceId();
|
|
200
212
|
uploadFile({
|
|
201
213
|
dispatch,
|
|
202
214
|
idToUploadTo,
|
|
203
215
|
localFile: attachmentState.caseFiles.selectedLocalFiles[fileIndex],
|
|
204
|
-
originalFile
|
|
216
|
+
originalFile,
|
|
205
217
|
index: fileIndex,
|
|
206
218
|
needsAnalyzing,
|
|
207
219
|
isSessionId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseDiscussionTabContext.d.ts","sourceRoot":"","sources":["../../../src/context/CaseDiscussionTabContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAItD,eAAO,MAAM,6BAA6B,gFAA8C,CAAC;AACzF,eAAO,MAAM,gCAAgC,oBAA4B,CAAC;AAC1E,eAAO,MAAM,gCAAgC,uEAAkD,CAAC;AAChG,eAAO,MAAM,mCAAmC,WAAqD,CAAC;AAEtG,wBAAgB,gCAAgC,CAAC,EAAE,QAAQ,EAAE;;CAAA,
|
|
1
|
+
{"version":3,"file":"CaseDiscussionTabContext.d.ts","sourceRoot":"","sources":["../../../src/context/CaseDiscussionTabContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAItD,eAAO,MAAM,6BAA6B,gFAA8C,CAAC;AACzF,eAAO,MAAM,gCAAgC,oBAA4B,CAAC;AAC1E,eAAO,MAAM,gCAAgC,uEAAkD,CAAC;AAChG,eAAO,MAAM,mCAAmC,WAAqD,CAAC;AAEtG,wBAAgB,gCAAgC,CAAC,EAAE,QAAQ,EAAE;;CAAA,qBAW5D"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { isGenericNetworkError } from '@rh-support/utils';
|
|
2
|
+
export { isGenericNetworkError };
|
|
1
3
|
export type CaseUpdateErrorContent = {
|
|
2
4
|
title: string;
|
|
3
5
|
message: string;
|
|
4
6
|
onRetry?: () => unknown;
|
|
5
7
|
};
|
|
6
8
|
export declare function getErrorStatusCode(error: unknown): number;
|
|
7
|
-
export declare function isGenericNetworkError(error: unknown): boolean;
|
|
8
9
|
export declare function useCaseUpdateErrorMessage(): {
|
|
9
10
|
showError: (e: unknown, fallbackOrContent: string | CaseUpdateErrorContent) => void;
|
|
10
11
|
showFieldError: (e: unknown, fieldName: string, onRetry?: () => unknown) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCaseUpdateErrorMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCaseUpdateErrorMessage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCaseUpdateErrorMessage.d.ts","sourceRoot":"","sources":["../../../src/hooks/useCaseUpdateErrorMessage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAI1D,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAKjC,MAAM,MAAM,sBAAsB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;CAC3B,CAAC;AA8BF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsBzD;AAOD,wBAAgB,yBAAyB;mBAgCf,OAAO,qBAAqB,MAAM,GAAG,sBAAsB;wBA2CtD,OAAO,aAAa,MAAM,YAAY,MAAM,OAAO;EAYjF"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { AlertActionLink } from '@patternfly/react-core';
|
|
2
2
|
import { getDirectErrorMessage, ToastNotification } from '@rh-support/components';
|
|
3
|
+
import { isGenericNetworkError } from '@rh-support/utils';
|
|
3
4
|
import React from 'react';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
+
export { isGenericNetworkError };
|
|
5
7
|
const PICKLIST_VALIDATION_PATTERN = /is not a valid active picklist value/i;
|
|
6
8
|
const CASE_GROUP_REQUIRED_PATTERN = /group.*required|required.*group/i;
|
|
7
9
|
function isCaseUpdateErrorContent(value) {
|
|
@@ -48,10 +50,6 @@ function parseStatusFromMessage(message) {
|
|
|
48
50
|
const match = message.match(/status code\s+(\d+)/i);
|
|
49
51
|
return match ? Number.parseInt(match[1], 10) : 0;
|
|
50
52
|
}
|
|
51
|
-
export function isGenericNetworkError(error) {
|
|
52
|
-
const message = typeof error === 'string' ? error : String((error === null || error === void 0 ? void 0 : error.message) || '');
|
|
53
|
-
return /Response not successful|Failed to fetch|Network request failed|NetworkError when attempting to fetch|Received status code\s+\d+/i.test(message);
|
|
54
|
-
}
|
|
55
53
|
export function useCaseUpdateErrorMessage() {
|
|
56
54
|
const { t } = useTranslation();
|
|
57
55
|
const showDesignedError = (content) => {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IAttachment } from '@cee-eng/hydrajs/@types/models/attachment';
|
|
2
|
+
import { IApiResponseDetails } from '@rh-support/types/shared';
|
|
3
|
+
import { ApolloQueryClient } from '@rh-support/utils';
|
|
4
|
+
import { CaseDetailsReducerDispatchType } from '../reducers/CaseDetailsPageReducer';
|
|
5
|
+
interface UseInProgressAttachmentPollParams {
|
|
6
|
+
apolloClient: ApolloQueryClient;
|
|
7
|
+
caseNumber: string;
|
|
8
|
+
caseSalesforceId: string | undefined;
|
|
9
|
+
caseAttachmentHydra: IApiResponseDetails<Partial<IAttachment[]>>;
|
|
10
|
+
dispatchCaseDetails: CaseDetailsReducerDispatchType;
|
|
11
|
+
}
|
|
12
|
+
export declare function useInProgressAttachmentPoll({ apolloClient, caseNumber, caseSalesforceId, caseAttachmentHydra, dispatchCaseDetails, }: UseInProgressAttachmentPollParams): void;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=useInProgressAttachmentPoll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInProgressAttachmentPoll.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInProgressAttachmentPoll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EACH,iBAAiB,EAKpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAwB,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AAO1G,UAAU,iCAAiC;IACvC,YAAY,EAAE,iBAAiB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,mBAAmB,EAAE,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACjE,mBAAmB,EAAE,8BAA8B,CAAC;CACvD;AAED,wBAAgB,2BAA2B,CAAC,EACxC,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,GACtB,EAAE,iCAAiC,GAAG,IAAI,CAyE1C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
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 { fetchCaseAttachmentsViaGraphQL, getApiResourceObject, isAttachmentUploadInProgress, } from '@rh-support/utils';
|
|
11
|
+
import { useEffect, useRef } from 'react';
|
|
12
|
+
import { CaseDetailsConstants } from '../reducers/CaseDetailsPageReducer';
|
|
13
|
+
/** How often to re-check In Progress attachments (ms) - 5s */
|
|
14
|
+
const POLL_INTERVAL_MS = 5000;
|
|
15
|
+
/** Stop polling after this many cycles to avoid infinite loops - 36 cycles = 3 minutes */
|
|
16
|
+
const MAX_POLL_CYCLES = 36;
|
|
17
|
+
export function useInProgressAttachmentPoll({ apolloClient, caseNumber, caseSalesforceId, caseAttachmentHydra, dispatchCaseDetails, }) {
|
|
18
|
+
var _a;
|
|
19
|
+
const pollCountRef = useRef(0);
|
|
20
|
+
const isFetchingRef = useRef(false);
|
|
21
|
+
const attachments = ((_a = caseAttachmentHydra.data) !== null && _a !== void 0 ? _a : []);
|
|
22
|
+
const hasInProgress = attachments.some((a) => a && isAttachmentUploadInProgress(a));
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!hasInProgress || !caseSalesforceId || caseAttachmentHydra.isFetching) {
|
|
25
|
+
pollCountRef.current = 0;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const pollOnce = () => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
if (isFetchingRef.current)
|
|
30
|
+
return;
|
|
31
|
+
if (pollCountRef.current >= MAX_POLL_CYCLES)
|
|
32
|
+
return;
|
|
33
|
+
isFetchingRef.current = true;
|
|
34
|
+
pollCountRef.current += 1;
|
|
35
|
+
try {
|
|
36
|
+
const freshAttachments = yield fetchCaseAttachmentsViaGraphQL(apolloClient, caseNumber, caseSalesforceId);
|
|
37
|
+
const stillInProgress = freshAttachments.some(isAttachmentUploadInProgress);
|
|
38
|
+
dispatchCaseDetails({
|
|
39
|
+
type: CaseDetailsConstants.updateState,
|
|
40
|
+
payload: {
|
|
41
|
+
caseAttachmentHydra: getApiResourceObject(freshAttachments),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return stillInProgress;
|
|
45
|
+
}
|
|
46
|
+
catch (_a) {
|
|
47
|
+
return true; // retry on next interval
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
isFetchingRef.current = false;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
let intervalId;
|
|
54
|
+
let stopped = false;
|
|
55
|
+
void pollOnce().then((stillInProgress) => {
|
|
56
|
+
if (stopped || stillInProgress === false)
|
|
57
|
+
return;
|
|
58
|
+
intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
if (pollCountRef.current >= MAX_POLL_CYCLES) {
|
|
60
|
+
clearInterval(intervalId);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const still = yield pollOnce();
|
|
64
|
+
if (still === false) {
|
|
65
|
+
clearInterval(intervalId);
|
|
66
|
+
}
|
|
67
|
+
}), POLL_INTERVAL_MS);
|
|
68
|
+
});
|
|
69
|
+
return () => {
|
|
70
|
+
stopped = true;
|
|
71
|
+
if (intervalId)
|
|
72
|
+
clearInterval(intervalId);
|
|
73
|
+
};
|
|
74
|
+
}, [
|
|
75
|
+
hasInProgress,
|
|
76
|
+
caseSalesforceId,
|
|
77
|
+
apolloClient,
|
|
78
|
+
caseNumber,
|
|
79
|
+
dispatchCaseDetails,
|
|
80
|
+
caseAttachmentHydra.isFetching,
|
|
81
|
+
]);
|
|
82
|
+
}
|
|
@@ -63,7 +63,7 @@ export function useS3Upload(caseNumber, apolloClient, caseSalesforceId) {
|
|
|
63
63
|
(error instanceof CaseAttachmentUploadError && error.attachmentId) ||
|
|
64
64
|
undefined;
|
|
65
65
|
if (attachmentIdFromError && apolloClient && caseSalesforceId) {
|
|
66
|
-
void markCaseAttachmentUploadFailed(apolloClient, caseNumber, attachmentIdFromError);
|
|
66
|
+
void markCaseAttachmentUploadFailed(apolloClient, caseNumber, attachmentIdFromError, error === null || error === void 0 ? void 0 : error.message);
|
|
67
67
|
}
|
|
68
68
|
throw error;
|
|
69
69
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IAttachment } from '@cee-eng/hydrajs/@types/models/attachment';
|
|
2
|
+
import { IApiResponseDetails } from '@rh-support/types/shared';
|
|
3
|
+
export declare function useSyncServerAttachments(caseNumber: string, caseAttachmentHydra: IApiResponseDetails<Partial<IAttachment[]>>): void;
|
|
4
|
+
//# sourceMappingURL=useSyncServerAttachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSyncServerAttachments.d.ts","sourceRoot":"","sources":["../../../src/hooks/useSyncServerAttachments.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AA0B/D,wBAAgB,wBAAwB,CACpC,UAAU,EAAE,MAAM,EAClB,mBAAmB,EAAE,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,GACjE,IAAI,CAwMN"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { useApolloClient } from '@apollo/client/react';
|
|
2
|
+
import { getApiResourceObject, isAttachmentUploadFailed, isAttachmentUploadInProgress, markCaseAttachmentUploadFailed, } from '@rh-support/utils';
|
|
3
|
+
import { useContext, useEffect, useRef } from 'react';
|
|
4
|
+
import { abortBackgroundUpload } from '../components/shared/fileUpload/reducer/AttachmentHelper';
|
|
5
|
+
import { AttachmentReducerConstants, defaultAnalysisMetadata, resetAttachment, udpateFileUploadMetadata, UploadStatusConstants, } from '../components/shared/fileUpload/reducer/AttachmentReducer';
|
|
6
|
+
import { AttachmentDispatchContext, AttachmentStateContext, } from '../components/shared/fileUpload/reducer/AttachmentReducerContext';
|
|
7
|
+
import { useCaseDetailsPageDispatchContext } from '../context/CaseDetailsPageContext';
|
|
8
|
+
import { CaseDetailsConstants } from '../reducers/CaseDetailsPageReducer';
|
|
9
|
+
export function useSyncServerAttachments(caseNumber, caseAttachmentHydra) {
|
|
10
|
+
const apolloClient = useApolloClient();
|
|
11
|
+
const dispatch = useContext(AttachmentDispatchContext);
|
|
12
|
+
const { attachmentState } = useContext(AttachmentStateContext);
|
|
13
|
+
const dispatchCaseDetails = useCaseDetailsPageDispatchContext();
|
|
14
|
+
const injectedUuidsRef = useRef(new Set());
|
|
15
|
+
const selectedLocalFilesRef = useRef(attachmentState.caseFiles.selectedLocalFiles);
|
|
16
|
+
selectedLocalFilesRef.current = attachmentState.caseFiles.selectedLocalFiles;
|
|
17
|
+
const hydraDataRef = useRef(caseAttachmentHydra.data);
|
|
18
|
+
hydraDataRef.current = caseAttachmentHydra.data;
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
var _a;
|
|
21
|
+
if (!dispatch || caseAttachmentHydra.isFetching)
|
|
22
|
+
return;
|
|
23
|
+
const attachments = ((_a = caseAttachmentHydra.data) !== null && _a !== void 0 ? _a : []);
|
|
24
|
+
const localFiles = selectedLocalFilesRef.current;
|
|
25
|
+
const localAttachmentIds = new Set(localFiles.map((f) => f.attachmentId).filter(Boolean));
|
|
26
|
+
const toInject = attachments.filter((a) => (a === null || a === void 0 ? void 0 : a.uuid) &&
|
|
27
|
+
(isAttachmentUploadInProgress(a) || isAttachmentUploadFailed(a)) &&
|
|
28
|
+
!injectedUuidsRef.current.has(a.uuid) &&
|
|
29
|
+
!localAttachmentIds.has(a.uuid));
|
|
30
|
+
if (toInject.length > 0) {
|
|
31
|
+
const syntheticFiles = toInject.map((attachment) => {
|
|
32
|
+
var _a, _b, _c;
|
|
33
|
+
const uuid = attachment.uuid;
|
|
34
|
+
const inProgress = isAttachmentUploadInProgress(attachment);
|
|
35
|
+
const onAbort = inProgress
|
|
36
|
+
? (_index) => {
|
|
37
|
+
var _a;
|
|
38
|
+
const files = selectedLocalFilesRef.current;
|
|
39
|
+
const idx = files.findIndex((f) => f.attachmentId === uuid);
|
|
40
|
+
if (idx < 0)
|
|
41
|
+
return;
|
|
42
|
+
// Abort the background S3 XHR if it's still running
|
|
43
|
+
abortBackgroundUpload(uuid);
|
|
44
|
+
udpateFileUploadMetadata(dispatch, {
|
|
45
|
+
uploadStatus: UploadStatusConstants.aborted,
|
|
46
|
+
onAbort: undefined,
|
|
47
|
+
percentUploaded: 0,
|
|
48
|
+
}, idx);
|
|
49
|
+
injectedUuidsRef.current.delete(uuid);
|
|
50
|
+
void markCaseAttachmentUploadFailed(apolloClient, caseNumber, uuid);
|
|
51
|
+
const current = ((_a = hydraDataRef.current) !== null && _a !== void 0 ? _a : []);
|
|
52
|
+
dispatchCaseDetails({
|
|
53
|
+
type: CaseDetailsConstants.updateState,
|
|
54
|
+
payload: {
|
|
55
|
+
caseAttachmentHydra: getApiResourceObject(current.map((a) => (a === null || a === void 0 ? void 0 : a.uuid) === uuid ? Object.assign(Object.assign({}, a), { uploadStatus: 'Failed' }) : a)),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
: undefined;
|
|
60
|
+
return {
|
|
61
|
+
name: attachment.fileName,
|
|
62
|
+
size: attachment.size > 0 ? attachment.size : ((_a = attachment.sizeKB) !== null && _a !== void 0 ? _a : 0) * 1024,
|
|
63
|
+
lastModified: Date.now(),
|
|
64
|
+
type: '',
|
|
65
|
+
description: (_b = attachment.description) !== null && _b !== void 0 ? _b : '',
|
|
66
|
+
uploadProgress: {
|
|
67
|
+
uploadStatus: inProgress
|
|
68
|
+
? UploadStatusConstants.uploadingOnCase
|
|
69
|
+
: UploadStatusConstants.uploadOnCaseFailed,
|
|
70
|
+
uploadErrorMessage: inProgress ? '' : 'Upload failed',
|
|
71
|
+
onAbort,
|
|
72
|
+
percentUploaded: 0,
|
|
73
|
+
},
|
|
74
|
+
analysisMetadata: Object.assign({}, defaultAnalysisMetadata),
|
|
75
|
+
uploadability: { ableToUpload: true, ableToUploadMessage: '' },
|
|
76
|
+
includeResults: false,
|
|
77
|
+
isPrivate: (_c = attachment.isPrivate) !== null && _c !== void 0 ? _c : false,
|
|
78
|
+
attachmentId: uuid,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
toInject.forEach((a) => injectedUuidsRef.current.add(a.uuid));
|
|
82
|
+
const placeholderOriginals = syntheticFiles.map((f) => new File([], f.name, { type: f.type || 'application/octet-stream' }));
|
|
83
|
+
dispatch({
|
|
84
|
+
type: AttachmentReducerConstants.caseFileSelected,
|
|
85
|
+
payload: {
|
|
86
|
+
caseFiles: {
|
|
87
|
+
selectedLocalFiles: syntheticFiles,
|
|
88
|
+
selectedOriginalFiles: placeholderOriginals,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Reconcile injected rows with latest SFDC status (use latest local list after possible inject)
|
|
94
|
+
const filesAfterInject = selectedLocalFilesRef.current;
|
|
95
|
+
filesAfterInject.forEach((localFile, index) => {
|
|
96
|
+
const uuid = localFile.attachmentId;
|
|
97
|
+
if (!uuid || !injectedUuidsRef.current.has(uuid))
|
|
98
|
+
return;
|
|
99
|
+
// If we just injected this uuid in this same effect pass, skip reconcile until next run
|
|
100
|
+
if (toInject.some((a) => a.uuid === uuid))
|
|
101
|
+
return;
|
|
102
|
+
const server = attachments.find((a) => (a === null || a === void 0 ? void 0 : a.uuid) === uuid);
|
|
103
|
+
if (!server) {
|
|
104
|
+
udpateFileUploadMetadata(dispatch, {
|
|
105
|
+
uploadStatus: UploadStatusConstants.deleted,
|
|
106
|
+
onAbort: undefined,
|
|
107
|
+
}, index);
|
|
108
|
+
injectedUuidsRef.current.delete(uuid);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (!isAttachmentUploadInProgress(server) && !isAttachmentUploadFailed(server)) {
|
|
112
|
+
if (localFile.uploadProgress.uploadStatus === UploadStatusConstants.uploadingOnCase ||
|
|
113
|
+
localFile.uploadProgress.uploadStatus === UploadStatusConstants.aborted) {
|
|
114
|
+
udpateFileUploadMetadata(dispatch, {
|
|
115
|
+
uploadStatus: UploadStatusConstants.uploadedOnCase,
|
|
116
|
+
percentUploaded: 100,
|
|
117
|
+
onAbort: undefined,
|
|
118
|
+
}, index);
|
|
119
|
+
injectedUuidsRef.current.delete(uuid);
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (isAttachmentUploadFailed(server) &&
|
|
124
|
+
localFile.uploadProgress.uploadStatus === UploadStatusConstants.uploadingOnCase) {
|
|
125
|
+
udpateFileUploadMetadata(dispatch, {
|
|
126
|
+
uploadStatus: UploadStatusConstants.uploadOnCaseFailed,
|
|
127
|
+
onAbort: undefined,
|
|
128
|
+
percentUploaded: 0,
|
|
129
|
+
}, index);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// Remove completed batch rows once the discussion list already has the attachment.
|
|
133
|
+
let didCleanup = false;
|
|
134
|
+
filesAfterInject.forEach((localFile, index) => {
|
|
135
|
+
if (localFile.uploadProgress.uploadStatus !== UploadStatusConstants.uploadedOnCase)
|
|
136
|
+
return;
|
|
137
|
+
const uuid = localFile.attachmentId;
|
|
138
|
+
if (!uuid)
|
|
139
|
+
return;
|
|
140
|
+
const server = attachments.find((a) => (a === null || a === void 0 ? void 0 : a.uuid) === uuid);
|
|
141
|
+
if (server && !isAttachmentUploadInProgress(server) && !isAttachmentUploadFailed(server)) {
|
|
142
|
+
udpateFileUploadMetadata(dispatch, {
|
|
143
|
+
uploadStatus: UploadStatusConstants.deleted,
|
|
144
|
+
onAbort: undefined,
|
|
145
|
+
}, index);
|
|
146
|
+
injectedUuidsRef.current.delete(uuid);
|
|
147
|
+
didCleanup = true;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
if (didCleanup) {
|
|
151
|
+
const latest = selectedLocalFilesRef.current;
|
|
152
|
+
const hasVisibleFiles = latest.some((f) => f.uploadProgress.uploadStatus !== UploadStatusConstants.deleted);
|
|
153
|
+
if (!hasVisibleFiles) {
|
|
154
|
+
resetAttachment(dispatch);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}, [
|
|
158
|
+
caseAttachmentHydra.data,
|
|
159
|
+
caseAttachmentHydra.isFetching,
|
|
160
|
+
dispatch,
|
|
161
|
+
apolloClient,
|
|
162
|
+
caseNumber,
|
|
163
|
+
dispatchCaseDetails,
|
|
164
|
+
]);
|
|
165
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApolloQueryClient, ICaseAttachment } from '@rh-support/utils';
|
|
2
|
+
import { IFileLocal } from '../components/shared/fileUpload/reducer/AttachmentReducer';
|
|
3
|
+
export declare function selectUploadingAttachmentUuids(selectedLocalFiles: IFileLocal[]): string[];
|
|
4
|
+
export declare function contentVersionIdFromServerAttachment(attachment: ICaseAttachment | undefined): string | undefined;
|
|
5
|
+
interface UseUploadingContentVersionSfIdsParams {
|
|
6
|
+
caseNumber: string;
|
|
7
|
+
selectedLocalFiles: IFileLocal[];
|
|
8
|
+
apolloClient: ApolloQueryClient;
|
|
9
|
+
serverAttachments?: Array<ICaseAttachment | undefined>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useUploadingContentVersionSfIds({ caseNumber, selectedLocalFiles, apolloClient, serverAttachments, }: UseUploadingContentVersionSfIdsParams): string[];
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=useUploadingContentVersionSfIds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useUploadingContentVersionSfIds.d.ts","sourceRoot":"","sources":["../../../src/hooks/useUploadingContentVersionSfIds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA2C,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGhH,OAAO,EAAE,UAAU,EAAyB,MAAM,2DAA2D,CAAC;AAK9G,wBAAgB,8BAA8B,CAAC,kBAAkB,EAAE,UAAU,EAAE,GAAG,MAAM,EAAE,CAOzF;AAED,wBAAgB,oCAAoC,CAAC,UAAU,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGhH;AAQD,UAAU,qCAAqC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,UAAU,EAAE,CAAC;IACjC,YAAY,EAAE,iBAAiB,CAAC;IAChC,iBAAiB,CAAC,EAAE,KAAK,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;CAC1D;AAED,wBAAgB,+BAA+B,CAAC,EAC5C,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,GACpB,EAAE,qCAAqC,GAAG,MAAM,EAAE,CA6FlD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
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 { GET_CONTENT_VERSION_ID_BY_CASE_AND_UUID } from '@rh-support/utils';
|
|
11
|
+
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
12
|
+
import { UploadStatusConstants } from '../components/shared/fileUpload/reducer/AttachmentReducer';
|
|
13
|
+
/** How often to retry ContentVersion id lookup while a file is still uploading. */
|
|
14
|
+
const RESOLVE_INTERVAL_MS = 2000;
|
|
15
|
+
export function selectUploadingAttachmentUuids(selectedLocalFiles) {
|
|
16
|
+
return selectedLocalFiles
|
|
17
|
+
.filter((file) => file.uploadProgress.uploadStatus === UploadStatusConstants.uploadingOnCase && Boolean(file.attachmentId))
|
|
18
|
+
.map((file) => file.attachmentId);
|
|
19
|
+
}
|
|
20
|
+
export function contentVersionIdFromServerAttachment(attachment) {
|
|
21
|
+
if (!(attachment === null || attachment === void 0 ? void 0 : attachment.uuid) || !attachment.id || attachment.id === attachment.uuid)
|
|
22
|
+
return undefined;
|
|
23
|
+
return attachment.id;
|
|
24
|
+
}
|
|
25
|
+
function readContentVersionId(data) {
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
27
|
+
const cvId = (_m = (_l = (_k = (_j = (_h = (_g = (_f = (_e = (_d = (_c = (_b = (_a = data === null || data === void 0 ? void 0 : data.redhat_support_uiapi) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.RedHatSupportCase) === null || _c === void 0 ? void 0 : _c.edges) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.node) === null || _f === void 0 ? void 0 : _f.ContentDocumentLinks) === null || _g === void 0 ? void 0 : _g.edges) === null || _h === void 0 ? void 0 : _h[0]) === null || _j === void 0 ? void 0 : _j.node) === null || _k === void 0 ? void 0 : _k.RedHatSupportContentDocument) === null || _l === void 0 ? void 0 : _l.LatestPublishedVersion) === null || _m === void 0 ? void 0 : _m.Id;
|
|
28
|
+
return typeof cvId === 'string' && cvId ? cvId : undefined;
|
|
29
|
+
}
|
|
30
|
+
export function useUploadingContentVersionSfIds({ caseNumber, selectedLocalFiles, apolloClient, serverAttachments, }) {
|
|
31
|
+
const uploadingUuids = useMemo(() => selectUploadingAttachmentUuids(selectedLocalFiles), [selectedLocalFiles]);
|
|
32
|
+
const uploadingKey = uploadingUuids.join('|');
|
|
33
|
+
const [resolvedByUuid, setResolvedByUuid] = useState({});
|
|
34
|
+
const resolvedRef = useRef(resolvedByUuid);
|
|
35
|
+
resolvedRef.current = resolvedByUuid;
|
|
36
|
+
const uuidsRef = useRef(uploadingUuids);
|
|
37
|
+
uuidsRef.current = uploadingUuids;
|
|
38
|
+
const hydraRef = useRef(serverAttachments);
|
|
39
|
+
hydraRef.current = serverAttachments;
|
|
40
|
+
const apolloRef = useRef(apolloClient);
|
|
41
|
+
apolloRef.current = apolloClient;
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (!caseNumber || !uploadingKey)
|
|
44
|
+
return;
|
|
45
|
+
let cancelled = false;
|
|
46
|
+
let inFlight = false;
|
|
47
|
+
const remember = (found) => {
|
|
48
|
+
if (cancelled || !Object.keys(found).length)
|
|
49
|
+
return;
|
|
50
|
+
const next = Object.assign(Object.assign({}, resolvedRef.current), found);
|
|
51
|
+
resolvedRef.current = next;
|
|
52
|
+
setResolvedByUuid(next);
|
|
53
|
+
};
|
|
54
|
+
const tick = () => __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
var _a;
|
|
56
|
+
if (cancelled || inFlight)
|
|
57
|
+
return;
|
|
58
|
+
const pending = uuidsRef.current.filter((uuid) => !resolvedRef.current[uuid]);
|
|
59
|
+
if (!pending.length)
|
|
60
|
+
return;
|
|
61
|
+
const fromServer = {};
|
|
62
|
+
const known = (_a = hydraRef.current) !== null && _a !== void 0 ? _a : [];
|
|
63
|
+
for (const uuid of pending) {
|
|
64
|
+
const match = known.find((attachment) => (attachment === null || attachment === void 0 ? void 0 : attachment.uuid) === uuid);
|
|
65
|
+
const cvId = contentVersionIdFromServerAttachment(match);
|
|
66
|
+
if (cvId)
|
|
67
|
+
fromServer[uuid] = cvId;
|
|
68
|
+
}
|
|
69
|
+
remember(fromServer);
|
|
70
|
+
const stillPending = pending.filter((uuid) => !resolvedRef.current[uuid]);
|
|
71
|
+
if (!stillPending.length)
|
|
72
|
+
return;
|
|
73
|
+
inFlight = true;
|
|
74
|
+
const found = {};
|
|
75
|
+
try {
|
|
76
|
+
yield Promise.all(stillPending.map((attachmentUUID) => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
if (cancelled || resolvedRef.current[attachmentUUID])
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
const { data } = yield apolloRef.current.query({
|
|
81
|
+
query: GET_CONTENT_VERSION_ID_BY_CASE_AND_UUID,
|
|
82
|
+
variables: { caseNumber, attachmentUUID },
|
|
83
|
+
fetchPolicy: 'network-only',
|
|
84
|
+
});
|
|
85
|
+
const cvId = readContentVersionId(data);
|
|
86
|
+
if (cvId && cvId !== attachmentUUID)
|
|
87
|
+
found[attachmentUUID] = cvId;
|
|
88
|
+
}
|
|
89
|
+
catch (_a) {
|
|
90
|
+
// Salesforce indexing lag or a transient error — next tick retries.
|
|
91
|
+
}
|
|
92
|
+
})));
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
inFlight = false;
|
|
96
|
+
}
|
|
97
|
+
remember(found);
|
|
98
|
+
});
|
|
99
|
+
void tick();
|
|
100
|
+
const intervalId = setInterval(() => {
|
|
101
|
+
void tick();
|
|
102
|
+
}, RESOLVE_INTERVAL_MS);
|
|
103
|
+
return () => {
|
|
104
|
+
cancelled = true;
|
|
105
|
+
clearInterval(intervalId);
|
|
106
|
+
};
|
|
107
|
+
}, [caseNumber, uploadingKey]);
|
|
108
|
+
return useMemo(() => {
|
|
109
|
+
const fromServer = new Map();
|
|
110
|
+
for (const attachment of serverAttachments !== null && serverAttachments !== void 0 ? serverAttachments : []) {
|
|
111
|
+
if (!(attachment === null || attachment === void 0 ? void 0 : attachment.uuid))
|
|
112
|
+
continue;
|
|
113
|
+
const cvId = contentVersionIdFromServerAttachment(attachment);
|
|
114
|
+
if (cvId)
|
|
115
|
+
fromServer.set(attachment.uuid, cvId);
|
|
116
|
+
}
|
|
117
|
+
return uploadingUuids
|
|
118
|
+
.map((uuid) => resolvedByUuid[uuid] || fromServer.get(uuid))
|
|
119
|
+
.filter((id) => Boolean(id));
|
|
120
|
+
}, [uploadingUuids, serverAttachments, resolvedByUuid]);
|
|
121
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWarnBeforeUnloadOnUpload.d.ts","sourceRoot":"","sources":["../../../src/hooks/useWarnBeforeUnloadOnUpload.ts"],"names":[],"mappings":"AAoCA,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,OAAO,EAAE,mBAAmB,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAsCtG"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { buildGraphQLGatewayHeaders, getGraphQLGatewayUri, UPDATE_CONTENT_VERSION_UPLOAD_STATUS_STRING, } from '@rh-support/utils';
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
3
|
+
function markAttachmentsFailedKeepalive(contentVersionSfIds, capturedUrl, capturedHeaders) {
|
|
4
|
+
if (!contentVersionSfIds.length) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
if (!capturedUrl || !capturedHeaders.authorization) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
for (const contentVersionId of contentVersionSfIds) {
|
|
11
|
+
try {
|
|
12
|
+
fetch(capturedUrl, {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
keepalive: true,
|
|
15
|
+
headers: capturedHeaders,
|
|
16
|
+
body: JSON.stringify({
|
|
17
|
+
query: UPDATE_CONTENT_VERSION_UPLOAD_STATUS_STRING,
|
|
18
|
+
variables: { contentVersionId, uploadStatus: 'Failed' },
|
|
19
|
+
}),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
console.error(err);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function useWarnBeforeUnloadOnUpload(isUploading, contentVersionSfIds) {
|
|
28
|
+
// Ref so the pagehide handler always reads the latest IDs without
|
|
29
|
+
// re-registering listeners on every render.
|
|
30
|
+
const idsRef = useRef([]);
|
|
31
|
+
idsRef.current = contentVersionSfIds !== null && contentVersionSfIds !== void 0 ? contentVersionSfIds : [];
|
|
32
|
+
const headersRef = useRef({ url: '', headers: {} });
|
|
33
|
+
if (isUploading) {
|
|
34
|
+
headersRef.current = {
|
|
35
|
+
url: getGraphQLGatewayUri(),
|
|
36
|
+
headers: buildGraphQLGatewayHeaders(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (!isUploading)
|
|
41
|
+
return;
|
|
42
|
+
const onBeforeUnload = (event) => {
|
|
43
|
+
event.preventDefault();
|
|
44
|
+
// Re-snapshot headers while the page is still fully alive.
|
|
45
|
+
headersRef.current = {
|
|
46
|
+
url: getGraphQLGatewayUri(),
|
|
47
|
+
headers: buildGraphQLGatewayHeaders(),
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
const onPageHide = (event) => {
|
|
51
|
+
if (event.persisted)
|
|
52
|
+
return;
|
|
53
|
+
const { url, headers } = headersRef.current;
|
|
54
|
+
markAttachmentsFailedKeepalive(idsRef.current, url, headers);
|
|
55
|
+
};
|
|
56
|
+
window.addEventListener('beforeunload', onBeforeUnload);
|
|
57
|
+
window.addEventListener('pagehide', onPageHide);
|
|
58
|
+
return () => {
|
|
59
|
+
window.removeEventListener('beforeunload', onBeforeUnload);
|
|
60
|
+
window.removeEventListener('pagehide', onPageHide);
|
|
61
|
+
};
|
|
62
|
+
}, [isUploading]);
|
|
63
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaseDetailsPageReducer.d.ts","sourceRoot":"","sources":["../../../src/reducers/CaseDetailsPageReducer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EACH,iBAAiB,
|
|
1
|
+
{"version":3,"file":"CaseDetailsPageReducer.d.ts","sourceRoot":"","sources":["../../../src/reducers/CaseDetailsPageReducer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EACH,iBAAiB,EAMpB,MAAM,mBAAmB,CAAC;AAI3B,KAAK,WAAW,GAAG,OAAO,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;AACjE,MAAM,MAAM,8BAA8B,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAE1E,oBAAY,oBAAoB;IAC5B,WAAW,gBAAgB;CAC9B;AAED,MAAM,WAAW,cAAc;IAC3B,kBAAkB,EAAE,mBAAmB,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;IACrE,mBAAmB,EAAE,mBAAmB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAGjE,0BAA0B,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,eAAe,EAAE,mBAAmB,CAAC,eAAe,EAAE,CAAC,CAAC;CAC3D;AAED,eAAO,MAAM,2BAA2B,EAAE,cAOzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,cAAc,EAAE,QAAQ,WAAW,KAAG,GASnF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GACzB,UAAU,8BAA8B,EACxC,YAAY,MAAM,EAClB,cAAc,iBAAiB,EAC/B,mBAAmB,MAAM,EACzB,8BAA4B,kBA+B/B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,UAAU,8BAA8B,EAAE,YAAY,MAAM,kBAoBhG,CAAC;AAsBF,eAAO,MAAM,qBAAqB,GAAU,WAAW,8BAA8B,EAAE,aAAa,MAAM,kBAEzG,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC7B,UAAU,8BAA8B,EACxC,UAAU,MAAM,EAChB,cAAc;IAAE,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;CAAE,EACvD,oBAAiB,EACjB,8BAA4B,EAC5B,cAAa,aAAa,GAAG,cAA8B,KAC5D,OAAO,CAAC,eAAe,EAAE,CA0C3B,CAAC"}
|
|
@@ -28,7 +28,7 @@ export declare function extractStringValue(val: SFValue): string | null;
|
|
|
28
28
|
* in {@link normalizeNodeToHistoryItem}.
|
|
29
29
|
*/
|
|
30
30
|
export declare const SPECIAL_FIELD_ACTIONS: Record<string, string>;
|
|
31
|
-
export declare const DEFAULT_AVATAR_SRC = "
|
|
31
|
+
export declare const DEFAULT_AVATAR_SRC = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 36'%3E%3Crect width='36' height='36' fill='%23f0f0f0'/%3E%3Cpath fill='%23d2d2d2' d='M17.7 20.1c-3.5 0-6.4-2.9-6.4-6.4s2.9-6.4 6.4-6.4 6.4 2.9 6.4 6.4-2.8 6.4-6.4 6.4z'/%3E%3Cpath fill='%23d2d2d2' d='M30.6 36c-.4-3.9-1.3-9-2.9-11-1.1-1.4-2.3-2.2-3.5-2.6s-1.8-.6-6.3-.6-6.1.7-6.1.7c-1.2.4-2.4 1.2-3.4 2.6-1.7 1.9-2.6 7.1-3 10.9h25.2z'/%3E%3C/svg%3E";
|
|
32
32
|
/**
|
|
33
33
|
* Only SF `UserType === 'Standard'` is treated as an internal (Red Hat) user.
|
|
34
34
|
* All other types — including `null`, `undefined`, and unknown portal types — default
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"caseHistoryUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/caseHistoryUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE3G;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsBzD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKzE;AAMD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO9D;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOxD,CAAC;AAEF,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"caseHistoryUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/caseHistoryUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE3G;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsBzD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKzE;AAMD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO9D;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOxD,CAAC;AAEF,eAAO,MAAM,kBAAkB,6aAC+Y,CAAC;AAI/a;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAajF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAYnD,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAEvF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB,CAuCnF"}
|
|
@@ -78,7 +78,7 @@ export const SPECIAL_FIELD_ACTIONS = {
|
|
|
78
78
|
ownerEscalated: 'escalated the case owner',
|
|
79
79
|
external: 'made the case visible to customers',
|
|
80
80
|
};
|
|
81
|
-
export const DEFAULT_AVATAR_SRC = '
|
|
81
|
+
export const DEFAULT_AVATAR_SRC = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 36 36'%3E%3Crect width='36' height='36' fill='%23f0f0f0'/%3E%3Cpath fill='%23d2d2d2' d='M17.7 20.1c-3.5 0-6.4-2.9-6.4-6.4s2.9-6.4 6.4-6.4 6.4 2.9 6.4 6.4-2.8 6.4-6.4 6.4z'/%3E%3Cpath fill='%23d2d2d2' d='M30.6 36c-.4-3.9-1.3-9-2.9-11-1.1-1.4-2.3-2.2-3.5-2.6s-1.8-.6-6.3-.6-6.1.7-6.1.7c-1.2.4-2.4 1.2-3.4 2.6-1.7 1.9-2.6 7.1-3 10.9h25.2z'/%3E%3C/svg%3E";
|
|
82
82
|
const INTERNAL_USER_TYPE = 'Standard';
|
|
83
83
|
/**
|
|
84
84
|
* Only SF `UserType === 'Standard'` is treated as an internal (Red Hat) user.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rh-support/troubleshoot",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.44",
|
|
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.6.
|
|
56
|
-
"@rh-support/react-context": "2.6.
|
|
55
|
+
"@rh-support/components": "2.6.37",
|
|
56
|
+
"@rh-support/react-context": "2.6.39",
|
|
57
57
|
"@rh-support/types": "2.0.31",
|
|
58
|
-
"@rh-support/user-permissions": "2.6.
|
|
59
|
-
"@rh-support/utils": "2.6.
|
|
58
|
+
"@rh-support/user-permissions": "2.6.34",
|
|
59
|
+
"@rh-support/utils": "2.6.33",
|
|
60
60
|
"@types/react-redux": "^7.1.33",
|
|
61
61
|
"@types/redux": "^3.6.0",
|
|
62
62
|
"date-fns": "3.6.0",
|
|
@@ -129,5 +129,5 @@
|
|
|
129
129
|
"defaults and supports es6-module",
|
|
130
130
|
"maintained node versions"
|
|
131
131
|
],
|
|
132
|
-
"gitHead": "
|
|
132
|
+
"gitHead": "8485d4e2b69d16341bf9012dc195faca15b273aa"
|
|
133
133
|
}
|