@abtnode/ux 1.16.20 → 1.16.21-beta-edf184e1
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.
- package/es/blocklet/configuration.js +9 -4
- package/es/blocklet/router/action/add-domain-alias.js +26 -6
- package/es/blocklet/router/add-domain.js +40 -12
- package/es/confirm.js +10 -4
- package/es/contexts/domain.js +75 -0
- package/es/form/form-autocomplete-input.js +282 -0
- package/es/hooks/use-snackbar.js +2 -0
- package/es/hooks/use-width.js +12 -0
- package/es/locales/en.js +8 -6
- package/es/locales/zh.js +8 -6
- package/es/notifications/addon.js +91 -0
- package/es/notifications/default-icon-variants.js +53 -0
- package/es/notifications/list.js +251 -0
- package/es/notifications/notification.js +148 -0
- package/es/notifications/page.js +316 -0
- package/es/notifications/tag.js +28 -0
- package/lib/blocklet/configuration.js +9 -4
- package/lib/blocklet/router/action/add-domain-alias.js +24 -6
- package/lib/blocklet/router/add-domain.js +39 -11
- package/lib/confirm.js +12 -6
- package/lib/contexts/domain.js +85 -0
- package/lib/form/form-autocomplete-input.js +295 -0
- package/lib/hooks/use-snackbar.js +8 -0
- package/lib/hooks/use-width.js +19 -0
- package/lib/locales/en.js +8 -6
- package/lib/locales/zh.js +8 -6
- package/lib/notifications/addon.js +99 -0
- package/lib/notifications/default-icon-variants.js +61 -0
- package/lib/notifications/list.js +216 -0
- package/lib/notifications/notification.js +139 -0
- package/lib/notifications/page.js +267 -0
- package/lib/notifications/tag.js +44 -0
- package/package.json +9 -7
package/es/locales/en.js
CHANGED
|
@@ -935,8 +935,8 @@ export default {
|
|
|
935
935
|
description: 'Please provide a valid site domain'
|
|
936
936
|
},
|
|
937
937
|
setup: {
|
|
938
|
-
tipStart: '
|
|
939
|
-
tipEnd: '
|
|
938
|
+
tipStart: 'Add the DNS records for the domain',
|
|
939
|
+
tipEnd: 'as per the following guidelines',
|
|
940
940
|
recordType: 'Record Type',
|
|
941
941
|
recordValue: 'Record Value'
|
|
942
942
|
},
|
|
@@ -957,25 +957,27 @@ export default {
|
|
|
957
957
|
domainAlias: {
|
|
958
958
|
inputDomain: 'Manually config domain',
|
|
959
959
|
nftDomain: 'Automatic config with DID Domain',
|
|
960
|
+
showTipHint: 'How do I configure domain name resolution?',
|
|
960
961
|
add: {
|
|
961
962
|
title: 'Add Additional Domain',
|
|
962
963
|
domainDescription: 'Please provide a valid domain name',
|
|
963
964
|
forceTip: 'Force add if domain name already exists',
|
|
964
|
-
helperText: 'If an HTTP or HTTPS URL is entered, it will be automatically converted into a domain name.'
|
|
965
|
+
helperText: 'If an HTTP or HTTPS URL is entered, it will be automatically converted into a domain name.',
|
|
966
|
+
isDidDomainError: 'This domain is a DID Domain. Please add it using the method for automatic domain configuration.'
|
|
965
967
|
},
|
|
966
968
|
addCustomDomain: {
|
|
967
969
|
name: 'Custom Domain'
|
|
968
970
|
},
|
|
969
971
|
addDomainNFT: {
|
|
970
|
-
showNFT: '
|
|
971
|
-
tips: '
|
|
972
|
+
showNFT: 'Configure domain automatically',
|
|
973
|
+
tips: 'DID Domain will do the domain name resolution automatically, no need to configure it manually, and the application will update the resolution record of the domain name automatically when needed.',
|
|
972
974
|
connect: {
|
|
973
975
|
title: 'Please show your Domain NFT',
|
|
974
976
|
scan: 'Scan following QR code with DID Wallet to authorize to blocklet to use your domain',
|
|
975
977
|
confirm: 'Confirm on your DID Wallet',
|
|
976
978
|
success: 'Authorization Successfully'
|
|
977
979
|
},
|
|
978
|
-
buyTip: "If your don't have
|
|
980
|
+
buyTip: "If your don't have DID Domain NFT yet, ",
|
|
979
981
|
buy: 'buy it now!'
|
|
980
982
|
},
|
|
981
983
|
delete: {
|
package/es/locales/zh.js
CHANGED
|
@@ -938,8 +938,8 @@ export default {
|
|
|
938
938
|
description: '请填写你所拥有的合法的站点域名'
|
|
939
939
|
},
|
|
940
940
|
setup: {
|
|
941
|
-
tipStart: '
|
|
942
|
-
tipEnd: '
|
|
941
|
+
tipStart: '请将',
|
|
942
|
+
tipEnd: '域名的 DNS 记录按照下面的提示添加',
|
|
943
943
|
recordType: '记录类型',
|
|
944
944
|
recordValue: '记录值'
|
|
945
945
|
},
|
|
@@ -960,26 +960,28 @@ export default {
|
|
|
960
960
|
domainAlias: {
|
|
961
961
|
inputDomain: '手动配置域名',
|
|
962
962
|
nftDomain: '通过 DID Domain 自动配置域名',
|
|
963
|
+
showTipHint: '如何配置域名解析?',
|
|
963
964
|
add: {
|
|
964
965
|
title: '添加额外域名',
|
|
965
966
|
domainDescription: '请填写有效的域名',
|
|
966
967
|
forceTip: '当域名已存在时强制添加',
|
|
967
|
-
helperText: '如果输入 HTTP 或者 HTTPS URL, 则会被自动转换为域名。'
|
|
968
|
+
helperText: '如果输入 HTTP 或者 HTTPS URL, 则会被自动转换为域名。',
|
|
969
|
+
isDidDomainError: '该域名是 DID Domain, 请使用自动配置域名的方式添加该域名。'
|
|
968
970
|
},
|
|
969
971
|
addCustomDomain: {
|
|
970
972
|
name: '自定义域名'
|
|
971
973
|
},
|
|
972
974
|
addDomainNFT: {
|
|
973
975
|
name: 'NFT 域名',
|
|
974
|
-
showNFT: '
|
|
975
|
-
tips: '
|
|
976
|
+
showNFT: '自动配置域名',
|
|
977
|
+
tips: 'DID 域名会自动完成域名解析,无需手动配置,并且应用会在需要的时候自动更新该域名的解析记录。',
|
|
976
978
|
connect: {
|
|
977
979
|
title: '请出示域名 NFT',
|
|
978
980
|
scan: '用 DID 钱包扫描下面的二维码, 出示域名 NFT',
|
|
979
981
|
confirm: '在您的 DID 钱包上确认',
|
|
980
982
|
success: '授权成功'
|
|
981
983
|
},
|
|
982
|
-
buyTip: '
|
|
984
|
+
buyTip: '如果还没有 DID 域名 NFT, ',
|
|
983
985
|
buy: '现在购买!'
|
|
984
986
|
},
|
|
985
987
|
delete: {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* eslint-disable import/no-unresolved */
|
|
2
|
+
/* eslint-disable react/jsx-one-expression-per-line */
|
|
3
|
+
import { useState, useRef } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import ClickAwayListener from '@mui/material/ClickAwayListener';
|
|
6
|
+
import Button from '@mui/material/IconButton';
|
|
7
|
+
import Paper from '@mui/material/Paper';
|
|
8
|
+
import Badge from '@mui/material/Badge';
|
|
9
|
+
import Popper from '@mui/material/Popper';
|
|
10
|
+
import NotificationIcon from '@arcblock/icons/lib/Notification';
|
|
11
|
+
import NotificationList from './list';
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
export default function NotificationAddon({
|
|
15
|
+
api,
|
|
16
|
+
notifications,
|
|
17
|
+
updateNotifications,
|
|
18
|
+
viewAllUrl,
|
|
19
|
+
teamDid
|
|
20
|
+
}) {
|
|
21
|
+
const [notificationOpen, setNotificationOpen] = useState(false);
|
|
22
|
+
const notificationAnchorRef = useRef(null);
|
|
23
|
+
const onToggleNotification = () => {
|
|
24
|
+
setNotificationOpen(prevOpen => !prevOpen);
|
|
25
|
+
};
|
|
26
|
+
const onCloseNotification = e => {
|
|
27
|
+
if (notificationAnchorRef.current && notificationAnchorRef.current.contains(e.target)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
setNotificationOpen(false);
|
|
31
|
+
};
|
|
32
|
+
const unreadCount = notifications.filter(x => x.read === false).length;
|
|
33
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
34
|
+
className: "notification-addon",
|
|
35
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
36
|
+
ref: notificationAnchorRef,
|
|
37
|
+
"aria-controls": "notify-list-grow",
|
|
38
|
+
"aria-haspopup": "true",
|
|
39
|
+
"data-cy": "toggle-notification-btn",
|
|
40
|
+
onClick: onToggleNotification,
|
|
41
|
+
children: unreadCount > 0 ? /*#__PURE__*/_jsx(Badge, {
|
|
42
|
+
badgeContent: unreadCount,
|
|
43
|
+
max: 99,
|
|
44
|
+
color: "primary",
|
|
45
|
+
children: /*#__PURE__*/_jsx(NotificationIcon, {
|
|
46
|
+
style: {
|
|
47
|
+
width: 'auto',
|
|
48
|
+
height: 24
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}) : /*#__PURE__*/_jsx(NotificationIcon, {
|
|
52
|
+
style: {
|
|
53
|
+
width: 'auto',
|
|
54
|
+
height: 24
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}), notificationOpen && /*#__PURE__*/_jsx(Popper, {
|
|
58
|
+
open: true,
|
|
59
|
+
anchorEl: notificationAnchorRef.current,
|
|
60
|
+
disablePortal: true,
|
|
61
|
+
placement: "bottom-end",
|
|
62
|
+
children: /*#__PURE__*/_jsx(Paper, {
|
|
63
|
+
id: "notify-list-grow",
|
|
64
|
+
children: /*#__PURE__*/_jsx(ClickAwayListener, {
|
|
65
|
+
onClickAway: onCloseNotification,
|
|
66
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
67
|
+
children: /*#__PURE__*/_jsx(NotificationList, {
|
|
68
|
+
notifications: notifications,
|
|
69
|
+
updateNotifications: updateNotifications,
|
|
70
|
+
api: api,
|
|
71
|
+
viewAllUrl: viewAllUrl,
|
|
72
|
+
onHide: onCloseNotification,
|
|
73
|
+
teamDid: teamDid
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
})]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
NotificationAddon.propTypes = {
|
|
82
|
+
notifications: PropTypes.arrayOf(PropTypes.object),
|
|
83
|
+
viewAllUrl: PropTypes.string.isRequired,
|
|
84
|
+
api: PropTypes.object.isRequired,
|
|
85
|
+
updateNotifications: PropTypes.func.isRequired,
|
|
86
|
+
teamDid: PropTypes.string
|
|
87
|
+
};
|
|
88
|
+
NotificationAddon.defaultProps = {
|
|
89
|
+
notifications: [],
|
|
90
|
+
teamDid: ''
|
|
91
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import SvgIcon from '@mui/material/SvgIcon';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
function CheckIcon(props) {
|
|
4
|
+
return /*#__PURE__*/_jsx(SvgIcon, {
|
|
5
|
+
...props,
|
|
6
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
7
|
+
d: "M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M10 17L5 12L6.41 10.59L10 14.17L17.59 6.58L19 8L10 17Z"
|
|
8
|
+
})
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function WarningIcon(props) {
|
|
12
|
+
return /*#__PURE__*/_jsx(SvgIcon, {
|
|
13
|
+
...props,
|
|
14
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
15
|
+
d: "M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z"
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function ErrorIcon(props) {
|
|
20
|
+
return /*#__PURE__*/_jsx(SvgIcon, {
|
|
21
|
+
...props,
|
|
22
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
23
|
+
d: "M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2, 6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12, 13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z"
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function InfoIcon(props) {
|
|
28
|
+
return /*#__PURE__*/_jsx(SvgIcon, {
|
|
29
|
+
...props,
|
|
30
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
31
|
+
d: "M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0, 0 22,12A10,10 0 0,0 12,2Z"
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const iconStyles = {
|
|
36
|
+
fontSize: 20,
|
|
37
|
+
marginInlineEnd: 8
|
|
38
|
+
};
|
|
39
|
+
const defaultIconVariants = {
|
|
40
|
+
success: /*#__PURE__*/_jsx(CheckIcon, {
|
|
41
|
+
style: iconStyles
|
|
42
|
+
}),
|
|
43
|
+
warning: /*#__PURE__*/_jsx(WarningIcon, {
|
|
44
|
+
style: iconStyles
|
|
45
|
+
}),
|
|
46
|
+
error: /*#__PURE__*/_jsx(ErrorIcon, {
|
|
47
|
+
style: iconStyles
|
|
48
|
+
}),
|
|
49
|
+
info: /*#__PURE__*/_jsx(InfoIcon, {
|
|
50
|
+
style: iconStyles
|
|
51
|
+
})
|
|
52
|
+
};
|
|
53
|
+
export default defaultIconVariants;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/* eslint-disable operator-linebreak */
|
|
2
|
+
import styled from '@emotion/styled';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { useContext, useState } from 'react';
|
|
5
|
+
import { Link, useNavigate } from 'react-router-dom';
|
|
6
|
+
import Button from '@arcblock/ux/lib/Button';
|
|
7
|
+
import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
8
|
+
import Avatar from '@mui/material/Avatar';
|
|
9
|
+
import Box from '@mui/material/Box';
|
|
10
|
+
import Checkbox from '@mui/material/Checkbox';
|
|
11
|
+
import Spinner from '@mui/material/CircularProgress';
|
|
12
|
+
import Divider from '@mui/material/Divider';
|
|
13
|
+
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
14
|
+
import List from '@mui/material/List';
|
|
15
|
+
import ListItemAvatar from '@mui/material/ListItemAvatar';
|
|
16
|
+
import ListItemButton from '@mui/material/ListItemButton';
|
|
17
|
+
import ListItemText from '@mui/material/ListItemText';
|
|
18
|
+
import Typography from '@mui/material/Typography';
|
|
19
|
+
import useTheme from '@mui/material/styles/useTheme';
|
|
20
|
+
import NotificationTag from './tag';
|
|
21
|
+
import Permission from '../permission';
|
|
22
|
+
import RelativeTime from '../relative-time';
|
|
23
|
+
import { useNodeContext } from '../contexts/node';
|
|
24
|
+
import { BlockletAdminRoles } from '../util';
|
|
25
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
26
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
27
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
28
|
+
export default function NotificationsList({
|
|
29
|
+
onHide,
|
|
30
|
+
api,
|
|
31
|
+
notifications,
|
|
32
|
+
updateNotifications,
|
|
33
|
+
viewAllUrl,
|
|
34
|
+
teamDid
|
|
35
|
+
}) {
|
|
36
|
+
const {
|
|
37
|
+
inService
|
|
38
|
+
} = useNodeContext();
|
|
39
|
+
const {
|
|
40
|
+
t,
|
|
41
|
+
locale
|
|
42
|
+
} = useContext(LocaleContext);
|
|
43
|
+
const [showRead, setShowRead] = useState(true);
|
|
44
|
+
const [isMarkingAll, setIsMarkingAll] = useState(false);
|
|
45
|
+
const navigate = useNavigate();
|
|
46
|
+
const theme = useTheme();
|
|
47
|
+
let filtered = showRead ? notifications : notifications.filter(x => x.read === false);
|
|
48
|
+
filtered = filtered.slice(0, 5);
|
|
49
|
+
const hasUnRead = notifications.filter(x => x.read === false).length > 0;
|
|
50
|
+
const onUnreadNotifications = async () => {
|
|
51
|
+
setIsMarkingAll(true);
|
|
52
|
+
const ids = notifications.filter(x => x.read === false).map(x => x.id).join(',');
|
|
53
|
+
if (inService) {
|
|
54
|
+
await api.readBlockletNotifications({
|
|
55
|
+
input: {
|
|
56
|
+
id: ids,
|
|
57
|
+
teamDid
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
await api.readNotifications({
|
|
62
|
+
input: {
|
|
63
|
+
id: ids
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
updateNotifications();
|
|
68
|
+
setIsMarkingAll(false);
|
|
69
|
+
};
|
|
70
|
+
const handleNotificationClick = (e, notification) => {
|
|
71
|
+
if (!notification.read) {
|
|
72
|
+
if (inService) {
|
|
73
|
+
api.readBlockletNotifications({
|
|
74
|
+
input: {
|
|
75
|
+
id: notification.id,
|
|
76
|
+
teamDid
|
|
77
|
+
}
|
|
78
|
+
}).then(() => updateNotifications());
|
|
79
|
+
} else {
|
|
80
|
+
api.readNotifications({
|
|
81
|
+
input: {
|
|
82
|
+
id: notification.id
|
|
83
|
+
}
|
|
84
|
+
}).then(() => updateNotifications());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
onHide(e);
|
|
88
|
+
navigate(viewAllUrl);
|
|
89
|
+
};
|
|
90
|
+
return /*#__PURE__*/_jsxs(Div, {
|
|
91
|
+
children: [/*#__PURE__*/_jsxs(Typography, {
|
|
92
|
+
component: "h3",
|
|
93
|
+
variant: "h6",
|
|
94
|
+
className: "notification-header",
|
|
95
|
+
children: [t('notification.title'), /*#__PURE__*/_jsx(Button, {
|
|
96
|
+
component: Link,
|
|
97
|
+
to: viewAllUrl,
|
|
98
|
+
"data-cy": "view-all-notifications-btn",
|
|
99
|
+
onClick: onHide,
|
|
100
|
+
children: t('notification.viewAll')
|
|
101
|
+
})]
|
|
102
|
+
}), /*#__PURE__*/_jsx(Divider, {}), /*#__PURE__*/_jsxs(List, {
|
|
103
|
+
className: "notification-list",
|
|
104
|
+
style: {
|
|
105
|
+
maxHeight: 'calc(100vh - 200px)',
|
|
106
|
+
overflow: 'auto'
|
|
107
|
+
},
|
|
108
|
+
children: [filtered.length === 0 && /*#__PURE__*/_jsx(Typography, {
|
|
109
|
+
component: "p",
|
|
110
|
+
variant: "body1",
|
|
111
|
+
className: "notification-tip",
|
|
112
|
+
children: t('notification.empty')
|
|
113
|
+
}), filtered.length > 0 && filtered.map(x => /*#__PURE__*/_jsxs(ListItemButton, {
|
|
114
|
+
alignItems: "flex-start",
|
|
115
|
+
disabled: x.read,
|
|
116
|
+
onClick: e => handleNotificationClick(e, x),
|
|
117
|
+
children: [/*#__PURE__*/_jsx(ListItemAvatar, {
|
|
118
|
+
className: "list-item-avatar",
|
|
119
|
+
children: /*#__PURE__*/_jsxs(_Fragment, {
|
|
120
|
+
children: [/*#__PURE__*/_jsx(Avatar, {
|
|
121
|
+
children: x.entityType.substr(0, 1).toUpperCase()
|
|
122
|
+
}), /*#__PURE__*/_jsx(NotificationTag, {
|
|
123
|
+
className: "notification-tag",
|
|
124
|
+
status: x.severity
|
|
125
|
+
})]
|
|
126
|
+
})
|
|
127
|
+
}), /*#__PURE__*/_jsx(ListItemText, {
|
|
128
|
+
primary: x.title,
|
|
129
|
+
secondary: /*#__PURE__*/_jsxs(Box, {
|
|
130
|
+
sx: {
|
|
131
|
+
display: 'flex',
|
|
132
|
+
flexDirection: 'column',
|
|
133
|
+
justifyContent: 'space-between'
|
|
134
|
+
},
|
|
135
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
136
|
+
component: "span",
|
|
137
|
+
sx: {
|
|
138
|
+
overflow: 'hidden',
|
|
139
|
+
'-webkit-line-clamp': '3',
|
|
140
|
+
'-webkit-box-orient': 'vertical',
|
|
141
|
+
display: '-webkit-box',
|
|
142
|
+
'text-overflow': 'ellipsis'
|
|
143
|
+
},
|
|
144
|
+
children: x.description
|
|
145
|
+
}), /*#__PURE__*/_jsx(RelativeTime, {
|
|
146
|
+
value: x.createdAt,
|
|
147
|
+
locale: locale,
|
|
148
|
+
style: {
|
|
149
|
+
color: theme.palette.text.secondary,
|
|
150
|
+
fontSize: '0.875rem',
|
|
151
|
+
marginTop: '4px'
|
|
152
|
+
}
|
|
153
|
+
})]
|
|
154
|
+
})
|
|
155
|
+
})]
|
|
156
|
+
}, x.id))]
|
|
157
|
+
}), /*#__PURE__*/_jsx(Divider, {}), /*#__PURE__*/_jsxs(Typography, {
|
|
158
|
+
component: "div",
|
|
159
|
+
className: "notification-footer",
|
|
160
|
+
children: [/*#__PURE__*/_jsx(FormControlLabel, {
|
|
161
|
+
control: /*#__PURE__*/_jsx(Checkbox, {
|
|
162
|
+
checked: showRead,
|
|
163
|
+
onChange: () => setShowRead(!showRead),
|
|
164
|
+
name: "showRead",
|
|
165
|
+
color: "primary"
|
|
166
|
+
}),
|
|
167
|
+
label: t('notification.showRead')
|
|
168
|
+
}), /*#__PURE__*/_jsx(Permission, {
|
|
169
|
+
permission: inService ? '' : 'mutate_notification',
|
|
170
|
+
role: inService ? BlockletAdminRoles : [],
|
|
171
|
+
children: hasUnRead && /*#__PURE__*/_jsxs(Button, {
|
|
172
|
+
disabled: isMarkingAll,
|
|
173
|
+
onClick: onUnreadNotifications,
|
|
174
|
+
className: "",
|
|
175
|
+
children: [isMarkingAll && /*#__PURE__*/_jsx(Spinner, {
|
|
176
|
+
size: 16,
|
|
177
|
+
style: {
|
|
178
|
+
marginRight: '1em'
|
|
179
|
+
}
|
|
180
|
+
}), t('notification.markAllAsRead')]
|
|
181
|
+
})
|
|
182
|
+
})]
|
|
183
|
+
})]
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const Div = styled.div`
|
|
187
|
+
width: 420px;
|
|
188
|
+
|
|
189
|
+
@media (max-width: ${props => props.theme.breakpoints.values.sm}px) {
|
|
190
|
+
width: calc(100vw - 10px);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.notification-header {
|
|
194
|
+
padding: 8px 16px;
|
|
195
|
+
display: flex;
|
|
196
|
+
justify-content: space-between;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.notification-tip {
|
|
200
|
+
padding: 8px 16px;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.notification-footer {
|
|
204
|
+
padding: 8px 16px;
|
|
205
|
+
display: flex;
|
|
206
|
+
justify-content: space-between;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.MuiButtonBase-root {
|
|
210
|
+
white-space: pre-wrap;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.list-item-avatar {
|
|
214
|
+
display: flex;
|
|
215
|
+
flex-direction: column;
|
|
216
|
+
align-items: center;
|
|
217
|
+
min-width: 80px;
|
|
218
|
+
|
|
219
|
+
.notification-tag {
|
|
220
|
+
margin-top: 4px;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.MuiButtonBase-root:not(.Mui-disabled) {
|
|
225
|
+
.MuiAvatar-root {
|
|
226
|
+
background: ${props => props.theme.palette.primary.light};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
`;
|
|
230
|
+
NotificationsList.propTypes = {
|
|
231
|
+
onHide: PropTypes.func,
|
|
232
|
+
api: PropTypes.shape({
|
|
233
|
+
readNotifications: PropTypes.func.isRequired,
|
|
234
|
+
readBlockletNotifications: PropTypes.func.isRequired
|
|
235
|
+
}).isRequired,
|
|
236
|
+
notifications: PropTypes.arrayOf(PropTypes.shape({
|
|
237
|
+
id: PropTypes.string,
|
|
238
|
+
read: PropTypes.bool,
|
|
239
|
+
entityType: PropTypes.string,
|
|
240
|
+
title: PropTypes.string,
|
|
241
|
+
createdAt: PropTypes.string,
|
|
242
|
+
description: PropTypes.string
|
|
243
|
+
}).isRequired).isRequired,
|
|
244
|
+
updateNotifications: PropTypes.func.isRequired,
|
|
245
|
+
viewAllUrl: PropTypes.string.isRequired,
|
|
246
|
+
teamDid: PropTypes.string
|
|
247
|
+
};
|
|
248
|
+
NotificationsList.defaultProps = {
|
|
249
|
+
onHide: () => {},
|
|
250
|
+
teamDid: ''
|
|
251
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
/* eslint-disable operator-linebreak */
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import { makeStyles } from '@mui/styles';
|
|
6
|
+
import styled from '@emotion/styled';
|
|
7
|
+
import { amber, green } from '@mui/material/colors';
|
|
8
|
+
import IconButton from '@mui/material/IconButton';
|
|
9
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
10
|
+
import { useNavigate } from 'react-router-dom';
|
|
11
|
+
import { useSnackbar, SnackbarContent } from 'notistack';
|
|
12
|
+
import useWidth from '../hooks/use-width';
|
|
13
|
+
import variants from './default-icon-variants';
|
|
14
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
const useStyles = makeStyles(theme => {
|
|
17
|
+
const breakpointsMap = {
|
|
18
|
+
xl: '400px',
|
|
19
|
+
lg: '400px',
|
|
20
|
+
md: '400px',
|
|
21
|
+
sm: '300px'
|
|
22
|
+
};
|
|
23
|
+
// const backgroundColor = emphasize(theme.palette.background.default, theme.palette.mode === 'light' ? 0.8 : 0.98);
|
|
24
|
+
const backgroundColor = theme.palette.background.default;
|
|
25
|
+
return {
|
|
26
|
+
lessPadding: {
|
|
27
|
+
paddingLeft: 8 * 2.5
|
|
28
|
+
},
|
|
29
|
+
contentRoot: {
|
|
30
|
+
...theme.typography.body2,
|
|
31
|
+
display: 'flex',
|
|
32
|
+
backgroundColor,
|
|
33
|
+
color: '#fff',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
padding: '6px 16px',
|
|
36
|
+
borderRadius: '4px',
|
|
37
|
+
boxShadow: '0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)'
|
|
38
|
+
},
|
|
39
|
+
success: props => ({
|
|
40
|
+
backgroundColor: `${green[600]} !important`,
|
|
41
|
+
width: breakpointsMap[props.breakpoint]
|
|
42
|
+
}),
|
|
43
|
+
error: props => ({
|
|
44
|
+
backgroundColor: `${theme.palette.error.dark} !important`,
|
|
45
|
+
width: breakpointsMap[props.breakpoint]
|
|
46
|
+
}),
|
|
47
|
+
info: props => ({
|
|
48
|
+
backgroundColor: `${theme.palette.primary.main} !important`,
|
|
49
|
+
width: breakpointsMap[props.breakpoint]
|
|
50
|
+
}),
|
|
51
|
+
warning: props => ({
|
|
52
|
+
backgroundColor: `${amber[700]} !important`,
|
|
53
|
+
width: breakpointsMap[props.breakpoint]
|
|
54
|
+
}),
|
|
55
|
+
icon: {
|
|
56
|
+
fontSize: 20
|
|
57
|
+
},
|
|
58
|
+
message: {
|
|
59
|
+
display: 'flex',
|
|
60
|
+
alignItems: 'center',
|
|
61
|
+
padding: '8px 0',
|
|
62
|
+
flex: 1,
|
|
63
|
+
width: 0
|
|
64
|
+
},
|
|
65
|
+
action: {
|
|
66
|
+
display: 'flex',
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
marginLeft: 'auto',
|
|
69
|
+
marginRight: -8,
|
|
70
|
+
width: 44
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
function NotificationComponent({
|
|
75
|
+
keyId: key,
|
|
76
|
+
notification = {},
|
|
77
|
+
viewAllUrl
|
|
78
|
+
}, ref) {
|
|
79
|
+
const classes = useStyles({
|
|
80
|
+
breakpoint: useWidth()
|
|
81
|
+
});
|
|
82
|
+
const combinedClassname = [classes.contentRoot, classes.lessPadding, classes[notification.severity]].join(' ');
|
|
83
|
+
const icon = variants[notification.severity];
|
|
84
|
+
const {
|
|
85
|
+
closeSnackbar
|
|
86
|
+
} = useSnackbar();
|
|
87
|
+
const onClickDismiss = () => closeSnackbar(key);
|
|
88
|
+
const navigate = useNavigate();
|
|
89
|
+
const onGoNotification = () => {
|
|
90
|
+
closeSnackbar(key);
|
|
91
|
+
navigate(viewAllUrl);
|
|
92
|
+
};
|
|
93
|
+
return /*#__PURE__*/_jsxs(SnackbarContent, {
|
|
94
|
+
ref: ref,
|
|
95
|
+
className: combinedClassname,
|
|
96
|
+
children: [/*#__PURE__*/_jsxs("div", {
|
|
97
|
+
className: classes.message,
|
|
98
|
+
children: [icon, /*#__PURE__*/_jsxs(Div, {
|
|
99
|
+
onClick: onGoNotification,
|
|
100
|
+
children: [/*#__PURE__*/_jsx("span", {
|
|
101
|
+
className: "title",
|
|
102
|
+
children: notification.title
|
|
103
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
104
|
+
className: "desc",
|
|
105
|
+
children: notification.description
|
|
106
|
+
})]
|
|
107
|
+
})]
|
|
108
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
109
|
+
className: classes.action,
|
|
110
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
111
|
+
"aria-label": "close",
|
|
112
|
+
color: "inherit",
|
|
113
|
+
onClick: onClickDismiss,
|
|
114
|
+
size: "large",
|
|
115
|
+
children: /*#__PURE__*/_jsx(CloseIcon, {
|
|
116
|
+
className: classes.icon
|
|
117
|
+
})
|
|
118
|
+
}, "close")
|
|
119
|
+
})]
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
export default /*#__PURE__*/forwardRef(NotificationComponent);
|
|
123
|
+
NotificationComponent.propTypes = {
|
|
124
|
+
viewAllUrl: PropTypes.string.isRequired,
|
|
125
|
+
keyId: PropTypes.number.isRequired,
|
|
126
|
+
notification: PropTypes.object.isRequired
|
|
127
|
+
};
|
|
128
|
+
const Div = styled.div`
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
display: flex;
|
|
131
|
+
flex-direction: column;
|
|
132
|
+
.title {
|
|
133
|
+
overflow: hidden;
|
|
134
|
+
text-overflow: ellipsis;
|
|
135
|
+
display: -webkit-box;
|
|
136
|
+
-webkit-line-clamp: 1;
|
|
137
|
+
-webkit-box-orient: vertical;
|
|
138
|
+
font-weight: bold;
|
|
139
|
+
}
|
|
140
|
+
.desc {
|
|
141
|
+
overflow: hidden;
|
|
142
|
+
text-overflow: ellipsis;
|
|
143
|
+
display: -webkit-box;
|
|
144
|
+
-webkit-line-clamp: 3;
|
|
145
|
+
-webkit-box-orient: vertical;
|
|
146
|
+
word-break: break-word;
|
|
147
|
+
}
|
|
148
|
+
`;
|