tycho-components 0.42.2 → 0.42.3

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.
@@ -3,6 +3,7 @@ import { User } from '../../configs/types/User';
3
3
  import { Comment, CommentRequest } from './types/Comment';
4
4
  declare function findNotifications(uid: string, mode: string): Promise<AxiosResponse<Comment[], any, {}, any>>;
5
5
  declare function findReadNotifications(uid: string, mode: string): Promise<AxiosResponse<Comment[], any, {}, any>>;
6
+ declare function countUnreadNotifications(uid: string, mode: string): Promise<AxiosResponse<number, any, {}, any>>;
6
7
  declare function markRead(id: string): Promise<AxiosResponse<Comment, any, {}, any>>;
7
8
  declare function resolve(id: string): Promise<AxiosResponse<Comment, any, {}, any>>;
8
9
  declare function update(id: string, comment: CommentRequest): Promise<AxiosResponse<Comment, any, {}, any>>;
@@ -19,6 +20,7 @@ declare const CommentService: {
19
20
  find: typeof find;
20
21
  findNotifications: typeof findNotifications;
21
22
  findReadNotifications: typeof findReadNotifications;
23
+ countUnreadNotifications: typeof countUnreadNotifications;
22
24
  findAvailableUsers: typeof findAvailableUsers;
23
25
  };
24
26
  export default CommentService;
