|
1 | | -import React, { useEffect, useRef } from 'react' |
2 | | -import { useDispatch, useSelector } from 'react-redux' |
3 | | -import cx from 'classnames' |
4 | | -import { |
5 | | - errorsSelector, |
6 | | - infiniteNotificationsSelector, |
7 | | - messagesSelector, |
8 | | - removeInfiniteNotification, |
9 | | - removeMessage, |
10 | | -} from 'uiSrc/slices/app/notifications' |
11 | | -import { setReleaseNotesViewed } from 'uiSrc/slices/app/info' |
12 | | -import { IError, IMessage, InfiniteMessage } from 'uiSrc/slices/interfaces' |
13 | | -import { ApiEncryptionErrors } from 'uiSrc/constants/apiErrors' |
14 | | -import { DEFAULT_ERROR_MESSAGE } from 'uiSrc/utils' |
15 | | -import { showOAuthProgress } from 'uiSrc/slices/oauth/cloud' |
16 | | -import { CustomErrorCodes } from 'uiSrc/constants' |
17 | | -import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' |
18 | | -import { ColorText } from 'uiSrc/components/base/text' |
19 | | -import { riToast, RiToaster } from 'uiSrc/components/base/display/toast' |
20 | | - |
21 | | -import errorMessages from './error-messages' |
22 | | -import { InfiniteMessagesIds } from './components' |
23 | | - |
24 | | -import styles from './styles.module.scss' |
25 | | - |
26 | | -const ONE_HOUR = 3_600_000 |
27 | | -const DEFAULT_ERROR_TITLE = 'Error' |
| 1 | +import React from 'react' |
| 2 | +import { RiToaster } from 'uiSrc/components/base/display/toast' |
| 3 | +import { useErrorNotifications, useMessageNotifications } from './hooks' |
| 4 | +import { InfiniteNotifications } from './components/infinite-messages/InfiniteNotifications' |
| 5 | +import { defaultContainerId } from './constants' |
28 | 6 |
|
29 | 7 | const Notifications = () => { |
30 | | - const messagesData = useSelector(messagesSelector) |
31 | | - const errorsData = useSelector(errorsSelector) |
32 | | - const infiniteNotifications = useSelector(infiniteNotificationsSelector) |
33 | | - |
34 | | - const dispatch = useDispatch() |
35 | | - const toastIdsRef = useRef(new Map()) |
36 | | - |
37 | | - const removeToast = (id: string) => { |
38 | | - if (toastIdsRef.current.has(id)) { |
39 | | - riToast.dismiss(toastIdsRef.current.get(id)) |
40 | | - toastIdsRef.current.delete(id) |
41 | | - } |
42 | | - dispatch(removeMessage(id)) |
43 | | - } |
44 | | - |
45 | | - const onSubmitNotification = (id: string, group?: string) => { |
46 | | - if (group === 'upgrade') { |
47 | | - dispatch(setReleaseNotesViewed(true)) |
48 | | - } |
49 | | - dispatch(removeMessage(id)) |
50 | | - } |
51 | | - |
52 | | - const getSuccessText = (text: string | JSX.Element | JSX.Element[]) => ( |
53 | | - <ColorText color="success">{text}</ColorText> |
| 8 | + useErrorNotifications() |
| 9 | + useMessageNotifications() |
| 10 | + |
| 11 | + return ( |
| 12 | + <> |
| 13 | + <InfiniteNotifications /> |
| 14 | + <RiToaster containerId={defaultContainerId} /> |
| 15 | + </> |
54 | 16 | ) |
55 | | - |
56 | | - const showSuccessToasts = (data: IMessage[]) => |
57 | | - data.forEach( |
58 | | - ({ |
59 | | - id = '', |
60 | | - title = '', |
61 | | - message = '', |
62 | | - showCloseButton = true, |
63 | | - actions, |
64 | | - className, |
65 | | - group, |
66 | | - }) => { |
67 | | - const handleClose = () => { |
68 | | - onSubmitNotification(id, group) |
69 | | - removeToast(id) |
70 | | - } |
71 | | - if (toastIdsRef.current.has(id)) { |
72 | | - removeToast(id) |
73 | | - return |
74 | | - } |
75 | | - const toastId = riToast( |
76 | | - { |
77 | | - className, |
78 | | - message: title, |
79 | | - description: getSuccessText(message), |
80 | | - actions: actions ?? { |
81 | | - primary: { |
82 | | - closes: true, |
83 | | - label: 'OK', |
84 | | - onClick: handleClose, |
85 | | - }, |
86 | | - }, |
87 | | - showCloseButton, |
88 | | - }, |
89 | | - { variant: riToast.Variant.Success, toastId: id }, |
90 | | - ) |
91 | | - toastIdsRef.current.set(id, toastId) |
92 | | - }, |
93 | | - ) |
94 | | - |
95 | | - const showErrorsToasts = (errors: IError[]) => |
96 | | - errors.forEach( |
97 | | - ({ |
98 | | - id = '', |
99 | | - message = DEFAULT_ERROR_MESSAGE, |
100 | | - instanceId = '', |
101 | | - name, |
102 | | - title = DEFAULT_ERROR_TITLE, |
103 | | - additionalInfo, |
104 | | - }) => { |
105 | | - if (toastIdsRef.current.has(id)) { |
106 | | - removeToast(id) |
107 | | - return |
108 | | - } |
109 | | - let toastId: ReturnType<typeof riToast> |
110 | | - if (ApiEncryptionErrors.includes(name)) { |
111 | | - toastId = errorMessages.ENCRYPTION( |
112 | | - () => removeToast(id), |
113 | | - instanceId, |
114 | | - id, |
115 | | - ) |
116 | | - } else if ( |
117 | | - additionalInfo?.errorCode === |
118 | | - CustomErrorCodes.CloudCapiKeyUnauthorized |
119 | | - ) { |
120 | | - toastId = errorMessages.CLOUD_CAPI_KEY_UNAUTHORIZED( |
121 | | - { message, title }, |
122 | | - additionalInfo, |
123 | | - () => removeToast(id), |
124 | | - id, |
125 | | - ) |
126 | | - } else if ( |
127 | | - additionalInfo?.errorCode === |
128 | | - CustomErrorCodes.RdiDeployPipelineFailure |
129 | | - ) { |
130 | | - toastId = errorMessages.RDI_DEPLOY_PIPELINE( |
131 | | - { title, message }, |
132 | | - () => removeToast(id), |
133 | | - id, |
134 | | - ) |
135 | | - } else { |
136 | | - toastId = errorMessages.DEFAULT( |
137 | | - message, |
138 | | - () => removeToast(id), |
139 | | - title, |
140 | | - id, |
141 | | - ) |
142 | | - } |
143 | | - |
144 | | - toastIdsRef.current.set(id, toastId) |
145 | | - }, |
146 | | - ) |
147 | | - const infiniteToastIdsRef = useRef(new Set<number | string>()) |
148 | | - |
149 | | - const showInfiniteToasts = (data: InfiniteMessage[]) => { |
150 | | - infiniteToastIdsRef.current.forEach((toastId) => { |
151 | | - setTimeout(() => { |
152 | | - riToast.dismiss(toastId) |
153 | | - infiniteToastIdsRef.current.delete(toastId) |
154 | | - }, 50) |
155 | | - }) |
156 | | - data.forEach((notification: InfiniteMessage) => { |
157 | | - const { |
158 | | - id, |
159 | | - message, |
160 | | - description, |
161 | | - actions, |
162 | | - className = '', |
163 | | - variant, |
164 | | - customIcon, |
165 | | - showCloseButton = true, |
166 | | - onClose: onCloseCallback, |
167 | | - } = notification |
168 | | - const toastId = riToast( |
169 | | - { |
170 | | - className: cx(styles.infiniteMessage, className), |
171 | | - message: message, |
172 | | - description: description, |
173 | | - actions, |
174 | | - showCloseButton, |
175 | | - customIcon, |
176 | | - onClose: () => { |
177 | | - switch (id) { |
178 | | - case InfiniteMessagesIds.oAuthProgress: |
179 | | - dispatch(showOAuthProgress(false)) |
180 | | - break |
181 | | - case InfiniteMessagesIds.databaseExists: |
182 | | - sendEventTelemetry({ |
183 | | - event: |
184 | | - TelemetryEvent.CLOUD_IMPORT_EXISTING_DATABASE_FORM_CLOSED, |
185 | | - }) |
186 | | - break |
187 | | - case InfiniteMessagesIds.subscriptionExists: |
188 | | - sendEventTelemetry({ |
189 | | - event: |
190 | | - TelemetryEvent.CLOUD_CREATE_DATABASE_IN_SUBSCRIPTION_FORM_CLOSED, |
191 | | - }) |
192 | | - break |
193 | | - case InfiniteMessagesIds.appUpdateAvailable: |
194 | | - sendEventTelemetry({ |
195 | | - event: TelemetryEvent.UPDATE_NOTIFICATION_CLOSED, |
196 | | - }) |
197 | | - break |
198 | | - default: |
199 | | - break |
200 | | - } |
201 | | - |
202 | | - dispatch(removeInfiniteNotification(id)) |
203 | | - onCloseCallback?.() |
204 | | - }, |
205 | | - }, |
206 | | - { |
207 | | - variant: variant ?? riToast.Variant.Notice, |
208 | | - autoClose: ONE_HOUR, |
209 | | - toastId: id, |
210 | | - }, |
211 | | - ) |
212 | | - infiniteToastIdsRef.current.add(toastId) |
213 | | - toastIdsRef.current.set(id, toastId) |
214 | | - }) |
215 | | - } |
216 | | - |
217 | | - useEffect(() => { |
218 | | - showSuccessToasts(messagesData) |
219 | | - }, [messagesData]) |
220 | | - useEffect(() => { |
221 | | - showErrorsToasts(errorsData) |
222 | | - }, [errorsData]) |
223 | | - useEffect(() => { |
224 | | - showInfiniteToasts(infiniteNotifications) |
225 | | - }, [infiniteNotifications]) |
226 | | - |
227 | | - return <RiToaster /> |
228 | 17 | } |
229 | 18 |
|
230 | 19 | export default Notifications |
0 commit comments