mirror of
https://github.com/docmost/docmost.git
synced 2026-05-20 08:34:04 +08:00
feat: notifications (#1947)
* feat: notifications * feat: watchers * improvements * handle page move for watchers * make watchers non-blocking * more
This commit is contained in:
@@ -5,11 +5,12 @@ import { PageHistoryService } from './services/page-history.service';
|
||||
import { TrashCleanupService } from './services/trash-cleanup.service';
|
||||
import { StorageModule } from '../../integrations/storage/storage.module';
|
||||
import { CollaborationModule } from '../../collaboration/collaboration.module';
|
||||
import { WatcherModule } from '../watcher/watcher.module';
|
||||
|
||||
@Module({
|
||||
controllers: [PageController],
|
||||
providers: [PageService, PageHistoryService, TrashCleanupService],
|
||||
exports: [PageService, PageHistoryService],
|
||||
imports: [StorageModule, CollaborationModule],
|
||||
imports: [StorageModule, CollaborationModule, WatcherModule],
|
||||
})
|
||||
export class PageModule {}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { KyselyDB } from '@docmost/db/types/kysely.types';
|
||||
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
|
||||
import { MovePageDto } from '../dto/move-page.dto';
|
||||
import { generateSlugId } from '../../../common/helpers';
|
||||
import { getPageTitle } from '../../../common/helpers';
|
||||
import { executeTx } from '@docmost/db/utils';
|
||||
import { AttachmentRepo } from '@docmost/db/repos/attachment/attachment.repo';
|
||||
import { v7 as uuid7 } from 'uuid';
|
||||
@@ -46,6 +47,7 @@ import { EventName } from '../../../common/events/event.contants';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { CollaborationGateway } from '../../../collaboration/collaboration.gateway';
|
||||
import { markdownToHtml } from '@docmost/editor-ext';
|
||||
import { WatcherService } from '../../watcher/watcher.service';
|
||||
|
||||
@Injectable()
|
||||
export class PageService {
|
||||
@@ -58,8 +60,10 @@ export class PageService {
|
||||
private readonly storageService: StorageService,
|
||||
@InjectQueue(QueueName.ATTACHMENT_QUEUE) private attachmentQueue: Queue,
|
||||
@InjectQueue(QueueName.AI_QUEUE) private aiQueue: Queue,
|
||||
@InjectQueue(QueueName.GENERAL_QUEUE) private generalQueue: Queue,
|
||||
private eventEmitter: EventEmitter2,
|
||||
private collaborationGateway: CollaborationGateway,
|
||||
private readonly watcherService: WatcherService,
|
||||
) {}
|
||||
|
||||
async findById(
|
||||
@@ -110,7 +114,7 @@ export class PageService {
|
||||
ydoc = createYdocFromJson(prosemirrorJson);
|
||||
}
|
||||
|
||||
return this.pageRepo.insertPage({
|
||||
const page = await this.pageRepo.insertPage({
|
||||
slugId: generateSlugId(),
|
||||
title: createPageDto.title,
|
||||
position: await this.nextPagePosition(
|
||||
@@ -127,6 +131,19 @@ export class PageService {
|
||||
textContent,
|
||||
ydoc,
|
||||
});
|
||||
|
||||
this.generalQueue
|
||||
.add(QueueJob.ADD_PAGE_WATCHERS, {
|
||||
userIds: [userId],
|
||||
pageId: page.id,
|
||||
spaceId: createPageDto.spaceId,
|
||||
workspaceId,
|
||||
})
|
||||
.catch((err) =>
|
||||
this.logger.warn(`Failed to queue add-page-watchers: ${err.message}`),
|
||||
);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
async nextPagePosition(spaceId: string, parentPageId?: string) {
|
||||
@@ -190,6 +207,17 @@ export class PageService {
|
||||
page.id,
|
||||
);
|
||||
|
||||
this.generalQueue
|
||||
.add(QueueJob.ADD_PAGE_WATCHERS, {
|
||||
userIds: [user.id],
|
||||
pageId: page.id,
|
||||
spaceId: page.spaceId,
|
||||
workspaceId: page.workspaceId,
|
||||
})
|
||||
.catch((err) =>
|
||||
this.logger.warn(`Failed to queue add-page-watchers: ${err.message}`),
|
||||
);
|
||||
|
||||
if (
|
||||
updatePageDto.content &&
|
||||
updatePageDto.operation &&
|
||||
@@ -321,6 +349,11 @@ export class PageService {
|
||||
trx,
|
||||
);
|
||||
|
||||
// Update watchers and remove those without access to new space
|
||||
await this.watcherService.movePageWatchersToSpace(pageIds, spaceId, {
|
||||
trx,
|
||||
});
|
||||
|
||||
await this.aiQueue.add(QueueJob.PAGE_MOVED_TO_SPACE, {
|
||||
pageId: pageIds,
|
||||
workspaceId: rootPage.workspaceId,
|
||||
@@ -434,7 +467,7 @@ export class PageService {
|
||||
// Add "Copy of " prefix to the root page title only for duplicates in same space
|
||||
let title = page.title;
|
||||
if (isDuplicateInSameSpace && page.id === rootPage.id) {
|
||||
const originalTitle = page.title || 'Untitled';
|
||||
const originalTitle = getPageTitle(page.title);
|
||||
title = `Copy of ${originalTitle}`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user