@rh-support/troubleshoot 2.2.188 → 2.2.189

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":"CaseInternalStatus.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseInternalStatus.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAQpE,MAAM,CAAC,OAAO,UAAU,kBAAkB,sBAwFzC"}
1
+ {"version":3,"file":"CaseInternalStatus.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDetails/CaseInternalStatus.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAQpE,MAAM,CAAC,OAAO,UAAU,kBAAkB,sBAyFzC"}
@@ -30,7 +30,8 @@ export default function CaseInternalStatus() {
30
30
  const globalMetadataDispatchContext = useContext(GlobalMetadataDispatchContext);
31
31
  const [isOpen, setIsOpen] = useState(false);
32
32
  const [selected, setSelected] = useState(internalStatus);
33
- const onToggleClick = () => {
33
+ const onToggleClick = (e) => {
34
+ e.stopPropagation();
34
35
  setIsOpen(!isOpen);
35
36
  };
36
37
  const toggle = (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: onToggleClick, isExpanded: isOpen, isDisabled: isIStatusUpdating, isFullWidth: true, className: "case-internal-status-selector-text" },
@@ -1 +1 @@
1
- {"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,YAAY,EAA0B,MAAM,yCAAyC,CAAC;AAa1G,OAAO,KAAoE,MAAM,OAAO,CAAC;AAsCzF,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;CAC5B;AAOD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBA4mBnD"}
1
+ {"version":3,"file":"CaseDiscussion.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseDiscussion/CaseDiscussion.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,YAAY,EAA0B,MAAM,yCAAyC,CAAC;AAa1G,OAAO,KAAoE,MAAM,OAAO,CAAC;AAsCzF,UAAU,MAAM;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,eAAe,EAAE,OAAO,CAAC;CAC5B;AAOD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,KAAK,EAAE,MAAM,qBA8mBnD"}
@@ -326,10 +326,12 @@ export default function CaseDiscussion(props) {
326
326
  }
327
327
  // eslint-disable-next-line react-hooks/exhaustive-deps
328
328
  }, [isPostingRemoteRequestCommentCompleted]);
