@edusight/notification-widget 1.0.36 → 1.0.41

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.
@@ -0,0 +1,2 @@
1
+ "use strict";const h=require("react"),D=()=>window.__notificationSDK?.client,_=({preferences:t,onPreferencesChange:f,onError:e})=>{const n=D(),[c,i]=h.useState(!1),[s,l]=h.useState(null),p=h.useRef(),S=h.useRef({}),j=h.useCallback((v,y)=>{try{l(null);const r={...t},o=v.split(".");let b=r;for(let a=0;a<o.length-1;a++)b[o[a]]===void 0&&(b[o[a]]={}),b=b[o[a]];b[o[o.length-1]]=y,f(r),S.current[v]=y,p.current&&clearTimeout(p.current),i(!0),p.current=setTimeout(async()=>{try{if(!n)throw new Error("Notification client not available");const a=window.__notificationSDK?.config;if(!a)throw new Error("SDK configuration not available");const{subscriberId:u,tenantId:g,environmentId:A}=a;if(!u||!g||!A)throw new Error("SubscriberId, TenantId or EnvironmentId not available in SDK configuration.");if(v.startsWith("deliverySchedule.")){const d={isEnabled:r.deliverySchedule.enabled||!1};r.deliverySchedule.weeklySchedule&&(d.weeklySchedule=r.deliverySchedule.weeklySchedule),await n.preferences.updateSchedule(g,u,d,A)}else{const d={emailEnabled:r.channels.email,pushEnabled:r.channels.push,inAppEnabled:r.channels.inApp,smsEnabled:r.channels.sms};r.subscriptions.length>0&&(d.categories={},r.subscriptions.forEach(m=>{d.categories[m.workflowId]={emailEnabled:m.channels.email,pushEnabled:m.channels.push,inAppEnabled:m.channels.inApp,smsEnabled:m.channels.sms}})),await n.preferences.update(g,u,d)}S.current={},l(null)}catch(a){const u=a instanceof Error?a:new Error("Failed to save preferences");process.env.NODE_ENV,l(u),e?.(u)}finally{i(!1)}},500)}catch(r){const o=r instanceof Error?r:new Error("Failed to update preference");l(o),e?.(o),i(!1)}},[t,f,n,e]);return h.useEffect(()=>()=>{p.current&&clearTimeout(p.current)},[]),{updatePreference:j,isSaving:c,error:s}},E=t=>!(!t||typeof t!="object"||["notificationId","channel","renderedContent","read","archived"].filter(n=>!(n in t)).length>0||typeof t.channel!="string"||typeof t.read!="boolean"||typeof t.archived!="boolean"||typeof t.renderedContent!="object"||t.renderedContent===null),N=(t,f,e)=>({type:"custom",label:t.label,icon:void 0,handler:async()=>{try{if(t.url){const n=t.target||"_self";window.open(t.url,n)}t.markAsReadOnClick}catch(n){throw n}}}),w=()=>{const t=(e,n)=>{if(!e||typeof e!="object")return{subject:"",body:""};let c="",i="";return e.push?(c=e.push.title||"",i=e.push.body||""):e.email?(c=e.email.subject||"",i=e.email.html||e.email.text||""):e.in_app?(c=e.in_app.title||"",i=e.in_app.message||""):e.sms?(c="SMS",i=e.sms.message||""):n==="in_app"?(c=e.title||"",i=e.message||""):(c=e.title||e.subject||"",i=e.message||e.body||e.text||""),{subject:c,body:i}},f=(e,n,c)=>{if(!e)return[];const i=[];if(Array.isArray(e))return e.forEach(s=>{i.push(N(s,n||"",c))}),i;if(e.primary){const s=e.primary;i.push({type:"custom",label:s.label||"Primary Action",icon:void 0,handler:async l=>{s.url&&window.open(s.url,"_self")}})}if(e.secondary){const s=e.secondary;i.push({type:"custom",label:s.label||"Secondary Action",icon:void 0,handler:async l=>{s.url&&window.open(s.url,"_self")}})}return i};return{toWidgetNotification(e){const{subject:n,body:c}=t(e.renderedContent,e.channel);return{id:e.notificationId,subject:n||"Notification",body:c||"",isRead:e.read,isArchived:e.archived,timestamp:e.createdAt?new Date(e.createdAt):new Date,tags:[],actions:f(e.renderedContent?.actions||e.actions),metadata:{channel:e.channel,renderedContent:e.renderedContent}}},toWidgetNotificationFromWebSocket(e){if(!E(e)){const i=e?.renderedContent&&typeof e.renderedContent=="object"?e.renderedContent:{},{subject:s,body:l}=t(i,e?.channel);return{id:e?.notificationId||`notification-${Date.now()}`,subject:s||"Notification",body:l||"",isRead:e?.read||!1,isArchived:e?.archived||!1,timestamp:e?.createdAt?new Date(e.createdAt):new Date,tags:[],actions:[],metadata:{channel:e?.channel||"in_app",renderedContent:i}}}const{subject:n,body:c}=t(e.renderedContent,e.channel);return{id:e.notificationId,subject:n||"Notification",body:c||"",isRead:e.read||!1,isArchived:e.archived||!1,timestamp:e.createdAt?new Date(e.createdAt):new Date,tags:[],actions:f(e.renderedContent?.actions||e.actions,e.notificationId),metadata:{channel:e.channel,renderedContent:e.renderedContent}}},validateWebSocketPayload:E}};exports.createNotificationMapper=w;exports.useLivePreferences=_;
2
+ //# sourceMappingURL=hooks-C6Z38jT_.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-C6Z38jT_.cjs","sources":["../src/hooks/useLivePreferences.ts","../src/utils/notification-mapper.ts"],"sourcesContent":["import { useCallback, useRef, useState, useEffect } from 'react';\n\nimport { NotificationPreferences } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UseLivePreferencesProps {\n preferences: NotificationPreferences;\n onPreferencesChange: (preferences: NotificationPreferences) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UseLivePreferencesResult {\n updatePreference: (path: string, value: any) => void;\n isSaving: boolean;\n error: Error | null;\n}\n\nexport const useLivePreferences = ({\n preferences,\n onPreferencesChange,\n onError,\n}: UseLivePreferencesProps): UseLivePreferencesResult => {\n const notificationClient = useNotificationsClient();\n const [isSaving, setIsSaving] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const saveTimeoutRef = useRef<NodeJS.Timeout>();\n const pendingUpdatesRef = useRef<{ [key: string]: any }>({});\n\n const updatePreference = useCallback(\n (path: string, value: any) => {\n try {\n setError(null);\n\n const updatedPreferences = { ...preferences };\n const pathParts = path.split('.');\n\n let current: any = updatedPreferences;\n for (let i = 0; i < pathParts.length - 1; i++) {\n if (current[pathParts[i]] === undefined) {\n current[pathParts[i]] = {};\n }\n current = current[pathParts[i]];\n }\n current[pathParts[pathParts.length - 1]] = value;\n\n onPreferencesChange(updatedPreferences);\n\n pendingUpdatesRef.current[path] = value;\n\n if (saveTimeoutRef.current) {\n clearTimeout(saveTimeoutRef.current);\n }\n\n setIsSaving(true);\n\n saveTimeoutRef.current = setTimeout(async () => {\n try {\n if (!notificationClient) {\n throw new Error('Notification client not available');\n }\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n\n if (!sdkConfig) {\n throw new Error('SDK configuration not available');\n }\n\n const { subscriberId, tenantId, environmentId } = sdkConfig;\n\n if (!subscriberId || !tenantId || !environmentId) {\n throw new Error(\n 'SubscriberId, TenantId or EnvironmentId not available in SDK configuration.',\n );\n }\n\n // Check if this is a schedule-related update\n const isScheduleUpdate = path.startsWith('deliverySchedule.');\n\n if (isScheduleUpdate) {\n // Handle schedule updates separately\n const schedulePayload: any = {\n isEnabled: updatedPreferences.deliverySchedule.enabled || false,\n };\n\n // Build weekly schedule\n if (updatedPreferences.deliverySchedule.weeklySchedule) {\n schedulePayload.weeklySchedule = updatedPreferences.deliverySchedule.weeklySchedule;\n }\n\n await notificationClient.preferences.updateSchedule(\n tenantId,\n subscriberId,\n schedulePayload,\n environmentId,\n );\n } else {\n // Handle global and subscription preferences\n const savePayload: any = {\n emailEnabled: updatedPreferences.channels.email,\n pushEnabled: updatedPreferences.channels.push,\n inAppEnabled: updatedPreferences.channels.inApp,\n smsEnabled: updatedPreferences.channels.sms,\n };\n\n if (updatedPreferences.subscriptions.length > 0) {\n savePayload.categories = {};\n updatedPreferences.subscriptions.forEach((sub) => {\n savePayload.categories[sub.workflowId] = {\n emailEnabled: sub.channels.email,\n pushEnabled: sub.channels.push,\n inAppEnabled: sub.channels.inApp,\n smsEnabled: sub.channels.sms,\n };\n });\n }\n\n await notificationClient.preferences.update(tenantId, subscriberId, savePayload);\n }\n\n pendingUpdatesRef.current = {};\n setError(null);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to save preferences');\n\n if (process.env.NODE_ENV === 'development') {\n console.error('Failed to save preferences:', error);\n }\n\n setError(error);\n onError?.(error);\n } finally {\n setIsSaving(false);\n }\n }, 500);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to update preference');\n setError(error);\n onError?.(error);\n setIsSaving(false);\n }\n },\n [preferences, onPreferencesChange, notificationClient, onError],\n );\n\n useEffect(() => {\n return () => {\n if (saveTimeoutRef.current) {\n clearTimeout(saveTimeoutRef.current);\n }\n };\n }, []);\n\n return {\n updatePreference,\n isSaving,\n error,\n };\n};\n","import type {\n RenderedNotificationItem,\n RenderedNotificationActionMap,\n NotificationAction as SDKNotificationAction,\n} from '@edusight/notification-sdk';\n\nimport type { Notification, NotificationAction } from '../types/core';\n\nexport type WebSocketNotificationReceivedPayload = RenderedNotificationItem;\n\nexport interface NotificationMapper {\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification;\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification;\n validateWebSocketPayload(payload: any): payload is WebSocketNotificationReceivedPayload;\n}\n\nconst validateWebSocketPayload = (\n payload: any,\n): payload is WebSocketNotificationReceivedPayload => {\n if (!payload || typeof payload !== 'object') {\n console.warn('Invalid WebSocket payload: not an object', payload);\n return false;\n }\n\n const requiredFields = ['notificationId', 'channel', 'renderedContent', 'read', 'archived'];\n const missingFields = requiredFields.filter((field) => !(field in payload));\n\n if (missingFields.length > 0) {\n console.warn('WebSocket payload missing required fields:', missingFields, payload);\n return false;\n }\n\n if (typeof payload.channel !== 'string') {\n console.warn('WebSocket payload channel is invalid', payload);\n return false;\n }\n\n if (typeof payload.read !== 'boolean' || typeof payload.archived !== 'boolean') {\n console.warn('WebSocket payload read/archived flags are invalid', payload);\n return false;\n }\n\n if (typeof payload.renderedContent !== 'object' || payload.renderedContent === null) {\n console.warn('WebSocket payload renderedContent is not an object', payload);\n return false;\n }\n\n return true;\n};\n\nconst mapSDKActionToWidgetAction = (\n sdkAction: SDKNotificationAction,\n notificationId: string,\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>,\n): NotificationAction => {\n return {\n type: 'custom',\n label: sdkAction.label,\n icon: undefined,\n handler: async () => {\n try {\n if (onActionExecute) {\n await onActionExecute(sdkAction.id, notificationId);\n }\n\n if (sdkAction.url) {\n const target = sdkAction.target || '_self';\n window.open(sdkAction.url, target);\n }\n\n if (sdkAction.markAsReadOnClick) {\n // This will be handled by the widget's action handler\n }\n } catch (error) {\n console.error('Error executing action:', error);\n throw error;\n }\n },\n };\n};\n\nexport const createNotificationMapper = (): NotificationMapper => {\n const extractSubjectAndBody = (\n renderedContent: Record<string, any>,\n channel?: string,\n ): { subject: string; body: string } => {\n if (!renderedContent || typeof renderedContent !== 'object') {\n return { subject: '', body: '' };\n }\n\n let subject = '';\n let body = '';\n\n if (renderedContent.push) {\n subject = renderedContent.push.title || '';\n body = renderedContent.push.body || '';\n } else if (renderedContent.email) {\n subject = renderedContent.email.subject || '';\n body = renderedContent.email.html || renderedContent.email.text || '';\n } else if (renderedContent.in_app) {\n subject = renderedContent.in_app.title || '';\n body = renderedContent.in_app.message || '';\n } else if (renderedContent.sms) {\n subject = 'SMS';\n body = renderedContent.sms.message || '';\n } else if (channel === 'in_app') {\n subject = renderedContent.title || '';\n body = renderedContent.message || '';\n } else {\n subject = renderedContent.title || renderedContent.subject || '';\n body = renderedContent.message || renderedContent.body || renderedContent.text || '';\n }\n\n return { subject, body };\n };\n\n const mapActionsToNotificationActions = (\n actions?: RenderedNotificationActionMap | SDKNotificationAction[],\n notificationId?: string,\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>,\n ): NotificationAction[] => {\n if (!actions) return [];\n\n const result: NotificationAction[] = [];\n\n if (Array.isArray(actions)) {\n actions.forEach((sdkAction) => {\n result.push(mapSDKActionToWidgetAction(sdkAction, notificationId || '', onActionExecute));\n });\n return result;\n }\n\n if (actions.primary) {\n const primaryAction = actions.primary;\n result.push({\n type: 'custom',\n label: primaryAction.label || 'Primary Action',\n icon: undefined,\n handler: async (notificationId: string) => {\n if (primaryAction.url) {\n window.open(primaryAction.url, '_self');\n }\n if (onActionExecute) {\n await onActionExecute('primary', notificationId);\n }\n },\n });\n }\n\n if (actions.secondary) {\n const secondaryAction = actions.secondary;\n result.push({\n type: 'custom',\n label: secondaryAction.label || 'Secondary Action',\n icon: undefined,\n handler: async (notificationId: string) => {\n if (secondaryAction.url) {\n window.open(secondaryAction.url, '_self');\n }\n if (onActionExecute) {\n await onActionExecute('secondary', notificationId);\n }\n },\n });\n }\n\n return result;\n };\n\n return {\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification {\n const { subject, body } = extractSubjectAndBody(\n renderedItem.renderedContent,\n renderedItem.channel,\n );\n\n return {\n id: renderedItem.notificationId,\n subject: subject || 'Notification',\n body: body || '',\n isRead: renderedItem.read,\n isArchived: renderedItem.archived,\n timestamp: renderedItem.createdAt ? new Date(renderedItem.createdAt) : new Date(),\n tags: [],\n actions: mapActionsToNotificationActions(\n renderedItem.renderedContent?.actions || renderedItem.actions,\n ),\n metadata: {\n channel: renderedItem.channel,\n renderedContent: renderedItem.renderedContent,\n },\n };\n },\n\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification {\n if (!validateWebSocketPayload(wsPayload)) {\n console.error('Invalid WebSocket payload structure, using fallback', wsPayload);\n const fallbackRenderedContent =\n wsPayload?.renderedContent && typeof wsPayload.renderedContent === 'object'\n ? wsPayload.renderedContent\n : {};\n const { subject, body } = extractSubjectAndBody(\n fallbackRenderedContent,\n wsPayload?.channel,\n );\n return {\n id: wsPayload?.notificationId || `notification-${Date.now()}`,\n subject: subject || 'Notification',\n body: body || '',\n isRead: wsPayload?.read || false,\n isArchived: wsPayload?.archived || false,\n timestamp: wsPayload?.createdAt ? new Date(wsPayload.createdAt) : new Date(),\n tags: [],\n actions: [],\n metadata: {\n channel: wsPayload?.channel || 'in_app',\n renderedContent: fallbackRenderedContent,\n },\n };\n }\n\n const { subject, body } = extractSubjectAndBody(wsPayload.renderedContent, wsPayload.channel);\n\n return {\n id: wsPayload.notificationId,\n subject: subject || 'Notification',\n body: body || '',\n isRead: wsPayload.read || false,\n isArchived: wsPayload.archived || false,\n timestamp: wsPayload.createdAt ? new Date(wsPayload.createdAt) : new Date(),\n tags: [],\n actions: mapActionsToNotificationActions(\n wsPayload.renderedContent?.actions || wsPayload.actions,\n wsPayload.notificationId,\n ),\n metadata: {\n channel: wsPayload.channel,\n renderedContent: (wsPayload as any).renderedContent,\n },\n };\n },\n\n validateWebSocketPayload,\n };\n};\n"],"names":["useNotificationsClient","useLivePreferences","preferences","onPreferencesChange","onError","notificationClient","isSaving","setIsSaving","useState","error","setError","saveTimeoutRef","useRef","pendingUpdatesRef","updatePreference","useCallback","path","value","updatedPreferences","pathParts","current","i","sdkConfig","subscriberId","tenantId","environmentId","schedulePayload","savePayload","sub","err","useEffect","validateWebSocketPayload","payload","field","mapSDKActionToWidgetAction","sdkAction","notificationId","onActionExecute","target","createNotificationMapper","extractSubjectAndBody","renderedContent","channel","subject","body","mapActionsToNotificationActions","actions","result","primaryAction","secondaryAction","renderedItem","wsPayload","fallbackRenderedContent"],"mappings":"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"}
@@ -1,65 +1,78 @@
1
- import { useState as E, useRef as j, useCallback as _, useEffect as N } from "react";
2
- const R = () => window.__notificationSDK?.client, T = ({
1
+ import { useState as A, useRef as E, useCallback as _, useEffect as w } from "react";
2
+ const N = () => window.__notificationSDK?.client, T = ({
3
3
  preferences: t,
4
4
  onPreferencesChange: f,
5
5
  onError: e
6
6
  }) => {
7
- const n = R(), [c, i] = E(!1), [r, l] = E(null), u = j(), m = j({}), y = _(
8
- (g, v) => {
7
+ const n = N(), [c, i] = A(!1), [a, l] = A(null), h = E(), g = E({}), D = _(
8
+ (m, S) => {
9
9
  try {
10
10
  l(null);
11
- const o = { ...t }, s = g.split(".");
12
- let p = o;
13
- for (let a = 0; a < s.length - 1; a++)
14
- p[s[a]] === void 0 && (p[s[a]] = {}), p = p[s[a]];
15
- p[s[s.length - 1]] = v, f(o), m.current[g] = v, u.current && clearTimeout(u.current), i(!0), u.current = setTimeout(async () => {
11
+ const r = { ...t }, o = m.split(".");
12
+ let p = r;
13
+ for (let s = 0; s < o.length - 1; s++)
14
+ p[o[s]] === void 0 && (p[o[s]] = {}), p = p[o[s]];
15
+ p[o[o.length - 1]] = S, f(r), g.current[m] = S, h.current && clearTimeout(h.current), i(!0), h.current = setTimeout(async () => {
16
16
  try {
17
17
  if (!n)
18
18
  throw new Error("Notification client not available");
19
- const a = window.__notificationSDK?.config;
20
- if (!a)
19
+ const s = window.__notificationSDK?.config;
20
+ if (!s)
21
21
  throw new Error("SDK configuration not available");
22
- const { subscriberId: h, tenantId: A, environmentId: D } = a;
23
- if (!h || !A || !D)
22
+ const { subscriberId: u, tenantId: v, environmentId: y } = s;
23
+ if (!u || !v || !y)
24
24
  throw new Error(
25
25
  "SubscriberId, TenantId or EnvironmentId not available in SDK configuration."
26
26
  );
27
- const d = {
28
- emailEnabled: o.channels.email,
29
- pushEnabled: o.channels.push,
30
- inAppEnabled: o.channels.inApp,
31
- smsEnabled: o.channels.sms
32
- };
33
- o.subscriptions.length > 0 && (d.categories = {}, o.subscriptions.forEach((b) => {
34
- d.categories[b.workflowId] = {
35
- emailEnabled: b.channels.email,
36
- pushEnabled: b.channels.push,
37
- inAppEnabled: b.channels.inApp,
38
- smsEnabled: b.channels.sms
27
+ if (m.startsWith("deliverySchedule.")) {
28
+ const d = {
29
+ isEnabled: r.deliverySchedule.enabled || !1
39
30
  };
40
- })), await n.preferences.update(A, h, d), m.current = {}, l(null);
41
- } catch (a) {
42
- const h = a instanceof Error ? a : new Error("Failed to save preferences");
43
- process.env.NODE_ENV, l(h), e?.(h);
31
+ r.deliverySchedule.weeklySchedule && (d.weeklySchedule = r.deliverySchedule.weeklySchedule), await n.preferences.updateSchedule(
32
+ v,
33
+ u,
34
+ d,
35
+ y
36
+ );
37
+ } else {
38
+ const d = {
39
+ emailEnabled: r.channels.email,
40
+ pushEnabled: r.channels.push,
41
+ inAppEnabled: r.channels.inApp,
42
+ smsEnabled: r.channels.sms
43
+ };
44
+ r.subscriptions.length > 0 && (d.categories = {}, r.subscriptions.forEach((b) => {
45
+ d.categories[b.workflowId] = {
46
+ emailEnabled: b.channels.email,
47
+ pushEnabled: b.channels.push,
48
+ inAppEnabled: b.channels.inApp,
49
+ smsEnabled: b.channels.sms
50
+ };
51
+ })), await n.preferences.update(v, u, d);
52
+ }
53
+ g.current = {}, l(null);
54
+ } catch (s) {
55
+ const u = s instanceof Error ? s : new Error("Failed to save preferences");
56
+ process.env.NODE_ENV, l(u), e?.(u);
44
57
  } finally {
45
58
  i(!1);
46
59
  }
47
60
  }, 500);
48
- } catch (o) {
49
- const s = o instanceof Error ? o : new Error("Failed to update preference");
50
- l(s), e?.(s), i(!1);
61
+ } catch (r) {
62
+ const o = r instanceof Error ? r : new Error("Failed to update preference");
63
+ l(o), e?.(o), i(!1);
51
64
  }
52
65
  },
53
66
  [t, f, n, e]
54
67
  );
55
- return N(() => () => {
56
- u.current && clearTimeout(u.current);
68
+ return w(() => () => {
69
+ h.current && clearTimeout(h.current);
57
70
  }, []), {
58
- updatePreference: y,
71
+ updatePreference: D,
59
72
  isSaving: c,
60
- error: r
73
+ error: a
61
74
  };
62
- }, S = (t) => !(!t || typeof t != "object" || ["notificationId", "channel", "renderedContent", "read", "archived"].filter((n) => !(n in t)).length > 0 || typeof t.channel != "string" || typeof t.read != "boolean" || typeof t.archived != "boolean" || typeof t.renderedContent != "object" || t.renderedContent === null), w = (t, f, e) => ({
75
+ }, j = (t) => !(!t || typeof t != "object" || ["notificationId", "channel", "renderedContent", "read", "archived"].filter((n) => !(n in t)).length > 0 || typeof t.channel != "string" || typeof t.read != "boolean" || typeof t.archived != "boolean" || typeof t.renderedContent != "object" || t.renderedContent === null), R = (t, f, e) => ({
63
76
  type: "custom",
64
77
  label: t.label,
65
78
  icon: void 0,
@@ -84,28 +97,28 @@ const R = () => window.__notificationSDK?.client, T = ({
84
97
  if (!e) return [];
85
98
  const i = [];
86
99
  if (Array.isArray(e))
87
- return e.forEach((r) => {
88
- i.push(w(r, n || "", c));
100
+ return e.forEach((a) => {
101
+ i.push(R(a, n || "", c));
89
102
  }), i;
90
103
  if (e.primary) {
91
- const r = e.primary;
104
+ const a = e.primary;
92
105
  i.push({
93
106
  type: "custom",
94
- label: r.label || "Primary Action",
107
+ label: a.label || "Primary Action",
95
108
  icon: void 0,
96
109
  handler: async (l) => {
97
- r.url && window.open(r.url, "_self");
110
+ a.url && window.open(a.url, "_self");
98
111
  }
99
112
  });
100
113
  }
101
114
  if (e.secondary) {
102
- const r = e.secondary;
115
+ const a = e.secondary;
103
116
  i.push({
104
117
  type: "custom",
105
- label: r.label || "Secondary Action",
118
+ label: a.label || "Secondary Action",
106
119
  icon: void 0,
107
120
  handler: async (l) => {
108
- r.url && window.open(r.url, "_self");
121
+ a.url && window.open(a.url, "_self");
109
122
  }
110
123
  });
111
124
  }
@@ -135,14 +148,14 @@ const R = () => window.__notificationSDK?.client, T = ({
135
148
  };
136
149
  },
137
150
  toWidgetNotificationFromWebSocket(e) {
138
- if (!S(e)) {
139
- const i = e?.renderedContent && typeof e.renderedContent == "object" ? e.renderedContent : {}, { subject: r, body: l } = t(
151
+ if (!j(e)) {
152
+ const i = e?.renderedContent && typeof e.renderedContent == "object" ? e.renderedContent : {}, { subject: a, body: l } = t(
140
153
  i,
141
154
  e?.channel
142
155
  );
143
156
  return {
144
157
  id: e?.notificationId || `notification-${Date.now()}`,
145
- subject: r || "Notification",
158
+ subject: a || "Notification",
146
159
  body: l || "",
147
160
  isRead: e?.read || !1,
148
161
  isArchived: e?.archived || !1,
@@ -174,11 +187,11 @@ const R = () => window.__notificationSDK?.client, T = ({
174
187
  }
175
188
  };
176
189
  },
177
- validateWebSocketPayload: S
190
+ validateWebSocketPayload: j
178
191
  };
179
192
  };
180
193
  export {
181
194
  I as c,
182
195
  T as u
183
196
  };
184
- //# sourceMappingURL=hooks-C7dzVxIU.js.map
197
+ //# sourceMappingURL=hooks-S0z2_-4B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-S0z2_-4B.js","sources":["../src/hooks/useLivePreferences.ts","../src/utils/notification-mapper.ts"],"sourcesContent":["import { useCallback, useRef, useState, useEffect } from 'react';\n\nimport { NotificationPreferences } from '../types/core';\n\nconst useNotificationsClient = () => {\n return (window as any).__notificationSDK?.client;\n};\n\nexport interface UseLivePreferencesProps {\n preferences: NotificationPreferences;\n onPreferencesChange: (preferences: NotificationPreferences) => void;\n onError?: (error: Error) => void;\n}\n\nexport interface UseLivePreferencesResult {\n updatePreference: (path: string, value: any) => void;\n isSaving: boolean;\n error: Error | null;\n}\n\nexport const useLivePreferences = ({\n preferences,\n onPreferencesChange,\n onError,\n}: UseLivePreferencesProps): UseLivePreferencesResult => {\n const notificationClient = useNotificationsClient();\n const [isSaving, setIsSaving] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const saveTimeoutRef = useRef<NodeJS.Timeout>();\n const pendingUpdatesRef = useRef<{ [key: string]: any }>({});\n\n const updatePreference = useCallback(\n (path: string, value: any) => {\n try {\n setError(null);\n\n const updatedPreferences = { ...preferences };\n const pathParts = path.split('.');\n\n let current: any = updatedPreferences;\n for (let i = 0; i < pathParts.length - 1; i++) {\n if (current[pathParts[i]] === undefined) {\n current[pathParts[i]] = {};\n }\n current = current[pathParts[i]];\n }\n current[pathParts[pathParts.length - 1]] = value;\n\n onPreferencesChange(updatedPreferences);\n\n pendingUpdatesRef.current[path] = value;\n\n if (saveTimeoutRef.current) {\n clearTimeout(saveTimeoutRef.current);\n }\n\n setIsSaving(true);\n\n saveTimeoutRef.current = setTimeout(async () => {\n try {\n if (!notificationClient) {\n throw new Error('Notification client not available');\n }\n\n const sdkConfig = (window as any).__notificationSDK?.config;\n\n if (!sdkConfig) {\n throw new Error('SDK configuration not available');\n }\n\n const { subscriberId, tenantId, environmentId } = sdkConfig;\n\n if (!subscriberId || !tenantId || !environmentId) {\n throw new Error(\n 'SubscriberId, TenantId or EnvironmentId not available in SDK configuration.',\n );\n }\n\n // Check if this is a schedule-related update\n const isScheduleUpdate = path.startsWith('deliverySchedule.');\n\n if (isScheduleUpdate) {\n // Handle schedule updates separately\n const schedulePayload: any = {\n isEnabled: updatedPreferences.deliverySchedule.enabled || false,\n };\n\n // Build weekly schedule\n if (updatedPreferences.deliverySchedule.weeklySchedule) {\n schedulePayload.weeklySchedule = updatedPreferences.deliverySchedule.weeklySchedule;\n }\n\n await notificationClient.preferences.updateSchedule(\n tenantId,\n subscriberId,\n schedulePayload,\n environmentId,\n );\n } else {\n // Handle global and subscription preferences\n const savePayload: any = {\n emailEnabled: updatedPreferences.channels.email,\n pushEnabled: updatedPreferences.channels.push,\n inAppEnabled: updatedPreferences.channels.inApp,\n smsEnabled: updatedPreferences.channels.sms,\n };\n\n if (updatedPreferences.subscriptions.length > 0) {\n savePayload.categories = {};\n updatedPreferences.subscriptions.forEach((sub) => {\n savePayload.categories[sub.workflowId] = {\n emailEnabled: sub.channels.email,\n pushEnabled: sub.channels.push,\n inAppEnabled: sub.channels.inApp,\n smsEnabled: sub.channels.sms,\n };\n });\n }\n\n await notificationClient.preferences.update(tenantId, subscriberId, savePayload);\n }\n\n pendingUpdatesRef.current = {};\n setError(null);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to save preferences');\n\n if (process.env.NODE_ENV === 'development') {\n console.error('Failed to save preferences:', error);\n }\n\n setError(error);\n onError?.(error);\n } finally {\n setIsSaving(false);\n }\n }, 500);\n } catch (err: any) {\n const error = err instanceof Error ? err : new Error('Failed to update preference');\n setError(error);\n onError?.(error);\n setIsSaving(false);\n }\n },\n [preferences, onPreferencesChange, notificationClient, onError],\n );\n\n useEffect(() => {\n return () => {\n if (saveTimeoutRef.current) {\n clearTimeout(saveTimeoutRef.current);\n }\n };\n }, []);\n\n return {\n updatePreference,\n isSaving,\n error,\n };\n};\n","import type {\n RenderedNotificationItem,\n RenderedNotificationActionMap,\n NotificationAction as SDKNotificationAction,\n} from '@edusight/notification-sdk';\n\nimport type { Notification, NotificationAction } from '../types/core';\n\nexport type WebSocketNotificationReceivedPayload = RenderedNotificationItem;\n\nexport interface NotificationMapper {\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification;\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification;\n validateWebSocketPayload(payload: any): payload is WebSocketNotificationReceivedPayload;\n}\n\nconst validateWebSocketPayload = (\n payload: any,\n): payload is WebSocketNotificationReceivedPayload => {\n if (!payload || typeof payload !== 'object') {\n console.warn('Invalid WebSocket payload: not an object', payload);\n return false;\n }\n\n const requiredFields = ['notificationId', 'channel', 'renderedContent', 'read', 'archived'];\n const missingFields = requiredFields.filter((field) => !(field in payload));\n\n if (missingFields.length > 0) {\n console.warn('WebSocket payload missing required fields:', missingFields, payload);\n return false;\n }\n\n if (typeof payload.channel !== 'string') {\n console.warn('WebSocket payload channel is invalid', payload);\n return false;\n }\n\n if (typeof payload.read !== 'boolean' || typeof payload.archived !== 'boolean') {\n console.warn('WebSocket payload read/archived flags are invalid', payload);\n return false;\n }\n\n if (typeof payload.renderedContent !== 'object' || payload.renderedContent === null) {\n console.warn('WebSocket payload renderedContent is not an object', payload);\n return false;\n }\n\n return true;\n};\n\nconst mapSDKActionToWidgetAction = (\n sdkAction: SDKNotificationAction,\n notificationId: string,\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>,\n): NotificationAction => {\n return {\n type: 'custom',\n label: sdkAction.label,\n icon: undefined,\n handler: async () => {\n try {\n if (onActionExecute) {\n await onActionExecute(sdkAction.id, notificationId);\n }\n\n if (sdkAction.url) {\n const target = sdkAction.target || '_self';\n window.open(sdkAction.url, target);\n }\n\n if (sdkAction.markAsReadOnClick) {\n // This will be handled by the widget's action handler\n }\n } catch (error) {\n console.error('Error executing action:', error);\n throw error;\n }\n },\n };\n};\n\nexport const createNotificationMapper = (): NotificationMapper => {\n const extractSubjectAndBody = (\n renderedContent: Record<string, any>,\n channel?: string,\n ): { subject: string; body: string } => {\n if (!renderedContent || typeof renderedContent !== 'object') {\n return { subject: '', body: '' };\n }\n\n let subject = '';\n let body = '';\n\n if (renderedContent.push) {\n subject = renderedContent.push.title || '';\n body = renderedContent.push.body || '';\n } else if (renderedContent.email) {\n subject = renderedContent.email.subject || '';\n body = renderedContent.email.html || renderedContent.email.text || '';\n } else if (renderedContent.in_app) {\n subject = renderedContent.in_app.title || '';\n body = renderedContent.in_app.message || '';\n } else if (renderedContent.sms) {\n subject = 'SMS';\n body = renderedContent.sms.message || '';\n } else if (channel === 'in_app') {\n subject = renderedContent.title || '';\n body = renderedContent.message || '';\n } else {\n subject = renderedContent.title || renderedContent.subject || '';\n body = renderedContent.message || renderedContent.body || renderedContent.text || '';\n }\n\n return { subject, body };\n };\n\n const mapActionsToNotificationActions = (\n actions?: RenderedNotificationActionMap | SDKNotificationAction[],\n notificationId?: string,\n onActionExecute?: (actionId: string, notificationId: string) => Promise<void>,\n ): NotificationAction[] => {\n if (!actions) return [];\n\n const result: NotificationAction[] = [];\n\n if (Array.isArray(actions)) {\n actions.forEach((sdkAction) => {\n result.push(mapSDKActionToWidgetAction(sdkAction, notificationId || '', onActionExecute));\n });\n return result;\n }\n\n if (actions.primary) {\n const primaryAction = actions.primary;\n result.push({\n type: 'custom',\n label: primaryAction.label || 'Primary Action',\n icon: undefined,\n handler: async (notificationId: string) => {\n if (primaryAction.url) {\n window.open(primaryAction.url, '_self');\n }\n if (onActionExecute) {\n await onActionExecute('primary', notificationId);\n }\n },\n });\n }\n\n if (actions.secondary) {\n const secondaryAction = actions.secondary;\n result.push({\n type: 'custom',\n label: secondaryAction.label || 'Secondary Action',\n icon: undefined,\n handler: async (notificationId: string) => {\n if (secondaryAction.url) {\n window.open(secondaryAction.url, '_self');\n }\n if (onActionExecute) {\n await onActionExecute('secondary', notificationId);\n }\n },\n });\n }\n\n return result;\n };\n\n return {\n toWidgetNotification(renderedItem: RenderedNotificationItem): Notification {\n const { subject, body } = extractSubjectAndBody(\n renderedItem.renderedContent,\n renderedItem.channel,\n );\n\n return {\n id: renderedItem.notificationId,\n subject: subject || 'Notification',\n body: body || '',\n isRead: renderedItem.read,\n isArchived: renderedItem.archived,\n timestamp: renderedItem.createdAt ? new Date(renderedItem.createdAt) : new Date(),\n tags: [],\n actions: mapActionsToNotificationActions(\n renderedItem.renderedContent?.actions || renderedItem.actions,\n ),\n metadata: {\n channel: renderedItem.channel,\n renderedContent: renderedItem.renderedContent,\n },\n };\n },\n\n toWidgetNotificationFromWebSocket(wsPayload: any): Notification {\n if (!validateWebSocketPayload(wsPayload)) {\n console.error('Invalid WebSocket payload structure, using fallback', wsPayload);\n const fallbackRenderedContent =\n wsPayload?.renderedContent && typeof wsPayload.renderedContent === 'object'\n ? wsPayload.renderedContent\n : {};\n const { subject, body } = extractSubjectAndBody(\n fallbackRenderedContent,\n wsPayload?.channel,\n );\n return {\n id: wsPayload?.notificationId || `notification-${Date.now()}`,\n subject: subject || 'Notification',\n body: body || '',\n isRead: wsPayload?.read || false,\n isArchived: wsPayload?.archived || false,\n timestamp: wsPayload?.createdAt ? new Date(wsPayload.createdAt) : new Date(),\n tags: [],\n actions: [],\n metadata: {\n channel: wsPayload?.channel || 'in_app',\n renderedContent: fallbackRenderedContent,\n },\n };\n }\n\n const { subject, body } = extractSubjectAndBody(wsPayload.renderedContent, wsPayload.channel);\n\n return {\n id: wsPayload.notificationId,\n subject: subject || 'Notification',\n body: body || '',\n isRead: wsPayload.read || false,\n isArchived: wsPayload.archived || false,\n timestamp: wsPayload.createdAt ? new Date(wsPayload.createdAt) : new Date(),\n tags: [],\n actions: mapActionsToNotificationActions(\n wsPayload.renderedContent?.actions || wsPayload.actions,\n wsPayload.notificationId,\n ),\n metadata: {\n channel: wsPayload.channel,\n renderedContent: (wsPayload as any).renderedContent,\n },\n };\n },\n\n validateWebSocketPayload,\n };\n};\n"],"names":["useNotificationsClient","useLivePreferences","preferences","onPreferencesChange","onError","notificationClient","isSaving","setIsSaving","useState","error","setError","saveTimeoutRef","useRef","pendingUpdatesRef","updatePreference","useCallback","path","value","updatedPreferences","pathParts","current","i","sdkConfig","subscriberId","tenantId","environmentId","schedulePayload","savePayload","sub","err","useEffect","validateWebSocketPayload","payload","field","mapSDKActionToWidgetAction","sdkAction","notificationId","onActionExecute","target","createNotificationMapper","extractSubjectAndBody","renderedContent","channel","subject","body","mapActionsToNotificationActions","actions","result","primaryAction","secondaryAction","renderedItem","wsPayload","fallbackRenderedContent"],"mappings":"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"}
package/dist/index.cjs.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),B=require("@edusight/notification-sdk"),i=require("react"),q=require("socket.io-client"),v=require("./hooks-kLhwdW29.cjs"),h=require("./components-D9Q1H53S.cjs"),V=()=>window.__notificationSDK?.client,z=({onPreferencesLoaded:t,onError:n})=>{const f=V(),[E,c]=i.useState(!0),[u,l]=i.useState(null),[r,d]=i.useState(null),w=i.useCallback(async()=>{try{if(c(!0),l(null),!f)throw new Error("Notification client not available");const m=window.__notificationSDK?.config;if(!m)throw new Error("SDK configuration not available");const{subscriberId:I,tenantId:C,environmentId:T}=m;if(!I||!C||!T)throw new Error("SubscriberId, TenantId or EnvironmentId not available in config");const b=await f.preferences.get(C,I,T),p={channels:{email:b.emailEnabled??!0,push:b.pushEnabled??!0,sms:b.smsEnabled??!1,inApp:b.inAppEnabled??!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:b.quietHoursStart??"22:00",end:b.quietHoursEnd??"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}};b.categories&&Object.entries(b.categories).forEach(([N,_])=>{p.subscriptions.push({workflowId:N,name:N,enabled:!0,channels:{email:_.emailEnabled??!0,push:_.pushEnabled??!0,sms:_.smsEnabled??!1,inApp:_.inAppEnabled??!0}})}),d(p),t(p)}catch(m){const I=m instanceof Error?m:new Error("Failed to load preferences");m?.response?.status===404||m?.status===404||(l(I),n?.(I));const T={channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}};d(T),t(T)}finally{c(!1)}},[f,t,n]);return i.useEffect(()=>{f&&w()},[f,w]),{isLoading:E,error:u,preferences:r}},H=()=>window.__notificationSDK?.client,$=()=>{const t=H(),[n,f]=i.useState([]),[E,c]=i.useState(!1),[u,l]=i.useState(!0),[r,d]=i.useState(0),w=5,m=i.useCallback(async()=>{if(!(!t||E||!u))try{c(!0);const C=window.__notificationSDK?.config;if(!C)return;const T=await t.preferences.listSpecific(C.tenantId,C.subscriberId,{includeWorkflows:!0,includeTemplates:!1,activeOnly:!0,limit:w,offset:r}),b=(T.items||[]).map(p=>({workflowId:p.identifier,name:p.name,enabled:p.preference.enabled,channels:p.preference.channels}));f(p=>{const N=new Set(p.map(k=>k.workflowId)),_=b.filter(k=>!N.has(k.workflowId));return[...p,..._]}),d(p=>p+w),(b.length<w||T.total!==void 0&&n.length+b.length>=T.total)&&l(!1)}catch{}finally{c(!1)}},[t,r,u,E,n.length]);return i.useEffect(()=>{t&&r===0&&n.length===0&&m()},[t,m,r,n.length]),{specificPreferences:n,isLoading:E,hasMore:u,loadMore:m,refetch:async()=>{f([]),d(0),l(!0)}}},J=({error:t,onRetry:n})=>s.jsxs("div",{className:"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg",role:"alert","data-testid":"error-boundary-fallback",children:[s.jsxs("div",{className:"flex items-center mb-2",children:[s.jsx(h.MdError,{className:"w-6 h-6 text-[var(--widget-error)] mr-2","aria-hidden":"true"}),s.jsx("h3",{className:"text-sm font-medium text-[var(--widget-error)]",children:"Something went wrong"})]}),s.jsx("p",{className:"text-sm mb-3 text-[var(--widget-error)]/80",children:"The notification widget encountered an error and couldn't load properly."}),process.env.NODE_ENV==="development"&&t&&s.jsxs("details",{className:"mb-3",children:[s.jsx("summary",{className:"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors",children:"Error details (development only)"}),s.jsxs("pre",{className:"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]",children:[t.message,t.stack&&`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),B=require("@edusight/notification-sdk"),i=require("react"),q=require("socket.io-client"),v=require("./hooks-C6Z38jT_.cjs"),y=require("./components-Cr9Sf7Cz.cjs"),V=()=>window.__notificationSDK?.client,z=({onPreferencesLoaded:t,onError:n})=>{const p=V(),[w,c]=i.useState(!0),[f,l]=i.useState(null),[r,u]=i.useState(null),m=i.useCallback(async()=>{try{if(c(!0),l(null),!p)throw new Error("Notification client not available");const h=window.__notificationSDK?.config;if(!h)throw new Error("SDK configuration not available");const{subscriberId:g,tenantId:k,environmentId:T}=h;if(!g||!k||!T)throw new Error("SubscriberId, TenantId or EnvironmentId not available in config");const E=await p.preferences.get(k,g,T);let d=null;try{d=await p.preferences.getSchedule(k,g,T)}catch{}const _={channels:{email:E.emailEnabled??!0,push:E.pushEnabled??!0,sms:E.smsEnabled??!1,inApp:E.inAppEnabled??!0},subscriptions:[],deliverySchedule:{enabled:d?.isEnabled||!1,timezone:"UTC",quietHours:{start:E.quietHoursStart??"22:00",end:E.quietHoursEnd??"08:00"},weekdays:d?.weeklySchedule?[!!d.weeklySchedule.monday,!!d.weeklySchedule.tuesday,!!d.weeklySchedule.wednesday,!!d.weeklySchedule.thursday,!!d.weeklySchedule.friday,!!d.weeklySchedule.saturday,!!d.weeklySchedule.sunday]:[!0,!0,!0,!0,!0,!1,!1],weeklySchedule:d?.weeklySchedule||void 0}};E.categories&&Object.entries(E.categories).forEach(([N,C])=>{_.subscriptions.push({workflowId:N,name:N,enabled:!0,channels:{email:C.emailEnabled??!0,push:C.pushEnabled??!0,sms:C.smsEnabled??!1,inApp:C.inAppEnabled??!0}})}),u(_),t(_)}catch(h){const g=h instanceof Error?h:new Error("Failed to load preferences");h?.response?.status===404||h?.status===404||(l(g),n?.(g));const T={channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{enabled:!1,timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}};u(T),t(T)}finally{c(!1)}},[p,t,n]);return i.useEffect(()=>{p&&m()},[p,m]),{isLoading:w,error:f,preferences:r}},H=()=>window.__notificationSDK?.client,$=()=>{const t=H(),[n,p]=i.useState([]),[w,c]=i.useState(!1),[f,l]=i.useState(!0),[r,u]=i.useState(0),m=5,h=i.useCallback(async()=>{if(!(!t||w||!f))try{c(!0);const k=window.__notificationSDK?.config;if(!k)return;const T=await t.preferences.listSpecific(k.tenantId,k.subscriberId,{includeWorkflows:!0,includeTemplates:!1,activeOnly:!0,limit:m,offset:r}),E=(T.items||[]).map(d=>({workflowId:d.identifier,name:d.name,enabled:d.preference.enabled,channels:d.preference.channels}));p(d=>{const _=new Set(d.map(C=>C.workflowId)),N=E.filter(C=>!_.has(C.workflowId));return[...d,...N]}),u(d=>d+m),(E.length<m||T.total!==void 0&&n.length+E.length>=T.total)&&l(!1)}catch{}finally{c(!1)}},[t,r,f,w,n.length]);return i.useEffect(()=>{t&&r===0&&n.length===0&&h()},[t,h,r,n.length]),{specificPreferences:n,isLoading:w,hasMore:f,loadMore:h,refetch:async()=>{p([]),u(0),l(!0)}}},J=({error:t,onRetry:n})=>s.jsxs("div",{className:"p-4 bg-[var(--widget-error)]/10 border border-[var(--widget-error)]/20 rounded-lg",role:"alert","data-testid":"error-boundary-fallback",children:[s.jsxs("div",{className:"flex items-center mb-2",children:[s.jsx(y.MdError,{className:"w-6 h-6 text-[var(--widget-error)] mr-2","aria-hidden":"true"}),s.jsx("h3",{className:"text-sm font-medium text-[var(--widget-error)]",children:"Something went wrong"})]}),s.jsx("p",{className:"text-sm mb-3 text-[var(--widget-error)]/80",children:"The notification widget encountered an error and couldn't load properly."}),process.env.NODE_ENV==="development"&&t&&s.jsxs("details",{className:"mb-3",children:[s.jsx("summary",{className:"text-xs cursor-pointer text-[var(--widget-error)] hover:text-[var(--widget-error)]/80 transition-colors",children:"Error details (development only)"}),s.jsxs("pre",{className:"mt-2 text-xs bg-[var(--widget-error)]/5 p-2 rounded overflow-auto max-h-32 text-[var(--widget-error)]",children:[t.message,t.stack&&`
2
2
 
3
- ${t.stack}`]})]}),s.jsxs("button",{type:"button",className:"inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-[var(--widget-error)] bg-[var(--widget-error)]/10 hover:bg-[var(--widget-error)]/20 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--widget-error)] transition-colors",onClick:n,"data-testid":"error-retry-button",children:[s.jsx(h.MdRefresh,{className:"mr-1 w-4 h-4","aria-hidden":"true"}),"Try again"]})]});class D extends i.Component{constructor(n){super(n),this.handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})},this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,f){this.setState({errorInfo:f}),this.props.onError&&this.props.onError(n,f)}render(){return this.state.hasError?s.jsx(J,{error:this.state.error,onRetry:this.handleRetry}):this.props.children}}const P=i.createContext(null),G=()=>{const t=i.useContext(P);if(!t)throw new Error("useSDK must be used within a NotificationWidget");return t},Q={notifications:[],unreadCount:0,preferences:{channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}},ui:{isOpen:!1,currentView:"notifications",selectedNotifications:[],isLoading:!1,error:null},websocket:{connected:!1,reconnecting:!1}},X=({config:t,children:n})=>{const[f,E]=i.useState({client:null,isInitialized:!1,error:null});return i.useEffect(()=>{let c=!0;return(async()=>{try{const l=window.__notificationSDK;if(l?.client&&JSON.stringify(l.config)===JSON.stringify(t)){c&&E({client:l.client,isInitialized:!0,error:null});return}const r=new B.NotificationClient({apiUrl:t.baseUrl,apiKey:t.apiKey,tenantId:t.tenantId,environmentId:t.environmentId});window.__notificationSDK={client:r,config:t},c&&E({client:r,isInitialized:!0,error:null})}catch(l){c&&E({client:null,isInitialized:!1,error:l})}})(),()=>{c=!1}},[t]),s.jsx(P.Provider,{value:f,children:n})},Y=(t,n)=>{switch(n.type){case"SET_NOTIFICATIONS":return{...t,notifications:n.payload,unreadCount:n.payload.filter(u=>!u.isRead).length};case"ADD_NOTIFICATION":const f=[n.payload,...t.notifications];return{...t,notifications:f,unreadCount:f.filter(u=>!u.isRead).length};case"UPDATE_NOTIFICATION":const E=t.notifications.map(u=>u.id===n.payload.id?{...u,...n.payload.updates}:u);return{...t,notifications:E,unreadCount:E.filter(u=>!u.isRead).length};case"DELETE_NOTIFICATION":const c=t.notifications.filter(u=>u.id!==n.payload);return{...t,notifications:c,unreadCount:c.filter(u=>!u.isRead).length};case"SET_PREFERENCES":return{...t,preferences:n.payload};case"SET_UI_STATE":return{...t,ui:{...t.ui,...n.payload}};case"SET_WEBSOCKET_STATE":return{...t,websocket:{...t.websocket,...n.payload}};default:return t}},Z=({position:t="right",size:n="medium",theme:f="light",className:E="",onError:c,onMorePreferencesClick:u})=>{const[l,r]=i.useReducer(Y,Q),{client:d,isInitialized:w,error:m}=G(),I=i.useRef(null),C=i.useCallback(e=>{r({type:"SET_PREFERENCES",payload:e})},[]),T=i.useCallback(e=>{c&&c(e)},[c]),{error:b}=z({onPreferencesLoaded:C,onError:T}),{specificPreferences:p,isLoading:N,hasMore:_,loadMore:k}=$(),{updatePreference:j,isSaving:A,error:O}=v.useLivePreferences({preferences:l.preferences,onPreferencesChange:C,onError:T});i.useEffect(()=>{if(p.length>0){const o=[...l.preferences.subscriptions];let a=!1;p.forEach(S=>{const g=o.findIndex(y=>y.workflowId===S.workflowId);if(g===-1)o.push(S),a=!0;else{const y=o[g];y.name===y.workflowId&&S.name&&S.name!==S.workflowId&&(o[g]={...y,name:S.name},a=!0)}}),a&&r({type:"SET_PREFERENCES",payload:{...l.preferences,subscriptions:o}})}},[p]);const K=i.useMemo(()=>p.map(e=>l.preferences.subscriptions.find(a=>a.workflowId===e.workflowId)||e),[p,l.preferences.subscriptions]),x=i.useCallback(e=>{try{const o=v.createNotificationMapper();switch(e.type){case"notification_received":{const a=e.data;if(!o.validateWebSocketPayload(a))break;const S=o.toWidgetNotificationFromWebSocket(a);r({type:"ADD_NOTIFICATION",payload:S});break}case"notification_updated":r({type:"UPDATE_NOTIFICATION",payload:{id:e.data.id||e.data.notificationId,updates:e.data}});break;case"notification_deleted":r({type:"DELETE_NOTIFICATION",payload:e.data.id||e.data.notificationId});break;case"preferences_updated":r({type:"SET_PREFERENCES",payload:e.data});break;default:}}catch{}},[]),R=i.useCallback(async()=>{if(!(!d||!w||I.current))try{r({type:"SET_WEBSOCKET_STATE",payload:{reconnecting:!0}});const e=window.__notificationSDK?.config;if(!e)throw new Error("SDK configuration not available for WebSocket connection");const S=`${d.getApiHost()}/v1/notifications`,g=q.io(S,{query:{tenantId:e.tenantId,subscriberId:e.subscriberId,environmentId:e.environmentId},transports:["websocket"],autoConnect:!1,reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3});I.current=g,g.on("notification",y=>{x({type:"notification_received",data:y})}),g.on("connect",()=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!0,reconnecting:!1}})}),g.on("disconnect",y=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}),g.on("reconnect_attempt",y=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!0}})}),g.on("connect_error",y=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(y)}),g.connect()}catch(e){r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(e)}},[d,w,x,c]),W=i.useCallback(()=>{if(I.current)try{I.current.disconnect&&I.current.disconnect(),I.current=null,r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}catch{}},[]),F=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!l.ui.isOpen}})},[l.ui.isOpen]),M=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!1}})},[]),L=i.useCallback(e=>{r({type:"SET_UI_STATE",payload:{currentView:e}})},[]),U=i.useCallback(async(e,o)=>{if(!d||!w)return;const a=window.__notificationSDK?.config;if(a){if(!e)throw new Error("notificationId is required");try{switch(o.type){case"mark_read":await d.inbox.markAsRead(e,a.tenantId,a.environmentId,a.subscriberId);break;case"mark_unread":await d.inbox.markAsUnread(e,a.tenantId,a.environmentId,a.subscriberId);break;case"archive":await d.inbox.archive(e,a.tenantId,a.environmentId,a.subscriberId);break;case"delete":await d.inbox.delete(e,a.tenantId,a.environmentId,a.subscriberId);break;default:o.handler&&await o.handler(e);break}switch(o.type){case"mark_read":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!0}}});break;case"mark_unread":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!1}}});break;case"archive":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isArchived:!0}}});break;case"delete":r({type:"DELETE_NOTIFICATION",payload:e});break}}catch(S){c&&c(S)}}},[d]);return i.useEffect(()=>{if(!d||!w)return;(async()=>{try{r({type:"SET_UI_STATE",payload:{isLoading:!0}});const o=window.__notificationSDK?.config;if(!o)throw new Error("SDK configuration not available");const a=v.createNotificationMapper(),g=((await d.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(y=>a.toWidgetNotification(y));r({type:"SET_NOTIFICATIONS",payload:g}),r({type:"SET_UI_STATE",payload:{isLoading:!1,error:null}})}catch(o){r({type:"SET_UI_STATE",payload:{isLoading:!1,error:o}}),c&&c(o)}})()},[d,w,c]),i.useEffect(()=>(d&&w&&R(),()=>{W()}),[d]),i.useEffect(()=>{if(!d||!w||l.websocket.connected)return;const e=setInterval(async()=>{try{const o=window.__notificationSDK?.config;if(!o)return;const a=v.createNotificationMapper(),g=((await d.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(y=>a.toWidgetNotification(y));r({type:"SET_NOTIFICATIONS",payload:g})}catch{}},3e4);return()=>clearInterval(e)},[d,l.websocket.connected]),i.useEffect(()=>{const e=o=>{if(o.key==="notification_widget_sync"&&o.newValue)try{const a=JSON.parse(o.newValue);x(a)}catch{}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[x]),i.useEffect(()=>{r({type:"SET_UI_STATE",payload:{isLoading:A}})},[A]),i.useEffect(()=>{const e=m||O||b;e&&r({type:"SET_UI_STATE",payload:{error:e}})},[m,O,b]),!w&&!m?s.jsx("div",{className:`mx-widget-root relative inline-block ${E}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":f,"data-testid":"notification-widget",children:s.jsx(h.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(h.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):m?s.jsx("div",{className:`mx-widget-root relative inline-block ${E}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":f,"data-testid":"notification-widget",children:s.jsx(h.ComponentErrorBoundary,{componentName:"BellComponent",fallback:s.jsx(h.SDKConnectionFallback,{error:m.message,onRetry:()=>window.location.reload()}),children:s.jsx(h.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):s.jsxs("div",{className:`mx-widget-root relative inline-block ${E}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":f,"data-testid":"notification-widget",children:[s.jsx(h.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(h.BellComponent,{unreadCount:l.unreadCount,onClick:F,size:n,disabled:l.ui.isLoading})}),s.jsx(h.ComponentErrorBoundary,{componentName:"InboxPopover",fallback:s.jsx(h.LoadingFallback,{message:"Unable to load notifications"}),children:s.jsx(h.InboxPopover,{isOpen:l.ui.isOpen,onClose:M,position:t,currentView:l.ui.currentView,onViewChange:L,notifications:l.notifications,onNotificationAction:U,preferences:l.preferences,onPreferenceChange:j,isPreferencesLoading:A,specificPreferences:K,onLoadMoreSpecific:k,hasMoreSpecific:_,isListLoading:N,onMorePreferencesClick:u})})]})},ee=({sdkConfig:t,...n})=>s.jsx(D,{onError:n.onError,children:s.jsx(X,{config:t,children:s.jsx(Z,{...n})})}),te="3.0.0",ne="@edusight/notification-widget";exports.BellComponent=h.BellComponent;exports.InboxPopover=h.InboxPopover;exports.NotificationItem=h.NotificationItem;exports.PreferencesView=h.PreferencesView;exports.NotificationWidget=ee;exports.NotificationWidgetErrorBoundary=D;exports.VERSION=te;exports.WIDGET_NAME=ne;
3
+ ${t.stack}`]})]}),s.jsxs("button",{type:"button",className:"inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-[var(--widget-error)] bg-[var(--widget-error)]/10 hover:bg-[var(--widget-error)]/20 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--widget-error)] transition-colors",onClick:n,"data-testid":"error-retry-button",children:[s.jsx(y.MdRefresh,{className:"mr-1 w-4 h-4","aria-hidden":"true"}),"Try again"]})]});class D extends i.Component{constructor(n){super(n),this.handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})},this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(n){return{hasError:!0,error:n}}componentDidCatch(n,p){this.setState({errorInfo:p}),this.props.onError&&this.props.onError(n,p)}render(){return this.state.hasError?s.jsx(J,{error:this.state.error,onRetry:this.handleRetry}):this.props.children}}const P=i.createContext(null),G=()=>{const t=i.useContext(P);if(!t)throw new Error("useSDK must be used within a NotificationWidget");return t},Q={notifications:[],unreadCount:0,preferences:{channels:{email:!0,push:!0,sms:!1,inApp:!0},subscriptions:[],deliverySchedule:{timezone:"UTC",quietHours:{start:"22:00",end:"08:00"},weekdays:[!0,!0,!0,!0,!0,!1,!1]}},ui:{isOpen:!1,currentView:"notifications",selectedNotifications:[],isLoading:!1,error:null},websocket:{connected:!1,reconnecting:!1}},X=({config:t,children:n})=>{const[p,w]=i.useState({client:null,isInitialized:!1,error:null});return i.useEffect(()=>{let c=!0;return(async()=>{try{const l=window.__notificationSDK;if(l?.client&&JSON.stringify(l.config)===JSON.stringify(t)){c&&w({client:l.client,isInitialized:!0,error:null});return}const r=new B.NotificationClient({apiUrl:t.baseUrl,apiKey:t.apiKey,tenantId:t.tenantId,environmentId:t.environmentId});window.__notificationSDK={client:r,config:t},c&&w({client:r,isInitialized:!0,error:null})}catch(l){c&&w({client:null,isInitialized:!1,error:l})}})(),()=>{c=!1}},[t]),s.jsx(P.Provider,{value:p,children:n})},Y=(t,n)=>{switch(n.type){case"SET_NOTIFICATIONS":return{...t,notifications:n.payload,unreadCount:n.payload.filter(f=>!f.isRead).length};case"ADD_NOTIFICATION":const p=[n.payload,...t.notifications];return{...t,notifications:p,unreadCount:p.filter(f=>!f.isRead).length};case"UPDATE_NOTIFICATION":const w=t.notifications.map(f=>f.id===n.payload.id?{...f,...n.payload.updates}:f);return{...t,notifications:w,unreadCount:w.filter(f=>!f.isRead).length};case"DELETE_NOTIFICATION":const c=t.notifications.filter(f=>f.id!==n.payload);return{...t,notifications:c,unreadCount:c.filter(f=>!f.isRead).length};case"SET_PREFERENCES":return{...t,preferences:n.payload};case"SET_UI_STATE":return{...t,ui:{...t.ui,...n.payload}};case"SET_WEBSOCKET_STATE":return{...t,websocket:{...t.websocket,...n.payload}};default:return t}},Z=({position:t="right",size:n="medium",theme:p="light",className:w="",onError:c,onMorePreferencesClick:f})=>{const[l,r]=i.useReducer(Y,Q),{client:u,isInitialized:m,error:h}=G(),g=i.useRef(null),k=i.useCallback(e=>{r({type:"SET_PREFERENCES",payload:e})},[]),T=i.useCallback(e=>{c&&c(e)},[c]),{error:E}=z({onPreferencesLoaded:k,onError:T}),{specificPreferences:d,isLoading:_,hasMore:N,loadMore:C}=$(),{updatePreference:j,isSaving:A,error:O}=v.useLivePreferences({preferences:l.preferences,onPreferencesChange:k,onError:T});i.useEffect(()=>{if(d.length>0){const o=[...l.preferences.subscriptions];let a=!1;d.forEach(I=>{const S=o.findIndex(b=>b.workflowId===I.workflowId);if(S===-1)o.push(I),a=!0;else{const b=o[S];b.name===b.workflowId&&I.name&&I.name!==I.workflowId&&(o[S]={...b,name:I.name},a=!0)}}),a&&r({type:"SET_PREFERENCES",payload:{...l.preferences,subscriptions:o}})}},[d]);const K=i.useMemo(()=>d.map(e=>l.preferences.subscriptions.find(a=>a.workflowId===e.workflowId)||e),[d,l.preferences.subscriptions]),x=i.useCallback(e=>{try{const o=v.createNotificationMapper();switch(e.type){case"notification_received":{const a=e.data;if(!o.validateWebSocketPayload(a))break;const I=o.toWidgetNotificationFromWebSocket(a);r({type:"ADD_NOTIFICATION",payload:I});break}case"notification_updated":r({type:"UPDATE_NOTIFICATION",payload:{id:e.data.id||e.data.notificationId,updates:e.data}});break;case"notification_deleted":r({type:"DELETE_NOTIFICATION",payload:e.data.id||e.data.notificationId});break;case"preferences_updated":r({type:"SET_PREFERENCES",payload:e.data});break;default:}}catch{}},[]),R=i.useCallback(async()=>{if(!(!u||!m||g.current))try{r({type:"SET_WEBSOCKET_STATE",payload:{reconnecting:!0}});const e=window.__notificationSDK?.config;if(!e)throw new Error("SDK configuration not available for WebSocket connection");const I=`${u.getApiHost()}/v1/notifications`,S=q.io(I,{query:{tenantId:e.tenantId,subscriberId:e.subscriberId,environmentId:e.environmentId},transports:["websocket"],autoConnect:!1,reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3});g.current=S,S.on("notification",b=>{x({type:"notification_received",data:b})}),S.on("connect",()=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!0,reconnecting:!1}})}),S.on("disconnect",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}),S.on("reconnect_attempt",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!0}})}),S.on("connect_error",b=>{r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(b)}),S.connect()}catch(e){r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}}),c&&c(e)}},[u,m,x,c]),W=i.useCallback(()=>{if(g.current)try{g.current.disconnect&&g.current.disconnect(),g.current=null,r({type:"SET_WEBSOCKET_STATE",payload:{connected:!1,reconnecting:!1}})}catch{}},[]),F=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!l.ui.isOpen}})},[l.ui.isOpen]),M=i.useCallback(()=>{r({type:"SET_UI_STATE",payload:{isOpen:!1}})},[]),L=i.useCallback(e=>{r({type:"SET_UI_STATE",payload:{currentView:e}})},[]),U=i.useCallback(async(e,o)=>{if(!u||!m)return;const a=window.__notificationSDK?.config;if(a){if(!e)throw new Error("notificationId is required");try{switch(o.type){case"mark_read":await u.inbox.markAsRead(e,a.tenantId,a.environmentId,a.subscriberId);break;case"mark_unread":await u.inbox.markAsUnread(e,a.tenantId,a.environmentId,a.subscriberId);break;case"archive":await u.inbox.archive(e,a.tenantId,a.environmentId,a.subscriberId);break;case"delete":await u.inbox.delete(e,a.tenantId,a.environmentId,a.subscriberId);break;default:o.handler&&await o.handler(e);break}switch(o.type){case"mark_read":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!0}}});break;case"mark_unread":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isRead:!1}}});break;case"archive":r({type:"UPDATE_NOTIFICATION",payload:{id:e,updates:{isArchived:!0}}});break;case"delete":r({type:"DELETE_NOTIFICATION",payload:e});break}}catch(I){c&&c(I)}}},[u]);return i.useEffect(()=>{if(!u||!m)return;(async()=>{try{r({type:"SET_UI_STATE",payload:{isLoading:!0}});const o=window.__notificationSDK?.config;if(!o)throw new Error("SDK configuration not available");const a=v.createNotificationMapper(),S=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(b=>a.toWidgetNotification(b));r({type:"SET_NOTIFICATIONS",payload:S}),r({type:"SET_UI_STATE",payload:{isLoading:!1,error:null}})}catch(o){r({type:"SET_UI_STATE",payload:{isLoading:!1,error:o}}),c&&c(o)}})()},[u,m,c]),i.useEffect(()=>(u&&m&&R(),()=>{W()}),[u]),i.useEffect(()=>{if(!u||!m||l.websocket.connected)return;const e=setInterval(async()=>{try{const o=window.__notificationSDK?.config;if(!o)return;const a=v.createNotificationMapper(),S=((await u.inbox.getRenderedNotifications({channel:"in_app",limit:50,offset:0},o.tenantId,o.environmentId,o.subscriberId))?.items||[]).map(b=>a.toWidgetNotification(b));r({type:"SET_NOTIFICATIONS",payload:S})}catch{}},3e4);return()=>clearInterval(e)},[u,l.websocket.connected]),i.useEffect(()=>{const e=o=>{if(o.key==="notification_widget_sync"&&o.newValue)try{const a=JSON.parse(o.newValue);x(a)}catch{}};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[x]),i.useEffect(()=>{r({type:"SET_UI_STATE",payload:{isLoading:A}})},[A]),i.useEffect(()=>{const e=h||O||E;e&&r({type:"SET_UI_STATE",payload:{error:e}})},[h,O,E]),!m&&!h?s.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:s.jsx(y.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(y.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):h?s.jsx("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:s.jsx(y.ComponentErrorBoundary,{componentName:"BellComponent",fallback:s.jsx(y.SDKConnectionFallback,{error:h.message,onRetry:()=>window.location.reload()}),children:s.jsx(y.BellComponent,{unreadCount:0,onClick:()=>{},size:n,disabled:!0})})}):s.jsxs("div",{className:`mx-widget-root relative inline-block ${w}`,"data-mx-widget":"root","data-widget-size":n||"small","data-theme":p,"data-testid":"notification-widget",children:[s.jsx(y.ComponentErrorBoundary,{componentName:"BellComponent",children:s.jsx(y.BellComponent,{unreadCount:l.unreadCount,onClick:F,size:n,disabled:l.ui.isLoading})}),s.jsx(y.ComponentErrorBoundary,{componentName:"InboxPopover",fallback:s.jsx(y.LoadingFallback,{message:"Unable to load notifications"}),children:s.jsx(y.InboxPopover,{isOpen:l.ui.isOpen,onClose:M,position:t,currentView:l.ui.currentView,onViewChange:L,notifications:l.notifications,onNotificationAction:U,preferences:l.preferences,onPreferenceChange:j,isPreferencesLoading:A,specificPreferences:K,onLoadMoreSpecific:C,hasMoreSpecific:N,isListLoading:_,onMorePreferencesClick:f})})]})},ee=({sdkConfig:t,...n})=>s.jsx(D,{onError:n.onError,children:s.jsx(X,{config:t,children:s.jsx(Z,{...n})})}),te="3.0.0",ne="@edusight/notification-widget";exports.BellComponent=y.BellComponent;exports.InboxPopover=y.InboxPopover;exports.NotificationItem=y.NotificationItem;exports.PreferencesView=y.PreferencesView;exports.NotificationWidget=ee;exports.NotificationWidgetErrorBoundary=D;exports.VERSION=te;exports.WIDGET_NAME=ne;
4
4
  //# sourceMappingURL=index.cjs.js.map