From a026939a8c2bee7d88b5f86498d1401a158982a6 Mon Sep 17 00:00:00 2001 From: Adam Coffman Date: Wed, 2 Aug 2023 12:33:05 -0500 Subject: [PATCH] show badge for comment count on comments tab in detail views --- .../tab-navigation.component.html | 8 +-- .../tab-navigation.component.ts | 1 + client/src/app/generated/civic.apollo.ts | 7 ++- .../assertions-detail.view.ts | 17 +++--- .../evidence-detail/evidence-detail.view.ts | 15 +++--- .../genes/genes-detail/genes-detail.view.ts | 15 +++--- .../molecular-profiles-detail.view.ts | 17 +++--- .../sources-detail/sources-detail.query.gql | 3 ++ .../sources-detail/sources-detail.view.html | 2 +- .../sources-detail/sources-detail.view.ts | 54 +++++++++++++------ .../variant-groups-detail.view.ts | 17 +++--- .../variants-detail/variants-detail.view.ts | 15 +++--- server/app/models/source.rb | 1 + 13 files changed, 107 insertions(+), 65 deletions(-) diff --git a/client/src/app/components/shared/tab-navigation/tab-navigation.component.html b/client/src/app/components/shared/tab-navigation/tab-navigation.component.html index 9cb4fbf60..f6e6d40f5 100644 --- a/client/src/app/components/shared/tab-navigation/tab-navigation.component.html +++ b/client/src/app/components/shared/tab-navigation/tab-navigation.component.html @@ -20,12 +20,12 @@ [nzType]="tab.iconName"> {{ tab.tabLabel }} + nzTitle="{{ tab.badgeCount }} {{ tab.tabLabel }}(s)." + [nzStyle]="{ transform: 'scale(0.75, 0.75) translate(0, -2px)', backgroundColor: tab.badgeColor || '#ff4d4f'}"> + diff --git a/client/src/app/components/shared/tab-navigation/tab-navigation.component.ts b/client/src/app/components/shared/tab-navigation/tab-navigation.component.ts index c384f8454..e8fac5917 100644 --- a/client/src/app/components/shared/tab-navigation/tab-navigation.component.ts +++ b/client/src/app/components/shared/tab-navigation/tab-navigation.component.ts @@ -7,6 +7,7 @@ export interface RouteableTab { tabLabel: string iconName: string badgeCount?: number + badgeColor?: string } @Component({ diff --git a/client/src/app/generated/civic.apollo.ts b/client/src/app/generated/civic.apollo.ts index 0e76c872a..ee06a5d52 100644 --- a/client/src/app/generated/civic.apollo.ts +++ b/client/src/app/generated/civic.apollo.ts @@ -6781,9 +6781,9 @@ export type SourceDetailQueryVariables = Exact<{ }>; -export type SourceDetailQuery = { __typename: 'Query', source?: { __typename: 'Source', id: number, citation?: string | undefined, sourceUrl?: string | undefined, displayType: string, citationId: string } | undefined }; +export type SourceDetailQuery = { __typename: 'Query', source?: { __typename: 'Source', id: number, citation?: string | undefined, sourceUrl?: string | undefined, displayType: string, citationId: string, comments: { __typename: 'CommentConnection', totalCount: number } } | undefined }; -export type SourceDetailFieldsFragment = { __typename: 'Source', id: number, citation?: string | undefined, sourceUrl?: string | undefined, displayType: string, citationId: string }; +export type SourceDetailFieldsFragment = { __typename: 'Source', id: number, citation?: string | undefined, sourceUrl?: string | undefined, displayType: string, citationId: string, comments: { __typename: 'CommentConnection', totalCount: number } }; export type SourceSummaryQueryVariables = Exact<{ sourceId: Scalars['Int']; @@ -9208,6 +9208,9 @@ export const SourceDetailFieldsFragmentDoc = gql` sourceUrl displayType citationId + comments { + totalCount + } } `; export const SourceSummaryFieldsFragmentDoc = gql` diff --git a/client/src/app/views/assertions/assertions-detail/assertions-detail.view.ts b/client/src/app/views/assertions/assertions-detail/assertions-detail.view.ts index 53dccf6e6..c384b160b 100644 --- a/client/src/app/views/assertions/assertions-detail/assertions-detail.view.ts +++ b/client/src/app/views/assertions/assertions-detail/assertions-detail.view.ts @@ -27,7 +27,6 @@ export class AssertionsDetailView implements OnDestroy { assertion$?: Observable> loading$?: Observable - commentsTotal$?: Observable flagsTotal$?: Observable viewer$: Observable @@ -85,21 +84,23 @@ export class AssertionsDetailView implements OnDestroy { this.assertion$ = observable.pipe(pluck('data', 'assertion')) - this.commentsTotal$ = this.assertion$.pipe( - pluck('comments', 'totalCount') - ) - this.flagsTotal$ = this.assertion$.pipe(pluck('flags', 'totalCount')) this.assertion$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (assertionResp) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: assertionResp?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: assertionResp?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/client/src/app/views/evidence/evidence-detail/evidence-detail.view.ts b/client/src/app/views/evidence/evidence-detail/evidence-detail.view.ts index b1cc8eb03..a34cebbdc 100644 --- a/client/src/app/views/evidence/evidence-detail/evidence-detail.view.ts +++ b/client/src/app/views/evidence/evidence-detail/evidence-detail.view.ts @@ -27,7 +27,6 @@ export class EvidenceDetailView implements OnDestroy { evidence$?: Observable> loading$?: Observable - commentsTotal$?: Observable flagsTotal$?: Observable viewer$: Observable @@ -85,19 +84,23 @@ export class EvidenceDetailView implements OnDestroy { this.evidence$ = observable.pipe(pluck('data', 'evidenceItem')) - this.commentsTotal$ = this.evidence$.pipe(pluck('comments', 'totalCount')) - this.flagsTotal$ = this.evidence$.pipe(pluck('flags', 'totalCount')) this.evidence$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (evidenceResponse) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: evidenceResponse?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: evidenceResponse?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/client/src/app/views/genes/genes-detail/genes-detail.view.ts b/client/src/app/views/genes/genes-detail/genes-detail.view.ts index 5c7e9294e..0086b97bb 100644 --- a/client/src/app/views/genes/genes-detail/genes-detail.view.ts +++ b/client/src/app/views/genes/genes-detail/genes-detail.view.ts @@ -22,7 +22,6 @@ export class GenesDetailView implements OnDestroy { loading$?: Observable gene$?: Observable> viewer$: Observable - commentsTotal$?: Observable flagsTotal$?: Observable routeSub: Subscription subscribable?: SubscribableInput @@ -72,19 +71,23 @@ export class GenesDetailView implements OnDestroy { this.gene$ = observable.pipe(pluck('data', 'gene')) - this.commentsTotal$ = this.gene$.pipe(pluck('comments', 'totalCount')) - this.flagsTotal$ = this.gene$.pipe(pluck('flags', 'totalCount')) this.gene$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (geneResp) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: geneResp?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: geneResp?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/client/src/app/views/molecular-profiles/molecular-profiles-detail/molecular-profiles-detail.view.ts b/client/src/app/views/molecular-profiles/molecular-profiles-detail/molecular-profiles-detail.view.ts index eb279d222..4c272f1e9 100644 --- a/client/src/app/views/molecular-profiles/molecular-profiles-detail/molecular-profiles-detail.view.ts +++ b/client/src/app/views/molecular-profiles/molecular-profiles-detail/molecular-profiles-detail.view.ts @@ -29,7 +29,6 @@ export class MolecularProfilesDetailView implements OnDestroy { molecularProfile$?: Observable> loading$?: Observable - commentsTotal$?: Observable flagsTotal$?: Observable viewer$: Observable @@ -85,23 +84,25 @@ export class MolecularProfilesDetailView implements OnDestroy { pluck('data', 'molecularProfile') ) - this.commentsTotal$ = this.molecularProfile$.pipe( - pluck('comments', 'totalCount') - ) - this.flagsTotal$ = this.molecularProfile$.pipe( pluck('flags', 'totalCount') ) this.molecularProfile$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (mpResp) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: mpResp?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: mpResp?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/client/src/app/views/sources/sources-detail/sources-detail.query.gql b/client/src/app/views/sources/sources-detail/sources-detail.query.gql index aecbdf90e..f6091a7ab 100644 --- a/client/src/app/views/sources/sources-detail/sources-detail.query.gql +++ b/client/src/app/views/sources/sources-detail/sources-detail.query.gql @@ -10,4 +10,7 @@ fragment SourceDetailFields on Source { sourceUrl displayType citationId + comments { + totalCount + } } diff --git a/client/src/app/views/sources/sources-detail/sources-detail.view.html b/client/src/app/views/sources/sources-detail/sources-detail.view.html index 14e5bd921..30cbf2bbd 100644 --- a/client/src/app/views/sources/sources-detail/sources-detail.view.html +++ b/client/src/app/views/sources/sources-detail/sources-detail.view.html @@ -35,7 +35,7 @@ - +
diff --git a/client/src/app/views/sources/sources-detail/sources-detail.view.ts b/client/src/app/views/sources/sources-detail/sources-detail.view.ts index 5cd9d53d3..403bbb20c 100644 --- a/client/src/app/views/sources/sources-detail/sources-detail.view.ts +++ b/client/src/app/views/sources/sources-detail/sources-detail.view.ts @@ -10,8 +10,8 @@ import { SourceDetailQueryVariables, } from '@app/generated/civic.apollo' import { QueryRef } from 'apollo-angular' -import { Observable, Subscription } from 'rxjs' -import { startWith } from 'rxjs/operators' +import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs' +import { startWith, takeUntil } from 'rxjs/operators' import { pluck } from 'rxjs-etc/operators' @Component({ @@ -25,17 +25,32 @@ export class SourcesDetailView implements OnDestroy { sourceId?: number queryRef?: QueryRef + destroy$ = new Subject() loading$?: Observable source$?: Observable> - tabs: RouteableTab[] + tabs$: BehaviorSubject + defaultTabs: RouteableTab[] = [ + { + routeName: 'summary', + iconName: 'pic-left', + tabLabel: 'Summary', + }, + { + routeName: 'comments', + iconName: 'civic-comment', + tabLabel: 'Comments', + }, + ] constructor( private viewerService: ViewerService, private route: ActivatedRoute, private gql: SourceDetailGQL ) { + this.tabs$ = new BehaviorSubject(this.defaultTabs) + this.viewer$ = this.viewerService.viewer$ this.routeSub = this.route.params.subscribe((params) => { @@ -49,22 +64,29 @@ export class SourcesDetailView implements OnDestroy { this.loading$ = observable.pipe(pluck('loading'), startWith(true)) this.source$ = observable.pipe(pluck('data', 'source')) + this.source$.pipe(takeUntil(this.destroy$)).subscribe({ + next: (sourceResp) => { + this.tabs$.next( + this.defaultTabs.map((tab) => { + if (tab.tabLabel === 'Comments') { + return { + badgeCount: sourceResp?.comments.totalCount, + badgeColor: '#cccccc', + ...tab, + } + } else { + return tab + } + }) + ) + }, + }) }) - - this.tabs = [ - { - routeName: 'summary', - iconName: 'pic-left', - tabLabel: 'Summary', - }, - { - routeName: 'comments', - iconName: 'civic-comment', - tabLabel: 'Comments', - }, - ] } + ngOnDestroy() { this.routeSub.unsubscribe() + this.destroy$.next() + this.destroy$.unsubscribe() } } diff --git a/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-detail.view.ts b/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-detail.view.ts index d55dbd602..290ce6bbd 100644 --- a/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-detail.view.ts +++ b/client/src/app/views/variant-groups/variant-groups-detail/variant-groups-detail.view.ts @@ -22,7 +22,6 @@ export class VariantGroupsDetailView implements OnInit, OnDestroy { loading$?: Observable variantGroup$?: Observable> viewer$: Observable - commentsTotal$?: Observable revisionsTotal$?: Observable flagsTotal$?: Observable routeSub: Subscription @@ -70,21 +69,23 @@ export class VariantGroupsDetailView implements OnInit, OnDestroy { this.variantGroup$ = observable.pipe(pluck('data', 'variantGroup')) - this.commentsTotal$ = this.variantGroup$.pipe( - pluck('comments', 'totalCount') - ) - this.flagsTotal$ = this.variantGroup$.pipe(pluck('flags', 'totalCount')) this.variantGroup$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (vgResp) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: vgResp?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: vgResp?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/client/src/app/views/variants/variants-detail/variants-detail.view.ts b/client/src/app/views/variants/variants-detail/variants-detail.view.ts index d48742137..a0158556d 100644 --- a/client/src/app/views/variants/variants-detail/variants-detail.view.ts +++ b/client/src/app/views/variants/variants-detail/variants-detail.view.ts @@ -26,7 +26,6 @@ export class VariantsDetailView implements OnDestroy { variant$?: Observable> loading$?: Observable - commentsTotal$?: Observable flagsTotal$?: Observable viewer$: Observable @@ -80,19 +79,23 @@ export class VariantsDetailView implements OnDestroy { this.variant$ = observable.pipe(pluck('data', 'variant')) - this.commentsTotal$ = this.variant$.pipe(pluck('comments', 'totalCount')) - this.flagsTotal$ = this.variant$.pipe(pluck('flags', 'totalCount')) this.variant$ - .pipe(pluck('revisions', 'totalCount'), takeUntil(this.destroy$)) + .pipe(takeUntil(this.destroy$)) .subscribe({ - next: (count) => { + next: (variantResp) => { this.tabs$.next( this.defaultTabs.map((tab) => { if (tab.tabLabel === 'Revisions') { return { - badgeCount: count as number, + badgeCount: variantResp?.revisions.totalCount, + ...tab, + } + } else if (tab.tabLabel === 'Comments') { + return { + badgeCount: variantResp?.comments.totalCount, + badgeColor: '#cccccc', ...tab, } } else { diff --git a/server/app/models/source.rb b/server/app/models/source.rb index 818aea871..2d579ffa6 100644 --- a/server/app/models/source.rb +++ b/server/app/models/source.rb @@ -2,6 +2,7 @@ class Source < ActiveRecord::Base include ModeratedField include Subscribable include WithTimepointCounts + include Commentable has_many :evidence_items has_and_belongs_to_many :genes