@novu/react 3.3.1 → 3.5.0-rc.1
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/cjs/components/Inbox.cjs +65 -61
- package/dist/cjs/components/Inbox.cjs.map +1 -1
- package/dist/cjs/components/NovuUI.cjs +59 -10
- package/dist/cjs/components/NovuUI.cjs.map +1 -1
- package/dist/cjs/components/NovuUI.d.cts +6 -2
- package/dist/cjs/components/ShadowRootDetector.cjs +63 -0
- package/dist/cjs/components/ShadowRootDetector.cjs.map +1 -0
- package/dist/cjs/components/ShadowRootDetector.d.cts +5 -0
- package/dist/cjs/hooks/NovuProvider.cjs +1 -1
- package/dist/cjs/hooks/useNotifications.cjs +8 -7
- package/dist/cjs/hooks/useNotifications.cjs.map +1 -1
- package/dist/cjs/hooks/useNotifications.d.cts +1 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/server/index.cjs +3 -0
- package/dist/cjs/server/index.cjs.map +1 -1
- package/dist/cjs/server/index.d.cts +3 -3
- package/dist/cjs/utils/appearance.cjs +53 -0
- package/dist/cjs/utils/appearance.cjs.map +1 -0
- package/dist/cjs/utils/appearance.d.cts +10 -0
- package/dist/cjs/utils/types.cjs.map +1 -1
- package/dist/cjs/utils/types.d.cts +18 -3
- package/dist/esm/components/Inbox.js +65 -61
- package/dist/esm/components/Inbox.js.map +1 -1
- package/dist/esm/components/NovuUI.d.ts +6 -2
- package/dist/esm/components/NovuUI.js +61 -12
- package/dist/esm/components/NovuUI.js.map +1 -1
- package/dist/esm/components/ShadowRootDetector.d.ts +5 -0
- package/dist/esm/components/ShadowRootDetector.js +28 -0
- package/dist/esm/components/ShadowRootDetector.js.map +1 -0
- package/dist/esm/hooks/NovuProvider.js +1 -1
- package/dist/esm/hooks/useNotifications.d.ts +1 -0
- package/dist/esm/hooks/useNotifications.js +8 -7
- package/dist/esm/hooks/useNotifications.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/server/index.d.ts +3 -3
- package/dist/esm/server/index.js +3 -0
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/utils/appearance.d.ts +10 -0
- package/dist/esm/utils/appearance.js +28 -0
- package/dist/esm/utils/appearance.js.map +1 -0
- package/dist/esm/utils/types.d.ts +18 -3
- package/package.json +9 -9
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/utils/appearance.ts
|
|
21
|
+
var appearance_exports = {};
|
|
22
|
+
__export(appearance_exports, {
|
|
23
|
+
adaptAppearanceForJs: () => adaptAppearanceForJs
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(appearance_exports);
|
|
26
|
+
function adaptAppearanceForJs(appearance, mountElement) {
|
|
27
|
+
if (!appearance) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
const jsAppearance = JSON.parse(JSON.stringify(appearance));
|
|
31
|
+
if (appearance.icons) {
|
|
32
|
+
const jsIcons = {};
|
|
33
|
+
const reactIcons = appearance.icons;
|
|
34
|
+
const iconKeys = Object.keys(reactIcons);
|
|
35
|
+
for (const iconKey of iconKeys) {
|
|
36
|
+
const reactRenderer = reactIcons[iconKey];
|
|
37
|
+
if (reactRenderer) {
|
|
38
|
+
jsIcons[iconKey] = (el, props) => {
|
|
39
|
+
return mountElement(el, reactRenderer(props));
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
jsAppearance.icons = jsIcons;
|
|
44
|
+
} else {
|
|
45
|
+
delete jsAppearance.icons;
|
|
46
|
+
}
|
|
47
|
+
return jsAppearance;
|
|
48
|
+
}
|
|
49
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
50
|
+
0 && (module.exports = {
|
|
51
|
+
adaptAppearanceForJs
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=appearance.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/appearance.ts"],"sourcesContent":["import type { Appearance as JsAppearance, IconRenderer, IconOverrides as JsIconOverrides, IconKey } from '@novu/js/ui';\n\nimport type { ReactAppearance, ReactIconRenderer } from './types';\nimport { MountedElement } from '../context/RendererContext';\n\nexport function adaptAppearanceForJs(\n appearance: ReactAppearance,\n mountElement: (el: HTMLElement, mountedElement: MountedElement) => () => void\n): JsAppearance | undefined {\n if (!appearance) {\n return undefined;\n }\n\n const jsAppearance: JsAppearance = JSON.parse(JSON.stringify(appearance));\n\n if (appearance.icons) {\n const jsIcons: JsIconOverrides = {};\n const reactIcons = appearance.icons;\n const iconKeys = Object.keys(reactIcons) as IconKey[];\n\n for (const iconKey of iconKeys) {\n const reactRenderer = reactIcons[iconKey];\n\n if (reactRenderer) {\n jsIcons[iconKey] = (el: HTMLDivElement, props: { class?: string }) => {\n return mountElement(el, reactRenderer(props));\n };\n }\n }\n\n // JsAppearance also has .icons directly (from JsTheme part of JsAppearance)\n jsAppearance.icons = jsIcons;\n } else {\n // If original didn't have icons, ensure the clone doesn't either\n delete jsAppearance.icons;\n }\n\n return jsAppearance;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKO,SAAS,qBACd,YACA,cAC0B;AAC1B,MAAI,CAAC,YAAY;AACf,WAAO;AAAA,EACT;AAEA,QAAM,eAA6B,KAAK,MAAM,KAAK,UAAU,UAAU,CAAC;AAExE,MAAI,WAAW,OAAO;AACpB,UAAM,UAA2B,CAAC;AAClC,UAAM,aAAa,WAAW;AAC9B,UAAM,WAAW,OAAO,KAAK,UAAU;AAEvC,eAAW,WAAW,UAAU;AAC9B,YAAM,gBAAgB,WAAW,OAAO;AAExC,UAAI,eAAe;AACjB,gBAAQ,OAAO,IAAI,CAAC,IAAoB,UAA8B;AACpE,iBAAO,aAAa,IAAI,cAAc,KAAK,CAAC;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAGA,iBAAa,QAAQ;AAAA,EACvB,OAAO;AAEL,WAAO,aAAa;AAAA,EACtB;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Appearance } from '@novu/js/ui';
|
|
2
|
+
import { ReactAppearance } from './types.cjs';
|
|
3
|
+
import { MountedElement } from '../context/RendererContext.cjs';
|
|
4
|
+
import '@novu/js';
|
|
5
|
+
import 'react';
|
|
6
|
+
import 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
declare function adaptAppearanceForJs(appearance: ReactAppearance, mountElement: (el: HTMLElement, mountedElement: MountedElement) => () => void): Appearance | undefined;
|
|
9
|
+
|
|
10
|
+
export { adaptAppearanceForJs };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/types.ts"],"sourcesContent":["import type {\n Notification,\n NotificationClickHandler,\n NotificationActionClickHandler,\n Tab,\n Appearance,\n Localization,\n RouterPush,\n PreferencesFilter,\n InboxProps,\n} from '@novu/js/ui';\nimport type { Subscriber } from '@novu/js';\n\nexport type NotificationsRenderer = (notification: Notification) => React.ReactNode;\nexport type SubjectRenderer = (notification: Notification) => React.ReactNode;\nexport type BodyRenderer = (notification: Notification) => React.ReactNode;\nexport type BellRenderer = (unreadCount: number) => React.ReactNode;\n\nexport type DefaultInboxProps = {\n open?: boolean;\n renderNotification?: NotificationsRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderBell?: BellRenderer;\n onNotificationClick?: NotificationClickHandler;\n onPrimaryActionClick?: NotificationActionClickHandler;\n onSecondaryActionClick?: NotificationActionClickHandler;\n placement?: InboxProps['placement'];\n placementOffset?: InboxProps['placementOffset'];\n};\n\nexport type BaseProps = {\n applicationIdentifier: string;\n subscriberHash?: string;\n backendUrl?: string;\n socketUrl?: string;\n appearance?:
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/types.ts"],"sourcesContent":["import type {\n Notification,\n NotificationClickHandler,\n NotificationActionClickHandler,\n Tab,\n Appearance as JsAppearance,\n Theme as JsTheme,\n IconKey,\n Localization,\n RouterPush,\n PreferencesFilter,\n PreferenceGroups,\n InboxProps,\n InboxPage,\n} from '@novu/js/ui';\nimport type { Subscriber } from '@novu/js';\nimport type { ReactNode } from 'react';\n\nexport type NotificationsRenderer = (notification: Notification) => React.ReactNode;\nexport type SubjectRenderer = (notification: Notification) => React.ReactNode;\nexport type BodyRenderer = (notification: Notification) => React.ReactNode;\nexport type BellRenderer = (unreadCount: number) => React.ReactNode;\n\nexport type ReactIconRendererProps = { class?: string };\nexport type ReactIconRenderer = (props: ReactIconRendererProps) => ReactNode;\n\nexport type ReactIconOverrides = {\n [key in IconKey]?: ReactIconRenderer;\n};\n\nexport type ReactTheme = Omit<JsTheme, 'icons'> & {\n icons?: ReactIconOverrides;\n};\n\nexport type ReactAppearance = ReactTheme & {\n baseTheme?: JsTheme | JsTheme[];\n};\n\nexport type DefaultInboxProps = {\n open?: boolean;\n renderNotification?: NotificationsRenderer;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n renderBell?: BellRenderer;\n onNotificationClick?: NotificationClickHandler;\n onPrimaryActionClick?: NotificationActionClickHandler;\n onSecondaryActionClick?: NotificationActionClickHandler;\n placement?: InboxProps['placement'];\n placementOffset?: InboxProps['placementOffset'];\n};\n\nexport type BaseProps = {\n applicationIdentifier: string;\n subscriberHash?: string;\n backendUrl?: string;\n socketUrl?: string;\n appearance?: ReactAppearance;\n localization?: Localization;\n tabs?: Array<Tab>;\n preferencesFilter?: PreferencesFilter;\n preferenceGroups?: PreferenceGroups;\n routerPush?: RouterPush;\n} & (\n | {\n // TODO: Backward compatibility support - remove in future versions (see NV-5801)\n /** @deprecated Use subscriber prop instead */\n subscriberId: string;\n subscriber?: never;\n }\n | {\n subscriber: Subscriber | string;\n subscriberId?: never;\n }\n);\n\nexport type NotificationRendererProps = {\n renderNotification: NotificationsRenderer;\n renderSubject?: never;\n renderBody?: never;\n};\n\nexport type SubjectBodyRendererProps = {\n renderNotification?: never;\n renderSubject?: SubjectRenderer;\n renderBody?: BodyRenderer;\n};\n\nexport type NoRendererProps = {\n renderNotification?: undefined;\n renderSubject?: undefined;\n renderBody?: undefined;\n};\n\nexport type DefaultProps = BaseProps &\n DefaultInboxProps & {\n children?: never;\n } & (NotificationRendererProps | SubjectBodyRendererProps | NoRendererProps);\n\nexport type WithChildrenProps = BaseProps & {\n children: React.ReactNode;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import { Notification, NotificationClickHandler, NotificationActionClickHandler, InboxProps,
|
|
1
|
+
import { Notification, IconKey, Theme, NotificationClickHandler, NotificationActionClickHandler, InboxProps, Localization, Tab, PreferencesFilter, PreferenceGroups, RouterPush } from '@novu/js/ui';
|
|
2
2
|
import { Subscriber } from '@novu/js';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
3
4
|
|
|
4
5
|
type NotificationsRenderer = (notification: Notification) => React.ReactNode;
|
|
5
6
|
type SubjectRenderer = (notification: Notification) => React.ReactNode;
|
|
6
7
|
type BodyRenderer = (notification: Notification) => React.ReactNode;
|
|
7
8
|
type BellRenderer = (unreadCount: number) => React.ReactNode;
|
|
9
|
+
type ReactIconRendererProps = {
|
|
10
|
+
class?: string;
|
|
11
|
+
};
|
|
12
|
+
type ReactIconRenderer = (props: ReactIconRendererProps) => ReactNode;
|
|
13
|
+
type ReactIconOverrides = {
|
|
14
|
+
[key in IconKey]?: ReactIconRenderer;
|
|
15
|
+
};
|
|
16
|
+
type ReactTheme = Omit<Theme, 'icons'> & {
|
|
17
|
+
icons?: ReactIconOverrides;
|
|
18
|
+
};
|
|
19
|
+
type ReactAppearance = ReactTheme & {
|
|
20
|
+
baseTheme?: Theme | Theme[];
|
|
21
|
+
};
|
|
8
22
|
type DefaultInboxProps = {
|
|
9
23
|
open?: boolean;
|
|
10
24
|
renderNotification?: NotificationsRenderer;
|
|
@@ -22,10 +36,11 @@ type BaseProps = {
|
|
|
22
36
|
subscriberHash?: string;
|
|
23
37
|
backendUrl?: string;
|
|
24
38
|
socketUrl?: string;
|
|
25
|
-
appearance?:
|
|
39
|
+
appearance?: ReactAppearance;
|
|
26
40
|
localization?: Localization;
|
|
27
41
|
tabs?: Array<Tab>;
|
|
28
42
|
preferencesFilter?: PreferencesFilter;
|
|
43
|
+
preferenceGroups?: PreferenceGroups;
|
|
29
44
|
routerPush?: RouterPush;
|
|
30
45
|
} & ({
|
|
31
46
|
/** @deprecated Use subscriber prop instead */
|
|
@@ -57,4 +72,4 @@ type WithChildrenProps = BaseProps & {
|
|
|
57
72
|
children: React.ReactNode;
|
|
58
73
|
};
|
|
59
74
|
|
|
60
|
-
export type { BaseProps, BellRenderer, BodyRenderer, DefaultInboxProps, DefaultProps, NoRendererProps, NotificationRendererProps, NotificationsRenderer, SubjectBodyRendererProps, SubjectRenderer, WithChildrenProps };
|
|
75
|
+
export type { BaseProps, BellRenderer, BodyRenderer, DefaultInboxProps, DefaultProps, NoRendererProps, NotificationRendererProps, NotificationsRenderer, ReactAppearance, ReactIconOverrides, ReactIconRenderer, ReactIconRendererProps, ReactTheme, SubjectBodyRendererProps, SubjectRenderer, WithChildrenProps };
|
|
@@ -7,7 +7,7 @@ import { InternalNovuProvider, useNovu, useUnsafeNovu } from "../hooks/NovuProvi
|
|
|
7
7
|
import { NovuUI } from "./NovuUI.js";
|
|
8
8
|
import { withRenderer } from "./Renderer.js";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
10
|
-
var
|
|
10
|
+
var DefaultInbox = (props) => {
|
|
11
11
|
const {
|
|
12
12
|
open,
|
|
13
13
|
renderNotification,
|
|
@@ -69,7 +69,6 @@ var _DefaultInbox = (props) => {
|
|
|
69
69
|
);
|
|
70
70
|
return /* @__PURE__ */ jsx(Mounter, { mount });
|
|
71
71
|
};
|
|
72
|
-
var DefaultInbox = withRenderer(_DefaultInbox);
|
|
73
72
|
var Inbox = React.memo((props) => {
|
|
74
73
|
const { applicationIdentifier, subscriberHash, backendUrl, socketUrl } = props;
|
|
75
74
|
const novu = useUnsafeNovu();
|
|
@@ -89,65 +88,55 @@ var Inbox = React.memo((props) => {
|
|
|
89
88
|
}
|
|
90
89
|
);
|
|
91
90
|
});
|
|
92
|
-
var InboxChild =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
appearance,
|
|
96
|
-
tabs,
|
|
97
|
-
preferencesFilter,
|
|
98
|
-
routerPush,
|
|
99
|
-
applicationIdentifier,
|
|
100
|
-
subscriberId,
|
|
101
|
-
subscriberHash,
|
|
102
|
-
backendUrl,
|
|
103
|
-
socketUrl
|
|
104
|
-
} = props;
|
|
105
|
-
const novu = useNovu();
|
|
106
|
-
const options = useMemo(() => {
|
|
107
|
-
return {
|
|
91
|
+
var InboxChild = withRenderer(
|
|
92
|
+
React.memo((props) => {
|
|
93
|
+
const {
|
|
108
94
|
localization,
|
|
109
95
|
appearance,
|
|
110
96
|
tabs,
|
|
111
97
|
preferencesFilter,
|
|
98
|
+
preferenceGroups,
|
|
112
99
|
routerPush,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
100
|
+
applicationIdentifier,
|
|
101
|
+
subscriberId,
|
|
102
|
+
subscriberHash,
|
|
103
|
+
backendUrl,
|
|
104
|
+
socketUrl
|
|
105
|
+
} = props;
|
|
106
|
+
const novu = useNovu();
|
|
107
|
+
const options = useMemo(() => {
|
|
108
|
+
return {
|
|
109
|
+
localization,
|
|
110
|
+
appearance,
|
|
111
|
+
tabs,
|
|
112
|
+
preferencesFilter,
|
|
113
|
+
preferenceGroups,
|
|
114
|
+
routerPush,
|
|
115
|
+
options: {
|
|
116
|
+
applicationIdentifier,
|
|
117
|
+
subscriberHash,
|
|
118
|
+
backendUrl,
|
|
119
|
+
socketUrl,
|
|
120
|
+
subscriber: buildSubscriber(props)
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}, [
|
|
124
|
+
localization,
|
|
125
|
+
appearance,
|
|
126
|
+
tabs,
|
|
127
|
+
preferencesFilter,
|
|
128
|
+
preferenceGroups,
|
|
129
|
+
applicationIdentifier,
|
|
130
|
+
subscriberId,
|
|
131
|
+
subscriberHash,
|
|
132
|
+
backendUrl,
|
|
133
|
+
socketUrl,
|
|
134
|
+
props.subscriber
|
|
135
|
+
]);
|
|
136
|
+
if (isWithChildrenProps(props)) {
|
|
137
|
+
return /* @__PURE__ */ jsx(NovuUI, { options, novu, children: props.children });
|
|
138
|
+
}
|
|
139
|
+
const {
|
|
151
140
|
open,
|
|
152
141
|
renderNotification,
|
|
153
142
|
renderSubject,
|
|
@@ -156,11 +145,26 @@ var InboxChild = React.memo((props) => {
|
|
|
156
145
|
onNotificationClick,
|
|
157
146
|
onPrimaryActionClick,
|
|
158
147
|
onSecondaryActionClick,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
148
|
+
placementOffset,
|
|
149
|
+
placement
|
|
150
|
+
} = props;
|
|
151
|
+
return /* @__PURE__ */ jsx(NovuUI, { options, novu, children: /* @__PURE__ */ jsx(
|
|
152
|
+
DefaultInbox,
|
|
153
|
+
{
|
|
154
|
+
open,
|
|
155
|
+
renderNotification,
|
|
156
|
+
renderSubject,
|
|
157
|
+
renderBody,
|
|
158
|
+
renderBell,
|
|
159
|
+
onNotificationClick,
|
|
160
|
+
onPrimaryActionClick,
|
|
161
|
+
onSecondaryActionClick,
|
|
162
|
+
placement,
|
|
163
|
+
placementOffset
|
|
164
|
+
}
|
|
165
|
+
) });
|
|
166
|
+
})
|
|
167
|
+
);
|
|
164
168
|
function isWithChildrenProps(props) {
|
|
165
169
|
return "children" in props;
|
|
166
170
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { Subscriber } from '@novu/js';\nimport { DefaultProps, DefaultInboxProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Inbox.tsx"],"sourcesContent":["import React, { useMemo } from 'react';\nimport { Subscriber } from '@novu/js';\nimport { DefaultProps, DefaultInboxProps, WithChildrenProps } from '../utils/types';\nimport { Mounter } from './Mounter';\nimport { useNovuUI } from '../context/NovuUIContext';\nimport { useRenderer } from '../context/RendererContext';\nimport { InternalNovuProvider, useNovu, useUnsafeNovu } from '../hooks/NovuProvider';\nimport { NovuUI } from './NovuUI';\nimport { withRenderer } from './Renderer';\n\nexport type InboxProps = DefaultProps | WithChildrenProps;\n\nconst DefaultInbox = (props: DefaultInboxProps) => {\n const {\n open,\n renderNotification,\n renderSubject,\n renderBody,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placement,\n placementOffset,\n } = props;\n const { novuUI } = useNovuUI();\n const { mountElement } = useRenderer();\n\n const mount = React.useCallback(\n (element: HTMLElement) => {\n if (renderNotification) {\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderNotification: renderNotification\n ? (el, notification) => mountElement(el, renderNotification(notification))\n : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n }\n\n return novuUI.mountComponent({\n name: 'Inbox',\n props: {\n open,\n renderSubject: renderSubject\n ? (el, notification) => mountElement(el, renderSubject(notification))\n : undefined,\n renderBody: renderBody ? (el, notification) => mountElement(el, renderBody(notification)) : undefined,\n renderBell: renderBell ? (el, unreadCount) => mountElement(el, renderBell(unreadCount)) : undefined,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n },\n element,\n });\n },\n [\n open,\n renderNotification,\n renderSubject,\n renderBody,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n ]\n );\n\n return <Mounter mount={mount} />;\n};\n\nexport const Inbox = React.memo((props: InboxProps) => {\n const { applicationIdentifier, subscriberHash, backendUrl, socketUrl } = props;\n const novu = useUnsafeNovu();\n\n if (novu) {\n return <InboxChild {...props} />;\n }\n\n return (\n <InternalNovuProvider\n applicationIdentifier={applicationIdentifier}\n subscriberHash={subscriberHash}\n backendUrl={backendUrl}\n socketUrl={socketUrl}\n subscriber={buildSubscriber(props)}\n userAgentType=\"components\"\n >\n <InboxChild {...props} />\n </InternalNovuProvider>\n );\n});\n\nconst InboxChild = withRenderer(\n React.memo((props: InboxProps) => {\n const {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n routerPush,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n } = props;\n const novu = useNovu();\n\n const options = useMemo(() => {\n return {\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n routerPush,\n options: {\n applicationIdentifier,\n subscriberHash,\n backendUrl,\n socketUrl,\n subscriber: buildSubscriber(props),\n },\n };\n }, [\n localization,\n appearance,\n tabs,\n preferencesFilter,\n preferenceGroups,\n applicationIdentifier,\n subscriberId,\n subscriberHash,\n backendUrl,\n socketUrl,\n props.subscriber,\n ]);\n\n if (isWithChildrenProps(props)) {\n return (\n <NovuUI options={options} novu={novu}>\n {props.children}\n </NovuUI>\n );\n }\n\n const {\n open,\n renderNotification,\n renderSubject,\n renderBody,\n renderBell,\n onNotificationClick,\n onPrimaryActionClick,\n onSecondaryActionClick,\n placementOffset,\n placement,\n } = props;\n\n return (\n <NovuUI options={options} novu={novu}>\n <DefaultInbox\n open={open}\n renderNotification={renderNotification}\n renderSubject={renderSubject}\n renderBody={renderBody}\n renderBell={renderBell}\n onNotificationClick={onNotificationClick}\n onPrimaryActionClick={onPrimaryActionClick}\n onSecondaryActionClick={onSecondaryActionClick}\n placement={placement}\n placementOffset={placementOffset}\n />\n </NovuUI>\n );\n })\n);\n\nfunction isWithChildrenProps(props: InboxProps): props is WithChildrenProps {\n return 'children' in props;\n}\n\nfunction buildSubscriber(options: InboxProps): Subscriber {\n let subscriberObj: Subscriber;\n\n if (options.subscriber) {\n subscriberObj = typeof options.subscriber === 'string' ? { subscriberId: options.subscriber } : options.subscriber;\n } else {\n subscriberObj = { subscriberId: options.subscriberId as string };\n }\n\n return subscriberObj;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,11 +2,15 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { Novu } from '@novu/js';
|
|
3
3
|
import { NovuUIOptions } from '@novu/js/ui';
|
|
4
4
|
import React__default from 'react';
|
|
5
|
+
import { ReactAppearance } from '../utils/types.js';
|
|
5
6
|
|
|
7
|
+
type NovuUIProps = Omit<NovuUIOptions, 'appearance'> & {
|
|
8
|
+
appearance?: ReactAppearance;
|
|
9
|
+
};
|
|
6
10
|
type RendererProps = React__default.PropsWithChildren<{
|
|
7
|
-
options:
|
|
11
|
+
options: NovuUIProps;
|
|
8
12
|
novu?: Novu;
|
|
9
13
|
}>;
|
|
10
|
-
declare const NovuUI: ({ options, novu, children }: RendererProps) => react_jsx_runtime.JSX.Element
|
|
14
|
+
declare const NovuUI: ({ options, novu, children }: RendererProps) => react_jsx_runtime.JSX.Element;
|
|
11
15
|
|
|
12
16
|
export { NovuUI };
|
|
@@ -1,33 +1,82 @@
|
|
|
1
1
|
// src/components/NovuUI.tsx
|
|
2
2
|
import { NovuUI as NovuUIClass } from "@novu/js/ui";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { NovuUIProvider } from "../context/NovuUIContext.js";
|
|
5
5
|
import { useDataRef } from "../hooks/internal/useDataRef.js";
|
|
6
|
-
import {
|
|
6
|
+
import { adaptAppearanceForJs } from "../utils/appearance.js";
|
|
7
|
+
import { useRenderer } from "../context/RendererContext.js";
|
|
8
|
+
import { ShadowRootDetector } from "./ShadowRootDetector.js";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
var findParentShadowRoot = (child) => {
|
|
11
|
+
if (!child) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
let node = child;
|
|
15
|
+
while (node) {
|
|
16
|
+
if (node instanceof Element && node.shadowRoot) {
|
|
17
|
+
return node.shadowRoot;
|
|
18
|
+
}
|
|
19
|
+
if (node instanceof ShadowRoot) {
|
|
20
|
+
return node;
|
|
21
|
+
}
|
|
22
|
+
node = node.parentNode;
|
|
23
|
+
if (!node || node === document) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
7
29
|
var NovuUI = ({ options, novu, children }) => {
|
|
8
|
-
const
|
|
30
|
+
const shadowRootDetector = useRef(null);
|
|
31
|
+
const { mountElement } = useRenderer();
|
|
32
|
+
const adaptedAppearanceForUpdate = useMemo(
|
|
33
|
+
() => adaptAppearanceForJs(options.appearance || {}, mountElement),
|
|
34
|
+
[options.appearance, mountElement]
|
|
35
|
+
);
|
|
36
|
+
const adaptedOptions = useMemo(() => {
|
|
37
|
+
return {
|
|
38
|
+
...options,
|
|
39
|
+
appearance: adaptedAppearanceForUpdate,
|
|
40
|
+
novu
|
|
41
|
+
};
|
|
42
|
+
}, [options, novu, adaptedAppearanceForUpdate]);
|
|
43
|
+
const optionsRef = useDataRef(adaptedOptions);
|
|
9
44
|
const [novuUI, setNovuUI] = useState();
|
|
10
45
|
useEffect(() => {
|
|
11
|
-
const
|
|
12
|
-
|
|
46
|
+
const parentShadowRoot = findParentShadowRoot(shadowRootDetector.current);
|
|
47
|
+
const instance = new NovuUIClass({
|
|
48
|
+
...optionsRef.current,
|
|
49
|
+
container: optionsRef.current.container ?? parentShadowRoot
|
|
50
|
+
});
|
|
51
|
+
setNovuUI(instance);
|
|
13
52
|
return () => {
|
|
14
|
-
|
|
53
|
+
instance.unmount();
|
|
15
54
|
};
|
|
16
55
|
}, []);
|
|
17
56
|
useEffect(() => {
|
|
18
57
|
if (!novuUI) {
|
|
19
58
|
return;
|
|
20
59
|
}
|
|
21
|
-
|
|
60
|
+
const parentShadowRoot = findParentShadowRoot(shadowRootDetector.current);
|
|
61
|
+
novuUI.updateContainer(options.container ?? parentShadowRoot);
|
|
62
|
+
novuUI.updateAppearance(adaptedAppearanceForUpdate);
|
|
22
63
|
novuUI.updateLocalization(options.localization);
|
|
23
64
|
novuUI.updateTabs(options.tabs);
|
|
24
65
|
novuUI.updateOptions(options.options);
|
|
25
66
|
novuUI.updateRouterPush(options.routerPush);
|
|
26
|
-
}, [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
67
|
+
}, [
|
|
68
|
+
shadowRootDetector,
|
|
69
|
+
novuUI,
|
|
70
|
+
adaptedAppearanceForUpdate,
|
|
71
|
+
options.localization,
|
|
72
|
+
options.tabs,
|
|
73
|
+
options.options,
|
|
74
|
+
options.routerPush
|
|
75
|
+
]);
|
|
76
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
77
|
+
/* @__PURE__ */ jsx(ShadowRootDetector, { ref: shadowRootDetector }),
|
|
78
|
+
novuUI && /* @__PURE__ */ jsx(NovuUIProvider, { value: { novuUI }, children })
|
|
79
|
+
] });
|
|
31
80
|
};
|
|
32
81
|
export {
|
|
33
82
|
NovuUI
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/NovuUI.tsx"],"sourcesContent":["import { Novu } from '@novu/js';\nimport type { NovuUIOptions } from '@novu/js/ui';\nimport { NovuUI as NovuUIClass } from '@novu/js/ui';\nimport React, { useEffect, useState } from 'react';\nimport { NovuUIProvider } from '../context/NovuUIContext';\nimport { useDataRef } from '../hooks/internal/useDataRef';\n\ntype RendererProps = React.PropsWithChildren<{\n options:
|
|
1
|
+
{"version":3,"sources":["../../../src/components/NovuUI.tsx"],"sourcesContent":["import { Novu } from '@novu/js';\nimport type { NovuUIOptions as JsNovuUIOptions } from '@novu/js/ui';\nimport { NovuUI as NovuUIClass } from '@novu/js/ui';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { NovuUIProvider } from '../context/NovuUIContext';\nimport { useDataRef } from '../hooks/internal/useDataRef';\nimport type { ReactAppearance } from '../utils/types';\nimport { adaptAppearanceForJs } from '../utils/appearance';\nimport { useRenderer } from '../context/RendererContext';\nimport { ShadowRootDetector } from './ShadowRootDetector';\n\ntype NovuUIProps = Omit<JsNovuUIOptions, 'appearance'> & {\n appearance?: ReactAppearance;\n};\n\ntype RendererProps = React.PropsWithChildren<{\n options: NovuUIProps;\n novu?: Novu;\n}>;\n\nconst findParentShadowRoot = (child?: HTMLDivElement | null): Node | null => {\n if (!child) {\n return null;\n }\n\n let node: Node | null = child;\n\n while (node) {\n if (node instanceof Element && node.shadowRoot) {\n return node.shadowRoot;\n }\n\n if (node instanceof ShadowRoot) {\n return node;\n }\n\n node = node.parentNode;\n\n if (!node || node === document) {\n break;\n }\n }\n\n return null;\n};\n\nexport const NovuUI = ({ options, novu, children }: RendererProps) => {\n const shadowRootDetector = useRef<HTMLDivElement>(null);\n const { mountElement } = useRenderer();\n\n const adaptedAppearanceForUpdate = useMemo(\n () => adaptAppearanceForJs(options.appearance || {}, mountElement),\n [options.appearance, mountElement]\n );\n\n const adaptedOptions = useMemo(() => {\n return {\n ...options,\n appearance: adaptedAppearanceForUpdate,\n novu,\n };\n }, [options, novu, adaptedAppearanceForUpdate]);\n\n const optionsRef = useDataRef(adaptedOptions);\n const [novuUI, setNovuUI] = useState<NovuUIClass | undefined>();\n\n useEffect(() => {\n const parentShadowRoot = findParentShadowRoot(shadowRootDetector.current);\n const instance = new NovuUIClass({\n ...optionsRef.current,\n container: optionsRef.current.container ?? parentShadowRoot,\n });\n setNovuUI(instance);\n\n return () => {\n instance.unmount();\n };\n }, []);\n\n useEffect(() => {\n if (!novuUI) {\n return;\n }\n\n const parentShadowRoot = findParentShadowRoot(shadowRootDetector.current);\n novuUI.updateContainer(options.container ?? parentShadowRoot);\n novuUI.updateAppearance(adaptedAppearanceForUpdate);\n novuUI.updateLocalization(options.localization);\n novuUI.updateTabs(options.tabs);\n novuUI.updateOptions(options.options);\n novuUI.updateRouterPush(options.routerPush);\n }, [\n shadowRootDetector,\n novuUI,\n adaptedAppearanceForUpdate,\n options.localization,\n options.tabs,\n options.options,\n options.routerPush,\n ]);\n\n return (\n <>\n <ShadowRootDetector ref={shadowRootDetector} />\n {novuUI && <NovuUIProvider value={{ novuUI }}>{children}</NovuUIProvider>}\n </>\n );\n};\n"],"mappings":";AAEA,SAAS,UAAU,mBAAmB;AACtC,SAAgB,WAAW,SAAS,QAAQ,gBAAgB;AAC5D,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAE3B,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,0BAA0B;AA6F/B,mBACE,KADF;AAlFJ,IAAM,uBAAuB,CAAC,UAA+C;AAC3E,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,MAAI,OAAoB;AAExB,SAAO,MAAM;AACX,QAAI,gBAAgB,WAAW,KAAK,YAAY;AAC9C,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,gBAAgB,YAAY;AAC9B,aAAO;AAAA,IACT;AAEA,WAAO,KAAK;AAEZ,QAAI,CAAC,QAAQ,SAAS,UAAU;AAC9B;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,SAAS,CAAC,EAAE,SAAS,MAAM,SAAS,MAAqB;AACpE,QAAM,qBAAqB,OAAuB,IAAI;AACtD,QAAM,EAAE,aAAa,IAAI,YAAY;AAErC,QAAM,6BAA6B;AAAA,IACjC,MAAM,qBAAqB,QAAQ,cAAc,CAAC,GAAG,YAAY;AAAA,IACjE,CAAC,QAAQ,YAAY,YAAY;AAAA,EACnC;AAEA,QAAM,iBAAiB,QAAQ,MAAM;AACnC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,YAAY;AAAA,MACZ;AAAA,IACF;AAAA,EACF,GAAG,CAAC,SAAS,MAAM,0BAA0B,CAAC;AAE9C,QAAM,aAAa,WAAW,cAAc;AAC5C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAkC;AAE9D,YAAU,MAAM;AACd,UAAM,mBAAmB,qBAAqB,mBAAmB,OAAO;AACxE,UAAM,WAAW,IAAI,YAAY;AAAA,MAC/B,GAAG,WAAW;AAAA,MACd,WAAW,WAAW,QAAQ,aAAa;AAAA,IAC7C,CAAC;AACD,cAAU,QAAQ;AAElB,WAAO,MAAM;AACX,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,mBAAmB,qBAAqB,mBAAmB,OAAO;AACxE,WAAO,gBAAgB,QAAQ,aAAa,gBAAgB;AAC5D,WAAO,iBAAiB,0BAA0B;AAClD,WAAO,mBAAmB,QAAQ,YAAY;AAC9C,WAAO,WAAW,QAAQ,IAAI;AAC9B,WAAO,cAAc,QAAQ,OAAO;AACpC,WAAO,iBAAiB,QAAQ,UAAU;AAAA,EAC5C,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAED,SACE,iCACE;AAAA,wBAAC,sBAAmB,KAAK,oBAAoB;AAAA,IAC5C,UAAU,oBAAC,kBAAe,OAAO,EAAE,OAAO,GAAI,UAAS;AAAA,KAC1D;AAEJ;","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/components/ShadowRootDetector.tsx
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var ShadowRootDetector = React.forwardRef((props, ref) => {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
ref,
|
|
9
|
+
style: {
|
|
10
|
+
position: "absolute",
|
|
11
|
+
width: 1,
|
|
12
|
+
height: 1,
|
|
13
|
+
padding: 0,
|
|
14
|
+
margin: -1,
|
|
15
|
+
overflow: "hidden",
|
|
16
|
+
clip: "rect(0, 0, 0, 0)",
|
|
17
|
+
whiteSpace: "nowrap",
|
|
18
|
+
borderWidth: 0
|
|
19
|
+
},
|
|
20
|
+
"data-shadow-root-detector": true,
|
|
21
|
+
...props
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
export {
|
|
26
|
+
ShadowRootDetector
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=ShadowRootDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ShadowRootDetector.tsx"],"sourcesContent":["import React from 'react';\n\nexport const ShadowRootDetector = React.forwardRef<HTMLDivElement>((props, ref) => {\n return (\n <div\n ref={ref}\n style={{\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n borderWidth: 0,\n }}\n data-shadow-root-detector\n {...props}\n />\n );\n});\n"],"mappings":";AAAA,OAAO,WAAW;AAId;AAFG,IAAM,qBAAqB,MAAM,WAA2B,CAAC,OAAO,QAAQ;AACjF,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,aAAa;AAAA,MACf;AAAA,MACA,6BAAyB;AAAA,MACxB,GAAG;AAAA;AAAA,EACN;AAEJ,CAAC;","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Novu } from "@novu/js";
|
|
3
3
|
import { createContext, useContext, useMemo } from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
var version = "3.
|
|
5
|
+
var version = "3.5.0-rc.1";
|
|
6
6
|
var name = "@novu/react";
|
|
7
7
|
var baseUserAgent = `${name}@${version}`;
|
|
8
8
|
var NovuContext = createContext(void 0);
|
|
@@ -3,7 +3,7 @@ import { useState, useEffect, useRef } from "react";
|
|
|
3
3
|
import { isSameFilter } from "@novu/js";
|
|
4
4
|
import { useNovu } from "./NovuProvider.js";
|
|
5
5
|
var useNotifications = (props) => {
|
|
6
|
-
const { tags, read, archived = false, snoozed = false, limit, onSuccess, onError } = props || {};
|
|
6
|
+
const { tags, data: dataFilter, read, archived = false, snoozed = false, limit, onSuccess, onError } = props || {};
|
|
7
7
|
const filterRef = useRef(void 0);
|
|
8
8
|
const { notifications, on } = useNovu();
|
|
9
9
|
const [data, setData] = useState();
|
|
@@ -27,14 +27,14 @@ var useNotifications = (props) => {
|
|
|
27
27
|
};
|
|
28
28
|
}, []);
|
|
29
29
|
useEffect(() => {
|
|
30
|
-
const newFilter = { tags, read, archived, snoozed };
|
|
30
|
+
const newFilter = { tags, data: dataFilter, read, archived, snoozed };
|
|
31
31
|
if (filterRef.current && isSameFilter(filterRef.current, newFilter)) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
notifications.clearCache({ filter: filterRef.current });
|
|
35
35
|
filterRef.current = newFilter;
|
|
36
36
|
fetchNotifications({ refetch: true });
|
|
37
|
-
}, [tags, read, archived, snoozed]);
|
|
37
|
+
}, [tags, dataFilter, read, archived, snoozed]);
|
|
38
38
|
const fetchNotifications = async (options) => {
|
|
39
39
|
if (options?.refetch) {
|
|
40
40
|
setError(void 0);
|
|
@@ -44,6 +44,7 @@ var useNotifications = (props) => {
|
|
|
44
44
|
setIsFetching(true);
|
|
45
45
|
const response = await notifications.list({
|
|
46
46
|
tags,
|
|
47
|
+
data: dataFilter,
|
|
47
48
|
read,
|
|
48
49
|
archived,
|
|
49
50
|
snoozed,
|
|
@@ -62,7 +63,7 @@ var useNotifications = (props) => {
|
|
|
62
63
|
setIsFetching(false);
|
|
63
64
|
};
|
|
64
65
|
const refetch = () => {
|
|
65
|
-
notifications.clearCache({ filter: { tags, read, archived, snoozed } });
|
|
66
|
+
notifications.clearCache({ filter: { tags, read, archived, snoozed, data: dataFilter } });
|
|
66
67
|
return fetchNotifications({ refetch: true });
|
|
67
68
|
};
|
|
68
69
|
const fetchMore = async () => {
|
|
@@ -70,13 +71,13 @@ var useNotifications = (props) => {
|
|
|
70
71
|
return fetchNotifications();
|
|
71
72
|
};
|
|
72
73
|
const readAll = async () => {
|
|
73
|
-
return await notifications.readAll({ tags });
|
|
74
|
+
return await notifications.readAll({ tags, data: dataFilter });
|
|
74
75
|
};
|
|
75
76
|
const archiveAll = async () => {
|
|
76
|
-
return await notifications.archiveAll({ tags });
|
|
77
|
+
return await notifications.archiveAll({ tags, data: dataFilter });
|
|
77
78
|
};
|
|
78
79
|
const archiveAllRead = async () => {
|
|
79
|
-
return await notifications.archiveAllRead({ tags });
|
|
80
|
+
return await notifications.archiveAllRead({ tags, data: dataFilter });
|
|
80
81
|
};
|
|
81
82
|
return {
|
|
82
83
|
readAll,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/hooks/useNotifications.ts"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { ListNotificationsResponse, Notification, NovuError, isSameFilter, NotificationFilter } from '@novu/js';\nimport { useNovu } from './NovuProvider';\n\nexport type UseNotificationsProps = {\n tags?: string[];\n read?: boolean;\n archived?: boolean;\n snoozed?: boolean;\n limit?: number;\n onSuccess?: (data: Notification[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseNotificationsResult = {\n notifications?: Notification[];\n error?: NovuError;\n isLoading: boolean;\n isFetching: boolean;\n hasMore: boolean;\n readAll: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n archiveAll: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n archiveAllRead: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n refetch: () => Promise<void>;\n fetchMore: () => Promise<void>;\n};\n\nexport const useNotifications = (props?: UseNotificationsProps): UseNotificationsResult => {\n const { tags, read, archived = false, snoozed = false, limit, onSuccess, onError } = props || {};\n const filterRef = useRef<NotificationFilter | undefined>(undefined);\n const { notifications, on } = useNovu();\n const [data, setData] = useState<Array<Notification>>();\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const length = data?.length;\n const after = length ? data[length - 1].id : undefined;\n\n const sync = (event: { data?: ListNotificationsResponse }) => {\n if (!event.data || (filterRef.current && !isSameFilter(filterRef.current, event.data.filter))) {\n return;\n }\n setData(event.data.notifications);\n setHasMore(event.data.hasMore);\n };\n\n useEffect(() => {\n const cleanup = on('notifications.list.updated', sync);\n\n return () => {\n cleanup();\n };\n }, []);\n\n useEffect(() => {\n const newFilter = { tags, read, archived, snoozed };\n if (filterRef.current && isSameFilter(filterRef.current, newFilter)) {\n return;\n }\n notifications.clearCache({ filter: filterRef.current });\n filterRef.current = newFilter;\n\n fetchNotifications({ refetch: true });\n }, [tags, read, archived, snoozed]);\n\n const fetchNotifications = async (options?: { refetch: boolean }) => {\n if (options?.refetch) {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n }\n setIsFetching(true);\n const response = await notifications.list({\n tags,\n read,\n archived,\n snoozed,\n limit,\n after: options?.refetch ? undefined : after,\n });\n if (response.error) {\n setError(response.error);\n onError?.(response.error);\n } else {\n onSuccess?.(response.data!.notifications);\n setData(response.data!.notifications);\n setHasMore(response.data!.hasMore);\n }\n setIsLoading(false);\n setIsFetching(false);\n };\n\n const refetch = () => {\n notifications.clearCache({ filter: { tags, read, archived, snoozed } });\n\n return fetchNotifications({ refetch: true });\n };\n\n const fetchMore = async () => {\n if (!hasMore || isFetching) return;\n\n return fetchNotifications();\n };\n\n const readAll = async () => {\n return await notifications.readAll({ tags });\n };\n\n const archiveAll = async () => {\n return await notifications.archiveAll({ tags });\n };\n\n const archiveAllRead = async () => {\n return await notifications.archiveAllRead({ tags });\n };\n\n return {\n readAll,\n archiveAll,\n archiveAllRead,\n notifications: data,\n error,\n isLoading,\n isFetching,\n refetch,\n fetchMore,\n hasMore,\n };\n};\n"],"mappings":";AAAA,SAAS,UAAU,WAAW,cAAc;AAC5C,SAA6D,oBAAwC;AACrG,SAAS,eAAe;
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/useNotifications.ts"],"sourcesContent":["import { useState, useEffect, useRef } from 'react';\nimport { ListNotificationsResponse, Notification, NovuError, isSameFilter, NotificationFilter } from '@novu/js';\nimport { useNovu } from './NovuProvider';\n\nexport type UseNotificationsProps = {\n tags?: string[];\n data?: Record<string, unknown>;\n read?: boolean;\n archived?: boolean;\n snoozed?: boolean;\n limit?: number;\n onSuccess?: (data: Notification[]) => void;\n onError?: (error: NovuError) => void;\n};\n\nexport type UseNotificationsResult = {\n notifications?: Notification[];\n error?: NovuError;\n isLoading: boolean;\n isFetching: boolean;\n hasMore: boolean;\n readAll: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n archiveAll: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n archiveAllRead: () => Promise<{\n data?: void | undefined;\n error?: NovuError | undefined;\n }>;\n refetch: () => Promise<void>;\n fetchMore: () => Promise<void>;\n};\n\nexport const useNotifications = (props?: UseNotificationsProps): UseNotificationsResult => {\n const { tags, data: dataFilter, read, archived = false, snoozed = false, limit, onSuccess, onError } = props || {};\n const filterRef = useRef<NotificationFilter | undefined>(undefined);\n const { notifications, on } = useNovu();\n const [data, setData] = useState<Array<Notification>>();\n const [error, setError] = useState<NovuError>();\n const [isLoading, setIsLoading] = useState(true);\n const [isFetching, setIsFetching] = useState(false);\n const [hasMore, setHasMore] = useState(false);\n const length = data?.length;\n const after = length ? data[length - 1].id : undefined;\n\n const sync = (event: { data?: ListNotificationsResponse }) => {\n if (!event.data || (filterRef.current && !isSameFilter(filterRef.current, event.data.filter))) {\n return;\n }\n setData(event.data.notifications);\n setHasMore(event.data.hasMore);\n };\n\n useEffect(() => {\n const cleanup = on('notifications.list.updated', sync);\n\n return () => {\n cleanup();\n };\n }, []);\n\n useEffect(() => {\n const newFilter = { tags, data: dataFilter, read, archived, snoozed };\n if (filterRef.current && isSameFilter(filterRef.current, newFilter)) {\n return;\n }\n notifications.clearCache({ filter: filterRef.current });\n filterRef.current = newFilter;\n\n fetchNotifications({ refetch: true });\n }, [tags, dataFilter, read, archived, snoozed]);\n\n const fetchNotifications = async (options?: { refetch: boolean }) => {\n if (options?.refetch) {\n setError(undefined);\n setIsLoading(true);\n setIsFetching(false);\n }\n setIsFetching(true);\n const response = await notifications.list({\n tags,\n data: dataFilter,\n read,\n archived,\n snoozed,\n limit,\n after: options?.refetch ? undefined : after,\n });\n if (response.error) {\n setError(response.error);\n onError?.(response.error);\n } else {\n onSuccess?.(response.data!.notifications);\n setData(response.data!.notifications);\n setHasMore(response.data!.hasMore);\n }\n setIsLoading(false);\n setIsFetching(false);\n };\n\n const refetch = () => {\n notifications.clearCache({ filter: { tags, read, archived, snoozed, data: dataFilter } });\n\n return fetchNotifications({ refetch: true });\n };\n\n const fetchMore = async () => {\n if (!hasMore || isFetching) return;\n\n return fetchNotifications();\n };\n\n const readAll = async () => {\n return await notifications.readAll({ tags, data: dataFilter });\n };\n\n const archiveAll = async () => {\n return await notifications.archiveAll({ tags, data: dataFilter });\n };\n\n const archiveAllRead = async () => {\n return await notifications.archiveAllRead({ tags, data: dataFilter });\n };\n\n return {\n readAll,\n archiveAll,\n archiveAllRead,\n notifications: data,\n error,\n isLoading,\n isFetching,\n refetch,\n fetchMore,\n hasMore,\n };\n};\n"],"mappings":"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","names":[]}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ChannelPreference, ChannelType, EventHandler, Events, FiltersCountResponse, InboxNotification, ListNotificationsResponse, Notification, NotificationFilter, NotificationStatus, NovuError, NovuOptions, Preference, PreferenceLevel, PreferencesResponse, SocketEventNames, WebSocketEvent } from '@novu/js';
|
|
2
|
-
export { Appearance, AppearanceKey, ElementStyles, Elements, Localization, LocalizationKey, NotificationActionClickHandler, NotificationClickHandler, NotificationRenderer, PreferencesFilter, RouterPush, Tab, Variables } from '@novu/js/ui';
|
|
2
|
+
export { Appearance, AppearanceKey, ElementStyles, Elements, Localization, LocalizationKey, NotificationActionClickHandler, NotificationClickHandler, NotificationRenderer, PreferenceGroups, PreferencesFilter, RouterPush, Tab, Variables } from '@novu/js/ui';
|
|
3
3
|
export { Bell, BellProps } from './components/Bell.js';
|
|
4
4
|
export { Inbox, InboxProps } from './components/Inbox.js';
|
|
5
5
|
export { Preferences } from './components/Preferences.js';
|