mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-25 18:26:05 +08:00
fix(server): add mode property on mention doc input (#10853)
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
|||||||
readNotification,
|
readNotification,
|
||||||
TestingApp,
|
TestingApp,
|
||||||
} from '../../../__tests__/utils';
|
} from '../../../__tests__/utils';
|
||||||
import { Models, NotificationType } from '../../../models';
|
import { DocMode, Models, NotificationType } from '../../../models';
|
||||||
import { MentionNotificationBodyType, NotificationObjectType } from '../types';
|
import { MentionNotificationBodyType, NotificationObjectType } from '../types';
|
||||||
|
|
||||||
let app: TestingApp;
|
let app: TestingApp;
|
||||||
@@ -50,6 +50,7 @@ test('should mention user in a doc', async t => {
|
|||||||
id: 'doc-id-1',
|
id: 'doc-id-1',
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
t.truthy(mentionId);
|
t.truthy(mentionId);
|
||||||
@@ -61,6 +62,7 @@ test('should mention user in a doc', async t => {
|
|||||||
id: 'doc-id-2',
|
id: 'doc-id-2',
|
||||||
title: 'doc-title-2',
|
title: 'doc-title-2',
|
||||||
elementId: 'element-id-2',
|
elementId: 'element-id-2',
|
||||||
|
mode: DocMode.edgeless,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,6 +84,7 @@ test('should mention user in a doc', async t => {
|
|||||||
t.is(body.doc.id, 'doc-id-1');
|
t.is(body.doc.id, 'doc-id-1');
|
||||||
t.is(body.doc.title, 'doc-title-1');
|
t.is(body.doc.title, 'doc-title-1');
|
||||||
t.is(body.doc.blockId, 'block-id-1');
|
t.is(body.doc.blockId, 'block-id-1');
|
||||||
|
t.is(body.doc.mode, DocMode.page);
|
||||||
t.is(body.createdByUser!.id, owner.id);
|
t.is(body.createdByUser!.id, owner.id);
|
||||||
t.is(body.createdByUser!.name, owner.name);
|
t.is(body.createdByUser!.name, owner.name);
|
||||||
t.is(body.workspace!.id, workspace.id);
|
t.is(body.workspace!.id, workspace.id);
|
||||||
@@ -97,12 +100,66 @@ test('should mention user in a doc', async t => {
|
|||||||
t.is(body2.doc.id, 'doc-id-2');
|
t.is(body2.doc.id, 'doc-id-2');
|
||||||
t.is(body2.doc.title, 'doc-title-2');
|
t.is(body2.doc.title, 'doc-title-2');
|
||||||
t.is(body2.doc.elementId, 'element-id-2');
|
t.is(body2.doc.elementId, 'element-id-2');
|
||||||
|
t.is(body2.doc.mode, DocMode.edgeless);
|
||||||
t.is(body2.createdByUser!.id, owner.id);
|
t.is(body2.createdByUser!.id, owner.id);
|
||||||
t.is(body2.workspace!.id, workspace.id);
|
t.is(body2.workspace!.id, workspace.id);
|
||||||
t.is(body2.workspace!.name, 'test-workspace-name');
|
t.is(body2.workspace!.name, 'test-workspace-name');
|
||||||
t.truthy(body2.workspace!.avatarUrl);
|
t.truthy(body2.workspace!.avatarUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should mention doc mode support string value', async t => {
|
||||||
|
const member = await app.signup();
|
||||||
|
const owner = await app.signup();
|
||||||
|
|
||||||
|
await app.switchUser(owner);
|
||||||
|
const workspace = await createWorkspace(app);
|
||||||
|
await models.workspace.update(workspace.id, {
|
||||||
|
name: 'test-workspace-name',
|
||||||
|
avatarKey: 'test-avatar-key',
|
||||||
|
});
|
||||||
|
const inviteId = await inviteUser(app, workspace.id, member.email);
|
||||||
|
await app.switchUser(member);
|
||||||
|
await acceptInviteById(app, workspace.id, inviteId);
|
||||||
|
|
||||||
|
await app.switchUser(owner);
|
||||||
|
const mentionId = await mentionUser(app, {
|
||||||
|
userId: member.id,
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
doc: {
|
||||||
|
id: 'doc-id-1',
|
||||||
|
title: 'doc-title-1',
|
||||||
|
blockId: 'block-id-1',
|
||||||
|
mode: 'page' as DocMode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
t.truthy(mentionId);
|
||||||
|
|
||||||
|
await app.switchUser(member);
|
||||||
|
const result = await listNotifications(app, {
|
||||||
|
first: 10,
|
||||||
|
offset: 0,
|
||||||
|
});
|
||||||
|
t.is(result.totalCount, 1);
|
||||||
|
const notifications = result.edges.map(edge => edge.node);
|
||||||
|
t.is(notifications.length, 1);
|
||||||
|
|
||||||
|
const notification = notifications[0] as NotificationObjectType;
|
||||||
|
t.is(notification.read, false);
|
||||||
|
t.truthy(notification.createdAt);
|
||||||
|
t.truthy(notification.updatedAt);
|
||||||
|
const body = notification.body as MentionNotificationBodyType;
|
||||||
|
t.is(body.workspace!.id, workspace.id);
|
||||||
|
t.is(body.doc.id, 'doc-id-1');
|
||||||
|
t.is(body.doc.title, 'doc-title-1');
|
||||||
|
t.is(body.doc.blockId, 'block-id-1');
|
||||||
|
t.is(body.doc.mode, DocMode.page);
|
||||||
|
t.is(body.createdByUser!.id, owner.id);
|
||||||
|
t.is(body.createdByUser!.name, owner.name);
|
||||||
|
t.is(body.workspace!.id, workspace.id);
|
||||||
|
t.is(body.workspace!.name, 'test-workspace-name');
|
||||||
|
t.truthy(body.workspace!.avatarUrl);
|
||||||
|
});
|
||||||
|
|
||||||
test('should throw error when mention user has no Doc.Read role', async t => {
|
test('should throw error when mention user has no Doc.Read role', async t => {
|
||||||
const member = await app.signup();
|
const member = await app.signup();
|
||||||
const owner = await app.signup();
|
const owner = await app.signup();
|
||||||
@@ -120,6 +177,7 @@ test('should throw error when mention user has no Doc.Read role', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@@ -141,6 +199,7 @@ test('should throw error when mention a not exists user', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@@ -161,6 +220,7 @@ test('should not mention user oneself', async t => {
|
|||||||
id: 'doc-id-1',
|
id: 'doc-id-1',
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@@ -187,6 +247,7 @@ test('should mark notification as read', async t => {
|
|||||||
id: 'doc-id-1',
|
id: 'doc-id-1',
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
t.truthy(mentionId);
|
t.truthy(mentionId);
|
||||||
@@ -229,6 +290,7 @@ test('should throw error when read the other user notification', async t => {
|
|||||||
id: 'doc-id-1',
|
id: 'doc-id-1',
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
t.truthy(mentionId);
|
t.truthy(mentionId);
|
||||||
@@ -252,7 +314,7 @@ test('should throw error when read the other user notification', async t => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.skip('should throw error when mention call with invalid params', async t => {
|
test('should throw error when mention call with invalid params', async t => {
|
||||||
const owner = await app.signup();
|
const owner = await app.signup();
|
||||||
await app.switchUser(owner);
|
await app.switchUser(owner);
|
||||||
await t.throwsAsync(
|
await t.throwsAsync(
|
||||||
@@ -261,12 +323,34 @@ test.skip('should throw error when mention call with invalid params', async t =>
|
|||||||
workspaceId: '',
|
workspaceId: '',
|
||||||
doc: {
|
doc: {
|
||||||
id: '',
|
id: '',
|
||||||
title: '',
|
title: 'doc-title-1'.repeat(100),
|
||||||
blockId: '',
|
blockId: '',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
message: 'Mention user not found.',
|
message: /Validation error/,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw error when mention mode value is invalid', async t => {
|
||||||
|
const owner = await app.signup();
|
||||||
|
await app.switchUser(owner);
|
||||||
|
await t.throwsAsync(
|
||||||
|
mentionUser(app, {
|
||||||
|
userId: randomUUID(),
|
||||||
|
workspaceId: randomUUID(),
|
||||||
|
doc: {
|
||||||
|
id: randomUUID(),
|
||||||
|
title: 'doc-title-1',
|
||||||
|
blockId: 'block-id-1',
|
||||||
|
mode: 'invalid-mode' as DocMode,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
'Variable "$input" got invalid value "invalid-mode" at "input.doc.mode"; Value "invalid-mode" does not exist in "DocMode" enum.',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -311,6 +395,7 @@ test('should list and count notifications', async t => {
|
|||||||
id: 'doc-id-1',
|
id: 'doc-id-1',
|
||||||
title: 'doc-title-1',
|
title: 'doc-title-1',
|
||||||
blockId: 'block-id-1',
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await mentionUser(app, {
|
await mentionUser(app, {
|
||||||
@@ -320,6 +405,7 @@ test('should list and count notifications', async t => {
|
|||||||
id: 'doc-id-2',
|
id: 'doc-id-2',
|
||||||
title: 'doc-title-2',
|
title: 'doc-title-2',
|
||||||
blockId: 'block-id-2',
|
blockId: 'block-id-2',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await mentionUser(app, {
|
await mentionUser(app, {
|
||||||
@@ -329,6 +415,7 @@ test('should list and count notifications', async t => {
|
|||||||
id: 'doc-id-3',
|
id: 'doc-id-3',
|
||||||
title: 'doc-title-3',
|
title: 'doc-title-3',
|
||||||
blockId: 'block-id-3',
|
blockId: 'block-id-3',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// mention user in another workspace
|
// mention user in another workspace
|
||||||
@@ -339,6 +426,7 @@ test('should list and count notifications', async t => {
|
|||||||
id: 'doc-id-4',
|
id: 'doc-id-4',
|
||||||
title: 'doc-title-4',
|
title: 'doc-title-4',
|
||||||
blockId: 'block-id-4',
|
blockId: 'block-id-4',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -469,6 +557,7 @@ test('should list and count notifications', async t => {
|
|||||||
id: 'doc-id-5',
|
id: 'doc-id-5',
|
||||||
title: 'doc-title-5',
|
title: 'doc-title-5',
|
||||||
blockId: 'block-id-5',
|
blockId: 'block-id-5',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from '../../../__tests__/utils';
|
} from '../../../__tests__/utils';
|
||||||
import { NotificationNotFound } from '../../../base';
|
import { NotificationNotFound } from '../../../base';
|
||||||
import {
|
import {
|
||||||
|
DocMode,
|
||||||
MentionNotificationBody,
|
MentionNotificationBody,
|
||||||
Models,
|
Models,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
@@ -239,7 +240,12 @@ test('should use latest doc title in mention notification', async t => {
|
|||||||
body: {
|
body: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
createdByUserId: owner.id,
|
createdByUserId: owner.id,
|
||||||
doc: { id: docId, title: 'doc-title-1', blockId: 'block-id-1' },
|
doc: {
|
||||||
|
id: docId,
|
||||||
|
title: 'doc-title-1',
|
||||||
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const mentionNotification = await notificationService.createMention({
|
const mentionNotification = await notificationService.createMention({
|
||||||
@@ -247,7 +253,12 @@ test('should use latest doc title in mention notification', async t => {
|
|||||||
body: {
|
body: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
createdByUserId: owner.id,
|
createdByUserId: owner.id,
|
||||||
doc: { id: docId, title: 'doc-title-2', blockId: 'block-id-2' },
|
doc: {
|
||||||
|
id: docId,
|
||||||
|
title: 'doc-title-2',
|
||||||
|
blockId: 'block-id-2',
|
||||||
|
mode: DocMode.page,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
t.truthy(mentionNotification);
|
t.truthy(mentionNotification);
|
||||||
@@ -268,6 +279,7 @@ test('should use latest doc title in mention notification', async t => {
|
|||||||
t.is(mention.body.type, NotificationType.Mention);
|
t.is(mention.body.type, NotificationType.Mention);
|
||||||
const body = mention.body as MentionNotificationBody;
|
const body = mention.body as MentionNotificationBody;
|
||||||
t.is(body.doc.title, 'doc-title-2-updated');
|
t.is(body.doc.title, 'doc-title-2-updated');
|
||||||
|
t.is(body.doc.mode, DocMode.page);
|
||||||
|
|
||||||
const mention2 = notifications[1];
|
const mention2 = notifications[1];
|
||||||
t.is(mention2.body.workspace!.id, workspace.id);
|
t.is(mention2.body.workspace!.id, workspace.id);
|
||||||
@@ -276,6 +288,7 @@ test('should use latest doc title in mention notification', async t => {
|
|||||||
t.is(mention2.body.type, NotificationType.Mention);
|
t.is(mention2.body.type, NotificationType.Mention);
|
||||||
const body2 = mention2.body as MentionNotificationBody;
|
const body2 = mention2.body as MentionNotificationBody;
|
||||||
t.is(body2.doc.title, 'doc-title-1-updated');
|
t.is(body2.doc.title, 'doc-title-1-updated');
|
||||||
|
t.is(body2.doc.mode, DocMode.page);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should raw doc title in mention notification if no doc found', async t => {
|
test('should raw doc title in mention notification if no doc found', async t => {
|
||||||
@@ -286,7 +299,12 @@ test('should raw doc title in mention notification if no doc found', async t =>
|
|||||||
body: {
|
body: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
createdByUserId: owner.id,
|
createdByUserId: owner.id,
|
||||||
doc: { id: docId, title: 'doc-title-1', blockId: 'block-id-1' },
|
doc: {
|
||||||
|
id: docId,
|
||||||
|
title: 'doc-title-1',
|
||||||
|
blockId: 'block-id-1',
|
||||||
|
mode: DocMode.page,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await notificationService.createMention({
|
await notificationService.createMention({
|
||||||
@@ -294,7 +312,12 @@ test('should raw doc title in mention notification if no doc found', async t =>
|
|||||||
body: {
|
body: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
createdByUserId: owner.id,
|
createdByUserId: owner.id,
|
||||||
doc: { id: docId, title: 'doc-title-2', blockId: 'block-id-2' },
|
doc: {
|
||||||
|
id: docId,
|
||||||
|
title: 'doc-title-2',
|
||||||
|
blockId: 'block-id-2',
|
||||||
|
mode: DocMode.edgeless,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
mock.method(models.doc, 'findMetas', async () => [null, null]);
|
mock.method(models.doc, 'findMetas', async () => [null, null]);
|
||||||
@@ -305,10 +328,12 @@ test('should raw doc title in mention notification if no doc found', async t =>
|
|||||||
t.is(mention.body.type, NotificationType.Mention);
|
t.is(mention.body.type, NotificationType.Mention);
|
||||||
const body = mention.body as MentionNotificationBody;
|
const body = mention.body as MentionNotificationBody;
|
||||||
t.is(body.doc.title, 'doc-title-2');
|
t.is(body.doc.title, 'doc-title-2');
|
||||||
|
t.is(body.doc.mode, DocMode.edgeless);
|
||||||
|
|
||||||
const mention2 = notifications[1];
|
const mention2 = notifications[1];
|
||||||
t.is(mention2.body.workspace!.name, 'Test Workspace');
|
t.is(mention2.body.workspace!.name, 'Test Workspace');
|
||||||
t.is(mention2.body.type, NotificationType.Mention);
|
t.is(mention2.body.type, NotificationType.Mention);
|
||||||
const body2 = mention2.body as MentionNotificationBody;
|
const body2 = mention2.body as MentionNotificationBody;
|
||||||
t.is(body2.doc.title, 'doc-title-1');
|
t.is(body2.doc.title, 'doc-title-1');
|
||||||
|
t.is(body2.doc.mode, DocMode.page);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ import { GraphQLJSONObject } from 'graphql-scalars';
|
|||||||
|
|
||||||
import { Paginated } from '../../base';
|
import { Paginated } from '../../base';
|
||||||
import {
|
import {
|
||||||
|
DocMode,
|
||||||
InvitationNotificationBody,
|
InvitationNotificationBody,
|
||||||
|
MentionDoc,
|
||||||
|
MentionDocCreate,
|
||||||
Notification,
|
Notification,
|
||||||
NotificationLevel,
|
NotificationLevel,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
@@ -28,6 +31,11 @@ registerEnumType(NotificationType, {
|
|||||||
description: 'Notification type',
|
description: 'Notification type',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerEnumType(DocMode, {
|
||||||
|
name: 'DocMode',
|
||||||
|
description: 'Doc mode',
|
||||||
|
});
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class NotificationWorkspaceType implements WorkspaceDocInfo {
|
export class NotificationWorkspaceType implements WorkspaceDocInfo {
|
||||||
@Field(() => ID)
|
@Field(() => ID)
|
||||||
@@ -64,13 +72,16 @@ export abstract class BaseNotificationBodyType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class MentionDocType {
|
export class MentionDocType implements MentionDoc {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
|
@Field(() => DocMode)
|
||||||
|
mode!: DocMode;
|
||||||
|
|
||||||
@Field(() => String, {
|
@Field(() => String, {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
@@ -163,13 +174,16 @@ export class PaginatedNotificationObjectType extends Paginated(
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@InputType()
|
@InputType()
|
||||||
export class MentionDocInput {
|
export class MentionDocInput implements MentionDocCreate {
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
id!: string;
|
id!: string;
|
||||||
|
|
||||||
@Field(() => String)
|
@Field(() => String)
|
||||||
title!: string;
|
title!: string;
|
||||||
|
|
||||||
|
@Field(() => DocMode)
|
||||||
|
mode!: DocMode;
|
||||||
|
|
||||||
@Field(() => String, {
|
@Field(() => String, {
|
||||||
description: 'The block id in the doc',
|
description: 'The block id in the doc',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
DocNotFound,
|
DocNotFound,
|
||||||
InvalidHistoryTimestamp,
|
InvalidHistoryTimestamp,
|
||||||
} from '../../base';
|
} from '../../base';
|
||||||
import { Models, PublicDocMode } from '../../models';
|
import { DocMode, Models, PublicDocMode } from '../../models';
|
||||||
import { CurrentUser, Public } from '../auth';
|
import { CurrentUser, Public } from '../auth';
|
||||||
import { PgWorkspaceDocStorageAdapter } from '../doc';
|
import { PgWorkspaceDocStorageAdapter } from '../doc';
|
||||||
import { DocReader } from '../doc/reader';
|
import { DocReader } from '../doc/reader';
|
||||||
@@ -111,7 +111,9 @@ export class WorkspacesController {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const publishPageMode =
|
const publishPageMode =
|
||||||
docMeta?.mode === PublicDocMode.Edgeless ? 'edgeless' : 'page';
|
docMeta?.mode === PublicDocMode.Edgeless
|
||||||
|
? DocMode.edgeless
|
||||||
|
: DocMode.page;
|
||||||
|
|
||||||
res.setHeader('publish-mode', publishPageMode);
|
res.setHeader('publish-mode', publishPageMode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import ava, { TestFn } from 'ava';
|
|||||||
import { createTestingModule, type TestingModule } from '../../__tests__/utils';
|
import { createTestingModule, type TestingModule } from '../../__tests__/utils';
|
||||||
import { Config } from '../../base/config';
|
import { Config } from '../../base/config';
|
||||||
import {
|
import {
|
||||||
|
DocMode,
|
||||||
Models,
|
Models,
|
||||||
NotificationLevel,
|
NotificationLevel,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
User,
|
User,
|
||||||
Workspace,
|
Workspace,
|
||||||
} from '../../models';
|
} from '../../models';
|
||||||
|
|
||||||
interface Context {
|
interface Context {
|
||||||
config: Config;
|
config: Config;
|
||||||
module: TestingModule;
|
module: TestingModule;
|
||||||
@@ -71,6 +71,7 @@ test('should create a mention notification with default level', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -94,6 +95,7 @@ test('should create a mention notification with custom level', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
elementId: 'elementId',
|
elementId: 'elementId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -118,6 +120,7 @@ test('should mark a mention notification as read', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -174,6 +177,7 @@ test('should find many notifications by user id, order by createdAt descending',
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -204,6 +208,7 @@ test('should find many notifications by user id, filter read notifications', asy
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -234,6 +239,7 @@ test('should clean expired notifications', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -270,6 +276,7 @@ test('should not clean unexpired notifications', async t => {
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -290,6 +297,7 @@ test('should find many notifications by user id, order by createdAt descending,
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.edgeless,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -357,6 +365,7 @@ test('should count notifications by user id, exclude read notifications', async
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
@@ -385,6 +394,7 @@ test('should count notifications by user id, include read notifications', async
|
|||||||
id: docId,
|
id: docId,
|
||||||
title: 'doc-title',
|
title: 'doc-title',
|
||||||
blockId: 'blockId',
|
blockId: 'blockId',
|
||||||
|
mode: DocMode.page,
|
||||||
},
|
},
|
||||||
createdByUserId: createdBy.id,
|
createdByUserId: createdBy.id,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,13 @@ export interface Doc {
|
|||||||
|
|
||||||
export type DocEditor = Pick<User, 'id' | 'name' | 'avatarUrl'>;
|
export type DocEditor = Pick<User, 'id' | 'name' | 'avatarUrl'>;
|
||||||
|
|
||||||
|
// TODO(@fengmk2): only used it inside the DocModel, use DocMode instead on the other places
|
||||||
export enum PublicDocMode {
|
export enum PublicDocMode {
|
||||||
Page,
|
Page,
|
||||||
Edgeless,
|
Edgeless,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum DocMode {
|
||||||
|
page = 'page',
|
||||||
|
edgeless = 'edgeless',
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { PaginationInput } from '../base';
|
import { PaginationInput } from '../base';
|
||||||
import { BaseModel } from './base';
|
import { BaseModel } from './base';
|
||||||
|
import { DocMode } from './common';
|
||||||
|
|
||||||
export { NotificationLevel, NotificationType };
|
export { NotificationLevel, NotificationType };
|
||||||
export type { Notification };
|
export type { Notification };
|
||||||
@@ -30,11 +31,15 @@ export const MentionDocSchema = z.object({
|
|||||||
id: IdSchema,
|
id: IdSchema,
|
||||||
// Allow empty string, will display as `Untitled` at frontend
|
// Allow empty string, will display as `Untitled` at frontend
|
||||||
title: z.string().trim().max(255),
|
title: z.string().trim().max(255),
|
||||||
|
mode: z.nativeEnum(DocMode),
|
||||||
// blockId or elementId is required at least one
|
// blockId or elementId is required at least one
|
||||||
blockId: IdSchema.optional(),
|
blockId: IdSchema.optional(),
|
||||||
elementId: IdSchema.optional(),
|
elementId: IdSchema.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export type MentionDoc = z.infer<typeof MentionDocSchema>;
|
||||||
|
export type MentionDocCreate = z.input<typeof MentionDocSchema>;
|
||||||
|
|
||||||
const MentionNotificationBodySchema = z.object({
|
const MentionNotificationBodySchema = z.object({
|
||||||
workspaceId: IdSchema,
|
workspaceId: IdSchema,
|
||||||
createdByUserId: IdSchema,
|
createdByUserId: IdSchema,
|
||||||
|
|||||||
@@ -300,6 +300,12 @@ type DocHistoryType {
|
|||||||
workspaceId: String!
|
workspaceId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"""Doc mode"""
|
||||||
|
enum DocMode {
|
||||||
|
edgeless
|
||||||
|
page
|
||||||
|
}
|
||||||
|
|
||||||
type DocNotFoundDataType {
|
type DocNotFoundDataType {
|
||||||
docId: String!
|
docId: String!
|
||||||
spaceId: String!
|
spaceId: String!
|
||||||
@@ -755,6 +761,7 @@ input MentionDocInput {
|
|||||||
"""The element id in the doc"""
|
"""The element id in the doc"""
|
||||||
elementId: String
|
elementId: String
|
||||||
id: String!
|
id: String!
|
||||||
|
mode: DocMode!
|
||||||
title: String!
|
title: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,6 +769,7 @@ type MentionDocType {
|
|||||||
blockId: String
|
blockId: String
|
||||||
elementId: String
|
elementId: String
|
||||||
id: String!
|
id: String!
|
||||||
|
mode: DocMode!
|
||||||
title: String!
|
title: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -385,6 +385,12 @@ export interface DocHistoryType {
|
|||||||
workspaceId: Scalars['String']['output'];
|
workspaceId: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Doc mode */
|
||||||
|
export enum DocMode {
|
||||||
|
edgeless = 'edgeless',
|
||||||
|
page = 'page',
|
||||||
|
}
|
||||||
|
|
||||||
export interface DocNotFoundDataType {
|
export interface DocNotFoundDataType {
|
||||||
__typename?: 'DocNotFoundDataType';
|
__typename?: 'DocNotFoundDataType';
|
||||||
docId: Scalars['String']['output'];
|
docId: Scalars['String']['output'];
|
||||||
@@ -889,6 +895,7 @@ export interface MentionDocInput {
|
|||||||
/** The element id in the doc */
|
/** The element id in the doc */
|
||||||
elementId?: InputMaybe<Scalars['String']['input']>;
|
elementId?: InputMaybe<Scalars['String']['input']>;
|
||||||
id: Scalars['String']['input'];
|
id: Scalars['String']['input'];
|
||||||
|
mode: DocMode;
|
||||||
title: Scalars['String']['input'];
|
title: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,6 +904,7 @@ export interface MentionDocType {
|
|||||||
blockId: Maybe<Scalars['String']['output']>;
|
blockId: Maybe<Scalars['String']['output']>;
|
||||||
elementId: Maybe<Scalars['String']['output']>;
|
elementId: Maybe<Scalars['String']['output']>;
|
||||||
id: Scalars['String']['output'];
|
id: Scalars['String']['output'];
|
||||||
|
mode: DocMode;
|
||||||
title: Scalars['String']['output'];
|
title: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user