@stack-spot/portal-components 2.0.2 → 2.1.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 (129) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/components/AnimatedHeight.d.ts +59 -0
  3. package/dist/components/AnimatedHeight.d.ts.map +1 -0
  4. package/dist/components/AnimatedHeight.js +105 -0
  5. package/dist/components/AnimatedHeight.js.map +1 -0
  6. package/dist/components/Placeholder.d.ts +6 -4
  7. package/dist/components/Placeholder.d.ts.map +1 -1
  8. package/dist/components/Placeholder.js +5 -4
  9. package/dist/components/Placeholder.js.map +1 -1
  10. package/dist/components/TimelineSection.d.ts +25 -0
  11. package/dist/components/TimelineSection.d.ts.map +1 -0
  12. package/dist/components/TimelineSection.js +27 -0
  13. package/dist/components/TimelineSection.js.map +1 -0
  14. package/dist/components/error/ErrorFeedback.d.ts +9 -1
  15. package/dist/components/error/ErrorFeedback.d.ts.map +1 -1
  16. package/dist/components/error/ErrorFeedback.js +41 -4
  17. package/dist/components/error/ErrorFeedback.js.map +1 -1
  18. package/dist/components/form/SearchInput.d.ts +9 -0
  19. package/dist/components/form/SearchInput.d.ts.map +1 -0
  20. package/dist/components/form/SearchInput.js +28 -0
  21. package/dist/components/form/SearchInput.js.map +1 -0
  22. package/dist/components/form/Select.d.ts +69 -0
  23. package/dist/components/form/Select.d.ts.map +1 -0
  24. package/dist/components/form/Select.js +161 -0
  25. package/dist/components/form/Select.js.map +1 -0
  26. package/dist/components/{Notifications → notification}/NotificationComponent.d.ts +2 -1
  27. package/dist/components/notification/NotificationComponent.d.ts.map +1 -0
  28. package/dist/components/{Notifications → notification}/NotificationComponent.js +12 -4
  29. package/dist/components/notification/NotificationComponent.js.map +1 -0
  30. package/dist/components/notification/NotificationItem.d.ts +42 -0
  31. package/dist/components/notification/NotificationItem.d.ts.map +1 -0
  32. package/dist/components/{Notifications → notification}/NotificationItem.js +27 -12
  33. package/dist/components/notification/NotificationItem.js.map +1 -0
  34. package/dist/components/notification/NotificationList.d.ts +39 -0
  35. package/dist/components/notification/NotificationList.d.ts.map +1 -0
  36. package/dist/components/notification/NotificationList.js +82 -0
  37. package/dist/components/notification/NotificationList.js.map +1 -0
  38. package/dist/components/notification/NotificationPlaceholder.d.ts +12 -0
  39. package/dist/components/notification/NotificationPlaceholder.d.ts.map +1 -0
  40. package/dist/components/notification/NotificationPlaceholder.js +22 -0
  41. package/dist/components/notification/NotificationPlaceholder.js.map +1 -0
  42. package/dist/components/{Notifications → notification}/types.d.ts +16 -0
  43. package/dist/components/notification/types.d.ts.map +1 -0
  44. package/dist/components/{Notifications → notification}/types.js +3 -0
  45. package/dist/components/notification/types.js.map +1 -0
  46. package/dist/containers/NotificationsPage.d.ts +2 -0
  47. package/dist/containers/NotificationsPage.d.ts.map +1 -0
  48. package/dist/containers/NotificationsPage.js +58 -0
  49. package/dist/containers/NotificationsPage.js.map +1 -0
  50. package/dist/context/notification/LazyNotificationList.d.ts +28 -0
  51. package/dist/context/notification/LazyNotificationList.d.ts.map +1 -0
  52. package/dist/context/notification/LazyNotificationList.js +128 -0
  53. package/dist/context/notification/LazyNotificationList.js.map +1 -0
  54. package/dist/context/notification/NotificationController.d.ts +24 -0
  55. package/dist/context/notification/NotificationController.d.ts.map +1 -0
  56. package/dist/context/notification/NotificationController.js +136 -0
  57. package/dist/context/notification/NotificationController.js.map +1 -0
  58. package/dist/context/notification/context.d.ts +9 -0
  59. package/dist/context/notification/context.d.ts.map +1 -0
  60. package/dist/context/notification/context.js +12 -0
  61. package/dist/context/notification/context.js.map +1 -0
  62. package/dist/context/notification/hooks.d.ts +13 -0
  63. package/dist/context/notification/hooks.d.ts.map +1 -0
  64. package/dist/context/notification/hooks.js +77 -0
  65. package/dist/context/notification/hooks.js.map +1 -0
  66. package/dist/context/notification/types.d.ts +57 -0
  67. package/dist/context/notification/types.d.ts.map +1 -0
  68. package/dist/context/notification/types.js +2 -0
  69. package/dist/context/notification/types.js.map +1 -0
  70. package/dist/hooks/manual-render.d.ts +8 -0
  71. package/dist/hooks/manual-render.d.ts.map +1 -0
  72. package/dist/hooks/manual-render.js +10 -0
  73. package/dist/hooks/manual-render.js.map +1 -0
  74. package/dist/index.d.ts +2 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/notifications.d.ts +11 -0
  79. package/dist/notifications.d.ts.map +1 -0
  80. package/dist/notifications.js +10 -0
  81. package/dist/notifications.js.map +1 -0
  82. package/dist/svg/GenericPlaceholder.d.ts +5 -0
  83. package/dist/svg/GenericPlaceholder.d.ts.map +1 -0
  84. package/dist/svg/GenericPlaceholder.js +4 -0
  85. package/dist/svg/GenericPlaceholder.js.map +1 -0
  86. package/dist/svg/index.d.ts +1 -0
  87. package/dist/svg/index.d.ts.map +1 -1
  88. package/dist/svg/index.js +1 -0
  89. package/dist/svg/index.js.map +1 -1
  90. package/dist/utils/promise.d.ts +2 -0
  91. package/dist/utils/promise.d.ts.map +1 -0
  92. package/dist/utils/promise.js +6 -0
  93. package/dist/utils/promise.js.map +1 -0
  94. package/package.json +8 -4
  95. package/src/components/AnimatedHeight.tsx +174 -0
  96. package/src/components/Placeholder.tsx +13 -8
  97. package/src/components/TimelineSection.tsx +54 -0
  98. package/src/components/error/ErrorFeedback.tsx +93 -55
  99. package/src/components/form/SearchInput.tsx +69 -0
  100. package/src/components/form/Select.tsx +264 -0
  101. package/src/components/{Notifications → notification}/NotificationComponent.tsx +13 -5
  102. package/src/components/{Notifications → notification}/NotificationItem.tsx +76 -34
  103. package/src/components/notification/NotificationList.tsx +167 -0
  104. package/src/components/notification/NotificationPlaceholder.tsx +40 -0
  105. package/src/components/{Notifications → notification}/types.ts +21 -0
  106. package/src/containers/NotificationsPage.tsx +98 -0
  107. package/src/context/notification/LazyNotificationList.ts +95 -0
  108. package/src/context/notification/NotificationController.ts +104 -0
  109. package/src/context/notification/context.tsx +23 -0
  110. package/src/context/notification/hooks.ts +82 -0
  111. package/src/context/notification/types.ts +64 -0
  112. package/src/hooks/manual-render.tsx +10 -0
  113. package/src/index.ts +2 -1
  114. package/src/notifications.ts +11 -0
  115. package/src/svg/GenericPlaceholder.tsx +19 -0
  116. package/src/svg/index.ts +1 -0
  117. package/src/utils/promise.ts +5 -0
  118. package/dist/components/Notifications/NotificationComponent.d.ts.map +0 -1
  119. package/dist/components/Notifications/NotificationComponent.js.map +0 -1
  120. package/dist/components/Notifications/NotificationItem.d.ts +0 -17
  121. package/dist/components/Notifications/NotificationItem.d.ts.map +0 -1
  122. package/dist/components/Notifications/NotificationItem.js.map +0 -1
  123. package/dist/components/Notifications/index.d.ts +0 -4
  124. package/dist/components/Notifications/index.d.ts.map +0 -1
  125. package/dist/components/Notifications/index.js +0 -4
  126. package/dist/components/Notifications/index.js.map +0 -1
  127. package/dist/components/Notifications/types.d.ts.map +0 -1
  128. package/dist/components/Notifications/types.js.map +0 -1
  129. package/src/components/Notifications/index.tsx +0 -3
