• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8479685547

29 Mar 2024 09:57AM UTC coverage: 21.612% (-0.001%) from 21.613%
8479685547

Pull #510

github

web-flow
Merge 6ef5e653f into bd248f296
Pull Request #510: feat: support import result notify

1395 of 2507 branches covered (55.64%)

0 of 12 new or added lines in 3 files covered. (0.0%)

1 existing line in 1 file now uncovered.

14588 of 67501 relevant lines covered (21.61%)

2.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/apps/nextjs-app/src/features/app/components/notifications/NotificationList.tsx
1
import { useMutation, useQueryClient } from '@tanstack/react-query';
×
2
import type { NotificationStatesEnum } from '@teable/core';
×
3
import { Inbox } from '@teable/icons';
×
4
import type { INotificationVo } from '@teable/openapi';
×
5
import { updateNotificationStatus } from '@teable/openapi';
×
6
import { ReactQueryKeys } from '@teable/sdk/config/react-query-keys';
×
7
import { Button } from '@teable/ui-lib';
×
8
import dayjs, { extend } from 'dayjs';
×
9
import relativeTime from 'dayjs/plugin/relativeTime';
×
NEW
10
import Link from 'next/link';
×
11
import React from 'react';
×
12
import { NotificationActionBar } from './NotificationActionBar';
×
13
import { NotificationIcon } from './NotificationIcon';
×
14

×
15
extend(relativeTime);
×
16

×
17
interface NotificationListProps {
×
18
  notifyStatus: NotificationStatesEnum;
×
19
  data?: INotificationVo[];
×
20
  className?: string;
×
21

×
22
  hasNextPage?: boolean;
×
23
  isFetchingNextPage?: boolean;
×
24
  onShowMoreClick?: () => void;
×
25
}
×
26

×
27
export const NotificationList: React.FC<NotificationListProps> = (props) => {
×
28
  const { notifyStatus, data, className, hasNextPage, isFetchingNextPage, onShowMoreClick } = props;
×
29
  const queryClient = useQueryClient();
×
30

×
31
  const newPagesArray = (updatedId: string) => {
×
32
    return data?.map((item) => ({
×
33
      ...item,
×
34
      notifications: item.notifications.filter(({ id }) => id !== updatedId),
×
35
    }));
×
36
  };
×
37

×
38
  const { mutateAsync: updateStatusMutator } = useMutation({
×
39
    mutationFn: updateNotificationStatus,
×
40
    onSuccess: async (_data, variables, _context) => {
×
41
      await queryClient.invalidateQueries(ReactQueryKeys.notifyUnreadCount());
×
42
      queryClient.setQueryData(
×
43
        ReactQueryKeys.notifyList({ status: notifyStatus }),
×
44
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
×
45
        (data: any) => ({
×
46
          pages: newPagesArray(variables.notificationId),
×
47
          pageParams: data.pageParams,
×
48
        })
×
49
      );
×
50
    },
×
51
  });
×
52

×
53
  const renderNotifications = () => {
×
54
    return data?.map(({ notifications }) => {
×
55
      return (
×
56
        notifications &&
×
57
        notifications.map(({ id, isRead, url, message, notifyIcon, notifyType, createdTime }) => {
×
58
          const fromNow = dayjs(createdTime).fromNow();
×
59

×
60
          return (
×
61
            <NotificationActionBar
×
62
              key={id}
×
63
              notifyStatus={notifyStatus}
×
64
              onStatusCheck={() =>
×
65
                updateStatusMutator({
×
66
                  notificationId: id,
×
67
                  updateNotifyStatusRo: { isRead: !isRead },
×
68
                })
×
69
              }
×
70
            >
×
71
              <div className="max-h-[80px]">
×
NEW
72
                <Link
×
73
                  className="flex flex-auto cursor-pointer items-center px-6 py-2 hover:bg-accent"
×
74
                  href={url}
×
NEW
75
                  onClick={async () => {
×
NEW
76
                    !isRead &&
×
NEW
77
                      updateStatusMutator({
×
NEW
78
                        notificationId: id,
×
NEW
79
                        updateNotifyStatusRo: { isRead: true },
×
NEW
80
                      });
×
NEW
81
                  }}
×
82
                >
×
83
                  <NotificationIcon notifyIcon={notifyIcon} notifyType={notifyType} />
×
84
                  <div className="mr-3 w-[calc(100%_-_100px)]  items-center whitespace-pre-wrap break-words text-sm font-normal">
×
85
                    <div>{message}</div>
×
86
                    <div className="truncate text-[11px] opacity-75" title={fromNow}>
×
87
                      {fromNow}
×
88
                    </div>
×
89
                  </div>
×
NEW
90
                </Link>
×
91
              </div>
×
92
            </NotificationActionBar>
×
93
          );
×
94
        })
×
95
      );
×
96
    });
×
97
  };
×
98

×
99
  return (
×
100
    <div className={className}>
×
101
      {!data || !data[0].notifications?.length ? (
×
102
        <div className="p-6">
×
103
          <div className="flex items-center justify-center text-5xl font-normal">
×
104
            <Inbox />
×
105
          </div>
×
106
          <p className="text-center">No {notifyStatus} notifications</p>
×
107
        </div>
×
108
      ) : (
×
109
        <>
×
110
          {renderNotifications()}
×
111
          {hasNextPage && (
×
112
            <Button
×
113
              variant="ghost"
×
114
              size={'xs'}
×
115
              className="flex w-full p-2 text-center text-[11px] opacity-75"
×
116
              onClick={onShowMoreClick}
×
117
              disabled={!hasNextPage || isFetchingNextPage}
×
118
            >
×
119
              Show more
×
120
            </Button>
×
121
          )}
×
122
        </>
×
123
      )}
×
124
    </div>
×
125
  );
×
126
};
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc