@rh-support/troubleshoot 2.6.49 → 2.6.57

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.
@@ -80,7 +80,7 @@ function CasePrivateNotes(props) {
80
80
  canUpdatePrivateNotes && (React.createElement("form", null,
81
81
  React.createElement(TextAreaResizable, { style: { minHeight: '200px' }, id: "rha-case-notes", disabled: isUpdating, maxLength: 255, name: "notes", value: notesState, onChange: onChange }),
82
82
  React.createElement("div", { className: "pf-v6-u-mt-md" },
83
- React.createElement(Button, { className: `${isExportingPDF ? 'hide-in-pdf' : ''}`, onClick: updateCase, disabled: isPrivateNotesEmpty || isUpdating || !formIsDirty, variant: "primary" },
83
+ React.createElement(Button, { className: `${isExportingPDF ? 'hide-in-pdf' : ''}`, onClick: updateCase, isDisabled: isPrivateNotesEmpty || isUpdating || !formIsDirty, variant: "primary" },
84
84
  React.createElement(Trans, null, "Update"),
85
85
  " ",
86
86
  React.createElement(LoadingIndicator, { show: isUpdating, isInline: true })),
@@ -2,6 +2,6 @@ import React from 'react';
2
2
  interface IProps {
3
3
  onChatWithAIClick?: () => void;
4
4
  }
5
- export declare const AskRedHat: React.FC<IProps>;
5
+ export declare const AskRedHat: ({ onChatWithAIClick }: IProps) => React.JSX.Element;
6
6
  export {};
7
7
  //# sourceMappingURL=AskRedHat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AskRedHat.d.ts","sourceRoot":"","sources":["../../../../src/components/TroubleshootSection/AskRedHat.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAa5D,UAAU,MAAM;IACZ,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,CAwTtC,CAAC"}
1
+ {"version":3,"file":"AskRedHat.d.ts","sourceRoot":"","sources":["../../../../src/components/TroubleshootSection/AskRedHat.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAgC5D,UAAU,MAAM;IACZ,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;CAClC;AAED,eAAO,MAAM,SAAS,0BAA2B,MAAM,sBAuZtD,CAAC"}
@@ -7,20 +7,39 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { Env } from '@cee-eng/hydrajs';
10
+ import { Env, pcm } from '@cee-eng/hydrajs';
11
11
  import { sendRHDirectMessageFeedback } from '@ifd-ui/ask-redhat-core';
12
- import { Button, Card, CardBody, CardHeader, Modal, ModalVariant, Spinner } from '@patternfly/react-core';
12
+ import { Button, Card, CardBody, CardHeader, Content, ContentVariants, EmptyState, EmptyStateBody, EmptyStateFooter, EmptyStateVariant, Icon, Modal, ModalVariant, Skeleton, Spinner, } from '@patternfly/react-core';
13
+ import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
14
+ import { useFetch } from '@rh-support/components';
15
+ import isEqual from 'lodash/isEqual';
13
16
  import React, { useContext, useRef, useState } from 'react';
14
17
  import { MODAL_MESSAGES, QUICK_RESPONSES, TOOLTIP_MESSAGES } from '../../constants/askRedHatMessages';
15
18
  import { useAIResponseState } from '../../context/AIResponseContext';
19
+ import { useCaseSelector } from '../../context/CaseContext';
16
20
  import { RouteContext } from '../../context/RouteContext';
21
+ import { SessionRestoreDispatchContext, SessionRestoreStateContext } from '../../context/SessionRestoreContext';
22
+ import { useARHResponse } from '../../hooks/useARHResponse';
17
23
  import { useParseRuleMarkdown } from '../../hooks/useParseRuleMarkdown';
18
24
  import { appSourceId_ARH } from '../../reducers/CaseConstNTypes';
25
+ import { createOrUpdateSessionResources } from '../../reducers/SessionRestoreReducer';
19
26
  import { CollapseIcon } from './icons/CollapseIcon';
20
27
  import { StarIcon } from './icons/StarIcon';
21
28
  import ResponseActions from './ResponseActions';
22
29
  import UserFeedback from './UserFeedback';
23
30
  import UserFeedbackComplete from './UserFeedbackComplete';
31
+ const { SessionResourceSource, SessionResourceVisibility } = pcm.preCase.session;
32
+ const getSessResFromARHSource = (source, visibilityStatus, rank = 1) => ({
33
+ visibilityStatus,
34
+ resourceEntityId: source.id,
35
+ url: source.link || source.url,
36
+ rank,
37
+ });
38
+ const getSessResFromAISources = (sources, visibilityStatus) => {
39
+ if (!sources || sources.length === 0)
40
+ return [];
41
+ return sources.map((source, index) => getSessResFromARHSource(source, visibilityStatus, index + 1));
42
+ };
24
43
  export const AskRedHat = ({ onChatWithAIClick }) => {
25
44
  var _a, _b, _c;
26
45
  const [isExpanded, setIsExpanded] = useState(false);
@@ -31,14 +50,70 @@ export const AskRedHat = ({ onChatWithAIClick }) => {
31
50
  const [isSubmittingFeedback, setIsSubmittingFeedback] = useState(false);
32
51
  const aiResponseState = useAIResponseState();
33
52
  const contentRef = useRef(null);
34
- const { routeState: { isCaseCreate }, } = useContext(RouteContext);
53
+ const { routeState: { isCaseCreate, activeSection }, } = useContext(RouteContext);
54
+ const { sessionRestore: { activeSessionId, sessionResourceTracking }, } = useContext(SessionRestoreStateContext);
55
+ const sessionRestoreDispatch = useContext(SessionRestoreDispatchContext);
56
+ const { product, version, summary, issue, caseType } = useCaseSelector((state) => ({
57
+ product: state.caseDetails.product,
58
+ version: state.caseDetails.version,
59
+ summary: state.caseDetails.summary,
60
+ issue: state.caseDetails.issue,
61
+ caseType: state.caseDetails.caseType,
62
+ }), isEqual);
63
+ const { request: updateSessionOrigin } = useFetch(pcm.preCase.session.updateSessionOrigin);
64
+ const config = {
65
+ appSourceId: appSourceId_ARH,
66
+ authToken: (_b = (_a = window === null || window === void 0 ? void 0 : window.sessionjs) === null || _a === void 0 ? void 0 : _a.getEncodedToken()) !== null && _b !== void 0 ? _b : '',
67
+ packageVersion: (_c = window === null || window === void 0 ? void 0 : window.supportVersionInfo) === null || _c === void 0 ? void 0 : _c.packageVersion,
68
+ appEnv: Env.getEnvName(),
69
+ };
70
+ const { fetchARHResponse } = useARHResponse({
71
+ activeSection,
72
+ product,
73
+ version,
74
+ summary,
75
+ issue,
76
+ caseType,
77
+ config,
78
+ });
35
79
  const onToggle = () => {
36
80
  if (isExpanded && contentRef.current) {
37
81
  contentRef.current.scrollTop = 0;
38
82
  }
83
+ if (!isExpanded) {
84
+ const payload = JSON.stringify({
85
+ product,
86
+ version,
87
+ summary,
88
+ issue,
89
+ });
90
+ const sessionResources = getSessResFromAISources(sources || [], SessionResourceVisibility.PRESENTED);
91
+ createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.ASK_RED_HAT, sessionResources, payload);
92
+ }
39
93
  setIsExpanded((prev) => !prev);
40
94
  };
41
- const handleChatWithAIClick = () => onChatWithAIClick === null || onChatWithAIClick === void 0 ? void 0 : onChatWithAIClick();
95
+ const handleChatWithAIClick = () => __awaiter(void 0, void 0, void 0, function* () {
96
+ var _a;
97
+ onChatWithAIClick === null || onChatWithAIClick === void 0 ? void 0 : onChatWithAIClick();
98
+ if (updateSessionOrigin) {
99
+ yield updateSessionOrigin(activeSessionId, {
100
+ id: (_a = sessionResourceTracking[SessionResourceSource.ASK_RED_HAT]) === null || _a === void 0 ? void 0 : _a.resourceOriginId,
101
+ aiChatStarted: true,
102
+ });
103
+ }
104
+ });
105
+ const handleSourceClick = (source, index) => () => {
106
+ if (!source || !activeSessionId)
107
+ return;
108
+ const payload = JSON.stringify({
109
+ product,
110
+ version,
111
+ summary,
112
+ issue,
113
+ });
114
+ const sessionResource = getSessResFromARHSource(source, SessionResourceVisibility.VISITED, index + 1);
115
+ createOrUpdateSessionResources(sessionRestoreDispatch, activeSessionId, sessionResourceTracking, SessionResourceSource.ASK_RED_HAT, [sessionResource], payload);
116
+ };
42
117
  const aiResponse = aiResponseState.aiResponse;
43
118
  const messageId = aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.messageId;
44
119
  const conversationId = aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.conversationId;
@@ -46,24 +121,18 @@ export const AskRedHat = ({ onChatWithAIClick }) => {
46
121
  const answer = aiResponseState.isStreaming && aiResponseState.accumulatedResponse
47
122
  ? aiResponseState.accumulatedResponse
48
123
  : (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.answer) || (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.content) || 'No AI response available yet.';
49
- const sources = (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.sources) || (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.references) || [];
124
+ const sources = React.useMemo(() => (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.sources) || (aiResponse === null || aiResponse === void 0 ? void 0 : aiResponse.references) || [], [aiResponse]);
50
125
  const sourcesCount = sources.length || 0;
51
126
  // Show loading only when streaming has started but no content received yet
52
127
  const isLoading = aiResponseState.isStreaming && aiResponseState.accumulatedResponse === '';
53
128
  const isStreaming = aiResponseState.isStreaming;
54
129
  const { parseMarkdown } = useParseRuleMarkdown();
55
- const config = {
56
- appSourceId: appSourceId_ARH,
57
- packageVersion: (_a = window === null || window === void 0 ? void 0 : window.supportVersionInfo) === null || _a === void 0 ? void 0 : _a.packageVersion,
58
- authToken: (_c = (_b = window === null || window === void 0 ? void 0 : window.sessionjs) === null || _b === void 0 ? void 0 : _b.getEncodedToken()) !== null && _c !== void 0 ? _c : '',
59
- appEnv: Env.getEnvName(),
60
- };
61
130
  const handleFeedbackSubmit = (selectedResponse, additionalFeedback) => __awaiter(void 0, void 0, void 0, function* () {
62
131
  setIsSubmittingFeedback(true);
63
132
  try {
64
133
  const payload = {
65
134
  rating: (feedbackType === 'positive' ? 'positive' : 'negative'),
66
- freeform: additionalFeedback || undefined,
135
+ freeform: additionalFeedback || '',
67
136
  predefined_response: selectedResponse || '',
68
137
  };
69
138
  yield sendRHDirectMessageFeedback(conversationId, messageId, payload, config);
@@ -91,15 +160,32 @@ export const AskRedHat = ({ onChatWithAIClick }) => {
91
160
  navigator.clipboard.writeText(answer);
92
161
  } }, TOOLTIP_MESSAGES.copy),
93
162
  };
163
+ if (aiResponseState.error) {
164
+ return (React.createElement("div", { className: "ask-redhat" },
165
+ React.createElement("p", { className: "ask-redhat-title" },
166
+ React.createElement(StarIcon, { width: 20, height: 20 }),
167
+ "Resolve your issue now with AI insights"),
168
+ React.createElement("div", { className: "ask-redhat-content-wrapper ask-redhat-error" },
169
+ React.createElement(EmptyState, { variant: EmptyStateVariant.xs, titleText: "", headingLevel: "h4" },
170
+ React.createElement("h4", null,
171
+ React.createElement(Icon, { iconSize: "lg", status: "danger", className: "pf-v6-u-mr-sm" },
172
+ React.createElement(ExclamationCircleIcon, null)),
173
+ ' ',
174
+ "Error while loading AI insights"),
175
+ React.createElement(EmptyStateBody, null,
176
+ React.createElement(Content, { component: ContentVariants.p }, "AI insights is currently unavailable, try reloading.")),
177
+ React.createElement(EmptyStateFooter, null,
178
+ React.createElement(Button, { variant: "tertiary", size: "sm", onClick: fetchARHResponse }, "Reload"))))));
179
+ }
94
180
  if (isLoading) {
95
181
  return (React.createElement("div", { className: "ask-redhat" },
96
182
  React.createElement("p", { className: "ask-redhat-title" },
97
183
  React.createElement(StarIcon, { width: 20, height: 20 }),
98
184
  isCaseCreate ? 'Resolve your issue now with AI insights' : 'Troubleshoot with AI insights'),
99
185
  React.createElement("div", { className: "ask-redhat-content-wrapper" },
100
- React.createElement("div", { className: "ask-redhat-content", style: { textAlign: 'center', padding: '2rem' } },
101
- React.createElement(Spinner, { size: "lg" }),
102
- React.createElement("p", { style: { marginTop: '1rem' } }, "Getting AI insights..."))),
186
+ React.createElement("div", { className: "pf-v6-u-display-flex pf-v6-u-flex-direction-column pf-v6-u-justify-content-space-between" }, [...Array(3)].map((_, i) => (React.createElement("div", { className: "pf-v6-u-mb-sm", key: `AI-insights-loading-${i}` },
187
+ React.createElement(Skeleton, { width: "100%", screenreaderText: "Getting AI insights..." }),
188
+ React.createElement("br", null)))))),
103
189
  !aiResponseState.isStreaming && (React.createElement("div", { className: "ask-redhat-toggle-button" },
104
190
  React.createElement(Button, { variant: "link", onClick: handleChatWithAIClick, className: "ask-redhat-chat-button" }, "Chat with AI to get started")))));
105
191
  }
@@ -123,16 +209,6 @@ export const AskRedHat = ({ onChatWithAIClick }) => {
123
209
  isExpanded ? React.createElement(CollapseIcon, null) : React.createElement(StarIcon, { width: 20, height: 20 }),
124
210
  isExpanded ? '' : 'Read more'))));
125
211
  }
126
- if (aiResponseState.error) {
127
- return (React.createElement("div", { className: "ask-redhat" },
128
- React.createElement("p", { className: "ask-redhat-title" },
129
- React.createElement(StarIcon, { width: 20, height: 20 }),
130
- "Resolve your issue now with AI insights"),
131
- React.createElement("div", { className: "ask-redhat-content-wrapper" },
132
- React.createElement("div", { className: "ask-redhat-content", style: { textAlign: 'center', padding: '2rem' } },
133
- React.createElement("p", { style: { color: '#d73502', marginBottom: '1rem' } }, "Unable to get AI insights. Please try again later."),
134
- React.createElement(Button, { variant: "link", onClick: handleChatWithAIClick, className: "ask-redhat-chat-button", icon: React.createElement(StarIcon, null) }, "Try again with AI Chat")))));
135
- }
136
212
  return (React.createElement("div", { className: "ask-redhat" },
137
213
  React.createElement("p", { className: "ask-redhat-title" },
138
214
  React.createElement(StarIcon, { width: 20, height: 20 }),
@@ -147,7 +223,7 @@ export const AskRedHat = ({ onChatWithAIClick }) => {
147
223
  React.createElement("div", { className: "ask-redhat-cards" }, sources.map((source, index) => (React.createElement(Card, { className: "ask-redhat-card", key: index },
148
224
  React.createElement(CardHeader, null,
149
225
  React.createElement("h3", { className: "ask-redhat-card-title" },
150
- React.createElement("a", { href: source.link, target: "_blank", rel: "noopener noreferrer" }, source.title))),
226
+ React.createElement("a", { href: source.link, target: "_blank", rel: "noopener noreferrer", onClick: handleSourceClick(source, index) }, source.title))),
151
227
  React.createElement(CardBody, null,
152
228
  React.createElement("p", null, source.snippet)))))))),
153
229
  React.createElement("div", { className: "response-actions-wrapper" },
@@ -1 +1 @@
1
- {"version":3,"file":"TroubleshootSection.d.ts","sourceRoot":"","sources":["../../../../src/components/TroubleshootSection/TroubleshootSection.tsx"],"names":[],"mappings":"AAAA,OAAO,6CAA6C,CAAC;AAUrD,OAAO,KAAqB,MAAM,OAAO,CAAC;AAc1C,UAAU,MAAM;IACZ,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4BAA4B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAUD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,qBAgLzC;kBAhLQ,mBAAmB;;;AAmL5B,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"TroubleshootSection.d.ts","sourceRoot":"","sources":["../../../../src/components/TroubleshootSection/TroubleshootSection.tsx"],"names":[],"mappings":"AAAA,OAAO,6CAA6C,CAAC;AAUrD,OAAO,KAA6B,MAAM,OAAO,CAAC;AAclD,UAAU,MAAM;IACZ,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4BAA4B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAUD,iBAAS,mBAAmB,CAAC,KAAK,EAAE,MAAM,qBAuLzC;kBAvLQ,mBAAmB;;;AA0L5B,eAAe,mBAAmB,CAAC"}
@@ -16,7 +16,7 @@ import { ErrorBoundary, LoadingDots } from '@rh-support/components';
16
16
  import { PreviousCaseTypes } from '@rh-support/utils';
17
17
  import isEmpty from 'lodash/isEmpty';
18
18
  import isEqual from 'lodash/isEqual';
19
- import React, { useContext } from 'react';
19
+ import React, { useContext, useRef } from 'react';
20
20
  import { Trans, useTranslation } from 'react-i18next';
21
21
  import { useAIResponseState } from '../../context/AIResponseContext';
22
22
  import { useCaseSelector } from '../../context/CaseContext';
@@ -40,6 +40,7 @@ function TroubleshootSection(props) {
40
40
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
41
41
  const { t } = useTranslation();
42
42
  const { aiServicesAvailable, isAIChatMode, setIsAIChatMode, onChatWithAIClick } = props;
43
+ const refetchControlReady = useRef(null);
43
44
  const { topContentState: { topContent }, } = useContext(TCStateContext);
44
45
  const { routeState: { isCaseCreate }, } = useContext(RouteContext);
45
46
  const aiResponseState = useAIResponseState();
@@ -58,7 +59,6 @@ function TroubleshootSection(props) {
58
59
  const isNotAnIdea = caseType !== PreviousCaseTypes.FEATURE_ENHANCEMENT;
59
60
  const shouldShowARHUI = () => {
60
61
  // Check if the case type is allowed (not in the excluded list)
61
- // test
62
62
  const isCaseTypeAllowed = !excludedCaseTypesforARH.includes(caseType !== null && caseType !== void 0 ? caseType : '');
63
63
  // Check if user is not a secure support or confirmed stateside support user
64
64
  const isNotSecureOrStatesideUser = !props.isSecureSupport && !props.hasConfirmedStatesideSupport;
@@ -67,8 +67,10 @@ function TroubleshootSection(props) {
67
67
  return isCaseTypeAllowed && isNotSecureOrStatesideUser && isAIServicesAvailable;
68
68
  };
69
69
  const handleInitialized = (success, error) => {
70
+ var _a;
70
71
  if (success) {
71
72
  console.log('Chat initialized successfully');
73
+ (_a = refetchControlReady.current) === null || _a === void 0 ? void 0 : _a.refetch();
72
74
  }
73
75
  else {
74
76
  console.error('Chat initialization failed:', error);
@@ -119,6 +121,13 @@ function TroubleshootSection(props) {
119
121
  },
120
122
  },
121
123
  onInitialized: handleInitialized,
124
+ onUnauthenticatedLogin: () => {
125
+ var _a, _b;
126
+ (_b = (_a = window === null || window === void 0 ? void 0 : window.sessionjs) === null || _a === void 0 ? void 0 : _a.login) === null || _b === void 0 ? void 0 : _b.call(_a);
127
+ },
128
+ onRefetchControlReady: (refetchControl) => {
129
+ refetchControlReady.current = refetchControl;
130
+ },
122
131
  };
123
132
  const handleChatWithAIClick = () => {
124
133
  setIsAIChatMode(true);
@@ -146,7 +146,7 @@ function WidgetFileUploader(props) {
146
146
  }
147
147
  }
148
148
  });
149
- return (React.createElement(Card, { id: "file-uploader-card", className: "file-diag", onPaste: handlePaste },
149
+ return (React.createElement(Card, { id: "file-uploader-card", className: "file-diag pf-v6-u-mb-lg", onPaste: handlePaste },
150
150
  React.createElement(CardHeader, { "aria-label": t('File uploader') },
151
151
  React.createElement("h3", { id: "file-uploader-title" }, props.isIdea || props.isSecureSupport ? (React.createElement(Trans, null, "File uploader")) : (React.createElement(Trans, null, "Upload a file for Red Hat to analyze")))),
152
152
  React.createElement(CardBody, { "aria-label": t('File upload area'), className: "file-upload-body" },
@@ -1,6 +1,9 @@
1
1
  import React, { Dispatch, SetStateAction } from 'react';
2
2
  import { RouteComponentProps } from 'react-router-dom';
3
3
  import { IRouteUrlParams } from '../../reducers/RouteConstNTypes';
4
+ export declare const getCaseTypeAIText: (caseType: string) => string;
5
+ export declare const generateCaseTypePrefix: (activeSection: string, caseType: string, lang: string) => string;
6
+ export declare const generateAIQuestion: (activeSection: string, product: string | undefined, version: string | undefined, summary: string | undefined, issue: string | undefined, caseType: string, lang: string) => string;
4
7
  interface IProps {
5
8
  routeProps: RouteComponentProps<IRouteUrlParams>;
6
9
  submitCaseAndNavigate: (isReSubmitting: boolean) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"WizardMain.d.ts","sourceRoot":"","sources":["../../../../src/components/wizardLayout/WizardMain.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAqD,MAAM,OAAO,CAAC;AAE3G,OAAO,EAAS,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAe9D,OAAO,EAAoB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AA0FpF,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,qBAAqB,EAAE,CAAC,cAAc,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,mBAAmB,EAAE,CAAC,gCAAgC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,iBAAS,UAAU,CAAC,KAAK,EAAE,MAAM,qBA2XhC;AACD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"WizardMain.d.ts","sourceRoot":"","sources":["../../../../src/components/wizardLayout/WizardMain.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAqD,MAAM,OAAO,CAAC;AAE3G,OAAO,EAAS,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAW9D,OAAO,EAAoB,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAcpF,eAAO,MAAM,iBAAiB,aAAc,MAAM,KAAG,MAEpD,CAAC;AAEF,eAAO,MAAM,sBAAsB,kBAAmB,MAAM,YAAY,MAAM,QAAQ,MAAM,KAAG,MAqB9F,CAAC;AAGF,eAAO,MAAM,kBAAkB,kBACZ,MAAM,WACZ,MAAM,GAAG,SAAS,WAClB,MAAM,GAAG,SAAS,WAClB,MAAM,GAAG,SAAS,SACpB,MAAM,GAAG,SAAS,YACf,MAAM,QACV,MAAM,KACb,MAwCF,CAAC;AACF,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,qBAAqB,EAAE,CAAC,cAAc,EAAE,OAAO,KAAK,IAAI,CAAC;IACzD,mBAAmB,EAAE,CAAC,gCAAgC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,iBAAS,UAAU,CAAC,KAAK,EAAE,MAAM,qBAmWhC;AACD,eAAe,UAAU,CAAC"}
@@ -19,24 +19,25 @@ var __rest = (this && this.__rest) || function (s, e) {
19
19
  return t;
20
20
  };
21
21
  import { Env } from '@cee-eng/hydrajs';
22
- import { askRHDirectAIResponse, getRHDirectStatusCheck, } from '@ifd-ui/ask-redhat-core';
22
+ import { getRHDirectHealthCheck, getRHDirectStatusCheck, } from '@ifd-ui/ask-redhat-core';
23
23
  import { Wizard, WizardNav, WizardNavItem, WizardStep, } from '@patternfly/react-core';
24
24
  import { LoadingIndicator } from '@rh-support/components';
25
- import i18n from 'i18next';
26
25
  import isEqual from 'lodash/isEqual';
27
26
  import React, { Suspense, useContext, useEffect, useRef, useState } from 'react';
28
27
  import { useTranslation } from 'react-i18next';
29
28
  import { Route } from 'react-router-dom';
30
- import { useAIResponseDispatch, useAIResponseState } from '../../context/AIResponseContext';
31
29
  import { useCaseSelector } from '../../context/CaseContext';
32
30
  import { RecommendationDispatchContext } from '../../context/RecommendationContext';
33
31
  import { RouteContext, RouteDispatchContext } from '../../context/RouteContext';
32
+ import { SessionRestoreDispatchContext, SessionRestoreStateContext } from '../../context/SessionRestoreContext';
33
+ import { useARHResponse } from '../../hooks/useARHResponse';
34
34
  import { useWizard } from '../../hooks/useWizard';
35
- import { streamingChunkReceived, streamingCompleted, streamingError, streamingStarted, } from '../../reducers/AIResponseReducer';
36
35
  import { appSourceId_ARH, excludedCaseTypesforARH } from '../../reducers/CaseConstNTypes';
36
+ import { getSessionDetailsFromCase } from '../../reducers/CaseHelpers';
37
37
  import { RecommendationsConstants } from '../../reducers/RecommendationsReducer';
38
38
  import { AppRouteSections } from '../../reducers/RouteConstNTypes';
39
39
  import { setActiveSectionChanged, updateisNextBtnClickedToShowValidationError } from '../../reducers/RouteReducer';
40
+ import { updateSession } from '../../reducers/SessionRestoreReducer';
40
41
  import RouteUtils from '../../utils/routeUtils';
41
42
  import SubmitCase from '../SubmitCase/SubmitCase';
42
43
  import MainSection from './MainSection';
@@ -46,10 +47,10 @@ import WizardNavigation from './WizardNavigation';
46
47
  const CASE_TYPE_AI_TEXT_MAP = {
47
48
  Other: 'Something',
48
49
  };
49
- const getCaseTypeAIText = (caseType) => {
50
+ export const getCaseTypeAIText = (caseType) => {
50
51
  return CASE_TYPE_AI_TEXT_MAP[caseType] || caseType;
51
52
  };
52
- const generateCaseTypePrefix = (activeSection, caseType, lang) => {
53
+ export const generateCaseTypePrefix = (activeSection, caseType, lang) => {
53
54
  if (activeSection === AppRouteSections.TROUBLESHOOT) {
54
55
  return '';
55
56
  }
@@ -69,7 +70,7 @@ const generateCaseTypePrefix = (activeSection, caseType, lang) => {
69
70
  return helpWithMap[lang] || helpWithMap.en;
70
71
  };
71
72
  // Generate AI question based on case details
72
- const generateAIQuestion = (activeSection, product, version, summary, issue, caseType, lang) => {
73
+ export const generateAIQuestion = (activeSection, product, version, summary, issue, caseType, lang) => {
73
74
  const baseMessageMap = {
74
75
  en: `My issue is primarily related to ${product !== null && product !== void 0 ? product : ''} ${version !== null && version !== void 0 ? version : ''}. I would title my problem: ${summary !== null && summary !== void 0 ? summary : ''}. More details are as follows: ${issue !== null && issue !== void 0 ? issue : ''}.`,
75
76
  de: `Mein Problem hängt hauptsächlich mit ${product !== null && product !== void 0 ? product : ''} ${version !== null && version !== void 0 ? version : ''} zusammen. Ich würde mein Problem so betiteln: ${summary !== null && summary !== void 0 ? summary : ''}. Weitere Details sind wie folgt: ${issue !== null && issue !== void 0 ? issue : ''}.`,
@@ -90,16 +91,29 @@ function WizardMain(props) {
90
91
  const [showRestFlag, setShowRestFlag] = useState(false);
91
92
  const [aiServicesAvailable, setAIServicesAvailable] = useState(false); // default to false until services are confirmed available
92
93
  const recommendationDispatch = useContext(RecommendationDispatchContext);
93
- const { isCreatingCase, product, version, summary, issue, caseType } = useCaseSelector((state) => ({
94
+ const sessionRestoreDispatch = useContext(SessionRestoreDispatchContext);
95
+ const { sessionRestore } = useContext(SessionRestoreStateContext);
96
+ const { isCreatingCase, caseDetails, selectedNotificationContacts } = useCaseSelector((state) => ({
94
97
  isCreatingCase: state.isCreatingCase,
95
- product: state.caseDetails.product,
96
- version: state.caseDetails.version,
97
- summary: state.caseDetails.summary,
98
- issue: state.caseDetails.issue,
99
- caseType: state.caseDetails.caseType,
98
+ caseDetails: state.caseDetails,
99
+ selectedNotificationContacts: state.selectedNotificationContacts,
100
100
  }), isEqual);
101
101
  const { routeState: { isCaseCreate, activeSection }, } = useContext(RouteContext);
102
- const aiResponseDispatch = useAIResponseDispatch();
102
+ const config = {
103
+ appSourceId: appSourceId_ARH,
104
+ authToken: (_b = (_a = window === null || window === void 0 ? void 0 : window.sessionjs) === null || _a === void 0 ? void 0 : _a.getEncodedToken()) !== null && _b !== void 0 ? _b : '',
105
+ packageVersion: (_c = window === null || window === void 0 ? void 0 : window.supportVersionInfo) === null || _c === void 0 ? void 0 : _c.packageVersion,
106
+ appEnv: Env.getEnvName(),
107
+ };
108
+ const { fetchARHResponse } = useARHResponse({
109
+ activeSection,
110
+ product: caseDetails.product,
111
+ version: caseDetails.version,
112
+ summary: caseDetails.summary,
113
+ issue: caseDetails.issue,
114
+ caseType: caseDetails.caseType,
115
+ config,
116
+ });
103
117
  const isTroubleshootSection = activeSection === AppRouteSections.TROUBLESHOOT;
104
118
  const isResourcesSection = activeSection === AppRouteSections.RESOURCES;
105
119
  const isSummarizeSection = activeSection === AppRouteSections.SUMMARIZE;
@@ -112,10 +126,10 @@ function WizardMain(props) {
112
126
  const isBackButtonClickedRef = useRef(false);
113
127
  const resultsRowRef = useRef(null);
114
128
  const previousARHFieldsRef = useRef({
115
- product: product,
116
- version: version,
117
- summary: summary,
118
- issue: issue,
129
+ product: caseDetails.product,
130
+ version: caseDetails.version,
131
+ summary: caseDetails.summary,
132
+ issue: caseDetails.issue,
119
133
  });
120
134
  const handleChatWithAIClick = () => {
121
135
  props.setIsAIChatMode(true);
@@ -143,11 +157,11 @@ function WizardMain(props) {
143
157
  // Check if the current section is relevant for AI services
144
158
  const isRelevantSection = isTroubleshootSection || isSummarizeSection || isResourcesSection;
145
159
  // Check if the case type is allowed (not in the excluded list)
146
- const isCaseTypeAllowed = !excludedCaseTypesforARH.includes(caseType || '');
160
+ const isCaseTypeAllowed = !excludedCaseTypesforARH.includes(caseDetails.caseType || '');
147
161
  // Check if user is not a secure support or confirmed stateside support user
148
162
  const isNotSecureOrStatesideUser = !props.isSecureSupport && !props.hasConfirmedStatesideSupport;
149
163
  // Check if the ARH fields have changed
150
- const isARHFieldsChanged = haveARHFieldsChanged();
164
+ const isARHFieldsChanged = haveARHFieldsChanged;
151
165
  // Check if user is external and has invalid entitlements
152
166
  const isNotUnentitledExternalUser = !(props.isUserExternal && props.hasInvalidEntitlements);
153
167
  return (isRelevantSection &&
@@ -157,21 +171,21 @@ function WizardMain(props) {
157
171
  isNotUnentitledExternalUser);
158
172
  };
159
173
  // Check if any of the ARH-relevant fields have changed
160
- const haveARHFieldsChanged = () => {
161
- const hasChanged = previousARHFieldsRef.current.product !== product ||
162
- previousARHFieldsRef.current.version !== version ||
163
- previousARHFieldsRef.current.summary !== summary ||
164
- previousARHFieldsRef.current.issue !== issue;
174
+ const haveARHFieldsChanged = React.useMemo(() => {
175
+ const hasChanged = previousARHFieldsRef.current.product !== caseDetails.product ||
176
+ previousARHFieldsRef.current.version !== caseDetails.version ||
177
+ previousARHFieldsRef.current.summary !== caseDetails.summary ||
178
+ previousARHFieldsRef.current.issue !== caseDetails.issue;
165
179
  if (hasChanged) {
166
180
  previousARHFieldsRef.current = {
167
- product,
168
- version,
169
- summary,
170
- issue,
181
+ product: caseDetails.product,
182
+ version: caseDetails.version,
183
+ summary: caseDetails.summary,
184
+ issue: caseDetails.issue,
171
185
  };
172
186
  }
173
187
  return hasChanged;
174
- };
188
+ }, [caseDetails.product, caseDetails.version, caseDetails.summary, caseDetails.issue]);
175
189
  useEffect(() => {
176
190
  if (!activeSection) {
177
191
  return;
@@ -194,6 +208,7 @@ function WizardMain(props) {
194
208
  appEnv: Env.getEnvName(),
195
209
  };
196
210
  try {
211
+ yield getRHDirectHealthCheck(config);
197
212
  yield getRHDirectStatusCheck(config);
198
213
  setAIServicesAvailable(true);
199
214
  }
@@ -206,7 +221,7 @@ function WizardMain(props) {
206
221
  // eslint-disable-next-line react-hooks/exhaustive-deps
207
222
  }, [
208
223
  activeSection,
209
- caseType,
224
+ caseDetails.caseType,
210
225
  isCaseCreate,
211
226
  aiServicesAvailable,
212
227
  props.isSecureSupport,
@@ -256,46 +271,19 @@ function WizardMain(props) {
256
271
  isBackButtonClickedRef.current = false;
257
272
  setIsNextButtonClicked(false);
258
273
  };
259
- const handleReturnToCaseCreation = () => {
274
+ const handleReturnToCaseCreation = () => __awaiter(this, void 0, void 0, function* () {
260
275
  props.setIsAIChatMode(false);
261
- };
276
+ if (sessionRestore.activeSessionId) {
277
+ const sessionDetails = getSessionDetailsFromCase(caseDetails, selectedNotificationContacts);
278
+ const newSession = {
279
+ returnToCase: true,
280
+ };
281
+ yield updateSession(sessionRestoreDispatch, sessionRestore.activeSessionId, sessionDetails, newSession);
282
+ }
283
+ });
262
284
  const customNav = (isExpanded, steps, activeStep, goToStepByIndex) => (React.createElement(WizardNav, { isExpanded: isExpanded }, steps.map((step) => {
263
285
  return (React.createElement(WizardNavItem, { key: step.id, id: step.id, content: step.name, isCurrent: activeStep.id === step.id, isDisabled: !step.canJumpTo, stepIndex: step.index, onClick: () => goToStepByIndex(step.index) }));
264
286
  })));
265
- const aiResponseState = useAIResponseState();
266
- const config = {
267
- appSourceId: appSourceId_ARH,
268
- authToken: (_b = (_a = window === null || window === void 0 ? void 0 : window.sessionjs) === null || _a === void 0 ? void 0 : _a.getEncodedToken()) !== null && _b !== void 0 ? _b : '',
269
- packageVersion: (_c = window === null || window === void 0 ? void 0 : window.supportVersionInfo) === null || _c === void 0 ? void 0 : _c.packageVersion,
270
- appEnv: Env.getEnvName(),
271
- };
272
- const fetchARHResponse = () => __awaiter(this, void 0, void 0, function* () {
273
- var _a;
274
- const detailedQuestion = generateAIQuestion(activeSection || '', product, version, summary, issue, caseType || '', i18n.language || 'en');
275
- //streaming callbacks
276
- const streamingCallbacks = {
277
- onChunk: (chunk, accumulatedResponse) => {
278
- aiResponseDispatch(streamingChunkReceived(chunk, accumulatedResponse));
279
- },
280
- onComplete: (finalResponse) => {
281
- aiResponseDispatch(streamingCompleted(finalResponse));
282
- },
283
- onError: (error) => {
284
- aiResponseDispatch(streamingError(error));
285
- },
286
- };
287
- aiResponseDispatch(streamingStarted());
288
- try {
289
- // Get existing conversation ID from state if available (need to map it with session data)
290
- const existingConversationId = (_a = aiResponseState === null || aiResponseState === void 0 ? void 0 : aiResponseState.aiResponse) === null || _a === void 0 ? void 0 : _a.conversationId;
291
- yield askRHDirectAIResponse(detailedQuestion, config, true, // response to be streamed or not
292
- existingConversationId, streamingCallbacks);
293
- }
294
- catch (error) {
295
- const errorMessage = error instanceof Error ? error.message : 'Failed to get AI response';
296
- aiResponseDispatch(streamingError(errorMessage));
297
- }
298
- });
299
287
  const CustomFooter = (activeStep, goToNextStep, goToPrevStep) => {
300
288
  useEffect(() => {
301
289
  if (steps.length > 2 && (activeStep === null || activeStep === void 0 ? void 0 : activeStep.index) === 2 && isNextButtonClicked) {
@@ -318,7 +306,7 @@ function WizardMain(props) {
318
306
  isBackButtonClickedRef.current = true;
319
307
  goToPrevStep({});
320
308
  focusWizardMainPanel();
321
- }, activeStep: activeStep, onSubmit: onSubmit, confirmSupportModal: props.confirmSupportModal, onShowRestUpdate: (flag) => setShowRestFlag(flag), userSeenRecommendations: userSeenRecommendations, setUserSeenRecommendations: setUserSeenRecommendations, userClickedNextonRecommendationsFn: setUserClickedNextonRecommendations, userClickedNextonRecommendationsValue: userClickedNextonRecommendations, setUserCanNavigateToTroubleshoot: setUserCanNavigateToTroubleshoot, resultsRowRef: resultsRowRef, setUserScrolledLabel: setUserScrolledLabel, isAIChatMode: props.isAIChatMode, onReturnToCaseCreation: handleReturnToCaseCreation }));
309
+ }, activeStep: activeStep, onSubmit: onSubmit, confirmSupportModal: props.confirmSupportModal, onShowRestUpdate: (flag) => setShowRestFlag(flag), userSeenRecommendations: userSeenRecommendations, setUserSeenRecommendations: setUserSeenRecommendations, userClickedNextonRecommendationsFn: setUserClickedNextonRecommendations, userClickedNextonRecommendationsValue: userClickedNextonRecommendations, setUserCanNavigateToTroubleshoot: setUserCanNavigateToTroubleshoot, resultsRowRef: resultsRowRef, setUserScrolledLabel: setUserScrolledLabel, isAIChatMode: props.isAIChatMode, setIsAIChatMode: props.setIsAIChatMode, onReturnToCaseCreation: handleReturnToCaseCreation }));
322
310
  };
323
311
  const steps = getStepsSequece(showRestFlag);
324
312
  const wizardSteps = steps.map((step) => {
@@ -17,6 +17,7 @@ interface IProps {
17
17
  resultsRowRef?: any;
18
18
  setUserScrolledLabel: (value: React.SetStateAction<boolean>) => void;
19
19
  isAIChatMode?: boolean;
20
+ setIsAIChatMode?: (value: boolean) => void;
20
21
  onReturnToCaseCreation?: () => void;
21
22
  }
22
23
  declare function WizardNavigation(props: IProps): React.JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"WizardNavigation.d.ts","sourceRoot":"","sources":["../../../../src/components/wizardLayout/WizardNavigation.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAOvD,OAAO,EAAoB,eAAe,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAM3G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACzD,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,EAAE,CAAC,gCAAgC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,0BAA0B,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5E,kCAAkC,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACpF,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,gCAAgC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACjF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,oBAAoB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAGD,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,qBAsVtC;kBAtVQ,gBAAgB;;;AAwVzB,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"WizardNavigation.d.ts","sourceRoot":"","sources":["../../../../src/components/wizardLayout/WizardNavigation.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAkD,MAAM,OAAO,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAOvD,OAAO,EAAoB,eAAe,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAM3G,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACzD,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IACzD,UAAU,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,mBAAmB,EAAE,CAAC,gCAAgC,EAAE,OAAO,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1C,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,0BAA0B,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5E,kCAAkC,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACpF,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,gCAAgC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACjF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,oBAAoB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAGD,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,qBA6VtC;kBA7VQ,gBAAgB;;;AA+VzB,eAAe,gBAAgB,CAAC"}
@@ -78,6 +78,13 @@ function WizardNavigation(props) {
78
78
  // eslint-disable-next-line react-hooks/exhaustive-deps
79
79
  }, [previousStep === null || previousStep === void 0 ? void 0 : previousStep.id, props.activeStep.id]);
80
80
  const [hasUserScrolled, setHasUserScrolled] = useState(false);
81
+ useEffect(() => {
82
+ var _a;
83
+ if (activeSection !== AppRouteSections.RESOURCES && props.isAIChatMode) {
84
+ (_a = props.setIsAIChatMode) === null || _a === void 0 ? void 0 : _a.call(props, false);
85
+ }
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
87
+ }, [activeSection]);
81
88
  useEffect(() => {
82
89
  if (props.activeStep.id !== (isCaseCreate ? AppRouteSections.SUMMARIZE : AppRouteSections.TROUBLESHOOT) ||
83
90
  recommendationState.numFound <= 2) {
@@ -253,7 +260,7 @@ function WizardNavigation(props) {
253
260
  // To handle entitled products
254
261
  return (React.createElement(React.Fragment, null,
255
262
  React.createElement(WizardFooterWrapper, null,
256
- props.isAIChatMode && activeSection === AppRouteSections.RESOURCES ? (React.createElement(Button, { onClick: props.onReturnToCaseCreation, variant: "link", className: "return-to-case-btn" }, isCaseCreate ? t('Return to case creation') : t('Return to resources'))) : (React.createElement(React.Fragment, null,
263
+ props.isAIChatMode && activeSection === AppRouteSections.RESOURCES ? (React.createElement(Button, { onClick: props.onReturnToCaseCreation, variant: "link", className: "return-to-case-btn" }, isCaseCreate ? t('Return to case creation') : t('Back to resources'))) : (React.createElement(React.Fragment, null,
257
264
  props.activeStep.order !== 0 && (React.createElement("button", { onClick: () => onBack({}), className: "btn btn-app btn-open-white main-nav-button", "data-tracking-id": `prev-of-${activeSection}`, type: "button", disabled: isDisabledGoBack() }, t('Go back'))),
258
265
  React.createElement("button", { disabled: nextButtonDisabledLogic(), onClick: onNext, className: "btn btn-app btn-primary main-nav-button", "data-tracking-id": `next-of-${activeSection}`, type: "button" }, t(props.activeStep.nextButtonLabel)),
259
266
  activeSection === AppRouteSections.RESOURCES && isFileRecommendationsTriggered && (React.createElement(Button, { onClick: handleFileRecsSelfSolved, variant: ButtonVariant.secondary, className: "issue-solved-button solved-issue-button", "data-tracking-id": "troubleshoot-self-solved-issue" }, t('I solved my issue'))))),
@@ -23,7 +23,7 @@
23
23
  }
24
24
 
25
25
  .ask-redhat-content {
26
- max-height: 120px;
26
+ max-height: 242px;
27
27
  color: #000;
28
28
  font-family: 'Red Hat Text';
29
29
  font-size: 16px;
@@ -79,6 +79,12 @@
79
79
  margin: 0;
80
80
  }
81
81
 
82
+ .ask-redhat-error {
83
+ border: 1px solid #c7c7c7;
84
+ border-radius: 6px;
85
+ padding: 12px 24px;
86
+ }
87
+
82
88
  :root {
83
89
  --color-red: var(--Core-color-palette-Red-red-40, #f56e6e);
84
90
  --color-purple: var(--Secondary-color-palette-Purple-purple-50, #5e40be);
@@ -124,7 +130,6 @@
124
130
  height: 100%;
125
131
  }
126
132
 
127
-
128
133
  .ask-redhat-chat-button .pf-v6-c-button__icon {
129
134
  display: flex;
130
135
  align-items: center;
@@ -370,6 +375,7 @@ body:has(.pf-chatbot--embedded) .pf-v6-c-wizard__main-body:last-child {
370
375
  .ask-redhat-core .pf-chatbot__beta-label .pf-v6-c-label__content {
371
376
  color: #707070 !important;
372
377
  line-height: var(--global-font-line-height-figma-only-body-small, 18px) !important;
378
+ font-weight: 500 !important;
373
379
  }
374
380
 
375
381
  .ask-redhat-core .pf-chatbot__header-container:after {
@@ -379,6 +385,13 @@ body:has(.pf-chatbot--embedded) .pf-v6-c-wizard__main-body:last-child {
379
385
  .ask-redhat-core .pf-chatbot__expand-collapse-button {
380
386
  color: #151515 !important;
381
387
  font-size: var(--global-font-size-body-sm, 12px) !important;
388
+ align-items: center !important;
389
+ }
390
+
391
+ .pf-chatbot__expand-collapse-button .pf-v6-svg {
392
+ width: 16px !important;
393
+ height: 16px !important;
394
+ color: black !important;
382
395
  }
383
396
 
384
397
  .pf-v6-c-button__icon.pf-m-end {
@@ -390,3 +403,7 @@ body:has(.pf-chatbot--embedded) .pf-v6-c-wizard__main-body:last-child {
390
403
  border-radius: var(--global-border-radius-small, 6px) !important;
391
404
  background: #fff !important;
392
405
  }
406
+
407
+ .ask-redhat-core .pf-chatbot__message-bar {
408
+ background: #fff !important;
409
+ }
@@ -47,11 +47,15 @@ button,
47
47
  padding-left: 1.8rem;
48
48
  margin-right: -1.8rem;
49
49
  padding-right: 1.8rem;
50
- margin-bottom: -2rem;
50
+ margin-bottom: -1rem;
51
51
  padding-bottom: 8rem;
52
52
  min-height: 300px;
53
53
  }
54
54
 
55
+ .case-details-tabs-content {
56
+ border-radius: 0 0 0 16px !important;
57
+ }
58
+
55
59
  .support-comment {
56
60
  display: block;
57
61
  margin-bottom: 1rem;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Custom hook to prompt from the Ask Red Hat
3
+ */
4
+ export declare const useARHResponse: ({ activeSection, product, version, summary, issue, caseType, config, }: {
5
+ activeSection: string;
6
+ product: string;
7
+ version: string;
8
+ summary: string;
9
+ issue: string;
10
+ caseType: string;
11
+ config: any;
12
+ }) => {
13
+ fetchARHResponse: () => Promise<void>;
14
+ };
15
+ //# sourceMappingURL=useARHResponse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useARHResponse.d.ts","sourceRoot":"","sources":["../../../src/hooks/useARHResponse.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,eAAO,MAAM,cAAc,2EAQxB;IACC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,GAAG,CAAC;CACf;;CAgDA,CAAC"}
@@ -0,0 +1,50 @@
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 { askRHDirectAIResponse } from '@ifd-ui/ask-redhat-core';
11
+ import i18n from 'i18next';
12
+ import { useCallback } from 'react';
13
+ import { generateAIQuestion } from '../components/wizardLayout/WizardMain';
14
+ import { useAIResponseDispatch, useAIResponseState } from '../context/AIResponseContext';
15
+ import { streamingChunkReceived, streamingCompleted, streamingError, streamingStarted, } from '../reducers/AIResponseReducer';
16
+ /**
17
+ * Custom hook to prompt from the Ask Red Hat
18
+ */
19
+ export const useARHResponse = ({ activeSection, product, version, summary, issue, caseType, config, }) => {
20
+ const aiResponseDispatch = useAIResponseDispatch();
21
+ const aiResponseState = useAIResponseState();
22
+ const fetchARHResponse = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
23
+ var _a;
24
+ const detailedQuestion = generateAIQuestion(activeSection || '', product, version, summary, issue, caseType || '', i18n.language || 'en');
25
+ // Streaming callbacks
26
+ const streamingCallbacks = {
27
+ onChunk: (chunk, accumulatedResponse) => {
28
+ aiResponseDispatch(streamingChunkReceived(chunk, accumulatedResponse));
29
+ },
30
+ onComplete: (finalResponse) => {
31
+ aiResponseDispatch(streamingCompleted(finalResponse));
32
+ },
33
+ onError: (error) => {
34
+ aiResponseDispatch(streamingError(error));
35
+ },
36
+ };
37
+ aiResponseDispatch(streamingStarted());
38
+ try {
39
+ // Get existing conversation ID from state if available (need to map it with session data)
40
+ const existingConversationId = (_a = aiResponseState === null || aiResponseState === void 0 ? void 0 : aiResponseState.aiResponse) === null || _a === void 0 ? void 0 : _a.conversationId;
41
+ yield askRHDirectAIResponse(detailedQuestion, config, true, // response to be streamed or not
42
+ existingConversationId, streamingCallbacks);
43
+ }
44
+ catch (error) {
45
+ const errorMessage = error instanceof Error ? error.message : 'Failed to get AI response';
46
+ aiResponseDispatch(streamingError(errorMessage));
47
+ }
48
+ }), [activeSection, product, version, summary, issue, caseType, config, aiResponseDispatch, aiResponseState]);
49
+ return { fetchARHResponse };
50
+ };
@@ -179,10 +179,12 @@ div.support-grid-case-details.support-case {
179
179
  min-height: 75vh;
180
180
  width: 100%;
181
181
  background-color: #f0f0f0;
182
+ border-radius: 0 0 0 16px;
182
183
 
183
184
  .grid-main-section {
184
185
  padding: 1rem;
185
186
  background-color: #fff;
187
+ border-radius: 0 0 0 16px;
186
188
 
187
189
  .case-overview-header {
188
190
  padding: 0.5rem;
@@ -419,7 +421,7 @@ div.support-grid-case-details.support-case {
419
421
  display: flex;
420
422
  align-items: center;
421
423
  width: 100%;
422
- padding: 1.8rem 1.5rem;
424
+ padding: 24px;
423
425
  font-weight: 500;
424
426
 
425
427
  span {
@@ -439,11 +441,7 @@ div.support-grid-case-details.support-case {
439
441
 
440
442
  &.sidebar-collapsed {
441
443
  button:first-of-type {
442
- margin-bottom: 0.4rem;
443
- padding: 1.8rem 1.5rem;
444
- background-color: #dedede;
445
- border-top: 1px solid #ccc;
446
- border-bottom: 1px solid #ccc;
444
+ padding: 24px;
447
445
  }
448
446
 
449
447
  button.sidebar-section-toggle-btn {
@@ -460,6 +460,14 @@ pfe-accordion {
460
460
  z-index: 1 !important;
461
461
  }
462
462
 
463
+ nav.pf-v6-c-wizard__nav.pf-m-expanded {
464
+ position: absolute;
465
+ left: 0;
466
+ z-index: 2 !important;
467
+ background: #fff;
468
+ width: 100%;
469
+ }
470
+
463
471
  .pf-v6-c-options-menu__menu {
464
472
  z-index: 9 !important;
465
473
  }
@@ -831,3 +839,11 @@ div.case-details-tabs pre {
831
839
  .pf-v6-c-alert {
832
840
  margin-top: 0;
833
841
  }
842
+
843
+ .pf-v6-c-wizard__nav {
844
+ border-radius: 0 0 0 16px !important;
845
+ }
846
+
847
+ .pf-v6-c-wizard__outer-wrap {
848
+ border-radius: 16px !important;
849
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/troubleshoot",
3
- "version": "2.6.49",
3
+ "version": "2.6.57",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org"
@@ -25,7 +25,7 @@
25
25
  "lib/**/*"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@cee-eng/hydrajs": "4.18.57",
28
+ "@cee-eng/hydrajs": "4.18.84",
29
29
  "@cee-eng/ui-toolkit": "1.1.8",
30
30
  "@patternfly/patternfly": "6.2.1",
31
31
  "@patternfly/react-core": "6.2.1",
@@ -49,9 +49,9 @@
49
49
  "react-virtualized": "^9.22.5"
50
50
  },
51
51
  "dependencies": {
52
- "@cee-eng/hydrajs": "4.18.57",
52
+ "@cee-eng/hydrajs": "4.18.84",
53
53
  "@cee-eng/ui-toolkit": "1.1.8",
54
- "@ifd-ui/ask-redhat-core": "^0.0.33",
54
+ "@ifd-ui/ask-redhat-core": "^0.0.34",
55
55
  "@patternfly/patternfly": "6.2.1",
56
56
  "@patternfly/react-core": "6.2.1",
57
57
  "@patternfly/react-table": "6.2.1",
@@ -59,11 +59,11 @@
59
59
  "@progress/kendo-licensing": "1.3.5",
60
60
  "@progress/kendo-react-pdf": "^5.16.0",
61
61
  "@redux-devtools/extension": "^3.3.0",
62
- "@rh-support/components": "2.5.45",
63
- "@rh-support/react-context": "2.5.45",
62
+ "@rh-support/components": "2.5.46",
63
+ "@rh-support/react-context": "2.5.61",
64
64
  "@rh-support/types": "2.0.5",
65
- "@rh-support/user-permissions": "2.5.20",
66
- "@rh-support/utils": "2.5.19",
65
+ "@rh-support/user-permissions": "2.5.21",
66
+ "@rh-support/utils": "2.5.20",
67
67
  "@types/react-redux": "^7.1.33",
68
68
  "@types/redux": "^3.6.0",
69
69
  "date-fns": "3.6.0",
@@ -135,5 +135,5 @@
135
135
  "defaults and supports es6-module",
136
136
  "maintained node versions"
137
137
  ],
138
- "gitHead": "f2a50ab076135e82a7947f2e3edc0f51e63365ef"
138
+ "gitHead": "6c4cd843a136a0df2fc9bb67dd13364a8660f6cf"
139
139
  }