@@ -1,3 +1,4 @@
1
+ // fixme: please, do not ignore lint rules. They exist for a reason. Next major: transform this enum into a disjoint string type.
1
2
  // eslint-disable-next-line no-restricted-syntax
2
3
  export var NotificationType;
3
4
  (function (NotificationType) {
@@ -5,6 +6,7 @@ export var NotificationType;
5
6
  NotificationType["Medium"] = "MEDIUM";
6
7
  NotificationType["Low"] = "LOW";
7
8
  })(NotificationType || (NotificationType = {}));
9
+ // fixme: please, do not ignore lint rules. They exist for a reason. Next major: transform this enum into a disjoint string type.
8
10
  // eslint-disable-next-line no-restricted-syntax
9
11
  export var NotificationContext;
10
12
  (function (NotificationContext) {
@@ -12,6 +14,7 @@ export var NotificationContext;
12
14
  NotificationContext["Workspace"] = "WORKSPACE";
13
15
  NotificationContext["Studio"] = "STUDIO";
14
16
  })(NotificationContext || (NotificationContext = {}));
17
+ // fixme: please, do not ignore lint rules. They exist for a reason. Next major: transform this enum into a disjoint string type.
15
18
  // eslint-disable-next-line no-restricted-syntax
16
19
  export var UnreadType;
