@servicetitan/notifications 28.5.0 → 29.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/__tests__/intercept.test.d.ts +2 -0
  2. package/dist/__tests__/intercept.test.d.ts.map +1 -0
  3. package/dist/__tests__/intercept.test.js +13 -0
  4. package/dist/__tests__/intercept.test.js.map +1 -0
  5. package/dist/__tests__/notifications-service.test.d.ts +2 -0
  6. package/dist/__tests__/notifications-service.test.d.ts.map +1 -0
  7. package/dist/__tests__/notifications-service.test.js +42 -0
  8. package/dist/__tests__/notifications-service.test.js.map +1 -0
  9. package/dist/api/notifications.api.d.ts +2 -2
  10. package/dist/api/notifications.api.d.ts.map +1 -1
  11. package/dist/common.d.ts +4 -22
  12. package/dist/common.d.ts.map +1 -1
  13. package/dist/common.js +4 -11
  14. package/dist/common.js.map +1 -1
  15. package/dist/components/__tests__/notifications.test.d.ts +2 -0
  16. package/dist/components/__tests__/notifications.test.d.ts.map +1 -0
  17. package/dist/components/__tests__/notifications.test.js +93 -0
  18. package/dist/components/__tests__/notifications.test.js.map +1 -0
  19. package/dist/components/notifications.d.ts +8 -1
  20. package/dist/components/notifications.d.ts.map +1 -1
  21. package/dist/components/notifications.js +43 -23
  22. package/dist/components/notifications.js.map +1 -1
  23. package/dist/demo/action-button-preview.d.ts.map +1 -1
  24. package/dist/demo/action-button-preview.js +2 -2
  25. package/dist/demo/action-button-preview.js.map +1 -1
  26. package/dist/demo/basic-preview.d.ts.map +1 -1
  27. package/dist/demo/basic-preview.js +1 -1
  28. package/dist/demo/basic-preview.js.map +1 -1
  29. package/dist/demo/container.d.ts +1 -3
  30. package/dist/demo/container.d.ts.map +1 -1
  31. package/dist/demo/container.js.map +1 -1
  32. package/dist/demo/duration-preview.d.ts.map +1 -1
  33. package/dist/demo/duration-preview.js +2 -2
  34. package/dist/demo/duration-preview.js.map +1 -1
  35. package/dist/demo/multiline-message-preview.d.ts.map +1 -1
  36. package/dist/demo/multiline-message-preview.js +2 -2
  37. package/dist/demo/multiline-message-preview.js.map +1 -1
  38. package/dist/demo/prevent-duplicates-preview.d.ts.map +1 -1
  39. package/dist/demo/prevent-duplicates-preview.js +2 -2
  40. package/dist/demo/prevent-duplicates-preview.js.map +1 -1
  41. package/dist/demo/progress-preview.d.ts.map +1 -1
  42. package/dist/demo/progress-preview.js +2 -2
  43. package/dist/demo/progress-preview.js.map +1 -1
  44. package/dist/demo/server-custom-preview.d.ts +1 -1
  45. package/dist/demo/server-custom-preview.d.ts.map +1 -1
  46. package/dist/demo/server-custom-preview.js +21 -7
  47. package/dist/demo/server-custom-preview.js.map +1 -1
  48. package/dist/demo/server-custom.d.ts +0 -1
  49. package/dist/demo/server-custom.d.ts.map +1 -1
  50. package/dist/demo/server-custom.js +25 -21
  51. package/dist/demo/server-custom.js.map +1 -1
  52. package/dist/demo/server-default.d.ts.map +1 -1
  53. package/dist/demo/server-default.js +1 -1
  54. package/dist/demo/server-default.js.map +1 -1
  55. package/dist/demo/status-variations-preview.d.ts.map +1 -1
  56. package/dist/demo/status-variations-preview.js +2 -2
  57. package/dist/demo/status-variations-preview.js.map +1 -1
  58. package/dist/demo/status-variations.d.ts.map +1 -1
  59. package/dist/demo/status-variations.js.map +1 -1
  60. package/dist/index.d.ts +3 -4
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +3 -4
  63. package/dist/index.js.map +1 -1
  64. package/dist/intercept.d.ts +4 -0
  65. package/dist/intercept.d.ts.map +1 -0
  66. package/dist/intercept.js +5 -0
  67. package/dist/intercept.js.map +1 -0
  68. package/dist/notifications-channel.d.ts +2 -6
  69. package/dist/notifications-channel.d.ts.map +1 -1
  70. package/dist/notifications-channel.js.map +1 -1
  71. package/dist/notifications-service.d.ts +10 -8
  72. package/dist/notifications-service.d.ts.map +1 -1
  73. package/dist/notifications-service.js.map +1 -1
  74. package/dist/notifications.stories.d.ts +14 -0
  75. package/dist/notifications.stories.d.ts.map +1 -0
  76. package/dist/notifications.stories.js +20 -0
  77. package/dist/notifications.stories.js.map +1 -0
  78. package/dist/stores/__mocks__/mock-notifications-channel.d.ts +11 -0
  79. package/dist/stores/__mocks__/mock-notifications-channel.d.ts.map +1 -0
  80. package/dist/stores/__mocks__/mock-notifications-channel.js +36 -0
  81. package/dist/stores/__mocks__/mock-notifications-channel.js.map +1 -0
  82. package/dist/stores/__tests__/notifications.store.test.d.ts +2 -0
  83. package/dist/stores/__tests__/notifications.store.test.d.ts.map +1 -0
  84. package/dist/stores/__tests__/notifications.store.test.js +360 -0
  85. package/dist/stores/__tests__/notifications.store.test.js.map +1 -0
  86. package/dist/stores/notifications.store.d.ts +20 -8
  87. package/dist/stores/notifications.store.d.ts.map +1 -1
  88. package/dist/stores/notifications.store.js +156 -45
  89. package/dist/stores/notifications.store.js.map +1 -1
  90. package/dist/utils/__tests__/date-from-string.test.d.ts +2 -0
  91. package/dist/utils/__tests__/date-from-string.test.d.ts.map +1 -0
  92. package/dist/utils/__tests__/date-from-string.test.js +39 -0
  93. package/dist/utils/__tests__/date-from-string.test.js.map +1 -0
  94. package/dist/utils/__tests__/use-compatible-navigate.test.d.ts +2 -0
  95. package/dist/utils/__tests__/use-compatible-navigate.test.d.ts.map +1 -0
  96. package/dist/utils/__tests__/use-compatible-navigate.test.js +27 -0
  97. package/dist/utils/__tests__/use-compatible-navigate.test.js.map +1 -0
  98. package/dist/utils/date-from-string.d.ts.map +1 -0
  99. package/dist/utils/date-from-string.js +19 -0
  100. package/dist/utils/date-from-string.js.map +1 -0
  101. package/package.json +6 -6
  102. package/src/__tests__/intercept.test.ts +18 -0
  103. package/src/__tests__/notifications-service.test.ts +62 -0
  104. package/src/api/notifications.api.ts +2 -2
  105. package/src/common.ts +12 -27
  106. package/src/components/__tests__/notifications.test.tsx +107 -0
  107. package/src/components/notifications.tsx +59 -36
  108. package/src/demo/action-button-preview.tsx +4 -6
  109. package/src/demo/basic-preview.tsx +2 -4
  110. package/src/demo/container.tsx +1 -4
  111. package/src/demo/duration-preview.tsx +4 -6
  112. package/src/demo/multiline-message-preview.tsx +3 -9
  113. package/src/demo/prevent-duplicates-preview.tsx +3 -9
  114. package/src/demo/progress-preview.tsx +3 -9
  115. package/src/demo/server-custom-preview.tsx +17 -14
  116. package/src/demo/server-custom.tsx +30 -29
  117. package/src/demo/server-default.tsx +1 -3
  118. package/src/demo/status-variations-preview.tsx +4 -6
  119. package/src/demo/status-variations.tsx +0 -1
  120. package/src/index.ts +13 -4
  121. package/src/intercept.ts +14 -0
  122. package/src/notifications-channel.ts +2 -6
  123. package/src/notifications-service.ts +14 -42
  124. package/src/stores/__mocks__/mock-notifications-channel.ts +31 -0
  125. package/src/stores/__tests__/notifications.store.test.ts +458 -0
  126. package/src/stores/notifications.store.ts +178 -53
  127. package/src/utils/__tests__/date-from-string.test.ts +53 -0
  128. package/src/utils/__tests__/use-compatible-navigate.test.ts +43 -0
  129. package/src/utils/date-from-string.ts +22 -0
  130. package/dist/components/__tests__/container.test.d.ts +0 -2
  131. package/dist/components/__tests__/container.test.d.ts.map +0 -1
  132. package/dist/components/__tests__/container.test.js +0 -59
  133. package/dist/components/__tests__/container.test.js.map +0 -1
  134. package/dist/components/container.d.ts +0 -3
  135. package/dist/components/container.d.ts.map +0 -1
  136. package/dist/components/container.js +0 -26
  137. package/dist/components/container.js.map +0 -1
  138. package/dist/components/default-notification.d.ts +0 -7
  139. package/dist/components/default-notification.d.ts.map +0 -1
  140. package/dist/components/default-notification.js +0 -26
  141. package/dist/components/default-notification.js.map +0 -1
  142. package/dist/components/default-notification.module.css +0 -3
  143. package/dist/components/no-ssr.d.ts +0 -5
  144. package/dist/components/no-ssr.d.ts.map +0 -1
  145. package/dist/components/no-ssr.js +0 -9
  146. package/dist/components/no-ssr.js.map +0 -1
  147. package/dist/components/notifications-unwrapped.d.ts +0 -3
  148. package/dist/components/notifications-unwrapped.d.ts.map +0 -1
  149. package/dist/components/notifications-unwrapped.js +0 -27
  150. package/dist/components/notifications-unwrapped.js.map +0 -1
  151. package/dist/components/shadow-dom.d.ts +0 -3
  152. package/dist/components/shadow-dom.d.ts.map +0 -1
  153. package/dist/components/shadow-dom.js +0 -41
  154. package/dist/components/shadow-dom.js.map +0 -1
  155. package/dist/components/use-style-sheets.d.ts +0 -2
  156. package/dist/components/use-style-sheets.d.ts.map +0 -1
  157. package/dist/components/use-style-sheets.js +0 -15
  158. package/dist/components/use-style-sheets.js.map +0 -1
  159. package/dist/create-element.d.ts +0 -2
  160. package/dist/create-element.d.ts.map +0 -1
  161. package/dist/create-element.js +0 -8
  162. package/dist/create-element.js.map +0 -1
  163. package/dist/date-from-string.d.ts.map +0 -1
  164. package/dist/date-from-string.js +0 -27
  165. package/dist/date-from-string.js.map +0 -1
  166. package/dist/register.d.ts +0 -3
  167. package/dist/register.d.ts.map +0 -1
  168. package/dist/register.js +0 -5
  169. package/dist/register.js.map +0 -1
  170. package/src/components/__tests__/container.test.tsx +0 -71
  171. package/src/components/container.tsx +0 -35
  172. package/src/components/default-notification.module.css +0 -3
  173. package/src/components/default-notification.module.css.d.ts +0 -4
  174. package/src/components/default-notification.tsx +0 -59
  175. package/src/components/no-ssr.tsx +0 -11
  176. package/src/components/notifications-unwrapped.tsx +0 -51
  177. package/src/components/shadow-dom.tsx +0 -53
  178. package/src/components/use-style-sheets.ts +0 -19
  179. package/src/create-element.ts +0 -12
  180. package/src/date-from-string.ts +0 -30
  181. package/src/register.ts +0 -6
  182. /package/dist/{date-from-string.d.ts → utils/date-from-string.d.ts} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"notifications-unwrapped.js","sourceRoot":"","sources":["../../src/components/notifications-unwrapped.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAM,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,MAAM,CAAC,MAAM,sBAAsB,GAAO,QAAQ,CAAC,GAAG,EAAE;IACpD,MAAM,CAAC,cAAc,CAAC,GAAG,uBAAuB,CAAC,sBAAsB,CAAC,CAAC;IACzE,MAAM,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;IAEpD,SAAS,CAAC,GAAG,EAAE;QACX,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,CACH,KAAC,KAAK,cACF,KAAC,SAAS,cACL,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;gBACpC,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;gBAElE,IAAI,CAAC,SAAS,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC;gBAChB,CAAC;gBAED,MAAM,WAAW,GAAG,GAAG,EAAE;oBACrB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAC7B,CAAC,CAAC;gBAEF,OAAO,cAAc,CAAC,CAAC,CAAC,CACpB,KAAC,SAAS,cACN,KAAC,SAAS,IAAC,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAI,IADnD,GAAG,YAAY,CAAC,EAAE,IAAI,YAAY,CAAC,MAAM,EAAE,CAE/C,CACf,CAAC,CAAC,CAAC,CACA,KAAC,SAAS,IAEN,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,WAAW,IAFf,GAAG,YAAY,CAAC,EAAE,IAAI,YAAY,CAAC,MAAM,EAAE,CAGlD,CACL,CAAC;YACN,CAAC,CAAC,GACM,GACR,CACX,CAAC;AACN,CAAC,CAAC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { FC, PropsWithChildren } from 'react';
2
- export declare const ShadowDOM: FC<PropsWithChildren>;
3
- //# sourceMappingURL=shadow-dom.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shadow-dom.d.ts","sourceRoot":"","sources":["../../src/components/shadow-dom.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAmBxD,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,iBAAiB,CAiC3C,CAAC"}
@@ -1,41 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { createPortal } from 'react-dom';
4
- import retargetEvents from 'react-shadow-dom-retarget-events';
5
- import { useStyleSheets } from './use-style-sheets';
6
- function createLink(url, onLoad) {
7
- const element = document.createElement('link');
8
- element.href = url;
9
- element.rel = 'stylesheet';
10
- element.crossOrigin = 'anonymous';
11
- element.onload = onLoad;
12
- element.onerror = onLoad;
13
- return element;
14
- }
15
- export const ShadowDOM = ({ children }) => {
16
- const [target, setTarget] = useState(null);
17
- const [loaded, setLoaded] = useState(false);
18
- const styleSheets = useStyleSheets();
19
- const handleRef = (element) => {
20
- if (!element || target) {
21
- return;
22
- }
23
- let stylesCount = 0;
24
- let stylesLoaded = 0;
25
- const root = element.attachShadow({ mode: 'open' });
26
- const handleLoad = () => {
27
- stylesLoaded++;
28
- if (stylesLoaded === stylesCount) {
29
- setLoaded(true);
30
- }
31
- };
32
- for (const url of styleSheets) {
33
- root.append(createLink(url, handleLoad));
34
- stylesCount++;
35
- }
36
- retargetEvents(root);
37
- setTarget(root.appendChild(document.createElement('div')));
38
- };
39
- return _jsx("div", { ref: handleRef, children: target && loaded ? createPortal(children, target) : null });
40
- };
41
- //# sourceMappingURL=shadow-dom.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shadow-dom.js","sourceRoot":"","sources":["../../src/components/shadow-dom.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAyB,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,SAAS,UAAU,CAAC,GAAW,EAAE,MAAkB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAE/C,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC;IACnB,OAAO,CAAC,GAAG,GAAG,YAAY,CAAC;IAC3B,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC;IAEzB,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAA0B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC7D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,MAAM,SAAS,GAAG,CAAC,OAA8B,EAAE,EAAE;QACjD,IAAI,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAEpD,MAAM,UAAU,GAAG,GAAG,EAAE;YACpB,YAAY,EAAE,CAAC;YAEf,IAAI,YAAY,KAAK,WAAW,EAAE,CAAC;gBAC/B,SAAS,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;YACzC,WAAW,EAAE,CAAC;QAClB,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,CAAC;QAErB,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEF,OAAO,cAAK,GAAG,EAAE,SAAS,YAAG,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAO,CAAC;AACjG,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare const useStyleSheets: () => string[];
2
- //# sourceMappingURL=use-style-sheets.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-style-sheets.d.ts","sourceRoot":"","sources":["../../src/components/use-style-sheets.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,gBAc1B,CAAC"}
@@ -1,15 +0,0 @@
1
- import { useContext, useMemo } from 'react';
2
- import { DefaultPortalContext } from '@servicetitan/design-system';
3
- export const useStyleSheets = () => {
4
- const defaultPortal = useContext(DefaultPortalContext);
5
- return useMemo(() => {
6
- const styleSheets = [];
7
- for (const element of Array.from(defaultPortal.children)) {
8
- if (element.tagName.toLowerCase() === 'link') {
9
- styleSheets.push(element.href);
10
- }
11
- }
12
- return styleSheets;
13
- }, [defaultPortal]);
14
- };
15
- //# sourceMappingURL=use-style-sheets.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-style-sheets.js","sourceRoot":"","sources":["../../src/components/use-style-sheets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAEvD,OAAO,OAAO,CAAC,GAAG,EAAE;QAChB,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;gBAC3C,WAAW,CAAC,IAAI,CAAE,OAA2B,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;QACL,CAAC;QAED,OAAO,WAAW,CAAC;IACvB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;AACxB,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare const createElement: <K extends keyof HTMLElementTagNameMap>(tagName: K, attributes: Record<string, string>) => HTMLElementTagNameMap[K];
2
- //# sourceMappingURL=create-element.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-element.d.ts","sourceRoot":"","sources":["../src/create-element.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,mDACb,CAAC,cACE,OAAO,MAAM,EAAE,MAAM,CAAC,6BASrC,CAAC"}
@@ -1,8 +0,0 @@
1
- export const createElement = (tagName, attributes) => {
2
- const element = document.createElement(tagName);
3
- for (const [qualifiedName, value] of Object.entries(attributes)) {
4
- element.setAttribute(qualifiedName, value);
5
- }
6
- return element;
7
- };
8
- //# sourceMappingURL=create-element.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-element.js","sourceRoot":"","sources":["../src/create-element.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,OAAU,EACV,UAAkC,EACpC,EAAE;IACA,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAEhD,KAAK,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-from-string.d.ts","sourceRoot":"","sources":["../src/date-from-string.ts"],"names":[],"mappings":"AAIA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,QAyBjD"}
@@ -1,27 +0,0 @@
1
- const dateISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.,]\d+)?Z?$/i;
2
- const dateISOMilliseconds = /[.,](\d+)/i;
3
- const dateNet = /\/Date\((-?\d+)(?:-\d+)?\)\//i;
4
- export function dateFromString(date) {
5
- if (typeof date === 'object') {
6
- return date;
7
- }
8
- if (dateISO.test(date)) {
9
- const ms = dateISOMilliseconds.exec(date);
10
- const fixedValue = date.replace(dateISOMilliseconds, '');
11
- const result = new Date(fixedValue);
12
- if (ms !== null) {
13
- let millisecond = parseInt(ms[1].substr(0, 3), 10);
14
- millisecond = isNaN(millisecond) ? 0 : millisecond;
15
- result.setMilliseconds(millisecond);
16
- }
17
- return result;
18
- }
19
- if (dateNet.test(date)) {
20
- const parsedDate = dateNet.exec(date);
21
- if (parsedDate !== null) {
22
- return new Date(parseInt(parsedDate[1], 10));
23
- }
24
- }
25
- throw 'Incorrect date format';
26
- }
27
- //# sourceMappingURL=date-from-string.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-from-string.js","sourceRoot":"","sources":["../src/date-from-string.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,sDAAsD,CAAC;AACvE,MAAM,mBAAmB,GAAG,YAAY,CAAC;AACzC,MAAM,OAAO,GAAG,+BAA+B,CAAC;AAEhD,MAAM,UAAU,cAAc,CAAC,IAAmB;IAC9C,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACd,IAAI,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;YACnD,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC;IACL,CAAC;IAED,MAAM,uBAAuB,CAAC;AAClC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { NotificationMapper } from './common';
2
- export declare function register(type: string, mapper: NotificationMapper): void;
3
- //# sourceMappingURL=register.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,QAEhE"}
package/dist/register.js DELETED
@@ -1,5 +0,0 @@
1
- import { NotificationsStore } from './stores/notifications.store';
2
- export function register(type, mapper) {
3
- NotificationsStore.register(type, mapper);
4
- }
5
- //# sourceMappingURL=register.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGlE,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,MAA0B;IAC7D,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC"}
@@ -1,71 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- import { render, waitFor, within } from '@testing-library/react';
3
- import { ReactNode } from 'react';
4
-
5
- import { Container } from '../container';
6
-
7
- describe('[notifications] Container', () => {
8
- beforeEach(() => {
9
- document.getElementById('servicetitan-notifications')?.remove();
10
- });
11
-
12
- const subject = (children?: ReactNode) => {
13
- return render(<Container>{children}</Container>);
14
- };
15
-
16
- test('renders #servicetitan-notifications.initialized > .ToastGroup', async () => {
17
- subject();
18
-
19
- await waitFor(() =>
20
- expect(
21
- document.querySelectorAll('#servicetitan-notifications.initialized > .ToastGroup')
22
- ).toHaveLength(1)
23
- );
24
- });
25
-
26
- test('renders children within .ToastGroup', async () => {
27
- subject(<button>Foo</button>);
28
-
29
- await waitFor(() => {
30
- expect(
31
- within(
32
- document.querySelector('#servicetitan-notifications.initialized > .ToastGroup')!
33
- ).getByRole('button', { name: 'Foo' })
34
- ).toBeInTheDocument();
35
- });
36
- });
37
-
38
- describe('when #servicetitan-notifications already exists', () => {
39
- let container: HTMLElement;
40
-
41
- beforeEach(() => {
42
- container = document.createElement('div');
43
- container.setAttribute('id', 'servicetitan-notifications');
44
- document.body.appendChild(container);
45
- });
46
-
47
- test('creates .ToastGroup within existing container', async () => {
48
- subject();
49
-
50
- await waitFor(() => {
51
- expect(container.querySelectorAll('.ToastGroup')).toHaveLength(1);
52
- });
53
- });
54
-
55
- describe('when .ToastGroup already exists', () => {
56
- let toastGroup: HTMLElement;
57
-
58
- beforeEach(() => {
59
- toastGroup = document.createElement('div');
60
- toastGroup.classList.add('ToastGroup');
61
- container.appendChild(toastGroup);
62
- });
63
-
64
- test('renders children inside existing ToastGroup', () => {
65
- subject(<button>Baz</button>);
66
-
67
- expect(within(toastGroup).getByRole('button', { name: 'Baz' })).toBeInTheDocument();
68
- });
69
- });
70
- });
71
- });
@@ -1,35 +0,0 @@
1
- import { Toast } from '@servicetitan/design-system';
2
- import { FC, Fragment, PropsWithChildren, useEffect, useState } from 'react';
3
- import { createPortal } from 'react-dom';
4
-
5
- import { createElement } from '../create-element';
6
-
7
- export const Container: FC<PropsWithChildren> = ({ children }) => {
8
- const [container] = useState(() => {
9
- return (
10
- document.getElementById('servicetitan-notifications') ??
11
- document.body.appendChild(createElement('div', { id: 'servicetitan-notifications' }))
12
- );
13
- });
14
- const [toastGroup, setToastGroup] = useState(() => findToastGroup(container));
15
- const [foundGroup] = useState(() => !!toastGroup);
16
-
17
- useEffect(() => {
18
- if (!toastGroup) {
19
- setToastGroup(findToastGroup(container));
20
- // This stops old code running in MFE from rendering duplicate Toast.Group
21
- container.classList.add('initialized');
22
- }
23
- }, [container, toastGroup]);
24
-
25
- return (
26
- <Fragment>
27
- {foundGroup ? null : <Toast.Group portal={container} />}
28
- {toastGroup ? createPortal(children, toastGroup) : null}
29
- </Fragment>
30
- );
31
- };
32
-
33
- function findToastGroup(parent: HTMLElement) {
34
- return parent.getElementsByClassName('ToastGroup')[0] ?? null;
35
- }
@@ -1,3 +0,0 @@
1
- .default-notification .message {
2
- white-space: pre-line;
3
- }
@@ -1,4 +0,0 @@
1
- export const __esModule: true;
2
- export const defaultNotification: string;
3
- export const message: string;
4
-
@@ -1,59 +0,0 @@
1
- import { FC } from 'react';
2
-
3
- import { Toast, ProgressBar } from '@servicetitan/design-system';
4
-
5
- import { useCompatibleNavigate } from '../utils/use-compatible-navigate';
6
- import { DefaultNotificationOptions, Status, isLinkAction } from '../common';
7
-
8
- import * as Styles from './default-notification.module.css';
9
-
10
- export interface DefaultNotificationProps extends DefaultNotificationOptions {
11
- onClose(): void;
12
- }
13
-
14
- export const DefaultNotification: FC<DefaultNotificationProps> = ({
15
- status = Status.Info,
16
- title,
17
- message,
18
- duration,
19
- progress,
20
- action,
21
- onClose,
22
- }) => {
23
- const navigate = useCompatibleNavigate();
24
-
25
- const handleActionClick = () => {
26
- if (action) {
27
- if (isLinkAction(action)) {
28
- if (action.external) {
29
- window.open(action.link);
30
- } else {
31
- navigate(action.link);
32
- }
33
- } else {
34
- action.onClick();
35
- }
36
- }
37
-
38
- onClose();
39
- };
40
-
41
- return (
42
- <Toast
43
- portal={false}
44
- status={status}
45
- title={title}
46
- duration={duration}
47
- primaryActionName={action?.label}
48
- onPrimaryActionClick={handleActionClick}
49
- className={Styles.defaultNotification}
50
- onClose={onClose}
51
- >
52
- <div className={Styles.message}>{message}</div>
53
-
54
- {progress != null && (
55
- <ProgressBar progress={progress} small blue className={message && 'm-t-1'} />
56
- )}
57
- </Toast>
58
- );
59
- };
@@ -1,11 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
-
3
- export const NoSSR = ({ children }: { children: JSX.Element }) => {
4
- const [isMounted, setIsMounted] = useState(false);
5
-
6
- useEffect(() => {
7
- setIsMounted(true);
8
- }, []);
9
-
10
- return isMounted ? children : null;
11
- };
@@ -1,51 +0,0 @@
1
- import { useEffect, FC } from 'react';
2
-
3
- import { useDependencies, useOptionalDependencies } from '@servicetitan/react-ioc';
4
- import { IS_WEB_COMPONENT_TOKEN } from '@servicetitan/web-components';
5
-
6
- import { observer } from 'mobx-react';
7
-
8
- import { NotificationsStore } from '../stores/notifications.store';
9
-
10
- import { ShadowDOM } from './shadow-dom';
11
- import { Container } from './container';
12
- import { NoSSR } from './no-ssr';
13
-
14
- export const NotificationsUnwrapped: FC = observer(() => {
15
- const [isWebComponent] = useOptionalDependencies(IS_WEB_COMPONENT_TOKEN);
16
- const [store] = useDependencies(NotificationsStore);
17
-
18
- useEffect(() => {
19
- return () => store.dispose();
20
- }, [store]);
21
-
22
- return (
23
- <NoSSR>
24
- <Container>
25
- {store.notifications.map(notification => {
26
- const Component = NotificationsStore.types.get(notification.type);
27
-
28
- if (!Component) {
29
- return null;
30
- }
31
-
32
- const handleClose = () => {
33
- store.read(notification);
34
- };
35
-
36
- return isWebComponent ? (
37
- <ShadowDOM key={`${notification.id}_${notification.status}`}>
38
- <Component notification={notification} onClose={handleClose} />
39
- </ShadowDOM>
40
- ) : (
41
- <Component
42
- key={`${notification.id}_${notification.status}`}
43
- notification={notification}
44
- onClose={handleClose}
45
- />
46
- );
47
- })}
48
- </Container>
49
- </NoSSR>
50
- );
51
- });
@@ -1,53 +0,0 @@
1
- import { useState, FC, PropsWithChildren } from 'react';
2
- import { createPortal } from 'react-dom';
3
-
4
- import retargetEvents from 'react-shadow-dom-retarget-events';
5
-
6
- import { useStyleSheets } from './use-style-sheets';
7
-
8
- function createLink(url: string, onLoad: () => void) {
9
- const element = document.createElement('link');
10
-
11
- element.href = url;
12
- element.rel = 'stylesheet';
13
- element.crossOrigin = 'anonymous';
14
- element.onload = onLoad;
15
- element.onerror = onLoad;
16
-
17
- return element;
18
- }
19
-
20
- export const ShadowDOM: FC<PropsWithChildren> = ({ children }) => {
21
- const [target, setTarget] = useState<Element | null>(null);
22
- const [loaded, setLoaded] = useState(false);
23
- const styleSheets = useStyleSheets();
24
-
25
- const handleRef = (element: HTMLDivElement | null) => {
26
- if (!element || target) {
27
- return;
28
- }
29
-
30
- let stylesCount = 0;
31
- let stylesLoaded = 0;
32
- const root = element.attachShadow({ mode: 'open' });
33
-
34
- const handleLoad = () => {
35
- stylesLoaded++;
36
-
37
- if (stylesLoaded === stylesCount) {
38
- setLoaded(true);
39
- }
40
- };
41
-
42
- for (const url of styleSheets) {
43
- root.append(createLink(url, handleLoad));
44
- stylesCount++;
45
- }
46
-
47
- retargetEvents(root);
48
-
49
- setTarget(root.appendChild(document.createElement('div')));
50
- };
51
-
52
- return <div ref={handleRef}>{target && loaded ? createPortal(children, target) : null}</div>;
53
- };
@@ -1,19 +0,0 @@
1
- import { useContext, useMemo } from 'react';
2
-
3
- import { DefaultPortalContext } from '@servicetitan/design-system';
4
-
5
- export const useStyleSheets = () => {
6
- const defaultPortal = useContext(DefaultPortalContext);
7
-
8
- return useMemo(() => {
9
- const styleSheets: string[] = [];
10
-
11
- for (const element of Array.from(defaultPortal.children)) {
12
- if (element.tagName.toLowerCase() === 'link') {
13
- styleSheets.push((element as HTMLLinkElement).href);
14
- }
15
- }
16
-
17
- return styleSheets;
18
- }, [defaultPortal]);
19
- };
@@ -1,12 +0,0 @@
1
- export const createElement = <K extends keyof HTMLElementTagNameMap>(
2
- tagName: K,
3
- attributes: Record<string, string>
4
- ) => {
5
- const element = document.createElement(tagName);
6
-
7
- for (const [qualifiedName, value] of Object.entries(attributes)) {
8
- element.setAttribute(qualifiedName, value);
9
- }
10
-
11
- return element;
12
- };
@@ -1,30 +0,0 @@
1
- const dateISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[.,]\d+)?Z?$/i;
2
- const dateISOMilliseconds = /[.,](\d+)/i;
3
- const dateNet = /\/Date\((-?\d+)(?:-\d+)?\)\//i;
4
-
5
- export function dateFromString(date: string | Date) {
6
- if (typeof date === 'object') {
7
- return date;
8
- }
9
-
10
- if (dateISO.test(date)) {
11
- const ms = dateISOMilliseconds.exec(date);
12
- const fixedValue = date.replace(dateISOMilliseconds, '');
13
- const result = new Date(fixedValue);
14
- if (ms !== null) {
15
- let millisecond = parseInt(ms[1].substr(0, 3), 10);
16
- millisecond = isNaN(millisecond) ? 0 : millisecond;
17
- result.setMilliseconds(millisecond);
18
- }
19
- return result;
20
- }
21
-
22
- if (dateNet.test(date)) {
23
- const parsedDate = dateNet.exec(date);
24
- if (parsedDate !== null) {
25
- return new Date(parseInt(parsedDate[1], 10));
26
- }
27
- }
28
-
29
- throw 'Incorrect date format';
30
- }
package/src/register.ts DELETED
@@ -1,6 +0,0 @@
1
- import { NotificationsStore } from './stores/notifications.store';
2
- import { NotificationMapper } from './common';
3
-
4
- export function register(type: string, mapper: NotificationMapper) {
5
- NotificationsStore.register(type, mapper);
6
- }