diff --git a/packages/frontend/core/src/components/notification/list.tsx b/packages/frontend/core/src/components/notification/list.tsx
index 7d06ad007..bfbb38f2d 100644
--- a/packages/frontend/core/src/components/notification/list.tsx
+++ b/packages/frontend/core/src/components/notification/list.tsx
@@ -18,6 +18,9 @@ import type {
InvitationAcceptedNotificationBodyType,
InvitationBlockedNotificationBodyType,
InvitationNotificationBodyType,
+ InvitationReviewApprovedNotificationBodyType,
+ InvitationReviewDeclinedNotificationBodyType,
+ InvitationReviewRequestNotificationBodyType,
MentionNotificationBodyType,
} from '@affine/graphql';
import { i18nTime, Trans, useI18n } from '@affine/i18n';
@@ -118,6 +121,12 @@ const NotificationItem = ({ notification }: { notification: Notification }) => {
) : type === NotificationType.InvitationBlocked ? (
+ ) : type === NotificationType.InvitationReviewRequest ? (
+
+ ) : type === NotificationType.InvitationReviewDeclined ? (
+
+ ) : type === NotificationType.InvitationReviewApproved ? (
+
) : (
@@ -194,6 +203,189 @@ const MentionNotificationItem = ({
);
};
+const InvitationReviewRequestNotificationItem = ({
+ notification,
+}: {
+ notification: Notification;
+}) => {
+ const notificationListService = useService(NotificationListService);
+ const { jumpToWorkspaceSettings } = useNavigateHelper();
+ const t = useI18n();
+ const body = notification.body as InvitationReviewRequestNotificationBodyType;
+ const memberInactived = !body.createdByUser;
+ const workspaceInactived = !body.workspace;
+ const handleClick = useCallback(() => {
+ notificationListService.readNotification(notification.id).catch(err => {
+ console.error(err);
+ });
+ if (!body.workspace?.id) {
+ return;
+ }
+ jumpToWorkspaceSettings(body.workspace.id, 'workspace:members');
+ }, [body, jumpToWorkspaceSettings, notification, notificationListService]);
+
+ return (
+
+
+
+
+
+ ),
+ 2: ,
+ }}
+ values={{
+ username:
+ body.createdByUser?.name ?? t['com.affine.inactive-member'](),
+ workspaceName:
+ body.workspace?.name ?? t['com.affine.inactive-workspace'](),
+ }}
+ />
+
+
+ {i18nTime(notification.createdAt, {
+ relative: true,
+ })}
+
+
+
+
+ );
+};
+
+const InvitationReviewDeclinedNotificationItem = ({
+ notification,
+}: {
+ notification: Notification;
+}) => {
+ const t = useI18n();
+ const body =
+ notification.body as InvitationReviewDeclinedNotificationBodyType;
+ const memberInactived = !body.createdByUser;
+ const workspaceInactived = !body.workspace;
+
+ return (
+
+
+
+
+
+ ),
+ 2: ,
+ }}
+ values={{
+ username:
+ body.createdByUser?.name ?? t['com.affine.inactive-member'](),
+ workspaceName:
+ body.workspace?.name ?? t['com.affine.inactive-workspace'](),
+ }}
+ />
+
+
+ {i18nTime(notification.createdAt, {
+ relative: true,
+ })}
+
+
+
+
+ );
+};
+
+const InvitationReviewApprovedNotificationItem = ({
+ notification,
+}: {
+ notification: Notification;
+}) => {
+ const notificationListService = useService(NotificationListService);
+ const { jumpToPage } = useNavigateHelper();
+ const t = useI18n();
+ const body =
+ notification.body as InvitationReviewApprovedNotificationBodyType;
+ const memberInactived = !body.createdByUser;
+ const workspaceInactived = !body.workspace;
+
+ const handleClick = useCallback(() => {
+ notificationListService.readNotification(notification.id).catch(err => {
+ console.error(err);
+ });
+ if (!body.workspace?.id) {
+ return;
+ }
+ jumpToPage(body.workspace.id, 'all');
+ }, [body, jumpToPage, notification, notificationListService]);
+
+ return (
+
+
+
+
+
+ ),
+ 2: ,
+ }}
+ values={{
+ username:
+ body.createdByUser?.name ?? t['com.affine.inactive-member'](),
+ workspaceName:
+ body.workspace?.name ?? t['com.affine.inactive-workspace'](),
+ }}
+ />
+
+ {!workspaceInactived && (
+
+ )}
+
+ {i18nTime(notification.createdAt, {
+ relative: true,
+ })}
+
+
+
+
+ );
+};
+
const InvitationAcceptedNotificationItem = ({
notification,
}: {
@@ -320,21 +512,6 @@ const InvitationNotificationItem = ({
const [isAccepting, setIsAccepting] = useState(false);
const { jumpToPage } = useNavigateHelper();
- const WorkspaceNameWithIcon = useCallback(
- ({
- children,
- ...props
- }: React.PropsWithChildren
>) => {
- return (
-
-
- {children}
-
- );
- },
- []
- );
-
const handleReadAndOpenWorkspace = useCallback(() => {
notificationListService.readNotification(notification.id).catch(err => {
console.error(err);
@@ -473,3 +650,15 @@ const DeleteButton = ({
/>
);
};
+
+const WorkspaceNameWithIcon = ({
+ children,
+ ...props
+}: React.PropsWithChildren>) => {
+ return (
+
+
+ {children}
+
+ );
+};
diff --git a/packages/frontend/i18n/src/i18n-completenesses.json b/packages/frontend/i18n/src/i18n-completenesses.json
index b6b479bcd..b0ad28913 100644
--- a/packages/frontend/i18n/src/i18n-completenesses.json
+++ b/packages/frontend/i18n/src/i18n-completenesses.json
@@ -1,26 +1,26 @@
{
- "ar": 94,
+ "ar": 93,
"ca": 4,
"da": 4,
- "de": 94,
- "el-GR": 94,
+ "de": 93,
+ "el-GR": 93,
"en": 100,
- "es-AR": 94,
+ "es-AR": 93,
"es-CL": 95,
- "es": 94,
- "fa": 94,
- "fr": 94,
+ "es": 93,
+ "fa": 93,
+ "fr": 93,
"hi": 2,
- "it-IT": 94,
+ "it-IT": 93,
"it": 1,
- "ja": 94,
+ "ja": 93,
"ko": 59,
- "pl": 94,
- "pt-BR": 94,
- "ru": 94,
- "sv-SE": 94,
- "uk": 94,
+ "pl": 93,
+ "pt-BR": 93,
+ "ru": 93,
+ "sv-SE": 93,
+ "uk": 93,
"ur": 2,
- "zh-Hans": 94,
- "zh-Hant": 94
+ "zh-Hans": 93,
+ "zh-Hant": 93
}
diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts
index 7697ab33f..c58f82531 100644
--- a/packages/frontend/i18n/src/i18n.gen.ts
+++ b/packages/frontend/i18n/src/i18n.gen.ts
@@ -7107,6 +7107,14 @@ export function useAFFiNEI18N(): {
* `No new notifications`
*/
["com.affine.notification.empty"](): string;
+ /**
+ * `Open workspace`
+ */
+ ["com.affine.notification.invitation-review-approved.open-workspace"](): string;
+ /**
+ * `Accept & Join`
+ */
+ ["com.affine.notification.invitation.accept"](): string;
/**
* `Tips`
*/
@@ -8474,6 +8482,62 @@ export const TypedTrans: {
["1"]: JSX.Element;
["2"]: JSX.Element;
}>>;
+ /**
+ * `<1>{{username}}1> has accept your invitation`
+ */
+ ["com.affine.notification.invitation-accepted"]: ComponentType>;
+ /**
+ * `<1>{{username}}1> has requested to join <2>{{workspaceName}}2>`
+ */
+ ["com.affine.notification.invitation-review-request"]: ComponentType, {
+ ["1"]: JSX.Element;
+ ["2"]: JSX.Element;
+ }>>;
+ /**
+ * `<1>{{username}}1> has declined your request to join <2>{{workspaceName}}2>`
+ */
+ ["com.affine.notification.invitation-review-declined"]: ComponentType, {
+ ["1"]: JSX.Element;
+ ["2"]: JSX.Element;
+ }>>;
+ /**
+ * `<1>{{username}}1> has approved your request to join <2>{{workspaceName}}2>`
+ */
+ ["com.affine.notification.invitation-review-approved"]: ComponentType, {
+ ["1"]: JSX.Element;
+ ["2"]: JSX.Element;
+ }>>;
+ /**
+ * `There is an issue regarding your invitation to <1>{{workspaceName}}1> `
+ */
+ ["com.affine.notification.invitation-blocked"]: ComponentType>;
+ /**
+ * `<1>{{username}}1> invited you to join <2>{{workspaceName}}2>`
+ */
+ ["com.affine.notification.invitation"]: ComponentType, {
+ ["1"]: JSX.Element;
+ ["2"]: JSX.Element;
+ }>>;
/**
* `Unable to join <1/> <2>{{workspaceName}}2> due to insufficient seats available.`
*/
diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json
index bb493a2d4..e2f7a0588 100644
--- a/packages/frontend/i18n/src/resources/en.json
+++ b/packages/frontend/i18n/src/resources/en.json
@@ -1767,6 +1767,14 @@
"com.affine.notification.unsupported": "Unsupported message",
"com.affine.notification.mention": "<1>{{username}}1> mentioned you in <2>{{docTitle}}2>",
"com.affine.notification.empty": "No new notifications",
+ "com.affine.notification.invitation-accepted": "<1>{{username}}1> has accept your invitation",
+ "com.affine.notification.invitation-review-request": "<1>{{username}}1> has requested to join <2>{{workspaceName}}2>",
+ "com.affine.notification.invitation-review-declined": "<1>{{username}}1> has declined your request to join <2>{{workspaceName}}2>",
+ "com.affine.notification.invitation-review-approved": "<1>{{username}}1> has approved your request to join <2>{{workspaceName}}2>",
+ "com.affine.notification.invitation-review-approved.open-workspace": "Open workspace",
+ "com.affine.notification.invitation-blocked": "There is an issue regarding your invitation to <1>{{workspaceName}}1> ",
+ "com.affine.notification.invitation": "<1>{{username}}1> invited you to join <2>{{workspaceName}}2>",
+ "com.affine.notification.invitation.accept": "Accept & Join",
"tips": "Tips",
"Template": "Template",
"com.affine.template-list.delete": "Delete Template",