17
20
  (function (UnreadType) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/notification/types.ts"],"names":[],"mappings":"AAAA,iIAAiI;AACjI,gDAAgD;AAChD,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,iCAAa,CAAA;IACb,qCAAiB,CAAA;IACjB,+BAAW,CAAA;AACb,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B;AAGD,iIAAiI;AACjI,gDAAgD;AAChD,MAAM,CAAN,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,0CAAmB,CAAA;IACnB,8CAAuB,CAAA;IACvB,wCAAiB,CAAA;AACnB,CAAC,EAJW,mBAAmB,KAAnB,mBAAmB,QAI9B;AA8BD,iIAAiI;AACjI,gDAAgD;AAChD,MAAM,CAAN,IAAY,UAEX;AAFD,WAAY,UAAU;IACpB,+BAAiB,CAAA;AACnB,CAAC,EAFW,UAAU,KAAV,UAAU,QAErB"}
@@ -0,0 +1,2 @@
1
+ export declare const NotificationsPage: () => import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=NotificationsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsPage.d.ts","sourceRoot":"","sources":["../../src/containers/NotificationsPage.tsx"],"names":[],"mappings":"AA0BA,eAAO,MAAM,iBAAiB,+CA0C7B,CAAA"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Text } from '@citric/core';
3
+ import { useTranslate } from '@stack-spot/portal-translate';
4
+ import { styled } from 'styled-components';
5
+ import { AsyncContent } from '../components/AsyncContent.js';
6
+ import { ErrorFeedback } from '../components/error/index.js';
7
+ import { SearchInput } from '../components/form/SearchInput.js';
8
+ import { Select } from '../components/form/Select.js';
9
+ import { NotificationList } from '../components/notification/NotificationList.js';
10
+ import { useNotificationList } from '../context/notification/hooks.js';
11
+ import { useNotificationController } from '../notifications.js';
12
+ const FilterBox = styled.div `
13
+ margin: 24px 0;
14
+ display: flex;
15
+ flex-direction: row;
16
+ gap: 8px;
17
+
18
+ > * {
19
+ flex: 1;
20
+ }
21
+ `;
22
+ const criticalities = ['HIGH', 'MEDIUM', 'LOW'];
23
+ const contexts = ['ACCOUNT', 'STUDIO', 'WORKSPACE'];
24
+ export const NotificationsPage = () => {
25
+ const t = useTranslate(dictionary);
26
+ const controller = useNotificationController();
27
+ const { hasMore, items, loadMore, applyFilters, filters, status, error } = useNotificationList();
28
+ return (_jsxs(_Fragment, { children: [_jsx("header", { children: _jsx(Text, { appearance: "h2", as: "h1", children: t.title }) }), _jsx(Text, { appearance: "body2", colorScheme: "light.700", children: t.description }), _jsxs(FilterBox, { children: [_jsx(SearchInput, { searchText: t.filter, defaultValue: filters.search, onChange: search => applyFilters({ search }) }), _jsx(Select, { value: filters.criticality, options: criticalities, onChange: criticality => applyFilters({ criticality }), emptyOption: t.allCriticalities, renderLabel: o => t[`criticality.${o}`] }), _jsx(Select, { value: filters.context, options: contexts, onChange: context => applyFilters({ context }), emptyOption: t.allContexts, renderLabel: o => t[`context.${o}`] })] }), _jsx(AsyncContent, { error: error, loading: status === 'startup', errorDetails: { errorComponent: () => _jsx(ErrorFeedback, { code: error.code }), reportError: () => { } }, children: _jsx(NotificationList, { items: items, loading: status === 'loading', onCommit: id => controller.markAsCommitted(id), infiniteScroll: { hasMore, loadMore }, onClickAction: controller.config.onClickAction, showEmptySearch: true }) })] }));
29
+ };
30
+ const dictionary = {
31
+ en: {
32
+ title: 'Notifications',
33
+ description: 'All notifications you received is shown up here.',
34
+ filter: 'Filter',
35
+ allCriticalities: 'All Criticalities',
36
+ 'criticality.HIGH': 'High',
37
+ 'criticality.MEDIUM': 'Medium',
38
+ 'criticality.LOW': 'Low',
39
+ allContexts: 'All contexts',
40
+ 'context.ACCOUNT': 'Account',
41
+ 'context.STUDIO': 'Studio',
42
+ 'context.WORKSPACE': 'Workspace',
43
+ },
44
+ pt: {
45
+ title: 'Notifications',
46
+ description: 'Todas as notificações que você recebeu são mostradas aqui.',
47
+ filter: 'Filtrar',
48
+ allCriticalities: 'Todas as criticidades',
49
+ 'criticality.HIGH': 'Alto',
50
+ 'criticality.MEDIUM': 'Médio',
51
+ 'criticality.LOW': 'Baixo',
52
+ allContexts: 'Todos os contextos',
53
+ 'context.ACCOUNT': 'Conta',
54
+ 'context.STUDIO': 'Estúdio',
55
+ 'context.WORKSPACE': 'Workspace',
56
+ },
57
+ };
58
+ //# sourceMappingURL=NotificationsPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationsPage.js","sourceRoot":"","sources":["../../src/containers/NotificationsPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { StackspotNotification } from '../../components/notification/types.js';
2
+ import { LazyNotificationListener, LoadNotificationsFilters, LoadNotificationsOptions, LoadResult } from './types.js';
3
+ interface ConstructorParams {
4
+ id: number;
5
+ load: (options: LoadNotificationsOptions) => Promise<LoadResult>;
6
+ filters?: LoadNotificationsFilters;
7
+ }
8
+ export declare class LazyNotificationList {
9
+ #private;
10
+ readonly id: number;
11
+ items: StackspotNotification[];
12
+ private page;
13
+ private total;
14
+ private filters;
15
+ private readonly load;
16
+ private listeners;
17
+ private currentFetch;
18
+ constructor({ id, load, filters }: ConstructorParams);
19
+ private notify;
20
+ applyFilters(filters: LoadNotificationsFilters): Promise<void>;
21
+ loadMore(): Promise<void>;
22
+ hasMore(): boolean;
23
+ subscribe(listener: LazyNotificationListener): () => void;
24
+ update(readStatusMap: Map<string, boolean>): void;
25
+ mute(): void;
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=LazyNotificationList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LazyNotificationList.d.ts","sourceRoot":"","sources":["../../../src/context/notification/LazyNotificationList.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAElH,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACpC;AAED,qBAAa,oBAAoB;;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,qBAAqB,EAAE,CAAK;IACnC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4D;IACjF,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,YAAY,CAA2B;gBAEnC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAY,EAAE,EAAE,iBAAiB;IAMzD,OAAO,CAAC,MAAM;IAuBR,YAAY,CAAC,OAAO,EAAE,wBAAwB;IAgBpD,QAAQ;IAKR,OAAO;IAIP,SAAS,CAAC,QAAQ,EAAE,wBAAwB;IAO5C,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAU1C,IAAI;CAGL"}
@@ -0,0 +1,128 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _LazyNotificationList_instances, _LazyNotificationList_loadMore;
7
+ import { pull, uniqBy } from 'lodash';
8
+ export class LazyNotificationList {
9
+ constructor({ id, load, filters = {} }) {
10
+ _LazyNotificationList_instances.add(this);
11
+ Object.defineProperty(this, "id", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: void 0
16
+ });
17
+ Object.defineProperty(this, "items", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: []
22
+ });
23
+ Object.defineProperty(this, "page", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: -1
28
+ });
29
+ Object.defineProperty(this, "total", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: 0
34
+ });
35
+ Object.defineProperty(this, "filters", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: void 0
40
+ });
41
+ Object.defineProperty(this, "load", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: void 0
46
+ });
47
+ Object.defineProperty(this, "listeners", {
48
+ enumerable: true,
49
+ configurable: true,
50
+ writable: true,
51
+ value: []
52
+ });
53
+ Object.defineProperty(this, "currentFetch", {
54
+ enumerable: true,
55
+ configurable: true,
56
+ writable: true,
57
+ value: void 0
58
+ });
59
+ this.id = id;
60
+ this.load = load;
61
+ this.filters = filters;
62
+ }
63
+ notify() {
64
+ const hasMore = this.hasMore();
65
+ this.listeners.forEach(l => l(this.items, hasMore));
66
+ }
67
+ async applyFilters(filters) {
68
+ const prevPage = this.page;
69
+ const prevFilters = this.filters;
70
+ this.filters = filters;
71
+ this.page = -1;
72
+ try {
73
+ await this.currentFetch;
74
+ this.currentFetch = __classPrivateFieldGet(this, _LazyNotificationList_instances, "m", _LazyNotificationList_loadMore).call(this, true);
75
+ await this.currentFetch;
76
+ }
77
+ catch (error) {
78
+ this.filters = prevFilters;
79
+ this.page = prevPage;
80
+ throw error;
81
+ }
82
+ }
83
+ loadMore() {
84
+ this.currentFetch ??= __classPrivateFieldGet(this, _LazyNotificationList_instances, "m", _LazyNotificationList_loadMore).call(this);
85
+ return this.currentFetch;
86
+ }
87
+ hasMore() {
88
+ return this.items.length < this.total;
89
+ }
90
+ subscribe(listener) {
91
+ this.listeners.push(listener);
92
+ return () => {
93
+ pull(this.listeners, listener);
94
+ };
95
+ }
96
+ update(readStatusMap) {
97
+ this.items.forEach(i => i.committed = readStatusMap.get(i.id) ?? i.committed);
98
+ if (this.filters.committed !== undefined) {
99
+ this.items = this.items.filter(i => i.committed === this.filters.committed);
100
+ // if the filtered list has one item or less, we update the list with the backend so it can show more items
101
+ if (this.items.length <= 1)
102
+ this.applyFilters(this.filters);
103
+ }
104
+ this.notify();
105
+ }
106
+ mute() {
107
+ this.listeners = [];
108
+ }
109
+ }
110
+ _LazyNotificationList_instances = new WeakSet(), _LazyNotificationList_loadMore = async function _LazyNotificationList_loadMore(reset = false) {
111
+ try {
112
+ const result = await this.load({ ...this.filters, page: this.page + 1 });
113
+ if (reset) {
114
+ this.items = [];
115
+ this.total = 0;
116
+ }
117
+ // we can't have items with the same id: this can happen if new notifications have been created after the first page was loaded.
118
+ this.items = uniqBy([...this.items, ...result.items], 'id');
119
+ // we can't keep loading more if we already loaded every item or if the API returned an empty list.
120
+ this.total = result.items.length ? (this.total || result.total) : this.items.length;
121
+ this.page++;
122
+ this.notify();
123
+ }
124
+ finally {
125
+ this.currentFetch = undefined;
126
+ }
127
+ };
128
+ //# sourceMappingURL=LazyNotificationList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LazyNotificationList.js","sourceRoot":"","sources":["../../../src/context/notification/LazyNotificationList.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { LazyNotificationList } from './LazyNotificationList.js';
2
+ import { LoadNotificationsFilters, NotificationConfig, UnreadNotificationListener } from './types.js';
3
+ export declare class NotificationController {
4
+ private lazyLists;
5
+ readonly config: NotificationConfig;
6
+ private readStatusMap;
7
+ private nextId;
8
+ private unreadNotification;
9
+ private lastUnreadVerification;
10
+ private pollingTimeoutId;
11
+ private unreadNotificationListeners;
12
+ constructor(config: NotificationConfig);
13
+ private hasUnreadNotificationInMemory;
14
+ private setUnreadNotification;
15
+ createLazyNotificationList(filters?: LoadNotificationsFilters): LazyNotificationList;
16
+ destroyLazyNotificationList(id: number): void;
17
+ checkUnread(): Promise<void>;
18
+ markAsCommitted(notificationId: string): Promise<void>;
19
+ onUnreadNotificationChange(listener: UnreadNotificationListener): () => void;
20
+ hasUnreadNotification(): boolean;
21
+ reset(): void;
22
+ mute(): void;
23
+ }
24
+ //# sourceMappingURL=NotificationController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationController.d.ts","sourceRoot":"","sources":["../../../src/context/notification/NotificationController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAIlG,qBAAa,sBAAsB;IACjC,OAAO,CAAC,SAAS,CAA0C;IAC3D,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;IACnC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,sBAAsB,CAAkB;IAChD,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,2BAA2B,CAAmC;gBAE1D,MAAM,EAAE,kBAAkB;IAMtC,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,qBAAqB;IAQ7B,0BAA0B,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,oBAAoB;IAmBpF,2BAA2B,CAAC,EAAE,EAAE,MAAM;IAKhC,WAAW;IAMX,eAAe,CAAC,cAAc,EAAE,MAAM;IAe5C,0BAA0B,CAAC,QAAQ,EAAE,0BAA0B;IAO/D,qBAAqB;IAIrB,KAAK;IAOL,IAAI;CAGL"}
@@ -0,0 +1,136 @@
1
+ import { pull } from 'lodash';
2
+ import { LazyNotificationList } from './LazyNotificationList.js';
3
+ const DEFAULT_POLLING_MS = 120000;
4
+ export class NotificationController {
5
+ constructor(config) {
6
+ Object.defineProperty(this, "lazyLists", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: new Map()
11
+ });
12
+ Object.defineProperty(this, "config", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ Object.defineProperty(this, "readStatusMap", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: new Map()
23
+ });
24
+ Object.defineProperty(this, "nextId", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: 1
29
+ });
30
+ Object.defineProperty(this, "unreadNotification", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: false
35
+ });
36
+ Object.defineProperty(this, "lastUnreadVerification", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: void 0
41
+ });
42
+ Object.defineProperty(this, "pollingTimeoutId", {
43
+ enumerable: true,
44
+ configurable: true,
45
+ writable: true,
46
+ value: void 0
47
+ });
48
+ Object.defineProperty(this, "unreadNotificationListeners", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: []
53
+ });
54
+ this.config = config;
55
+ config.pollingMS ??= DEFAULT_POLLING_MS;
56
+ config.notificationsPath ??= '/notifications';
57
+ }
58
+ hasUnreadNotificationInMemory() {
59
+ for (const [, read] of this.readStatusMap) {
60
+ if (!read.valueOf())
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+ setUnreadNotification(value) {
66
+ this.unreadNotification = value;
67
+ if (!value) {
68
+ this.pollingTimeoutId = window.setTimeout(() => this.checkUnread(), this.config.pollingMS);
69
+ }
70
+ this.unreadNotificationListeners.forEach(l => l(value));
71
+ }
72
+ createLazyNotificationList(filters) {
73
+ const list = new LazyNotificationList({
74
+ id: this.nextId++,
75
+ filters,
76
+ load: async (options) => {
77
+ const result = await this.config.load(options);
78
+ result.items.forEach((i) => {
79
+ this.readStatusMap.set(i.id, i.committed);
80
+ // updating the unread indicator, since it might be stale
81
+ if (!i.committed)
82
+ this.setUnreadNotification(true);
83
+ });
84
+ this.lazyLists.forEach(l => l !== list && list.update(this.readStatusMap));
85
+ return result;
86
+ },
87
+ });
88
+ this.lazyLists.set(list.id, list);
89
+ return list;
90
+ }
91
+ destroyLazyNotificationList(id) {
92
+ this.lazyLists.get(id)?.mute();
93
+ this.lazyLists.delete(id);
94
+ }
95
+ async checkUnread() {
96
+ window.clearInterval(this.pollingTimeoutId);
97
+ this.setUnreadNotification(await this.config.checkForUnreadNotificationsSince(this.lastUnreadVerification));
98
+ this.lastUnreadVerification = new Date();
99
+ }
100
+ async markAsCommitted(notificationId) {
101
+ if (this.readStatusMap.get(notificationId))
102
+ return;
103
+ this.readStatusMap.set(notificationId, true);
104
+ this.lazyLists.forEach(l => l.update(this.readStatusMap));
105
+ try {
106
+ await this.config.markAsCommitted(notificationId);
107
+ // update the notification indicator: this is an inconsistency, we should actually ask the API, but since it's an expensive
108
+ // operation in the backend, we won't, instead, we'll only check the notifications we have loaded in memory.
109
+ if (!this.hasUnreadNotificationInMemory())
110
+ this.setUnreadNotification(false);
111
+ }
112
+ catch {
113
+ this.readStatusMap.set(notificationId, false);
114
+ this.lazyLists.forEach(l => l.update(this.readStatusMap));
115
+ }
116
+ }
117
+ onUnreadNotificationChange(listener) {
118
+ this.unreadNotificationListeners.push(listener);
119
+ return () => {
120
+ pull(this.unreadNotificationListeners, listener);
121
+ };
122
+ }
123
+ hasUnreadNotification() {
124
+ return this.unreadNotification;
125
+ }
126
+ reset() {
127
+ this.lazyLists.clear();
128
+ this.readStatusMap.clear();
129
+ this.lastUnreadVerification = undefined;
130
+ this.unreadNotification = false;
131
+ }
132
+ mute() {
133
+ this.unreadNotificationListeners = [];
134
+ }
135
+ }
136
+ //# sourceMappingURL=NotificationController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationController.js","sourceRoot":"","sources":["../../../src/context/notification/NotificationController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /// <reference types="react" />
2
+ import { NotificationController } from './NotificationController.js';
3
+ export interface Props {
4
+ children: React.ReactNode;
5
+ controller: NotificationController;
6
+ }
7
+ export declare const NotificationProvider: ({ children, controller }: Props) => import("react/jsx-runtime").JSX.Element;
8
+ export declare function useNotificationController(): NotificationController;
9
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/context/notification/context.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEjE,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,EAAE,sBAAsB,CAAC;CACpC;AAID,eAAO,MAAM,oBAAoB,6BAA8B,KAAK,4CAEnE,CAAA;AAED,wBAAgB,yBAAyB,2BAQxC"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext } from 'react';
3
+ const context = createContext(undefined);
4
+ export const NotificationProvider = ({ children, controller }) => (_jsx(context.Provider, { value: controller, children: children }));
5
+ export function useNotificationController() {
6
+ const controller = useContext(context);
7
+ if (!controller) {
8
+ throw new Error('A NotificationController was requested, but no NotificationController is available in the React Context. Please, be sure to wrap your component in a NotificationProvider.');
9
+ }
10
+ return controller;
11
+ }
12
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/context/notification/context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAQjD,MAAM,OAAO,GAAG,aAAa,CAAqC,SAAS,CAAC,CAAA;AAE5E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAS,EAAE,EAAE,CAAC,CACvE,KAAC,OAAO,CAAC,QAAQ,IAAC,KAAK,EAAE,UAAU,YAAG,QAAQ,GAAoB,CACnE,CAAA;AAED,MAAM,UAAU,yBAAyB;IACvC,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;IACtC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,4KAA4K,CAC7K,CAAA;IACH,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { LoadNotificationsFilters } from './types.js';
2
+ export declare function useNotificationList(initialFilters?: LoadNotificationsFilters): {
3
+ status: "loading" | "error" | "startup" | "idle";
4
+ items: import("../../notifications.js").StackspotNotification[];
5
+ hasMore: boolean;
6
+ loadMore: () => Promise<void>;
7
+ refresh: () => Promise<void>;
8
+ applyFilters: (newFilters: LoadNotificationsFilters) => Promise<void>;
9
+ filters: LoadNotificationsFilters;
10
+ error: any;
11
+ };
12
+ export declare function useUnreadNotifications(): boolean;
13
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../src/context/notification/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAElD,wBAAgB,mBAAmB,CAAC,cAAc,GAAE,wBAA6B;;;;;;+BAwB3B,wBAAwB;;;EAsC7E;AAED,wBAAgB,sBAAsB,YAWrC"}
@@ -0,0 +1,77 @@
1
+ import { useCallback, useMemo, useRef, useState } from 'react';
2
+ import { useManualRender } from '../../hooks/manual-render.js';
3
+ import { useEffectOnce } from '../../hooks/use-effect-once.js';
4
+ import { useNotificationController } from './context.js';
5
+ export function useNotificationList(initialFilters = {}) {
6
+ const { repaint } = useManualRender();
7
+ const [status, setStatus] = useState('startup');
8
+ const error = useRef();
9
+ const controller = useNotificationController();
10
+ const [filters, setFilters] = useState(initialFilters);
11
+ const list = useMemo(() => controller.createLazyNotificationList(initialFilters), []);
12
+ useEffectOnce(() => {
13
+ async function start() {
14
+ list.subscribe(repaint);
15
+ try {
16
+ await list.loadMore();
17
+ setStatus('idle');
18
+ }
19
+ catch (e) {
20
+ setStatus('error');
21
+ error.current = e;
22
+ }
23
+ }
24
+ start();
25
+ return () => controller.destroyLazyNotificationList(list.id);
26
+ });
27
+ const applyFilters = useCallback(async (newFilters) => {
28
+ setStatus('loading');
29
+ // since we're inside a useCallback, we don't have direct access to the current value of "filters". The only way we can access this
30
+ // value is from the function "setFilters". But "setFilters" run async. For this reason, we wait the function to run and retrieve the
31
+ // current value before continuing, hence the use of the await and promise below.
32
+ const { next, prev } = await new Promise((resolve) => {
33
+ setFilters((filters) => {
34
+ const prev = filters;
35
+ const next = { ...filters, ...newFilters };
36
+ resolve({ prev, next });
37
+ return next;
38
+ });
39
+ });
40
+ try {
41
+ await list.applyFilters(next);
42
+ setStatus('idle');
43
+ error.current = undefined;
44
+ }
45
+ catch (e) {
46
+ setFilters(prev);
47
+ if (error.current) {
48
+ error.current = e;
49
+ setStatus('error');
50
+ }
51
+ else {
52
+ setStatus('idle');
53
+ }
54
+ }
55
+ }, []);
56
+ return {
57
+ status,
58
+ items: list.items,
59
+ hasMore: list.hasMore(),
60
+ loadMore: () => list.loadMore(),
61
+ refresh: () => applyFilters(filters),
62
+ applyFilters,
63
+ filters,
64
+ error: error.current,
65
+ };
66
+ }
67
+ export function useUnreadNotifications() {
68
+ const [hasUnreadNotifications, setUnreadNotifications] = useState(false);
69
+ const controller = useNotificationController();
70
+ useEffectOnce(() => {
71
+ const unsubscribe = controller.onUnreadNotificationChange(setUnreadNotifications);
72
+ controller.checkUnread();
73
+ return unsubscribe;
74
+ });
75
+ return hasUnreadNotifications;
76
+ }
77
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../src/context/notification/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { StackspotNotification } from '../../components/notification/types.js';
2
+ export type NotificationPriority = 'HIGH' | 'MEDIUM' | 'LOW';
3
+ export type NotificationContext = 'ACCOUNT' | 'STUDIO' | 'WORKSPACE';
4
+ export interface LoadNotificationsFilters {
5
+ committed?: boolean;
6
+ criticality?: NotificationPriority;
7
+ search?: string;
8
+ context?: NotificationContext;
9
+ size?: number;
10
+ }
11
+ export interface LoadNotificationsOptions extends LoadNotificationsFilters {
12
+ page: number;
13
+ }
14
+ export interface LoadResult {
15
+ items: StackspotNotification[];
16
+ total: number;
17
+ }
18
+ export type LazyNotificationListener = (notifications: StackspotNotification[], hasMore: boolean) => void;
19
+ export interface NotificationConfig {
20
+ /**
21
+ * Fetches the notifications according to the options passed as parameters.
22
+ * @param options page, size and filters.
23
+ * @returns a promise that resolves to a {@link LoadResult}.
24
+ */
25
+ load(options: LoadNotificationsOptions): Promise<LoadResult>;
26
+ /**
27
+ * Check for unread notifications since the date passed as parameter.
28
+ * @param date the date to start the search from
29
+ * @returns a promise that resolves to true if there are unread notifications or false otherwise.
30
+ */
31
+ checkForUnreadNotificationsSince(date?: Date): Promise<boolean>;
32
+ /**
33
+ * Marks the notification with the id passed as parameter as read (committed).
34
+ * @param id the id of the notification.
35
+ */
36
+ markAsCommitted(id: string): Promise<void>;
37
+ /**
38
+ * How long (ms) we should wait before checking for unread notifications again.
39
+ * @default 120000
40
+ */
41
+ pollingMS?: number;
42
+ /**
43
+ * Path to the notifications page.
44
+ * @default '/notifications'
45
+ */
46
+ notificationsPath?: string;
47
+ /**
48
+ * A function to call whenever an action button of a notification is clicked. It receives the id of the notification as a parameter.
49
+ *
50
+ * Useful for adding a behavior other than committing the notification and redirecting to its action. Example: analytics.
51
+ *
52
+ * @param id the id of the notification.
53
+ */
54
+ onClickAction?: (id: string) => void;
55
+ }
56
+ export type UnreadNotificationListener = (hasUnreadNotification: boolean) => void;
57
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/context/notification/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAE3E,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;AAE5D,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAA;AAEpE,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACxE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,aAAa,EAAE,qBAAqB,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;AAEzG,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D;;;;OAIG;IACH,gCAAgC,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChE;;;OAGG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,qBAAqB,EAAE,OAAO,KAAK,IAAI,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map