diff --git a/packages/api/src/entity/highlight.ts b/packages/api/src/entity/highlight.ts index 22572e7fe..65cea59fb 100644 --- a/packages/api/src/entity/highlight.ts +++ b/packages/api/src/entity/highlight.ts @@ -80,7 +80,7 @@ export class Highlight { @Column('text', { nullable: true }) color?: string | null - @ManyToMany(() => Label) + @ManyToMany(() => Label, { cascade: true }) @JoinTable({ name: 'entity_labels', joinColumn: { name: 'highlight_id' }, diff --git a/packages/api/src/entity/library_item.ts b/packages/api/src/entity/library_item.ts index 7b1740481..87f02eff1 100644 --- a/packages/api/src/entity/library_item.ts +++ b/packages/api/src/entity/library_item.ts @@ -197,4 +197,16 @@ export class LibraryItem { inverseJoinColumn: { name: 'id' }, }) highlights?: Highlight[] + + @Column('text', { nullable: true }) + labelNames?: string[] | null + + @Column('text', { nullable: true }) + highlightLabels?: string[] | null + + @Column('text', { nullable: true }) + highlightAnnotations?: string[] | null + + @Column('text', { nullable: true }) + note?: string | null } diff --git a/packages/api/src/entity/link_label.ts b/packages/api/src/entity/link_label.ts deleted file mode 100644 index 744393c3c..000000000 --- a/packages/api/src/entity/link_label.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - CreateDateColumn, - Entity, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, -} from 'typeorm' -import { Link } from './link' -import { Label } from './label' - -@Entity({ name: 'link_labels' }) -export class LinkLabel { - @PrimaryGeneratedColumn('uuid') - id!: string - - @ManyToOne(() => Link) - @JoinColumn({ name: 'link_id' }) - link!: Link - - @ManyToOne(() => Label) - @JoinColumn({ name: 'label_id' }) - label!: Label - - @CreateDateColumn() - createdAt!: Date -} diff --git a/packages/api/src/events/highlight_subscriber.ts b/packages/api/src/events/highlight_subscriber.ts new file mode 100644 index 000000000..5da980eda --- /dev/null +++ b/packages/api/src/events/highlight_subscriber.ts @@ -0,0 +1,103 @@ +import { + EntityManager, + EntitySubscriberInterface, + EventSubscriber, + InsertEvent, + ObjectLiteral, + RemoveEvent, + UpdateEvent, +} from 'typeorm' +import { Highlight } from '../entity/highlight' +import { Label } from '../entity/label' +import { LibraryItem } from '../entity/library_item' +import { createPubSubClient, EntityType } from '../pubsub' + +@EventSubscriber() +export class HighlightSubscriber + implements EntitySubscriberInterface +{ + private readonly pubsubClient = createPubSubClient() + + async updateLibraryItem(manager: EntityManager, libraryItemId: string) { + // get all the highlights belonging to the library_item + const highlights = await manager.getRepository(Highlight).find({ + where: { libraryItem: { id: libraryItemId } }, + relations: { + labels: true, + }, + }) + + const highlightLabels: string[] = [] + const highlightAnnotations: string[] = [] + + // for each highlight, add the lowercased label names to highlight_labels + // and the annotation to highlight_annotations + highlights.forEach((highlight) => { + highlight.labels && + highlightLabels.push( + ...highlight.labels.map((label) => label.name.toLowerCase()) + ) + highlightAnnotations.push(highlight.annotation || '') + }) + + // update highlight_labels and highlight_annotations on library_item + await manager.update(LibraryItem, libraryItemId, { + highlightAnnotations, + highlightLabels, + }) + } + + listenTo() { + return Highlight + } + + async afterInsert(event: InsertEvent): Promise { + await this.updateLibraryItem(event.manager, event.entity.libraryItem.id) + + await this.pubsubClient.entityCreated( + EntityType.HIGHLIGHT, + event.entity, + event.entity.libraryItem.user.id + ) + } + + async afterUpdate(event: UpdateEvent): Promise { + if (event.entity) { + await this.updateLibraryItem( + event.manager, + event.databaseEntity.libraryItem.id + ) + + // publish update event + await this.pubsubClient.entityUpdated( + EntityType.HIGHLIGHT, + { ...event.entity, libraryItem: event.databaseEntity.libraryItem }, + event.databaseEntity.libraryItem.user.id + ) + + // publish label added event if a label was added + if (event.entity.labels) { + await this.pubsubClient.entityCreated