329
- const onToggleClick = () => {
329
+ const onToggleClick = (e) => {
330
+ e.stopPropagation();
330
331
  setIsOpen(!isOpen);
331
332
  };
332
- const onSortToggleClick = () => {
333
+ const onSortToggleClick = (e) => {
334
+ e.stopPropagation();
333
335
  setIsSortOpen(!isSortOpen);
334
336
  };
335
337
  const onFilterSelect = (_event, prevOption) => {
@@ -12,6 +12,15 @@
12
12
  .timeline-empty::after {
13
13
  display: none;
14
14
  }
15
+ .timeline::before {
16
+ bottom: var(--timeline-bottom, 0px);
17
+ }
18
+
19
+ .right-node {
20
+ overflow: hidden;
21
+ text-overflow: ellipsis;
22
+ white-space: nowrap;
23
+ }
15
24
 
16
25
  .timeline::after {
17
26
  content: '';
@@ -25,7 +34,7 @@
25
34
 
26
35
  /* This value is calculated in timeline.tsx */
27
36
  bottom: calc(var(--timeline-bottom) + var(--timeline-bottom-offset, 18.35%));
28
- left: calc(15% + 15px);
37
+ left: calc(15% + 14.5px);
29
38
  transform: translateX(-50%);
30
39
  }
31
40
 
@@ -1 +1 @@
1
- {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AA0BxB,OAAO,KAAuD,MAAM,OAAO,CAAC;AA4P5E,QAAA,MAAM,QAAQ;;uBAwRb,CAAC;AACF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../../../../src/components/CaseEditView/Tabs/CaseHistory/Timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AA0BxB,OAAO,KAAsC,MAAM,OAAO,CAAC;AA8P3D,QAAA,MAAM,QAAQ;;uBAgUb,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -16,7 +16,7 @@ import globalDangerColor100 from '@patternfly/react-tokens/dist/js/global_danger
16
16
  import { format, fromUnixTime, isSameDay, parse } from 'date-fns';
17
17
  import debounce from 'lodash/debounce';
18
18
  import isEmpty from 'lodash/isEmpty';
19
- import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
19
+ import React, { useEffect, useRef, useState } from 'react';
20
20
  import { Trans, useTranslation } from 'react-i18next';
21
21
  const TimelineEvent = ({ date, text, side, user, useAvatar }) => {
22
22
  if (side === 'left') {
@@ -31,7 +31,7 @@ const TimelineEvent = ({ date, text, side, user, useAvatar }) => {
31
31
  React.createElement("div", { className: `contentTimeline content-${side}-history content-${side}-${user}` },
32
32
  React.createElement("p", { className: `content-time-${side}-history` }, text))));
33
33
  }
34
- return (React.createElement("div", { className: `${side}-node ${user}`, role: "complementary", "aria-label": `${user}'s timeline event content ` },
34
+ return (React.createElement("div", { className: `${side}-node ${user}`, role: "complementary", "aria-label": `${user}'s timeline event content` },
35
35
  React.createElement("div", { className: `contentTimeline content-${side}-history content-${side}-${user}` },
36
36
  React.createElement("h2", { className: `content-date-${side}-history` }, date),
37
37
  text && React.createElement("p", { className: `content-time-${side}-history` }, text))));
@@ -39,7 +39,7 @@ const TimelineEvent = ({ date, text, side, user, useAvatar }) => {
39
39
  const TimelineNode = React.forwardRef(({ leftEvent, rightEvent, user, useAvatar }, ref) => {
40
40
  return (React.createElement("div", { className: "timeline-node", role: "region", "aria-label": "Timeline node" },
41
41
  leftEvent && React.createElement(TimelineEvent, Object.assign({}, leftEvent, { side: "left", useAvatar: useAvatar })),
42
- React.createElement("div", { ref: ref, "aria-label": `${useAvatar ? 'User profile picture' : 'Timeline marker'}`, tabIndex: 0 }, useAvatar ? (React.createElement(Avatar, { src: 'https://www.patternfly.org/images/668560cd.svg', className: `timeline-avatar timeline-avatar-${user}`, alt: `${user}'s avatar` })) : (React.createElement("div", { className: `timeline-marker timeline-${user}` }))),
42
+ React.createElement("div", { ref: ref, "aria-label": `${useAvatar ? 'User profile picture' : 'Timeline marker'}`, tabIndex: -1 }, useAvatar ? (React.createElement(Avatar, { src: 'https://www.patternfly.org/images/668560cd.svg', className: `timeline-avatar timeline-avatar-${user}`, alt: `${user}'s avatar` })) : (React.createElement("div", { className: `timeline-marker timeline-${user}` }))),
43
43
  rightEvent && React.createElement(TimelineEvent, Object.assign({}, rightEvent, { side: "right" }))));
44
44
  });
45
45
  //Handling changes in case fields to be displayed to the user
@@ -60,6 +60,7 @@ const applyReplacements = (item) => {
60
60
  Customer_Escalation__c: 'Customer Escalation',
61
61
  SlaStartDate: 'SLA Start Date',
62
62
  Case_Language__c: 'Case Language',
63
+ Alternate_Id__c: 'Personal reference number',
63
64
  };
64
65
  const languageCodeMapping = {
65
66
  de: 'German',
@@ -86,6 +87,7 @@ const applyReplacements = (item) => {
86
87
  'Case Group': 'caseGroup',
87
88
  'SLA Start Date': 'slaStartDate',
88
89
  'Case Language': 'caseLanguage',
90
+ Alternate_Id__c: 'Personal reference number',
89
91
  };
90
92
  const baseKey = keyMap[fieldName] || fieldName.replace(/\s/g, '');
91
93
  const key = `${baseKey}${prefix}Name`;
@@ -198,9 +200,10 @@ function stripHTML(htmlString) {
198
200
  const Timeline = ({ caseNumber }) => {
199
201
  const { t } = useTranslation();
200
202
  const [timelineEvents, setTimelineEvents] = useState([]);
203
+ const [originalTimelineEvents, setOriginalTimelineEvents] = useState([]);
201
204
  const [isFetchingData, setIsFetchingData] = useState();
202
205
  const lastNodeRef = useRef(null);
203
- const [dateValue, setDateValue] = React.useState('');
206
+ const [dateValue, setDateValue] = useState('');
204
207
  const [searchValue, setSearchValue] = useState('');
205
208
  const [filteredEvents, setFilteredEvents] = useState([]);
206
209
  const [isSelectOpen, setIsSelectOpen] = useState(false);
@@ -221,19 +224,21 @@ const Timeline = ({ caseNumber }) => {
221
224
  { title: '15', value: 15 },
222
225
  { title: '20', value: 20 },
223
226
  ], isCompact: true, variant: "top" }));
224
- const handleSelectToggle = () => {
227
+ const handleSelectToggle = (e) => {
228
+ e.preventDefault();
225
229
  setIsSelectOpen(!isSelectOpen);
226
230
  };
227
- const handleSelect = (_event, value) => {
228
- setSelectedOrder(value);
231
+ const handleSelect = (e, value) => {
232
+ e.preventDefault();
233
+ if (value !== selectedOrder) {
234
+ setSelectedOrder(value);
235
+ reorderTimelineEvents(value);
236
+ }
229
237
  setIsSelectOpen(false);
230
- reorderTimelineEvents(value);
231
238
  };
232
239
  const reorderTimelineEvents = (order) => {
233
- setTimelineEvents((prevEvents) => {
234
- const reversedEvents = [...prevEvents].reverse();
235
- return applyAvatarLogic(reversedEvents);
236
- });
240
+ const events = order === 'Newest to Oldest' ? [...originalTimelineEvents] : [...originalTimelineEvents].reverse();
241
+ setTimelineEvents(applyAvatarLogic(events));
237
242
  };
238
243
  const applyAvatarLogic = (events) => {
239
244
  let previousUser = null;
@@ -258,6 +263,7 @@ const Timeline = ({ caseNumber }) => {
258
263
  const response = yield caseHistory.getHistoryv1(caseNumber, options);
259
264
  const transformedData = transformApiResponseToTimelineData(response);
260
265
  setTimelineEvents(transformedData);
266
+ setOriginalTimelineEvents(transformedData);
261
267
  }
262
268
  catch (error) {
263
269
  console.error('Failed to fetch history:', error);
@@ -270,25 +276,48 @@ const Timeline = ({ caseNumber }) => {
270
276
  }
271
277
  fetchHistory();
272
278
  }, [caseNumber]);
273
- //Using useLayoutEffect because we are measuring styles based on DOM, useLayoutEffect runs after DOM Mutations https://react.dev/reference/react/useLayoutEffect
274
- useLayoutEffect(() => {
275
- const updateLineStyle = debounce(() => {
276
- var _a;
279
+ const futureDateValidator = (date) => {
280
+ const today = new Date();
281
+ today.setHours(0, 0, 0, 0); // Normalize to midnight
282
+ if (date > today) {
283
+ return 'Date cannot be in the future.';
284
+ }
285
+ return '';
286
+ };
287
+ const updateLineStyle = () => {
288
+ var _a;
289
+ const timelineElement = document.querySelector('.timeline');
290
+ if (timelineElement) {
277
291
  if (lastNodeRef.current) {
278
292
  const timelineBottom = lastNodeRef.current.getBoundingClientRect().bottom + window.scrollY;
279
- const timelineElement = document.querySelector('.timeline');
293
+ const timelineTop = timelineElement.getBoundingClientRect().top + window.scrollY;
280
294
  const avatarHeight = ((_a = lastNodeRef.current.querySelector('.timeline-avatar')) === null || _a === void 0 ? void 0 : _a.clientHeight) || 0;
281
- if (timelineElement) {
282
- const timelineTop = timelineElement.getBoundingClientRect().top + window.scrollY;
283
- const calculatedBottomValue = `${timelineTop + timelineElement.offsetHeight - timelineBottom + avatarHeight}px`;
284
- timelineElement.style.setProperty('--timeline-bottom', calculatedBottomValue);
285
- }
295
+ const calculatedBottomValue = `${timelineTop + timelineElement.offsetHeight - timelineBottom + avatarHeight}px`;
296
+ timelineElement.style.setProperty('--timeline-bottom', calculatedBottomValue);
286
297
  }
287
- }, 100);
288
- updateLineStyle();
289
- window.addEventListener('resize', updateLineStyle);
290
- return () => window.removeEventListener('resize', updateLineStyle);
291
- }, [timelineEvents, perPage, dateValue]);
298
+ else {
299
+ timelineElement.style.setProperty('--timeline-bottom', '0px');
300
+ }
301
+ }
302
+ };
303
+ //Using useLayoutEffect because we are measuring styles based on DOM, useLayoutEffect runs after DOM Mutations https://react.dev/reference/react/useLayoutEffect
304
+ useEffect(() => {
305
+ const debouncedUpdateLineStyle = debounce(updateLineStyle, 100);
306
+ window.addEventListener('resize', debouncedUpdateLineStyle);
307
+ if (!isFetchingData && filteredEvents.length > 0) {
308
+ requestAnimationFrame(() => {
309
+ updateLineStyle();
310
+ });
311
+ }
312
+ else {
313
+ // No events or still fetching, set --timeline-bottom to 0px
314
+ const timelineElement = document.querySelector('.timeline');
315
+ if (timelineElement) {
316
+ timelineElement.style.setProperty('--timeline-bottom', '0px');
317
+ }
318
+ }
319
+ return () => window.removeEventListener('resize', debouncedUpdateLineStyle);
320
+ }, [isFetchingData, filteredEvents, page, perPage]);
292
321
  const handleSearchChange = (value) => {
293
322
  setSearchValue(value.target.value);
294
323
  };
@@ -305,9 +334,10 @@ const Timeline = ({ caseNumber }) => {
305
334
  filteredBySearch = filteredBySearch.filter(({ left, right }) => {
306
335
  const dateString = left.date.toLowerCase();
307
336
  const timeString = left.text.toLowerCase();
337
+ const rightDateString = right.date.toLowerCase();
308
338
  return (dateString.includes(lowercasedFilter) ||
309
339
  timeString.includes(lowercasedFilter) ||
310
- right.date.toLowerCase().includes(lowercasedFilter));
340
+ rightDateString.includes(lowercasedFilter));
311
341
  });
312
342
  }
313
343
  let finalFilteredEvents = filteredBySearch;
@@ -319,6 +349,7 @@ const Timeline = ({ caseNumber }) => {
319
349
  });
320
350
  }
321
351
  setFilteredEvents(finalFilteredEvents);
352
+ setPage(1);
322
353
  }, [searchValue, dateValue, timelineEvents]);
323
354
  const handleReload = (e) => {
324
355
  e.preventDefault();
@@ -332,7 +363,6 @@ const Timeline = ({ caseNumber }) => {
332
363
  React.createElement(EmptyStateBody, null,
333
364
  React.createElement(Trans, null,
334
365
  "Try ",
335
- ' ',
336
366
  React.createElement("a", { href: "#", onClick: handleReload }, "reloading the page"),
337
367
  ' ',
338
368
  "or check back later"))));
@@ -343,18 +373,19 @@ const Timeline = ({ caseNumber }) => {
343
373
  React.createElement(EmptyStateBody, null,
344
374
  React.createElement(Trans, null, "Try modifying your search query or changing the date range and try again."))));
345
375
  }
346
- return (React.createElement(React.Fragment, null, filteredEvents.slice((page - 1) * perPage, page * perPage).map((node, index) => (React.createElement(TimelineNode, { key: index, leftEvent: node.left, rightEvent: node.right, user: node.right.user, useAvatar: node.right.useAvatar, ref: index === perPage - 1 ? lastNodeRef : null })))));
376
+ const paginatedEvents = filteredEvents.slice((page - 1) * perPage, page * perPage);
377
+ return (React.createElement(React.Fragment, null, paginatedEvents.map((node, index) => (React.createElement(TimelineNode, { key: index, leftEvent: node.left, rightEvent: node.right, user: node.right.user, useAvatar: node.right.useAvatar, ref: index === paginatedEvents.length - 1 ? lastNodeRef : null })))));
347
378
  };
348
379
  return (React.createElement(React.Fragment, null,
349
380
  React.createElement("div", { className: "timelineMenu" },
350
381
  React.createElement(SearchInput, { placeholder: t('Search for a user, action, or keyword'), value: searchValue, onChange: handleSearchChange, onClear: handleClear, className: "case-history-timeline-search" }),
351
382
  React.createElement("div", { className: "case-history-timeline-datepicker" },
352
- React.createElement(DatePicker, { value: dateValue, onChange: (_event, value) => handleDateChange(value) }),
383
+ React.createElement(DatePicker, { value: dateValue, onChange: (_event, value) => handleDateChange(value), validators: [futureDateValidator] }),
353
384
  React.createElement(Button, { onClick: () => setDateValue(''), isDisabled: isEmpty(dateValue) }, "Reset"))),
354
385
  React.createElement("div", { className: "timeline-controls" },
355
386
  React.createElement("div", { className: "timeline-pagination" }, renderPagination()),
356
387
  React.createElement("div", { className: "timeline-sort-order-select" },
357
- React.createElement(Select, { id: "order-select", isOpen: isSelectOpen, selected: selectedOrder, onSelect: handleSelect, onOpenChange: (isOpen) => setIsSelectOpen(isOpen), toggle: (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: handleSelectToggle, isExpanded: isSelectOpen, style: { width: '200px' } }, selectedOrder)), shouldFocusToggleOnSelect: true },
388
+ React.createElement(Select, { id: "order-select", isOpen: isSelectOpen, selected: selectedOrder, onSelect: handleSelect, onOpenChange: (isOpen) => setIsSelectOpen(isOpen), shouldFocusToggleOnSelect: false, toggle: (toggleRef) => (React.createElement(MenuToggle, { ref: toggleRef, onClick: handleSelectToggle, isExpanded: isSelectOpen, style: { width: '200px' } }, selectedOrder)) },
358
389
  React.createElement(SelectOption, { value: "Newest to Oldest" }, "Newest to Oldest"),
359
390
  React.createElement(SelectOption, { value: "Oldest to Newest" }, "Oldest to Newest")))),
360
391
  isFetchingData ? (React.createElement("div", { className: "timeline-loading-spinner" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/troubleshoot",
3
- "version": "2.2.188",
3
+ "version": "2.2.189",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org"
@@ -60,11 +60,11 @@
60
60
  "@progress/kendo-licensing": "1.3.5",
61
61
  "@progress/kendo-react-pdf": "^5.16.0",
62
62
  "@redux-devtools/extension": "^3.3.0",
63
- "@rh-support/components": "2.1.90",
64
- "@rh-support/react-context": "2.1.99",
63
+ "@rh-support/components": "2.1.91",
64
+ "@rh-support/react-context": "2.1.100",
65
65
  "@rh-support/types": "2.0.5",
66
- "@rh-support/user-permissions": "2.1.55",
67
- "@rh-support/utils": "2.1.44",
66
+ "@rh-support/user-permissions": "2.1.56",
67
+ "@rh-support/utils": "2.1.45",
68
68
  "date-fns": "^4.1.0",
69
69
  "dompurify": "^2.2.6",
70
70
  "dot": "^1.1.3",
@@ -134,5 +134,5 @@
134
134
  "defaults and supports es6-module",
135
135
  "maintained node versions"
136
136
  ],
137
- "gitHead": "6f241c61742b1a72ccc831ab45b267c163ea1284"
137
+ "gitHead": "672881ff1c4cabf0dee016387c49f6abbdc952a7"
138
138
  }