@apia/notifications 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { INotification } from './types.js';
3
+
4
+ interface INotificationProps {
5
+ animationName?: string;
6
+ animationTimeout?: number;
7
+ className?: string;
8
+ disableClose?: boolean;
9
+ notification: INotification;
10
+ }
11
+ declare const Notification: React.FC<INotificationProps>;
12
+
13
+ export { type INotificationProps, Notification };
14
+ //# sourceMappingURL=Notification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Notification.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,133 @@
1
+ import { jsx, jsxs } from '@apia/theme/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { Alert, Box, Close } from '@apia/theme';
4
+ import { CSSTransition } from 'react-transition-group';
5
+ import { getIndex, useUpdateEffect, useUnmount } from '@apia/util';
6
+ import { isIconName, Icon } from '@apia/icons';
7
+ import { defaultNotifier, onCloseNotificationCallbacks } from './defaultNotifier.js';
8
+ import Trace from './Trace.js';
9
+
10
+ const Notification = ({
11
+ animationName = "fromRight",
12
+ animationTimeout = 150,
13
+ className,
14
+ disableClose,
15
+ notification
16
+ }) => {
17
+ const innerNotification = React.useMemo(
18
+ () => ({ ...notification }),
19
+ [notification]
20
+ );
21
+ const nodeRef = React.useRef(null);
22
+ if (!innerNotification.title)
23
+ innerNotification.title = getIndex(
24
+ [window.LBL_ERROR, window.LBL_WARNING, window.LBL_COMPLETE_OPERATION],
25
+ [
26
+ innerNotification.type === "danger",
27
+ innerNotification.type === "warning",
28
+ innerNotification.type === "success"
29
+ ]
30
+ );
31
+ if (!innerNotification.icon)
32
+ innerNotification.icon = getIndex(
33
+ ["Check", "Alert", "Close"],
34
+ [
35
+ innerNotification.type === "success",
36
+ innerNotification.type === "warning",
37
+ innerNotification.type === "danger"
38
+ ]
39
+ );
40
+ const [shouldShow, setShouldShow] = React.useState(true);
41
+ const close = React.useCallback(() => {
42
+ defaultNotifier.delete(innerNotification);
43
+ }, [innerNotification]);
44
+ useUpdateEffect(() => {
45
+ if (!innerNotification.isOpen)
46
+ setShouldShow(false);
47
+ }, [innerNotification.isOpen]);
48
+ useUnmount(() => {
49
+ if (onCloseNotificationCallbacks[innerNotification.id])
50
+ onCloseNotificationCallbacks[innerNotification.id]();
51
+ });
52
+ let notificationType = "warning";
53
+ if (["sysException", "exception", "danger"].includes(innerNotification.type))
54
+ notificationType = "danger";
55
+ if (["greenMessage", "success"].includes(innerNotification.type))
56
+ notificationType = "success";
57
+ if (["info"].includes(innerNotification.type))
58
+ notificationType = "info";
59
+ const onClick = React.useCallback(() => {
60
+ setShouldShow(false);
61
+ defaultNotifier.close(innerNotification);
62
+ }, [innerNotification]);
63
+ return /* @__PURE__ */ jsx(
64
+ CSSTransition,
65
+ {
66
+ in: shouldShow,
67
+ timeout: animationTimeout,
68
+ classNames: animationName,
69
+ appear: true,
70
+ unmountOnExit: true,
71
+ onExited: close,
72
+ nodeRef,
73
+ children: /* @__PURE__ */ jsxs(
74
+ Alert,
75
+ {
76
+ "data-testid": notificationType,
77
+ role: "alert",
78
+ ref: nodeRef,
79
+ variant: `alerts.${notificationType}`,
80
+ className: `${className ?? ""} notification notification__alert ${notificationType}`,
81
+ tabIndex: 0,
82
+ onKeyDown: React.useCallback((ev) => {
83
+ if (ev.key.toLowerCase() === "escape" || ev.key.toLowerCase() === "enter" || ev.key === " ") {
84
+ ev.preventDefault();
85
+ ev.stopPropagation();
86
+ setShouldShow(false);
87
+ }
88
+ }, []),
89
+ children: [
90
+ (!disableClose || innerNotification.icon || innerNotification.title) && /* @__PURE__ */ jsxs(Box, { className: "notification__header", children: [
91
+ (innerNotification.title || innerNotification.icon) && /* @__PURE__ */ jsxs(Box, { as: "h4", className: "notification__title", children: [
92
+ innerNotification.icon && /* @__PURE__ */ jsx(Box, { className: "notification__icon", children: isIconName(
93
+ innerNotification.icon
94
+ ) ? /* @__PURE__ */ jsx(
95
+ Icon,
96
+ {
97
+ title: "",
98
+ name: innerNotification.icon
99
+ }
100
+ ) : innerNotification.icon }),
101
+ innerNotification.title
102
+ ] }),
103
+ !disableClose && /* @__PURE__ */ jsx(
104
+ Close,
105
+ {
106
+ type: "button",
107
+ onClick,
108
+ tabIndex: -1,
109
+ className: "notification__closeButton"
110
+ }
111
+ )
112
+ ] }),
113
+ /* @__PURE__ */ jsx(Box, { className: "notification__body", children: /* @__PURE__ */ jsxs(Box, { className: "notification__content", children: [
114
+ /* @__PURE__ */ jsx(Box, { className: "notification__message", children: /* @__PURE__ */ jsx(
115
+ Box,
116
+ {
117
+ dangerouslySetInnerHTML: {
118
+ __html: innerNotification.message
119
+ },
120
+ className: "notification__text"
121
+ }
122
+ ) }),
123
+ innerNotification.trace && /* @__PURE__ */ jsx(Trace, { trace: innerNotification.trace })
124
+ ] }) })
125
+ ]
126
+ }
127
+ )
128
+ }
129
+ );
130
+ };
131
+
132
+ export { Notification };
133
+ //# sourceMappingURL=Notification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Notification.js","sources":["../src/Notification.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Alert, Box, Close } from '@apia/theme';\nimport { CSSTransition } from 'react-transition-group';\nimport { getIndex, useUnmount, useUpdateEffect } from '@apia/util';\nimport { Icon, isIconName, TIconName } from '@apia/icons';\nimport { INotification } from './types';\nimport {\n defaultNotifier,\n onCloseNotificationCallbacks,\n} from './defaultNotifier';\nimport Trace from './Trace';\n\nexport interface INotificationProps {\n animationName?: string;\n animationTimeout?: number;\n className?: string;\n disableClose?: boolean;\n notification: INotification;\n}\n\nexport const Notification: React.FC<INotificationProps> = ({\n animationName = 'fromRight',\n animationTimeout = 150,\n className,\n disableClose,\n notification,\n}) => {\n const innerNotification = React.useMemo(\n () => ({ ...notification }),\n [notification],\n );\n const nodeRef = React.useRef(null);\n if (!innerNotification.title)\n innerNotification.title = getIndex(\n [window.LBL_ERROR, window.LBL_WARNING, window.LBL_COMPLETE_OPERATION],\n [\n innerNotification.type === 'danger',\n innerNotification.type === 'warning',\n innerNotification.type === 'success',\n ],\n );\n if (!innerNotification.icon)\n innerNotification.icon = getIndex<TIconName>(\n ['Check', 'Alert', 'Close'],\n [\n innerNotification.type === 'success',\n innerNotification.type === 'warning',\n innerNotification.type === 'danger',\n ],\n );\n\n const [shouldShow, setShouldShow] = React.useState(true);\n\n const close = React.useCallback(() => {\n defaultNotifier.delete(innerNotification);\n }, [innerNotification]);\n\n useUpdateEffect(() => {\n if (!innerNotification.isOpen) setShouldShow(false);\n }, [innerNotification.isOpen]);\n\n useUnmount(() => {\n if (onCloseNotificationCallbacks[innerNotification.id])\n onCloseNotificationCallbacks[innerNotification.id]();\n });\n\n let notificationType: INotification['type'] = 'warning';\n if (['sysException', 'exception', 'danger'].includes(innerNotification.type))\n notificationType = 'danger';\n if (['greenMessage', 'success'].includes(innerNotification.type))\n notificationType = 'success';\n if (['info'].includes(innerNotification.type)) notificationType = 'info';\n\n const onClick = React.useCallback(() => {\n setShouldShow(false);\n defaultNotifier.close(innerNotification);\n }, [innerNotification]);\n\n return (\n <CSSTransition\n in={shouldShow}\n timeout={animationTimeout}\n classNames={animationName}\n appear\n unmountOnExit\n onExited={close}\n nodeRef={nodeRef}\n >\n <Alert\n data-testid={notificationType}\n role=\"alert\"\n ref={nodeRef}\n variant={`alerts.${notificationType}`}\n className={`${\n className ?? ''\n } notification notification__alert ${notificationType}`}\n tabIndex={0}\n onKeyDown={React.useCallback((ev: React.KeyboardEvent) => {\n if (\n ev.key.toLowerCase() === 'escape' ||\n ev.key.toLowerCase() === 'enter' ||\n ev.key === ' '\n ) {\n ev.preventDefault();\n ev.stopPropagation();\n setShouldShow(false);\n }\n }, [])}\n >\n {(!disableClose ||\n innerNotification.icon ||\n innerNotification.title) && (\n <Box className=\"notification__header\">\n {(innerNotification.title || innerNotification.icon) && (\n <Box as=\"h4\" className=\"notification__title\">\n {innerNotification.icon && (\n <Box className=\"notification__icon\">\n {isIconName(\n innerNotification.icon as unknown as TIconName,\n ) ? (\n <Icon\n title=\"\"\n name={innerNotification.icon as unknown as TIconName}\n />\n ) : (\n innerNotification.icon\n )}\n </Box>\n )}\n {innerNotification.title}\n </Box>\n )}\n {!disableClose && (\n <Close\n type=\"button\"\n onClick={onClick}\n tabIndex={-1}\n className=\"notification__closeButton\"\n />\n )}\n </Box>\n )}\n <Box className=\"notification__body\">\n <Box className=\"notification__content\">\n <Box className=\"notification__message\">\n <Box\n dangerouslySetInnerHTML={{\n __html: innerNotification.message,\n }}\n className=\"notification__text\"\n />\n </Box>\n {innerNotification.trace && (\n <Trace trace={innerNotification.trace} />\n )}\n </Box>\n </Box>\n </Alert>\n </CSSTransition>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import React__default from 'react';
2
+
3
+ declare const _default: React__default.MemoExoticComponent<((props: object) => React__default.JSX.Element) & {
4
+ displayName: string;
5
+ }>;
6
+
7
+ export { _default as default };
8
+ //# sourceMappingURL=NotificationsList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsList.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,84 @@
1
+ import { jsx } from '@apia/theme/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { makeStyledComponent, spacing, Box, getVariant } from '@apia/theme';
4
+ import { keyframes } from '@emotion/react';
5
+ import { Notification } from './Notification.js';
6
+ import { defaultNotifier } from './defaultNotifier.js';
7
+ import { useMount } from '@apia/util';
8
+
9
+ const vibrate = keyframes`
10
+ 0% {
11
+ transform: rotate(0);
12
+ }
13
+
14
+ 25% {
15
+ transform: rotate(1.5deg);
16
+ }
17
+
18
+ 75% {
19
+ transform: rotate(-1.5deg);
20
+ }
21
+
22
+ 100% {
23
+ transform: rotate(0);
24
+ }`;
25
+ const useSelector = defaultNotifier.useSelector;
26
+ const NotificationsList = makeStyledComponent(
27
+ "NotificationsList",
28
+ "layout.common.notifications.list",
29
+ {
30
+ ".notificationsFloatingList": {
31
+ bottom: "10px",
32
+ height: "min-content",
33
+ maxHeight: "calc(100vh - 20px)",
34
+ maxWidth: "floatingNotifications",
35
+ position: "fixed",
36
+ pr: "5px",
37
+ right: "5px",
38
+ width: "100%",
39
+ zIndex: "notifications",
40
+ "& > *:not(:last-child)": {
41
+ mb: spacing(5)
42
+ },
43
+ ".notification.animate": {
44
+ animation: `${vibrate} 0.1s linear infinite`
45
+ }
46
+ },
47
+ ".fromRight-enter, .fromRight-appear": { transform: "translateX(550px)" },
48
+ ".fromRight-enter-active, .fromRight-appear-active": {
49
+ transition: "transform 150ms",
50
+ transform: "translateX(0)"
51
+ },
52
+ ".fromRight-exit": { transform: "translateX(0)" },
53
+ ".fromRight-exit-active": {
54
+ transition: "transform 150ms",
55
+ transform: "translateX(550px)"
56
+ }
57
+ },
58
+ () => {
59
+ const notifications = useSelector((current) => {
60
+ return current;
61
+ });
62
+ useMount(() => {
63
+ document.addEventListener("keydown", (ev) => {
64
+ if (ev.code === "Escape") {
65
+ defaultNotifier.closeAll();
66
+ }
67
+ });
68
+ });
69
+ return /* @__PURE__ */ jsx(
70
+ Box,
71
+ {
72
+ className: "notificationsFloatingList",
73
+ ...getVariant("layout.common.components.notifications.list"),
74
+ children: notifications.map((current) => {
75
+ return /* @__PURE__ */ jsx(Notification, { notification: current }, current.id);
76
+ })
77
+ }
78
+ );
79
+ }
80
+ );
81
+ var NotificationsList$1 = React__default.memo(NotificationsList);
82
+
83
+ export { NotificationsList$1 as default };
84
+ //# sourceMappingURL=NotificationsList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsList.js","sources":["../src/NotificationsList.tsx"],"sourcesContent":["import React from 'react';\nimport { Box } from '@apia/theme';\nimport { getVariant, makeStyledComponent, spacing } from '@apia/theme';\nimport { keyframes } from '@emotion/react';\nimport { Notification } from './Notification';\nimport { defaultNotifier } from './defaultNotifier';\nimport { useMount } from '@apia/util';\n\nconst vibrate = keyframes`\n0% {\n transform: rotate(0);\n}\n\n25% {\n transform: rotate(1.5deg);\n}\n\n75% {\n transform: rotate(-1.5deg);\n}\n\n100% {\n transform: rotate(0);\n}`;\n\nconst useSelector = defaultNotifier.useSelector;\n\nconst NotificationsList = makeStyledComponent(\n 'NotificationsList',\n 'layout.common.notifications.list',\n {\n '.notificationsFloatingList': {\n bottom: '10px',\n height: 'min-content',\n maxHeight: 'calc(100vh - 20px)',\n maxWidth: 'floatingNotifications',\n position: 'fixed',\n pr: '5px',\n right: '5px',\n width: '100%',\n zIndex: 'notifications',\n\n '& > *:not(:last-child)': {\n mb: spacing(5),\n },\n\n '.notification.animate': {\n animation: `${vibrate} 0.1s linear infinite`,\n },\n },\n\n '.fromRight-enter, .fromRight-appear': { transform: 'translateX(550px)' },\n '.fromRight-enter-active, .fromRight-appear-active': {\n transition: 'transform 150ms',\n transform: 'translateX(0)',\n },\n '.fromRight-exit': { transform: 'translateX(0)' },\n '.fromRight-exit-active': {\n transition: 'transform 150ms',\n transform: 'translateX(550px)',\n },\n },\n () => {\n const notifications = useSelector((current) => {\n return current;\n });\n\n useMount(() => {\n document.addEventListener('keydown', (ev) => {\n if (ev.code === 'Escape') {\n defaultNotifier.closeAll();\n }\n });\n });\n\n return (\n <Box\n className=\"notificationsFloatingList\"\n {...getVariant('layout.common.components.notifications.list')}\n >\n {notifications.map((current) => {\n return <Notification notification={current} key={current.id} />;\n })}\n </Box>\n );\n },\n);\n\nexport default React.memo(NotificationsList);\n"],"names":["React"],"mappings":";;;;;;;;AAQA,MAAM,OAAU,GAAA,SAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA,CAAA,CAAA;AAiBhB,MAAM,cAAc,eAAgB,CAAA,WAAA,CAAA;AAEpC,MAAM,iBAAoB,GAAA,mBAAA;AAAA,EACxB,mBAAA;AAAA,EACA,kCAAA;AAAA,EACA;AAAA,IACE,4BAA8B,EAAA;AAAA,MAC5B,MAAQ,EAAA,MAAA;AAAA,MACR,MAAQ,EAAA,aAAA;AAAA,MACR,SAAW,EAAA,oBAAA;AAAA,MACX,QAAU,EAAA,uBAAA;AAAA,MACV,QAAU,EAAA,OAAA;AAAA,MACV,EAAI,EAAA,KAAA;AAAA,MACJ,KAAO,EAAA,KAAA;AAAA,MACP,KAAO,EAAA,MAAA;AAAA,MACP,MAAQ,EAAA,eAAA;AAAA,MAER,wBAA0B,EAAA;AAAA,QACxB,EAAA,EAAI,QAAQ,CAAC,CAAA;AAAA,OACf;AAAA,MAEA,uBAAyB,EAAA;AAAA,QACvB,SAAA,EAAW,GAAG,OAAO,CAAA,qBAAA,CAAA;AAAA,OACvB;AAAA,KACF;AAAA,IAEA,qCAAA,EAAuC,EAAE,SAAA,EAAW,mBAAoB,EAAA;AAAA,IACxE,mDAAqD,EAAA;AAAA,MACnD,UAAY,EAAA,iBAAA;AAAA,MACZ,SAAW,EAAA,eAAA;AAAA,KACb;AAAA,IACA,iBAAA,EAAmB,EAAE,SAAA,EAAW,eAAgB,EAAA;AAAA,IAChD,wBAA0B,EAAA;AAAA,MACxB,UAAY,EAAA,iBAAA;AAAA,MACZ,SAAW,EAAA,mBAAA;AAAA,KACb;AAAA,GACF;AAAA,EACA,MAAM;AACJ,IAAM,MAAA,aAAA,GAAgB,WAAY,CAAA,CAAC,OAAY,KAAA;AAC7C,MAAO,OAAA,OAAA,CAAA;AAAA,KACR,CAAA,CAAA;AAED,IAAA,QAAA,CAAS,MAAM;AACb,MAAS,QAAA,CAAA,gBAAA,CAAiB,SAAW,EAAA,CAAC,EAAO,KAAA;AAC3C,QAAI,IAAA,EAAA,CAAG,SAAS,QAAU,EAAA;AACxB,UAAA,eAAA,CAAgB,QAAS,EAAA,CAAA;AAAA,SAC3B;AAAA,OACD,CAAA,CAAA;AAAA,KACF,CAAA,CAAA;AAED,IACE,uBAAA,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,SAAU,EAAA,2BAAA;AAAA,QACT,GAAG,WAAW,6CAA6C,CAAA;AAAA,QAE3D,QAAA,EAAA,aAAA,CAAc,GAAI,CAAA,CAAC,OAAY,KAAA;AAC9B,UAAA,uBAAQ,GAAA,CAAA,YAAA,EAAA,EAAa,YAAc,EAAA,OAAA,EAAA,EAAc,QAAQ,EAAI,CAAA,CAAA;AAAA,SAC9D,CAAA;AAAA,OAAA;AAAA,KACH,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAEA,0BAAeA,cAAA,CAAM,KAAK,iBAAiB,CAAA;;;;"}
package/dist/Trace.js ADDED
@@ -0,0 +1,77 @@
1
+ import { jsxs, jsx, Fragment } from '@apia/theme/jsx-runtime';
2
+ import { Icon } from '@apia/icons';
3
+ import { Box, IconButton, Button } from '@apia/theme';
4
+
5
+ const Trace = ({ trace }) => {
6
+ const openModal = () => {
7
+ document.dispatchEvent(
8
+ new CustomEvent("openModal", {
9
+ detail: {
10
+ NavBar: /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
11
+ Button,
12
+ {
13
+ variant: "outline-sm",
14
+ onClick: () => {
15
+ void navigator.clipboard.writeText(
16
+ document.querySelector(".TraceModal__content")?.innerText ?? ""
17
+ );
18
+ },
19
+ children: "Copy trace"
20
+ }
21
+ ) }),
22
+ children: /* @__PURE__ */ jsx(
23
+ Box,
24
+ {
25
+ dangerouslySetInnerHTML: {
26
+ __html: trace.replaceAll(
27
+ /\((\w+\.java:\d+)\)/g,
28
+ "(<strong>$1</strong>)"
29
+ )
30
+ }
31
+ }
32
+ ),
33
+ noHeader: true,
34
+ size: "xxl"
35
+ }
36
+ })
37
+ );
38
+ };
39
+ return /* @__PURE__ */ jsxs(Box, { as: "code", className: "notification__trace", children: [
40
+ /* @__PURE__ */ jsxs(Box, { as: "strong", className: "notification__traceLabel", children: [
41
+ /* @__PURE__ */ jsx(
42
+ IconButton,
43
+ {
44
+ size: "IconMd",
45
+ onClick: openModal,
46
+ title: "View trace",
47
+ sx: {
48
+ height: "24px",
49
+ width: "24px"
50
+ },
51
+ children: /* @__PURE__ */ jsx(Icon, { size: "iconXs", title: "", name: "External" })
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsx(
55
+ IconButton,
56
+ {
57
+ size: "IconMd",
58
+ title: "Copy trace",
59
+ sx: {
60
+ height: "24px",
61
+ width: "24px"
62
+ },
63
+ onClick: () => void navigator.clipboard.writeText(
64
+ trace.replaceAll(/<br *\/?>/g, "\n")
65
+ ),
66
+ children: /* @__PURE__ */ jsx(Icon, { size: "iconXs", title: "", name: "Copy" })
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsx(Box, { as: "span", children: "Trace:" })
70
+ ] }),
71
+ /* @__PURE__ */ jsx(Box, { className: "notification__traceText", children: trace })
72
+ ] });
73
+ };
74
+ var Trace$1 = Trace;
75
+
76
+ export { Trace$1 as default };
77
+ //# sourceMappingURL=Trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trace.js","sources":["../src/Trace.tsx"],"sourcesContent":["import { Icon } from '@apia/icons';\nimport { Box, Button, IconButton } from '@apia/theme';\n\ninterface ITrace {\n trace: string;\n}\n\nconst Trace = ({ trace }: ITrace) => {\n const openModal = () => {\n document.dispatchEvent(\n new CustomEvent('openModal', {\n detail: {\n NavBar: (\n <>\n <Button\n variant=\"outline-sm\"\n onClick={() => {\n void navigator.clipboard.writeText(\n document.querySelector<HTMLElement>('.TraceModal__content')\n ?.innerText ?? '',\n );\n }}\n >\n Copy trace\n </Button>\n </>\n ),\n children: (\n <Box\n dangerouslySetInnerHTML={{\n __html: trace.replaceAll(\n /\\((\\w+\\.java:\\d+)\\)/g,\n '(<strong>$1</strong>)',\n ),\n }}\n />\n ),\n noHeader: true,\n size: 'xxl',\n },\n }),\n );\n };\n\n return (\n <Box as=\"code\" className=\"notification__trace\">\n <Box as=\"strong\" className=\"notification__traceLabel\">\n <IconButton\n size=\"IconMd\"\n onClick={openModal}\n title=\"View trace\"\n sx={{\n height: '24px',\n width: '24px',\n }}\n >\n <Icon size=\"iconXs\" title=\"\" name=\"External\" />\n </IconButton>\n <IconButton\n size=\"IconMd\"\n title=\"Copy trace\"\n sx={{\n height: '24px',\n width: '24px',\n }}\n onClick={() =>\n void navigator.clipboard.writeText(\n trace.replaceAll(/<br *\\/?>/g, '\\n'),\n )\n }\n >\n <Icon size=\"iconXs\" title=\"\" name=\"Copy\" />\n </IconButton>\n <Box as=\"span\">Trace:</Box>\n </Box>\n <Box className=\"notification__traceText\">{trace}</Box>\n </Box>\n );\n};\n\nexport default Trace;\n"],"names":[],"mappings":";;;;AAOA,MAAM,KAAQ,GAAA,CAAC,EAAE,KAAA,EAAoB,KAAA;AACnC,EAAA,MAAM,YAAY,MAAM;AACtB,IAAS,QAAA,CAAA,aAAA;AAAA,MACP,IAAI,YAAY,WAAa,EAAA;AAAA,QAC3B,MAAQ,EAAA;AAAA,UACN,wBAEI,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,OAAQ,EAAA,YAAA;AAAA,cACR,SAAS,MAAM;AACb,gBAAA,KAAK,UAAU,SAAU,CAAA,SAAA;AAAA,kBACvB,QAAS,CAAA,aAAA,CAA2B,sBAAsB,CAAA,EACtD,SAAa,IAAA,EAAA;AAAA,iBACnB,CAAA;AAAA,eACF;AAAA,cACD,QAAA,EAAA,YAAA;AAAA,aAAA;AAAA,WAGH,EAAA,CAAA;AAAA,UAEF,QACE,kBAAA,GAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,uBAAyB,EAAA;AAAA,gBACvB,QAAQ,KAAM,CAAA,UAAA;AAAA,kBACZ,sBAAA;AAAA,kBACA,uBAAA;AAAA,iBACF;AAAA,eACF;AAAA,aAAA;AAAA,WACF;AAAA,UAEF,QAAU,EAAA,IAAA;AAAA,UACV,IAAM,EAAA,KAAA;AAAA,SACR;AAAA,OACD,CAAA;AAAA,KACH,CAAA;AAAA,GACF,CAAA;AAEA,EAAA,uBACG,IAAA,CAAA,GAAA,EAAA,EAAI,EAAG,EAAA,MAAA,EAAO,WAAU,qBACvB,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,GAAI,EAAA,EAAA,EAAA,EAAG,QAAS,EAAA,SAAA,EAAU,0BACzB,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,IAAK,EAAA,QAAA;AAAA,UACL,OAAS,EAAA,SAAA;AAAA,UACT,KAAM,EAAA,YAAA;AAAA,UACN,EAAI,EAAA;AAAA,YACF,MAAQ,EAAA,MAAA;AAAA,YACR,KAAO,EAAA,MAAA;AAAA,WACT;AAAA,UAEA,8BAAC,IAAK,EAAA,EAAA,IAAA,EAAK,UAAS,KAAM,EAAA,EAAA,EAAG,MAAK,UAAW,EAAA,CAAA;AAAA,SAAA;AAAA,OAC/C;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,IAAK,EAAA,QAAA;AAAA,UACL,KAAM,EAAA,YAAA;AAAA,UACN,EAAI,EAAA;AAAA,YACF,MAAQ,EAAA,MAAA;AAAA,YACR,KAAO,EAAA,MAAA;AAAA,WACT;AAAA,UACA,OAAS,EAAA,MACP,KAAK,SAAA,CAAU,SAAU,CAAA,SAAA;AAAA,YACvB,KAAA,CAAM,UAAW,CAAA,YAAA,EAAc,IAAI,CAAA;AAAA,WACrC;AAAA,UAGF,8BAAC,IAAK,EAAA,EAAA,IAAA,EAAK,UAAS,KAAM,EAAA,EAAA,EAAG,MAAK,MAAO,EAAA,CAAA;AAAA,SAAA;AAAA,OAC3C;AAAA,sBACC,GAAA,CAAA,GAAA,EAAA,EAAI,EAAG,EAAA,MAAA,EAAO,QAAM,EAAA,QAAA,EAAA,CAAA;AAAA,KACvB,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,GAAA,EAAA,EAAI,SAAU,EAAA,yBAAA,EAA2B,QAAM,EAAA,KAAA,EAAA,CAAA;AAAA,GAClD,EAAA,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEA,cAAe,KAAA;;;;"}
@@ -0,0 +1,24 @@
1
+ import { TApiaSystemMessageObj } from '@apia/util';
2
+ import { TNotificationType } from '../defaultNotifier.js';
3
+ import { INotification } from '../types.js';
4
+ import { TMessage, TNotificationMessage } from './types.js';
5
+
6
+ /**
7
+ * Devuelve un array de notificaciones a partir de
8
+ * una respuesta de Apia.
9
+ */
10
+ declare const getNotificationMessageObj: (data: TApiaSystemMessageObj) => INotification<TNotificationType>[] | null;
11
+ /**
12
+ * Toma un objeto de notificación de servidor y lo convierte a un
13
+ * objeto de notificación de cliente.
14
+ */
15
+ declare const parseServerNotification: (serverNotification: TMessage | TMessage[], type: TNotificationType) => INotification<TNotificationType>[];
16
+ /**
17
+ * Toma un objeto de respuesta de servidor que puede eventualmente
18
+ * tener notificaciones y las pasa al sistema de notificaciones si
19
+ * es que hay alguna.
20
+ */
21
+ declare const dispatchNotifications: (alert: TNotificationMessage) => void;
22
+
23
+ export { TMessage, TNotificationMessage, dispatchNotifications, getNotificationMessageObj, parseServerNotification };
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { arrayOrArray } from '@apia/util';
2
+ import { uniqueId, notify } from '../defaultNotifier.js';
3
+
4
+ const getNotificationMessageObj = (data) => {
5
+ const notifications = [];
6
+ if (data?.sysMessages?.message) {
7
+ notifications.push(
8
+ ...parseServerNotification(data.sysMessages.message, "warning")
9
+ );
10
+ }
11
+ if (data?.sysExceptions) {
12
+ notifications.push(
13
+ ...parseServerNotification(data.sysExceptions.exception, "danger")
14
+ );
15
+ }
16
+ if (data?.exceptions?.exception) {
17
+ notifications.push(
18
+ ...parseServerNotification(data.exceptions.exception, "danger")
19
+ );
20
+ }
21
+ if (notifications.length > 0)
22
+ return notifications;
23
+ return null;
24
+ };
25
+ function parseServerNotificationType(type) {
26
+ switch (type) {
27
+ case "1":
28
+ return "success";
29
+ case "2":
30
+ return "warning";
31
+ case "3":
32
+ return "danger";
33
+ default:
34
+ return "warning";
35
+ }
36
+ }
37
+ const parseServerNotification = (serverNotification, type) => {
38
+ const messages = arrayOrArray(serverNotification);
39
+ return messages.map((current) => {
40
+ const returnNotification = {
41
+ message: current.text,
42
+ trace: current.content,
43
+ title: current.title,
44
+ type: current.type !== void 0 ? parseServerNotificationType(current.type) : type,
45
+ isOpen: true,
46
+ id: uniqueId()
47
+ };
48
+ return returnNotification;
49
+ });
50
+ };
51
+ const dispatchNotifications = (alert) => {
52
+ if (alert) {
53
+ if (alert.sysMessages?.message)
54
+ parseServerNotification(alert.sysMessages?.message, "warning").forEach(
55
+ notify
56
+ );
57
+ if (alert.exceptions?.exception)
58
+ parseServerNotification(alert.exceptions?.exception, "danger").forEach(
59
+ notify
60
+ );
61
+ if (alert.sysExceptions?.exception)
62
+ parseServerNotification(alert.sysExceptions?.exception, "danger").forEach(
63
+ notify
64
+ );
65
+ }
66
+ };
67
+
68
+ export { dispatchNotifications, getNotificationMessageObj, parseServerNotification };
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/apia/index.ts"],"sourcesContent":["import { arrayOrArray, TApiaSystemMessageObj } from '@apia/util';\nimport { notify, TNotificationType, uniqueId } from '../defaultNotifier';\nimport { INotification } from '../types';\nimport { TMessage, TNotificationMessage } from './types';\n\n/**\n * Devuelve un array de notificaciones a partir de\n * una respuesta de Apia.\n */\nexport const getNotificationMessageObj = (\n data: TApiaSystemMessageObj,\n): INotification<TNotificationType>[] | null => {\n const notifications: INotification<TNotificationType>[] = [];\n if (data?.sysMessages?.message) {\n notifications.push(\n ...parseServerNotification(data.sysMessages.message, 'warning'),\n );\n }\n if (data?.sysExceptions) {\n notifications.push(\n ...parseServerNotification(data.sysExceptions.exception, 'danger'),\n );\n }\n if (data?.exceptions?.exception) {\n notifications.push(\n ...parseServerNotification(data.exceptions.exception, 'danger'),\n );\n }\n if (notifications.length > 0) return notifications;\n return null;\n};\n\nfunction parseServerNotificationType(type: string): TNotificationType {\n switch (type) {\n case '1':\n return 'success';\n case '2':\n return 'warning';\n case '3':\n return 'danger';\n default:\n return 'warning';\n }\n}\n\n/**\n * Toma un objeto de notificación de servidor y lo convierte a un\n * objeto de notificación de cliente.\n */\nexport const parseServerNotification = (\n serverNotification: TMessage | TMessage[],\n type: TNotificationType,\n): INotification<TNotificationType>[] => {\n const messages = arrayOrArray(serverNotification);\n return messages.map((current) => {\n const returnNotification: INotification<TNotificationType> = {\n message: current.text,\n trace: current.content,\n title: current.title,\n type:\n current.type !== undefined\n ? parseServerNotificationType(current.type)\n : (type as TNotificationType),\n isOpen: true,\n id: uniqueId(),\n };\n return returnNotification;\n });\n};\n\n/**\n * Toma un objeto de respuesta de servidor que puede eventualmente\n * tener notificaciones y las pasa al sistema de notificaciones si\n * es que hay alguna.\n */\nexport const dispatchNotifications = (alert: TNotificationMessage) => {\n if (alert) {\n if (alert.sysMessages?.message)\n parseServerNotification(alert.sysMessages?.message, 'warning').forEach(\n notify,\n );\n if (alert.exceptions?.exception)\n parseServerNotification(alert.exceptions?.exception, 'danger').forEach(\n notify,\n );\n if (alert.sysExceptions?.exception)\n parseServerNotification(alert.sysExceptions?.exception, 'danger').forEach(\n notify,\n );\n }\n};\n\nexport * from './types';\n"],"names":[],"mappings":";;;AASa,MAAA,yBAAA,GAA4B,CACvC,IAC8C,KAAA;AAC9C,EAAA,MAAM,gBAAoD,EAAC,CAAA;AAC3D,EAAI,IAAA,IAAA,EAAM,aAAa,OAAS,EAAA;AAC9B,IAAc,aAAA,CAAA,IAAA;AAAA,MACZ,GAAG,uBAAA,CAAwB,IAAK,CAAA,WAAA,CAAY,SAAS,SAAS,CAAA;AAAA,KAChE,CAAA;AAAA,GACF;AACA,EAAA,IAAI,MAAM,aAAe,EAAA;AACvB,IAAc,aAAA,CAAA,IAAA;AAAA,MACZ,GAAG,uBAAA,CAAwB,IAAK,CAAA,aAAA,CAAc,WAAW,QAAQ,CAAA;AAAA,KACnE,CAAA;AAAA,GACF;AACA,EAAI,IAAA,IAAA,EAAM,YAAY,SAAW,EAAA;AAC/B,IAAc,aAAA,CAAA,IAAA;AAAA,MACZ,GAAG,uBAAA,CAAwB,IAAK,CAAA,UAAA,CAAW,WAAW,QAAQ,CAAA;AAAA,KAChE,CAAA;AAAA,GACF;AACA,EAAA,IAAI,cAAc,MAAS,GAAA,CAAA;AAAG,IAAO,OAAA,aAAA,CAAA;AACrC,EAAO,OAAA,IAAA,CAAA;AACT,EAAA;AAEA,SAAS,4BAA4B,IAAiC,EAAA;AACpE,EAAA,QAAQ,IAAM;AAAA,IACZ,KAAK,GAAA;AACH,MAAO,OAAA,SAAA,CAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAO,OAAA,SAAA,CAAA;AAAA,IACT,KAAK,GAAA;AACH,MAAO,OAAA,QAAA,CAAA;AAAA,IACT;AACE,MAAO,OAAA,SAAA,CAAA;AAAA,GACX;AACF,CAAA;AAMa,MAAA,uBAAA,GAA0B,CACrC,kBAAA,EACA,IACuC,KAAA;AACvC,EAAM,MAAA,QAAA,GAAW,aAAa,kBAAkB,CAAA,CAAA;AAChD,EAAO,OAAA,QAAA,CAAS,GAAI,CAAA,CAAC,OAAY,KAAA;AAC/B,IAAA,MAAM,kBAAuD,GAAA;AAAA,MAC3D,SAAS,OAAQ,CAAA,IAAA;AAAA,MACjB,OAAO,OAAQ,CAAA,OAAA;AAAA,MACf,OAAO,OAAQ,CAAA,KAAA;AAAA,MACf,MACE,OAAQ,CAAA,IAAA,KAAS,SACb,2BAA4B,CAAA,OAAA,CAAQ,IAAI,CACvC,GAAA,IAAA;AAAA,MACP,MAAQ,EAAA,IAAA;AAAA,MACR,IAAI,QAAS,EAAA;AAAA,KACf,CAAA;AACA,IAAO,OAAA,kBAAA,CAAA;AAAA,GACR,CAAA,CAAA;AACH,EAAA;AAOa,MAAA,qBAAA,GAAwB,CAAC,KAAgC,KAAA;AACpE,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,IAAI,MAAM,WAAa,EAAA,OAAA;AACrB,MAAA,uBAAA,CAAwB,KAAM,CAAA,WAAA,EAAa,OAAS,EAAA,SAAS,CAAE,CAAA,OAAA;AAAA,QAC7D,MAAA;AAAA,OACF,CAAA;AACF,IAAA,IAAI,MAAM,UAAY,EAAA,SAAA;AACpB,MAAA,uBAAA,CAAwB,KAAM,CAAA,UAAA,EAAY,SAAW,EAAA,QAAQ,CAAE,CAAA,OAAA;AAAA,QAC7D,MAAA;AAAA,OACF,CAAA;AACF,IAAA,IAAI,MAAM,aAAe,EAAA,SAAA;AACvB,MAAA,uBAAA,CAAwB,KAAM,CAAA,aAAA,EAAe,SAAW,EAAA,QAAQ,CAAE,CAAA,OAAA;AAAA,QAChE,MAAA;AAAA,OACF,CAAA;AAAA,GACJ;AACF;;;;"}
@@ -0,0 +1,21 @@
1
+ interface TMessage {
2
+ text: string;
3
+ content?: string;
4
+ title?: string;
5
+ type?: string;
6
+ }
7
+ interface TNotificationMessage {
8
+ onClose?: string;
9
+ sysMessages?: {
10
+ message: TMessage | TMessage[];
11
+ };
12
+ sysExceptions?: {
13
+ exception: TMessage | TMessage[];
14
+ };
15
+ exceptions?: {
16
+ exception: TMessage | TMessage[];
17
+ };
18
+ }
19
+
20
+ export type { TMessage, TNotificationMessage };
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import { INotification, TNotificationId, TNotificationSelector } from './types.js';
2
+ import { EventEmitter } from '@apia/util';
3
+
4
+ declare const onCloseNotificationCallbacks: Record<string, () => unknown>;
5
+ type TNotificationType = 'danger' | 'success' | 'warning';
6
+ declare function uniqueId(): string;
7
+ type TDispatchedNotification = Omit<INotification<TNotificationType>, 'id' | 'type' | 'isOpen'> & Partial<Pick<INotification<TNotificationType>, 'id' | 'type'>>;
8
+ declare class DefaultNotifier extends EventEmitter<{
9
+ changedList: boolean;
10
+ }> {
11
+ notifications: INotification<TNotificationType>[];
12
+ areNotificationsOpen(): boolean;
13
+ shout(): void;
14
+ close(id: TNotificationId | INotification): void;
15
+ closeAll(): void;
16
+ delete(id: TNotificationId | INotification): void;
17
+ useSelector: (selector: TNotificationSelector<TNotificationType>) => INotification<TNotificationType>[];
18
+ notify(notification: TDispatchedNotification): void;
19
+ on<K extends 'changedList'>(eventName: K, fn: (params: {
20
+ changedList: boolean;
21
+ }[K]) => unknown): () => void;
22
+ }
23
+ declare const defaultNotifier: DefaultNotifier;
24
+ declare function notify(notification: TDispatchedNotification): void;
25
+
26
+ export { DefaultNotifier, type TDispatchedNotification, type TNotificationType, defaultNotifier, notify, onCloseNotificationCallbacks, uniqueId };
27
+ //# sourceMappingURL=defaultNotifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultNotifier.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ import { EventEmitter, useLatest, useMount } from '@apia/util';
2
+ import { useState } from 'react';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __publicField = (obj, key, value) => {
7
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
8
+ return value;
9
+ };
10
+ const onCloseNotificationCallbacks = {};
11
+ function shallowEqual(a, b) {
12
+ if (a.length !== b.length)
13
+ return false;
14
+ for (let i = 0; i < a.length; i++)
15
+ if (a[i] !== b[i])
16
+ return false;
17
+ return true;
18
+ }
19
+ let id = 0;
20
+ function uniqueId() {
21
+ return `notification_${id++}`;
22
+ }
23
+ class DefaultNotifier extends EventEmitter {
24
+ constructor() {
25
+ super(...arguments);
26
+ __publicField(this, "notifications", []);
27
+ __publicField(this, "useSelector", (selector) => {
28
+ const [state, setState] = useState([]);
29
+ const lastState = useLatest(state);
30
+ useMount(() => {
31
+ return this.on("changedList", () => {
32
+ const newState = selector(this.notifications);
33
+ if (!shallowEqual(newState, lastState.current)) {
34
+ setState([...newState]);
35
+ }
36
+ });
37
+ });
38
+ return state;
39
+ });
40
+ }
41
+ areNotificationsOpen() {
42
+ return !!document.querySelector(".notification");
43
+ }
44
+ shout() {
45
+ this.emit("changedList", true);
46
+ }
47
+ close(id2) {
48
+ const actualId = typeof id2 === "object" ? id2.id : id2;
49
+ this.notifications = this.notifications.map((current) => {
50
+ if (current.id === actualId) {
51
+ current.onClose?.();
52
+ return { ...current, isOpen: false };
53
+ }
54
+ return current;
55
+ });
56
+ this.shout();
57
+ }
58
+ closeAll() {
59
+ this.notifications = this.notifications.map((current) => {
60
+ current.onClose?.();
61
+ return {
62
+ ...current,
63
+ isOpen: false
64
+ };
65
+ });
66
+ this.shout();
67
+ }
68
+ delete(id2) {
69
+ const actualId = typeof id2 === "object" ? id2.id : id2;
70
+ this.notifications = this.notifications.filter(
71
+ (current) => current.id !== actualId
72
+ );
73
+ this.shout();
74
+ }
75
+ notify(notification) {
76
+ const id2 = notification.id ?? uniqueId();
77
+ let hasAnimated = false;
78
+ document.querySelectorAll(".notificationsFloatingList .notification__text").forEach((current) => {
79
+ if (current.textContent === notification.message) {
80
+ const notificationElement = current.closest(
81
+ ".notification"
82
+ );
83
+ if (notificationElement) {
84
+ notificationElement.classList.add("animate");
85
+ setTimeout(() => {
86
+ notificationElement.classList.remove("animate");
87
+ }, 200);
88
+ hasAnimated = true;
89
+ } else
90
+ console.warn(
91
+ "A notification with that text was found, but it could not be animated"
92
+ );
93
+ }
94
+ });
95
+ if (hasAnimated)
96
+ return;
97
+ this.notifications.push({
98
+ ...notification,
99
+ isOpen: true,
100
+ type: notification.type ?? "warning",
101
+ id: id2
102
+ });
103
+ this.shout();
104
+ }
105
+ on(eventName, fn) {
106
+ fn(true);
107
+ return super.on(eventName, fn);
108
+ }
109
+ }
110
+ const defaultNotifier = new DefaultNotifier();
111
+ function notify(notification) {
112
+ defaultNotifier.notify(notification);
113
+ }
114
+
115
+ export { DefaultNotifier, defaultNotifier, notify, onCloseNotificationCallbacks, uniqueId };
116
+ //# sourceMappingURL=defaultNotifier.js.map