@servicetitan/notifications 28.5.0 → 29.0.0
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/dist/__tests__/intercept.test.d.ts +2 -0
- package/dist/__tests__/intercept.test.d.ts.map +1 -0
- package/dist/__tests__/intercept.test.js +13 -0
- package/dist/__tests__/intercept.test.js.map +1 -0
- package/dist/__tests__/notifications-service.test.d.ts +2 -0
- package/dist/__tests__/notifications-service.test.d.ts.map +1 -0
- package/dist/__tests__/notifications-service.test.js +42 -0
- package/dist/__tests__/notifications-service.test.js.map +1 -0
- package/dist/api/notifications.api.d.ts +2 -2
- package/dist/api/notifications.api.d.ts.map +1 -1
- package/dist/common.d.ts +4 -22
- package/dist/common.d.ts.map +1 -1
- package/dist/common.js +4 -11
- package/dist/common.js.map +1 -1
- package/dist/components/__tests__/notifications.test.d.ts +2 -0
- package/dist/components/__tests__/notifications.test.d.ts.map +1 -0
- package/dist/components/__tests__/notifications.test.js +93 -0
- package/dist/components/__tests__/notifications.test.js.map +1 -0
- package/dist/components/notifications.d.ts +8 -1
- package/dist/components/notifications.d.ts.map +1 -1
- package/dist/components/notifications.js +43 -23
- package/dist/components/notifications.js.map +1 -1
- package/dist/demo/action-button-preview.d.ts.map +1 -1
- package/dist/demo/action-button-preview.js +2 -2
- package/dist/demo/action-button-preview.js.map +1 -1
- package/dist/demo/basic-preview.d.ts.map +1 -1
- package/dist/demo/basic-preview.js +1 -1
- package/dist/demo/basic-preview.js.map +1 -1
- package/dist/demo/container.d.ts +1 -3
- package/dist/demo/container.d.ts.map +1 -1
- package/dist/demo/container.js.map +1 -1
- package/dist/demo/duration-preview.d.ts.map +1 -1
- package/dist/demo/duration-preview.js +2 -2
- package/dist/demo/duration-preview.js.map +1 -1
- package/dist/demo/multiline-message-preview.d.ts.map +1 -1
- package/dist/demo/multiline-message-preview.js +2 -2
- package/dist/demo/multiline-message-preview.js.map +1 -1
- package/dist/demo/prevent-duplicates-preview.d.ts.map +1 -1
- package/dist/demo/prevent-duplicates-preview.js +2 -2
- package/dist/demo/prevent-duplicates-preview.js.map +1 -1
- package/dist/demo/progress-preview.d.ts.map +1 -1
- package/dist/demo/progress-preview.js +2 -2
- package/dist/demo/progress-preview.js.map +1 -1
- package/dist/demo/server-custom-preview.d.ts +1 -1
- package/dist/demo/server-custom-preview.d.ts.map +1 -1
- package/dist/demo/server-custom-preview.js +21 -7
- package/dist/demo/server-custom-preview.js.map +1 -1
- package/dist/demo/server-custom.d.ts +0 -1
- package/dist/demo/server-custom.d.ts.map +1 -1
- package/dist/demo/server-custom.js +25 -21
- package/dist/demo/server-custom.js.map +1 -1
- package/dist/demo/server-default.d.ts.map +1 -1
- package/dist/demo/server-default.js +1 -1
- package/dist/demo/server-default.js.map +1 -1
- package/dist/demo/status-variations-preview.d.ts.map +1 -1
- package/dist/demo/status-variations-preview.js +2 -2
- package/dist/demo/status-variations-preview.js.map +1 -1
- package/dist/demo/status-variations.d.ts.map +1 -1
- package/dist/demo/status-variations.js.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/intercept.d.ts +4 -0
- package/dist/intercept.d.ts.map +1 -0
- package/dist/intercept.js +5 -0
- package/dist/intercept.js.map +1 -0
- package/dist/notifications-channel.d.ts +2 -6
- package/dist/notifications-channel.d.ts.map +1 -1
- package/dist/notifications-channel.js.map +1 -1
- package/dist/notifications-service.d.ts +10 -8
- package/dist/notifications-service.d.ts.map +1 -1
- package/dist/notifications-service.js.map +1 -1
- package/dist/notifications.stories.d.ts +14 -0
- package/dist/notifications.stories.d.ts.map +1 -0
- package/dist/notifications.stories.js +20 -0
- package/dist/notifications.stories.js.map +1 -0
- package/dist/stores/__mocks__/mock-notifications-channel.d.ts +11 -0
- package/dist/stores/__mocks__/mock-notifications-channel.d.ts.map +1 -0
- package/dist/stores/__mocks__/mock-notifications-channel.js +36 -0
- package/dist/stores/__mocks__/mock-notifications-channel.js.map +1 -0
- package/dist/stores/__tests__/notifications.store.test.d.ts +2 -0
- package/dist/stores/__tests__/notifications.store.test.d.ts.map +1 -0
- package/dist/stores/__tests__/notifications.store.test.js +360 -0
- package/dist/stores/__tests__/notifications.store.test.js.map +1 -0
- package/dist/stores/notifications.store.d.ts +20 -8
- package/dist/stores/notifications.store.d.ts.map +1 -1
- package/dist/stores/notifications.store.js +156 -45
- package/dist/stores/notifications.store.js.map +1 -1
- package/dist/utils/__tests__/date-from-string.test.d.ts +2 -0
- package/dist/utils/__tests__/date-from-string.test.d.ts.map +1 -0
- package/dist/utils/__tests__/date-from-string.test.js +39 -0
- package/dist/utils/__tests__/date-from-string.test.js.map +1 -0
- package/dist/utils/__tests__/use-compatible-navigate.test.d.ts +2 -0
- package/dist/utils/__tests__/use-compatible-navigate.test.d.ts.map +1 -0
- package/dist/utils/__tests__/use-compatible-navigate.test.js +27 -0
- package/dist/utils/__tests__/use-compatible-navigate.test.js.map +1 -0
- package/dist/utils/date-from-string.d.ts.map +1 -0
- package/dist/utils/date-from-string.js +19 -0
- package/dist/utils/date-from-string.js.map +1 -0
- package/package.json +6 -6
- package/src/__tests__/intercept.test.ts +18 -0
- package/src/__tests__/notifications-service.test.ts +62 -0
- package/src/api/notifications.api.ts +2 -2
- package/src/common.ts +12 -27
- package/src/components/__tests__/notifications.test.tsx +107 -0
- package/src/components/notifications.tsx +59 -36
- package/src/demo/action-button-preview.tsx +4 -6
- package/src/demo/basic-preview.tsx +2 -4
- package/src/demo/container.tsx +1 -4
- package/src/demo/duration-preview.tsx +4 -6
- package/src/demo/multiline-message-preview.tsx +3 -9
- package/src/demo/prevent-duplicates-preview.tsx +3 -9
- package/src/demo/progress-preview.tsx +3 -9
- package/src/demo/server-custom-preview.tsx +17 -14
- package/src/demo/server-custom.tsx +30 -29
- package/src/demo/server-default.tsx +1 -3
- package/src/demo/status-variations-preview.tsx +4 -6
- package/src/demo/status-variations.tsx +0 -1
- package/src/index.ts +13 -4
- package/src/intercept.ts +14 -0
- package/src/notifications-channel.ts +2 -6
- package/src/notifications-service.ts +14 -42
- package/src/stores/__mocks__/mock-notifications-channel.ts +31 -0
- package/src/stores/__tests__/notifications.store.test.ts +458 -0
- package/src/stores/notifications.store.ts +178 -53
- package/src/utils/__tests__/date-from-string.test.ts +53 -0
- package/src/utils/__tests__/use-compatible-navigate.test.ts +43 -0
- package/src/utils/date-from-string.ts +22 -0
- package/dist/components/__tests__/container.test.d.ts +0 -2
- package/dist/components/__tests__/container.test.d.ts.map +0 -1
- package/dist/components/__tests__/container.test.js +0 -59
- package/dist/components/__tests__/container.test.js.map +0 -1
- package/dist/components/container.d.ts +0 -3
- package/dist/components/container.d.ts.map +0 -1
- package/dist/components/container.js +0 -26
- package/dist/components/container.js.map +0 -1
- package/dist/components/default-notification.d.ts +0 -7
- package/dist/components/default-notification.d.ts.map +0 -1
- package/dist/components/default-notification.js +0 -26
- package/dist/components/default-notification.js.map +0 -1
- package/dist/components/default-notification.module.css +0 -3
- package/dist/components/no-ssr.d.ts +0 -5
- package/dist/components/no-ssr.d.ts.map +0 -1
- package/dist/components/no-ssr.js +0 -9
- package/dist/components/no-ssr.js.map +0 -1
- package/dist/components/notifications-unwrapped.d.ts +0 -3
- package/dist/components/notifications-unwrapped.d.ts.map +0 -1
- package/dist/components/notifications-unwrapped.js +0 -27
- package/dist/components/notifications-unwrapped.js.map +0 -1
- package/dist/components/shadow-dom.d.ts +0 -3
- package/dist/components/shadow-dom.d.ts.map +0 -1
- package/dist/components/shadow-dom.js +0 -41
- package/dist/components/shadow-dom.js.map +0 -1
- package/dist/components/use-style-sheets.d.ts +0 -2
- package/dist/components/use-style-sheets.d.ts.map +0 -1
- package/dist/components/use-style-sheets.js +0 -15
- package/dist/components/use-style-sheets.js.map +0 -1
- package/dist/create-element.d.ts +0 -2
- package/dist/create-element.d.ts.map +0 -1
- package/dist/create-element.js +0 -8
- package/dist/create-element.js.map +0 -1
- package/dist/date-from-string.d.ts.map +0 -1
- package/dist/date-from-string.js +0 -27
- package/dist/date-from-string.js.map +0 -1
- package/dist/register.d.ts +0 -3
- package/dist/register.d.ts.map +0 -1
- package/dist/register.js +0 -5
- package/dist/register.js.map +0 -1
- package/src/components/__tests__/container.test.tsx +0 -71
- package/src/components/container.tsx +0 -35
- package/src/components/default-notification.module.css +0 -3
- package/src/components/default-notification.module.css.d.ts +0 -4
- package/src/components/default-notification.tsx +0 -59
- package/src/components/no-ssr.tsx +0 -11
- package/src/components/notifications-unwrapped.tsx +0 -51
- package/src/components/shadow-dom.tsx +0 -53
- package/src/components/use-style-sheets.ts +0 -19
- package/src/create-element.ts +0 -12
- package/src/date-from-string.ts +0 -30
- package/src/register.ts +0 -6
- /package/dist/{date-from-string.d.ts → utils/date-from-string.d.ts} +0 -0
@@ -1,48 +1,48 @@
|
|
1
|
+
import { toast, toastProps } from '@servicetitan/anvil2';
|
1
2
|
import { injectable, inject, optional } from '@servicetitan/react-ioc';
|
2
|
-
|
3
|
-
import { observable, computed, action, runInAction, comparer, makeObservable } from 'mobx';
|
4
|
-
|
5
|
-
import { NotificationsChannel, NOTIFICATIONS_CHANNEL_TOKEN } from '../notifications-channel';
|
3
|
+
import { action, runInAction, comparer, makeObservable } from 'mobx';
|
6
4
|
|
7
5
|
import {
|
6
|
+
DefaultServerNotificationPayload,
|
8
7
|
NotificationsApi,
|
9
8
|
Notification as ServerNotification,
|
10
|
-
NotificationProcessStatus,
|
9
|
+
NotificationProcessStatus as ServerNotificationStatus,
|
11
10
|
} from '../api/notifications.api';
|
12
|
-
|
13
|
-
import {
|
14
|
-
|
15
|
-
|
16
|
-
NotificationMapper,
|
17
|
-
toClientNotification,
|
18
|
-
DEFAULT_CLIENT_NOTIFICATION_TYPE,
|
19
|
-
DefaultNotificationOptions,
|
20
|
-
} from '../common';
|
21
|
-
import { dateFromString } from '../date-from-string';
|
11
|
+
import { DefaultNotificationOptions, Notification, Status, isLinkAction, isNewer } from '../common';
|
12
|
+
import { NotificationInterceptor } from '../intercept';
|
13
|
+
import { NotificationsChannel, NOTIFICATIONS_CHANNEL_TOKEN } from '../notifications-channel';
|
14
|
+
import { dateFromString } from '../utils/date-from-string';
|
22
15
|
|
23
16
|
const EVENT_NAME = 'NotificationEvent';
|
17
|
+
const CLIENT_NOTIFICATION_TYPE = 'ClientNotification';
|
18
|
+
const CLIENT_NOTIFICATION_VERSION = 1;
|
19
|
+
const DAY_INTERVAL = 24 * 60 * 60 * 1000;
|
24
20
|
|
25
21
|
interface ClosedNotification {
|
26
|
-
status:
|
22
|
+
status: ServerNotificationStatus;
|
27
23
|
timestamp: number;
|
28
24
|
}
|
29
25
|
|
30
|
-
|
26
|
+
interface ClientNotification extends Notification<DefaultNotificationOptions> {
|
27
|
+
toastId?: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
type NavigateCallback = (path: string) => void;
|
31
|
+
|
32
|
+
type ToastMethod = 'info' | 'success' | 'warning' | 'danger';
|
31
33
|
|
32
34
|
@injectable()
|
33
35
|
export class NotificationsStore {
|
34
|
-
static
|
35
|
-
|
36
|
-
@observable
|
37
|
-
private innerNotifications = new Map<number, Notification>();
|
36
|
+
static readonly interceptors = new Map<string, NotificationInterceptor>();
|
38
37
|
|
39
38
|
private index = -1;
|
40
|
-
|
41
39
|
private userId = 0;
|
42
|
-
|
43
40
|
private intervalId?: number;
|
44
41
|
|
45
|
-
private
|
42
|
+
private readonly notifications = new Map<number, ClientNotification>();
|
43
|
+
private readonly closedNotifications = new Map<number, ClosedNotification>();
|
44
|
+
|
45
|
+
#navigate?: NavigateCallback;
|
46
46
|
|
47
47
|
constructor(
|
48
48
|
@inject(NotificationsApi) @optional() private readonly notificationsApi?: NotificationsApi,
|
@@ -53,17 +53,24 @@ export class NotificationsStore {
|
|
53
53
|
makeObservable(this);
|
54
54
|
}
|
55
55
|
|
56
|
-
static
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
static intercept(type: string, fn?: NotificationInterceptor) {
|
57
|
+
if (fn) {
|
58
|
+
NotificationsStore.interceptors.set(type, fn);
|
59
|
+
} else {
|
60
|
+
NotificationsStore.interceptors.delete(type);
|
61
|
+
}
|
61
62
|
}
|
62
63
|
|
63
64
|
private get publisher() {
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
return this.notificationsChannel?.();
|
66
|
+
}
|
67
|
+
|
68
|
+
get navigate(): NavigateCallback | undefined {
|
69
|
+
return this.#navigate;
|
70
|
+
}
|
71
|
+
|
72
|
+
set navigate(fn: NavigateCallback) {
|
73
|
+
this.#navigate = fn;
|
67
74
|
}
|
68
75
|
|
69
76
|
initialize = async (userId: number) => {
|
@@ -98,33 +105,38 @@ export class NotificationsStore {
|
|
98
105
|
|
99
106
|
@action
|
100
107
|
add = (options: DefaultNotificationOptions, preventDuplicates?: boolean) => {
|
101
|
-
const notification = {
|
108
|
+
const notification: ClientNotification = {
|
102
109
|
id: this.index,
|
103
110
|
userId: this.userId,
|
104
|
-
type:
|
105
|
-
status:
|
111
|
+
type: CLIENT_NOTIFICATION_TYPE,
|
112
|
+
status: ServerNotificationStatus.Info,
|
106
113
|
isRead: false,
|
107
114
|
createdOn: new Date(),
|
108
115
|
modifiedOn: new Date(),
|
109
|
-
version:
|
110
|
-
payload: options,
|
116
|
+
version: CLIENT_NOTIFICATION_VERSION,
|
117
|
+
payload: { ...options },
|
111
118
|
};
|
112
119
|
|
113
|
-
if (
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
120
|
+
if (preventDuplicates) {
|
121
|
+
if (
|
122
|
+
[...this.notifications.values()].some(({ payload }) =>
|
123
|
+
comparer.structural(payload, notification.payload)
|
124
|
+
)
|
125
|
+
) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
this.notifications.set(notification.id, notification);
|
121
129
|
}
|
130
|
+
|
131
|
+
const method = this.getToastMethod(notification);
|
132
|
+
notification.toastId = toast[method](this.getToastProps(notification));
|
133
|
+
this.index -= 1;
|
122
134
|
};
|
123
135
|
|
124
136
|
@action
|
125
137
|
read = (notification: Notification) => {
|
126
138
|
if (notification.id > 0) {
|
127
|
-
if (notification.status ===
|
139
|
+
if (notification.status === ServerNotificationStatus.InProgress) {
|
128
140
|
this.closedNotifications.set(notification.id, {
|
129
141
|
status: notification.status,
|
130
142
|
timestamp: Date.now(),
|
@@ -140,16 +152,15 @@ export class NotificationsStore {
|
|
140
152
|
}
|
141
153
|
}
|
142
154
|
|
143
|
-
this.
|
155
|
+
this.notifications.delete(notification.id);
|
144
156
|
};
|
145
157
|
|
146
158
|
@action
|
147
|
-
private onPublisherEvent = (notification: ServerNotification) => {
|
159
|
+
private readonly onPublisherEvent = (notification: ServerNotification) => {
|
148
160
|
if (notification.userId !== this.userId) {
|
149
161
|
return;
|
150
162
|
}
|
151
163
|
|
152
|
-
// FIXME: FAR-385
|
153
164
|
this.updateIfNewer({
|
154
165
|
...notification,
|
155
166
|
createdOn: dateFromString(notification.createdOn),
|
@@ -166,9 +177,7 @@ export class NotificationsStore {
|
|
166
177
|
}
|
167
178
|
|
168
179
|
private updateIfNewer(notification: ServerNotification) {
|
169
|
-
const existing = this.innerNotifications.get(notification.id);
|
170
180
|
const closed = this.closedNotifications.get(notification.id);
|
171
|
-
|
172
181
|
if (closed) {
|
173
182
|
if (closed.status === notification.status) {
|
174
183
|
return;
|
@@ -177,8 +186,124 @@ export class NotificationsStore {
|
|
177
186
|
this.closedNotifications.delete(notification.id);
|
178
187
|
}
|
179
188
|
|
180
|
-
|
181
|
-
|
189
|
+
const clientNotification = this.toClientNotification(notification);
|
190
|
+
if (!clientNotification) {
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
|
194
|
+
const existing = this.notifications.get(notification.id);
|
195
|
+
if (existing) {
|
196
|
+
if (!isNewer(existing, notification)) {
|
197
|
+
return;
|
198
|
+
}
|
199
|
+
if (
|
200
|
+
notification.status === existing.status ||
|
201
|
+
notification.status === ServerNotificationStatus.InProgress
|
202
|
+
) {
|
203
|
+
toast.update(existing.toastId!, this.getToastProps(clientNotification));
|
204
|
+
return;
|
205
|
+
}
|
206
|
+
toast.dismiss(existing.toastId);
|
207
|
+
}
|
208
|
+
|
209
|
+
const method = this.getToastMethod(clientNotification);
|
210
|
+
clientNotification.toastId = toast[method](this.getToastProps(clientNotification));
|
211
|
+
this.notifications.set(notification.id, clientNotification);
|
212
|
+
}
|
213
|
+
|
214
|
+
private getToastMethod({ payload: { status } }: ClientNotification): ToastMethod {
|
215
|
+
switch (status) {
|
216
|
+
case Status.Success:
|
217
|
+
return 'success';
|
218
|
+
case Status.Error:
|
219
|
+
return 'danger';
|
220
|
+
case Status.Warning:
|
221
|
+
return 'warning';
|
222
|
+
default:
|
223
|
+
return 'info';
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
private getToastProps(notification: ClientNotification): toastProps {
|
228
|
+
const { action, duration, message = '', progress, title } = notification.payload;
|
229
|
+
return {
|
230
|
+
actions: this.getToastActions(notification),
|
231
|
+
duration: action ? false : duration,
|
232
|
+
message,
|
233
|
+
onClose: () => this.handleClose(notification),
|
234
|
+
progress,
|
235
|
+
title,
|
236
|
+
};
|
237
|
+
}
|
238
|
+
|
239
|
+
private getToastActions(notification: ClientNotification): toastProps['actions'] | undefined {
|
240
|
+
const { action } = notification.payload;
|
241
|
+
if (!action) {
|
242
|
+
return;
|
243
|
+
}
|
244
|
+
|
245
|
+
return {
|
246
|
+
primary: {
|
247
|
+
label: action.label,
|
248
|
+
onClick: () => this.handleClick(notification),
|
249
|
+
},
|
250
|
+
};
|
251
|
+
}
|
252
|
+
|
253
|
+
private handleClick({ payload: { action }, toastId }: ClientNotification) {
|
254
|
+
if (action) {
|
255
|
+
if (isLinkAction(action)) {
|
256
|
+
if (action.external) {
|
257
|
+
window.open(action.link);
|
258
|
+
} else {
|
259
|
+
this.navigate?.(action.link);
|
260
|
+
}
|
261
|
+
} else {
|
262
|
+
action.onClick();
|
263
|
+
}
|
264
|
+
}
|
265
|
+
|
266
|
+
toast.dismiss(toastId);
|
267
|
+
}
|
268
|
+
|
269
|
+
private handleClose(notification: Notification) {
|
270
|
+
this.read(notification);
|
271
|
+
}
|
272
|
+
|
273
|
+
private toClientNotification(
|
274
|
+
serverNotification: ServerNotification
|
275
|
+
): ClientNotification | undefined {
|
276
|
+
const result: Notification<DefaultServerNotificationPayload> = {
|
277
|
+
...serverNotification,
|
278
|
+
payload: {
|
279
|
+
...JSON.parse(serverNotification.payload ?? '{}'),
|
280
|
+
status: this.toClientStatus(serverNotification.status),
|
281
|
+
},
|
282
|
+
};
|
283
|
+
|
284
|
+
const interceptor = NotificationsStore.interceptors.get(serverNotification.type);
|
285
|
+
if (!interceptor) {
|
286
|
+
return result;
|
287
|
+
}
|
288
|
+
|
289
|
+
const dismiss = () => {
|
290
|
+
const toastId = this.notifications.get(result.id)?.toastId;
|
291
|
+
if (toastId) {
|
292
|
+
toast.dismiss(toastId);
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
return interceptor(result, dismiss);
|
297
|
+
}
|
298
|
+
|
299
|
+
private toClientStatus(status: ServerNotificationStatus) {
|
300
|
+
switch (status) {
|
301
|
+
case ServerNotificationStatus.Success:
|
302
|
+
return Status.Success;
|
303
|
+
case ServerNotificationStatus.Failure:
|
304
|
+
return Status.Error;
|
305
|
+
default:
|
306
|
+
return Status.Info;
|
182
307
|
}
|
183
308
|
}
|
184
309
|
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { dateFromString } from '../date-from-string';
|
2
|
+
|
3
|
+
describe(dateFromString.name, () => {
|
4
|
+
let value: string | Date;
|
5
|
+
|
6
|
+
const subject = () => dateFromString(value);
|
7
|
+
|
8
|
+
describe('with Date value', () => {
|
9
|
+
beforeEach(() => (value = new Date()));
|
10
|
+
|
11
|
+
test('returns value', () => {
|
12
|
+
expect(subject()).toBe(value);
|
13
|
+
});
|
14
|
+
});
|
15
|
+
|
16
|
+
describe('with a ISO date string', () => {
|
17
|
+
const date = new Date(2025, 1, 3, 14, 15, 9, 265);
|
18
|
+
|
19
|
+
beforeEach(() => (value = date.toISOString()));
|
20
|
+
|
21
|
+
test('converts string to date', () => {
|
22
|
+
expect(subject()).toEqual(date);
|
23
|
+
});
|
24
|
+
});
|
25
|
+
|
26
|
+
describe('with a .NET date string', () => {
|
27
|
+
const now = Date.now();
|
28
|
+
|
29
|
+
beforeEach(() => (value = `/Date(${now})/`));
|
30
|
+
|
31
|
+
function itConvertsStringToDate() {
|
32
|
+
test('converts string to date', () => {
|
33
|
+
expect(subject()).toEqual(new Date(now));
|
34
|
+
});
|
35
|
+
}
|
36
|
+
|
37
|
+
itConvertsStringToDate();
|
38
|
+
|
39
|
+
describe('when date has optional local offset', () => {
|
40
|
+
beforeEach(() => (value = `/Date(${now}-0500)/`));
|
41
|
+
|
42
|
+
itConvertsStringToDate();
|
43
|
+
});
|
44
|
+
});
|
45
|
+
|
46
|
+
describe('with unrecognized value', () => {
|
47
|
+
beforeEach(() => (value = 'foo'));
|
48
|
+
|
49
|
+
test('throws error', () => {
|
50
|
+
expect(subject).toThrow('Incorrect date format');
|
51
|
+
});
|
52
|
+
});
|
53
|
+
});
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { renderHook } from '@testing-library/react';
|
2
|
+
import * as ReactRouterDOM from 'react-router-dom';
|
3
|
+
|
4
|
+
import { useCompatibleNavigate } from '../use-compatible-navigate';
|
5
|
+
|
6
|
+
jest.mock('react-router-dom', () => ({
|
7
|
+
useHistory: jest.fn(),
|
8
|
+
useNavigate: jest.fn(),
|
9
|
+
}));
|
10
|
+
|
11
|
+
describe(useCompatibleNavigate.name, () => {
|
12
|
+
const subject = () => renderHook(() => useCompatibleNavigate());
|
13
|
+
|
14
|
+
describe('when useNavigate exists', () => {
|
15
|
+
const navigate = jest.fn();
|
16
|
+
|
17
|
+
beforeEach(() =>
|
18
|
+
jest.mocked((ReactRouterDOM as any).useNavigate).mockReturnValue(navigate)
|
19
|
+
);
|
20
|
+
|
21
|
+
test('returns useNavigate result', () => {
|
22
|
+
const {
|
23
|
+
result: { current: value },
|
24
|
+
} = subject();
|
25
|
+
|
26
|
+
expect(value).toBe(navigate);
|
27
|
+
});
|
28
|
+
|
29
|
+
describe('when useHistory exists', () => {
|
30
|
+
const history: any = { push: jest.fn() };
|
31
|
+
|
32
|
+
beforeEach(() => jest.mocked(ReactRouterDOM.useHistory).mockReturnValue(history));
|
33
|
+
|
34
|
+
test('returns history.push', () => {
|
35
|
+
const {
|
36
|
+
result: { current: value },
|
37
|
+
} = subject();
|
38
|
+
|
39
|
+
expect(value).toBe(history.push);
|
40
|
+
});
|
41
|
+
});
|
42
|
+
});
|
43
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
const dateISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.,]\d+)?Z?$/i;
|
2
|
+
const dateNet = /\/Date\((-?\d+)(?:[+-]\d+)?\)\//i;
|
3
|
+
|
4
|
+
export function dateFromString(date: string | Date) {
|
5
|
+
if (typeof date === 'object') {
|
6
|
+
return date;
|
7
|
+
}
|
8
|
+
|
9
|
+
if (dateISO.test(date)) {
|
10
|
+
const d = date.split(/\D+/).map(s => +s);
|
11
|
+
return new Date(Date.UTC(d[0], --d[1], d[2], d[3], d[4], d[5], d[6]));
|
12
|
+
}
|
13
|
+
|
14
|
+
if (dateNet.test(date)) {
|
15
|
+
const parsedDate = dateNet.exec(date);
|
16
|
+
if (parsedDate !== null) {
|
17
|
+
return new Date(parseInt(parsedDate[1], 10));
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
throw new Error('Incorrect date format');
|
22
|
+
}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"container.test.d.ts","sourceRoot":"","sources":["../../../src/components/__tests__/container.test.tsx"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC"}
|
@@ -1,59 +0,0 @@
|
|
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 { jsx as _jsx } from "react/jsx-runtime";
|
11
|
-
import '@testing-library/jest-dom';
|
12
|
-
import { render, waitFor, within } from '@testing-library/react';
|
13
|
-
import { Container } from '../container';
|
14
|
-
describe('[notifications] Container', () => {
|
15
|
-
beforeEach(() => {
|
16
|
-
var _a;
|
17
|
-
(_a = document.getElementById('servicetitan-notifications')) === null || _a === void 0 ? void 0 : _a.remove();
|
18
|
-
});
|
19
|
-
const subject = (children) => {
|
20
|
-
return render(_jsx(Container, { children: children }));
|
21
|
-
};
|
22
|
-
test('renders #servicetitan-notifications.initialized > .ToastGroup', () => __awaiter(void 0, void 0, void 0, function* () {
|
23
|
-
subject();
|
24
|
-
yield waitFor(() => expect(document.querySelectorAll('#servicetitan-notifications.initialized > .ToastGroup')).toHaveLength(1));
|
25
|
-
}));
|
26
|
-
test('renders children within .ToastGroup', () => __awaiter(void 0, void 0, void 0, function* () {
|
27
|
-
subject(_jsx("button", { children: "Foo" }));
|
28
|
-
yield waitFor(() => {
|
29
|
-
expect(within(document.querySelector('#servicetitan-notifications.initialized > .ToastGroup')).getByRole('button', { name: 'Foo' })).toBeInTheDocument();
|
30
|
-
});
|
31
|
-
}));
|
32
|
-
describe('when #servicetitan-notifications already exists', () => {
|
33
|
-
let container;
|
34
|
-
beforeEach(() => {
|
35
|
-
container = document.createElement('div');
|
36
|
-
container.setAttribute('id', 'servicetitan-notifications');
|
37
|
-
document.body.appendChild(container);
|
38
|
-
});
|
39
|
-
test('creates .ToastGroup within existing container', () => __awaiter(void 0, void 0, void 0, function* () {
|
40
|
-
subject();
|
41
|
-
yield waitFor(() => {
|
42
|
-
expect(container.querySelectorAll('.ToastGroup')).toHaveLength(1);
|
43
|
-
});
|
44
|
-
}));
|
45
|
-
describe('when .ToastGroup already exists', () => {
|
46
|
-
let toastGroup;
|
47
|
-
beforeEach(() => {
|
48
|
-
toastGroup = document.createElement('div');
|
49
|
-
toastGroup.classList.add('ToastGroup');
|
50
|
-
container.appendChild(toastGroup);
|
51
|
-
});
|
52
|
-
test('renders children inside existing ToastGroup', () => {
|
53
|
-
subject(_jsx("button", { children: "Baz" }));
|
54
|
-
expect(within(toastGroup).getByRole('button', { name: 'Baz' })).toBeInTheDocument();
|
55
|
-
});
|
56
|
-
});
|
57
|
-
});
|
58
|
-
});
|
59
|
-
//# sourceMappingURL=container.test.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"container.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/container.test.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,2BAA2B,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACvC,UAAU,CAAC,GAAG,EAAE;;QACZ,MAAA,QAAQ,CAAC,cAAc,CAAC,4BAA4B,CAAC,0CAAE,MAAM,EAAE,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,CAAC,QAAoB,EAAE,EAAE;QACrC,OAAO,MAAM,CAAC,KAAC,SAAS,cAAE,QAAQ,GAAa,CAAC,CAAC;IACrD,CAAC,CAAC;IAEF,IAAI,CAAC,+DAA+D,EAAE,GAAS,EAAE;QAC7E,OAAO,EAAE,CAAC;QAEV,MAAM,OAAO,CAAC,GAAG,EAAE,CACf,MAAM,CACF,QAAQ,CAAC,gBAAgB,CAAC,uDAAuD,CAAC,CACrF,CAAC,YAAY,CAAC,CAAC,CAAC,CACpB,CAAC;IACN,CAAC,CAAA,CAAC,CAAC;IAEH,IAAI,CAAC,qCAAqC,EAAE,GAAS,EAAE;QACnD,OAAO,CAAC,mCAAoB,CAAC,CAAC;QAE9B,MAAM,OAAO,CAAC,GAAG,EAAE;YACf,MAAM,CACF,MAAM,CACF,QAAQ,CAAC,aAAa,CAAC,uDAAuD,CAAE,CACnF,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CACzC,CAAC,iBAAiB,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACP,CAAC,CAAA,CAAC,CAAC;IAEH,QAAQ,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC7D,IAAI,SAAsB,CAAC;QAE3B,UAAU,CAAC,GAAG,EAAE;YACZ,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1C,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;YAC3D,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,+CAA+C,EAAE,GAAS,EAAE;YAC7D,OAAO,EAAE,CAAC;YAEV,MAAM,OAAO,CAAC,GAAG,EAAE;gBACf,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACtE,CAAC,CAAC,CAAC;QACP,CAAC,CAAA,CAAC,CAAC;QAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;YAC7C,IAAI,UAAuB,CAAC;YAE5B,UAAU,CAAC,GAAG,EAAE;gBACZ,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC3C,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBACvC,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;gBACrD,OAAO,CAAC,mCAAoB,CAAC,CAAC;gBAE9B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;YACxF,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/components/container.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAY,iBAAiB,EAAuB,MAAM,OAAO,CAAC;AAK7E,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,iBAAiB,CAwB3C,CAAC"}
|
@@ -1,26 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { Toast } from '@servicetitan/design-system';
|
3
|
-
import { Fragment, useEffect, useState } from 'react';
|
4
|
-
import { createPortal } from 'react-dom';
|
5
|
-
import { createElement } from '../create-element';
|
6
|
-
export const Container = ({ children }) => {
|
7
|
-
const [container] = useState(() => {
|
8
|
-
var _a;
|
9
|
-
return ((_a = document.getElementById('servicetitan-notifications')) !== null && _a !== void 0 ? _a : document.body.appendChild(createElement('div', { id: 'servicetitan-notifications' })));
|
10
|
-
});
|
11
|
-
const [toastGroup, setToastGroup] = useState(() => findToastGroup(container));
|
12
|
-
const [foundGroup] = useState(() => !!toastGroup);
|
13
|
-
useEffect(() => {
|
14
|
-
if (!toastGroup) {
|
15
|
-
setToastGroup(findToastGroup(container));
|
16
|
-
// This stops old code running in MFE from rendering duplicate Toast.Group
|
17
|
-
container.classList.add('initialized');
|
18
|
-
}
|
19
|
-
}, [container, toastGroup]);
|
20
|
-
return (_jsxs(Fragment, { children: [foundGroup ? null : _jsx(Toast.Group, { portal: container }), toastGroup ? createPortal(children, toastGroup) : null] }));
|
21
|
-
};
|
22
|
-
function findToastGroup(parent) {
|
23
|
-
var _a;
|
24
|
-
return (_a = parent.getElementsByClassName('ToastGroup')[0]) !== null && _a !== void 0 ? _a : null;
|
25
|
-
}
|
26
|
-
//# sourceMappingURL=container.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/components/container.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,OAAO,EAAM,QAAQ,EAAqB,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,SAAS,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC7D,MAAM,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE;;QAC9B,OAAO,CACH,MAAA,QAAQ,CAAC,cAAc,CAAC,4BAA4B,CAAC,mCACrD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,4BAA4B,EAAE,CAAC,CAAC,CACxF,CAAC;IACN,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9E,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAElD,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;YACzC,0EAA0E;YAC1E,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAE5B,OAAO,CACH,MAAC,QAAQ,eACJ,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,KAAK,CAAC,KAAK,IAAC,MAAM,EAAE,SAAS,GAAI,EACtD,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAChD,CACd,CAAC;AACN,CAAC,CAAC;AAEF,SAAS,cAAc,CAAC,MAAmB;;IACvC,OAAO,MAAA,MAAM,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,mCAAI,IAAI,CAAC;AAClE,CAAC"}
|
@@ -1,7 +0,0 @@
|
|
1
|
-
import { FC } from 'react';
|
2
|
-
import { DefaultNotificationOptions } from '../common';
|
3
|
-
export interface DefaultNotificationProps extends DefaultNotificationOptions {
|
4
|
-
onClose(): void;
|
5
|
-
}
|
6
|
-
export declare const DefaultNotification: FC<DefaultNotificationProps>;
|
7
|
-
//# sourceMappingURL=default-notification.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"default-notification.d.ts","sourceRoot":"","sources":["../../src/components/default-notification.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAK3B,OAAO,EAAE,0BAA0B,EAAwB,MAAM,WAAW,CAAC;AAI7E,MAAM,WAAW,wBAAyB,SAAQ,0BAA0B;IACxE,OAAO,IAAI,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CA6C5D,CAAC"}
|
@@ -1,26 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { Toast, ProgressBar } from '@servicetitan/design-system';
|
3
|
-
import { useCompatibleNavigate } from '../utils/use-compatible-navigate';
|
4
|
-
import { Status, isLinkAction } from '../common';
|
5
|
-
import * as Styles from './default-notification.module.css';
|
6
|
-
export const DefaultNotification = ({ status = Status.Info, title, message, duration, progress, action, onClose, }) => {
|
7
|
-
const navigate = useCompatibleNavigate();
|
8
|
-
const handleActionClick = () => {
|
9
|
-
if (action) {
|
10
|
-
if (isLinkAction(action)) {
|
11
|
-
if (action.external) {
|
12
|
-
window.open(action.link);
|
13
|
-
}
|
14
|
-
else {
|
15
|
-
navigate(action.link);
|
16
|
-
}
|
17
|
-
}
|
18
|
-
else {
|
19
|
-
action.onClick();
|
20
|
-
}
|
21
|
-
}
|
22
|
-
onClose();
|
23
|
-
};
|
24
|
-
return (_jsxs(Toast, { portal: false, status: status, title: title, duration: duration, primaryActionName: action === null || action === void 0 ? void 0 : action.label, onPrimaryActionClick: handleActionClick, className: Styles.defaultNotification, onClose: onClose, children: [_jsx("div", { className: Styles.message, children: message }), progress != null && (_jsx(ProgressBar, { progress: progress, small: true, blue: true, className: message && 'm-t-1' }))] }));
|
25
|
-
};
|
26
|
-
//# sourceMappingURL=default-notification.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"default-notification.js","sourceRoot":"","sources":["../../src/components/default-notification.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAA8B,MAAM,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE7E,OAAO,KAAK,MAAM,MAAM,mCAAmC,CAAC;AAM5D,MAAM,CAAC,MAAM,mBAAmB,GAAiC,CAAC,EAC9D,MAAM,GAAG,MAAM,CAAC,IAAI,EACpB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,OAAO,GACV,EAAE,EAAE;IACD,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IAEzC,MAAM,iBAAiB,GAAG,GAAG,EAAE;QAC3B,IAAI,MAAM,EAAE,CAAC;YACT,IAAI,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACJ,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACd,CAAC,CAAC;IAEF,OAAO,CACH,MAAC,KAAK,IACF,MAAM,EAAE,KAAK,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAChC,oBAAoB,EAAE,iBAAiB,EACvC,SAAS,EAAE,MAAM,CAAC,mBAAmB,EACrC,OAAO,EAAE,OAAO,aAEhB,cAAK,SAAS,EAAE,MAAM,CAAC,OAAO,YAAG,OAAO,GAAO,EAE9C,QAAQ,IAAI,IAAI,IAAI,CACjB,KAAC,WAAW,IAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,QAAC,IAAI,QAAC,SAAS,EAAE,OAAO,IAAI,OAAO,GAAI,CAChF,IACG,CACX,CAAC;AACN,CAAC,CAAC"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"no-ssr.d.ts","sourceRoot":"","sources":["../../src/components/no-ssr.tsx"],"names":[],"mappings":";AAEA,eAAO,MAAM,KAAK,iBAAkB;IAAE,QAAQ,EAAE,WAAW,CAAA;CAAE,uBAQ5D,CAAC"}
|
@@ -1,9 +0,0 @@
|
|
1
|
-
import { useState, useEffect } from 'react';
|
2
|
-
export const NoSSR = ({ children }) => {
|
3
|
-
const [isMounted, setIsMounted] = useState(false);
|
4
|
-
useEffect(() => {
|
5
|
-
setIsMounted(true);
|
6
|
-
}, []);
|
7
|
-
return isMounted ? children : null;
|
8
|
-
};
|
9
|
-
//# sourceMappingURL=no-ssr.js.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"no-ssr.js","sourceRoot":"","sources":["../../src/components/no-ssr.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,QAAQ,EAA6B,EAAE,EAAE;IAC7D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,SAAS,CAAC,GAAG,EAAE;QACX,YAAY,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC,CAAC"}
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"notifications-unwrapped.d.ts","sourceRoot":"","sources":["../../src/components/notifications-unwrapped.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,EAAE,EAAE,MAAM,OAAO,CAAC;AAatC,eAAO,MAAM,sBAAsB,EAAE,EAqCnC,CAAC"}
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useEffect } from 'react';
|
3
|
-
import { useDependencies, useOptionalDependencies } from '@servicetitan/react-ioc';
|
4
|
-
import { IS_WEB_COMPONENT_TOKEN } from '@servicetitan/web-components';
|
5
|
-
import { observer } from 'mobx-react';
|
6
|
-
import { NotificationsStore } from '../stores/notifications.store';
|
7
|
-
import { ShadowDOM } from './shadow-dom';
|
8
|
-
import { Container } from './container';
|
9
|
-
import { NoSSR } from './no-ssr';
|
10
|
-
export const NotificationsUnwrapped = observer(() => {
|
11
|
-
const [isWebComponent] = useOptionalDependencies(IS_WEB_COMPONENT_TOKEN);
|
12
|
-
const [store] = useDependencies(NotificationsStore);
|
13
|
-
useEffect(() => {
|
14
|
-
return () => store.dispose();
|
15
|
-
}, [store]);
|
16
|
-
return (_jsx(NoSSR, { children: _jsx(Container, { children: store.notifications.map(notification => {
|
17
|
-
const Component = NotificationsStore.types.get(notification.type);
|
18
|
-
if (!Component) {
|
19
|
-
return null;
|
20
|
-
}
|
21
|
-
const handleClose = () => {
|
22
|
-
store.read(notification);
|
23
|
-
};
|
24
|
-
return isWebComponent ? (_jsx(ShadowDOM, { children: _jsx(Component, { notification: notification, onClose: handleClose }) }, `${notification.id}_${notification.status}`)) : (_jsx(Component, { notification: notification, onClose: handleClose }, `${notification.id}_${notification.status}`));
|
25
|
-
}) }) }));
|
26
|
-
});
|
27
|
-
//# sourceMappingURL=notifications-unwrapped.js.map
|