@@ -31,6 +31,9 @@ function findNotifications(uid, mode) {
31
31
  function findReadNotifications(uid, mode) {
32
32
  return api.get(`${import.meta.env.VITE_APP_COMMENT_API_URL}/${mode}/notifications/read/${uid}`);
33
33
  }
34
+ function countUnreadNotifications(uid, mode) {
35
+ return api.get(`${import.meta.env.VITE_APP_COMMENT_API_URL}/${mode}/notifications/count/${uid}`);
36
+ }
34
37
  function markRead(id) {
35
38
  if (StorybookUtils.isStorybook()) {
36
39
  storybookComments = storybookComments.map((c) => c.id === id
@@ -117,6 +120,7 @@ const CommentService = {
117
120
  find,
118
121
  findNotifications,
119
122
  findReadNotifications,
123
+ countUnreadNotifications,
120
124
  findAvailableUsers,
121
125
  };
122
126
  export default CommentService;
@@ -5,12 +5,14 @@ import { Avatar, IconButton } from 'tycho-storybook';
5
5
  import DateUtils from '../../../functions/DateUtils';
6
6
  import CommentService from '../CommentService';
7
7
  import './style.scss';
8
+ const POLL_INTERVAL_MS = 2 * 60 * 1000;
9
+ const READ_NOTIFICATIONS_LIMIT = 5;
8
10
  export default function HeaderNotifications({ uid, mode, mobile }) {
9
11
  const { t } = useTranslation('comments');
10
12
  const [open, setOpen] = useState(false);
11
13
  const [visible, setVisible] = useState(true);
12
14
  const [notifications, setNotifications] = useState();
13
- const [comments, setComments] = useState();
15
+ const [unreadCount, setUnreadCount] = useState(0);
14
16
  const [tab, setTab] = useState('unread');
15
17
  const handleOpen = (notification) => {
16
18
  if (!notification.url)
@@ -18,27 +20,45 @@ export default function HeaderNotifications({ uid, mode, mobile }) {
18
20
  location.href = notification.url;
19
21
  setOpen(false);
20
22
  };
21
- const load = () => {
23
+ const loadUnreadCount = () => {
24
+ CommentService.countUnreadNotifications(uid, mode)
25
+ .then((r) => {
26
+ setUnreadCount(r.data ?? 0);
27
+ setVisible(true);
28
+ })
29
+ .catch(() => {
30
+ setVisible(false);
31
+ });
32
+ };
33
+ const loadNotifications = () => {
22
34
  const serviceMethod = tab === 'read'
23
35
  ? CommentService.findReadNotifications
24
36
  : CommentService.findNotifications;
25
37
  serviceMethod(uid, mode)
26
38
  .then((r) => {
39
+ const data = tab === 'read' ? r.data.slice(0, READ_NOTIFICATIONS_LIMIT) : r.data;
40
+ setNotifications(data);
27
41
  if (tab !== 'read') {
28
- setComments(r.data);
42
+ setUnreadCount(data.length);
29
43
  }
30
- setNotifications(r.data);
31
44
  })
32
45
  .catch(() => {
33
46
  setVisible(false);
34
47
  });
35
48
  };
36
49
  useEffect(() => {
37
- load();
38
- }, [uid, tab]);
50
+ loadUnreadCount();
51
+ const intervalId = window.setInterval(loadUnreadCount, POLL_INTERVAL_MS);
52
+ return () => window.clearInterval(intervalId);
53
+ }, [uid, mode]);
54
+ useEffect(() => {
55
+ if (!open)
56
+ return;
57
+ loadNotifications();
58
+ }, [open, uid, mode, tab]);
39
59
  if (!visible)
40
60
  return null;
41
- return (_jsxs("div", { className: "ds-dropdown-container notifications-container", children: [_jsx(IconButton, { name: "notifications_active", className: comments && comments.length > 0 ? 'shake' : '', size: "large", onClick: () => setOpen(!open), mode: mobile ? 'outlined' : 'filled' }), open && (_jsx("div", { className: "ds-dropdown-list", children: _jsxs("div", { className: "notifications-panel", children: [_jsxs("div", { className: "header", children: [_jsx("span", { children: t('notification.title') }), _jsx(IconButton, { name: "close", size: "small", mode: "ghost", onClick: () => setOpen(false) })] }), _jsxs("div", { className: "tabs", children: [_jsxs("button", { className: tab === 'unread' ? 'active-tab' : '', onClick: () => setTab('unread'), children: [t('notification.unread'), " (", comments?.length || 0, ")"] }), _jsx("button", { className: tab === 'read' ? 'active-tab' : '', onClick: () => setTab('read'), children: t('notification.all') })] }), _jsxs("div", { className: "content", children: [notifications &&
61
+ return (_jsxs("div", { className: "ds-dropdown-container notifications-container", children: [_jsx(IconButton, { name: "notifications_active", className: unreadCount > 0 ? 'shake' : '', size: "large", onClick: () => setOpen(!open), mode: mobile ? 'outlined' : 'filled' }), open && (_jsx("div", { className: "ds-dropdown-list", children: _jsxs("div", { className: "notifications-panel", children: [_jsxs("div", { className: "header", children: [_jsx("span", { children: t('notification.title') }), _jsx(IconButton, { name: "close", size: "small", mode: "ghost", onClick: () => setOpen(false) })] }), _jsxs("div", { className: "tabs", children: [_jsxs("button", { className: tab === 'unread' ? 'active-tab' : '', onClick: () => setTab('unread'), children: [t('notification.unread'), " (", unreadCount, ")"] }), _jsx("button", { className: tab === 'read' ? 'active-tab' : '', onClick: () => setTab('read'), children: t('notification.all') })] }), _jsxs("div", { className: "content", children: [notifications &&
42
62
  notifications.map((not, idx) => (_jsxs("div", { className: "item", onClick: () => handleOpen(not), children: [_jsx(Avatar, { src: not.picture, size: "small" }), _jsxs("div", { className: "message", children: [_jsx("span", { className: "text", children: _jsx(Trans, { t: t, i18nKey: "notification.text", values: {
43
63
  user: not.name,
44
64
  } }) }), _jsx("span", { className: "date", children: DateUtils.formatDateTime(not.edited ? not.edited : not.date, 'MM/dd/yyyy - HH:mm') })] })] }, idx.valueOf()))), notifications && notifications.length === 0 && (_jsx("div", { className: "empty-notifications", children: t('notification.empty') }))] })] }) }))] }));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tycho-components",
3
3
  "private": false,
4
- "version": "0.42.2",
4
+ "version": "0.42.3",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {