From f16427511ef9f912d754491b660427743e58e8a5 Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Fri, 1 Dec 2023 19:42:16 +0100 Subject: [PATCH 01/18] wip: add subscription on new pericope --- api/src/common/subscription-token.ts | 1 + .../pericope-tr.module.ts | 2 +- .../pericope-tr.resolver.ts | 21 +++++++++- .../pericope-tr.service.ts | 29 ++++++++++++- .../pericopies/pericopies.module.ts | 2 + .../pericopies/pericopies.resolver.ts | 13 ++++++ .../pericopies/pericopies.service.ts | 36 +++++++++++++++- api/src/schema.gql | 1 + frontend/graphql.schema.json | 16 +++++++ .../pericope-translations/PericopeTrPage.tsx | 9 ++++ .../pericope-translations/gql.graphql | 13 +++++- frontend/src/generated/graphql.tsx | 42 +++++++++++++++++++ 12 files changed, 179 insertions(+), 6 deletions(-) diff --git a/api/src/common/subscription-token.ts b/api/src/common/subscription-token.ts index eae3553d..568e2a66 100644 --- a/api/src/common/subscription-token.ts +++ b/api/src/common/subscription-token.ts @@ -9,6 +9,7 @@ export class SubscriptionToken { static pericopiesAdded = 'pericopiesAdded'; static pericopeDeleted = 'pericopeDeleted'; static pericopeVoteStatusToggled = 'pericopeVoteStatusToggled'; + static pericopiesRecommendedHasChanged = 'pericopiesRecommendedHasChanged'; static questionsAdded = 'questionsAdded'; static questionsOnWordRangeAdded = 'questionsOnWordRangeAdded'; static answersAdded = 'answersAdded'; diff --git a/api/src/components/pericope-translations/pericope-tr.module.ts b/api/src/components/pericope-translations/pericope-tr.module.ts index 2f7732cd..619c2913 100644 --- a/api/src/components/pericope-translations/pericope-tr.module.ts +++ b/api/src/components/pericope-translations/pericope-tr.module.ts @@ -14,6 +14,6 @@ import { PericopiesModule } from '../pericopies/pericopies.module'; forwardRef(() => AuthenticationModule), ], providers: [PericopeTrService, PericopeTrResolver], - exports: [], + exports: [PericopeTrService], }) export class PericopeTrModule {} diff --git a/api/src/components/pericope-translations/pericope-tr.resolver.ts b/api/src/components/pericope-translations/pericope-tr.resolver.ts index bdc2f162..75fdec25 100644 --- a/api/src/components/pericope-translations/pericope-tr.resolver.ts +++ b/api/src/components/pericope-translations/pericope-tr.resolver.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger, UseGuards } from '@nestjs/common'; +import { Inject, Injectable, Logger, UseGuards } from '@nestjs/common'; import { Args, Context, @@ -7,6 +7,7 @@ import { Mutation, Query, Resolver, + Subscription, } from '@nestjs/graphql'; import { PericopeTrService } from './pericope-tr.service'; import { @@ -21,11 +22,17 @@ import { import { BearerTokenAuthGuard } from '../../guards/bearer-token-auth.guard'; import { ErrorType } from '../../common/types'; import { LanguageInput } from '../common/types'; +import { SubscriptionToken } from '../../common/subscription-token'; +import { PUB_SUB } from '../../pubSub.module'; +import { PubSub } from 'graphql-subscriptions'; @Injectable() @Resolver() export class PericopeTrResolver { - constructor(private pericopeTrService: PericopeTrService) {} + constructor( + private pericopeTrService: PericopeTrService, + @Inject(PUB_SUB) private readonly pubSub: PubSub, + ) {} @Query(() => PericopiesTextsWithTranslationConnection) async getPericopiesTr( @@ -123,4 +130,14 @@ export class PericopeTrResolver { }; } } + + @Subscription(() => PericopiesTextsWithTranslationConnection, { + name: SubscriptionToken.pericopiesRecommendedHasChanged, + }) + async subscribeToPericopiesTextsWithTranslation() { + console.log('subscribeTo pericopiesRecommendedHasChanged'); + return this.pubSub.asyncIterator( + SubscriptionToken.pericopiesRecommendedHasChanged, + ); + } } diff --git a/api/src/components/pericope-translations/pericope-tr.service.ts b/api/src/components/pericope-translations/pericope-tr.service.ts index fb2f6bd1..5647e8f9 100644 --- a/api/src/components/pericope-translations/pericope-tr.service.ts +++ b/api/src/components/pericope-translations/pericope-tr.service.ts @@ -1,7 +1,9 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { ErrorType } from '../../common/types'; import { calc_vote_weight } from '../../common/utility'; import { PostgresService } from '../../core/postgres.service'; +import { PUB_SUB } from '../../pubSub.module'; +import { PubSub } from 'graphql-subscriptions'; import { LanguageInput } from '../common/types'; import { PericopiesService, @@ -34,6 +36,7 @@ import { PericopiesTextsWithTranslationConnection, PericopiesTextsWithTranslationEdge, } from './types'; +import { SubscriptionToken } from '../../common/subscription-token'; const errorishPageInfo = { hasNextPage: false, @@ -42,11 +45,14 @@ const errorishPageInfo = { endCursor: null, }; +const PAGE_SIZE = 30; // todo: same as at frontend, so maybe move it to common utils lib + @Injectable() export class PericopeTrService { constructor( private pg: PostgresService, private pericopiesService: PericopiesService, + @Inject(PUB_SUB) private readonly pubSub: PubSub, ) {} async getPericopiesTextsWithTranslationConnection( @@ -440,4 +446,25 @@ export class PericopeTrService { }, })); } + + async publishNewRecommendedPericopiesTr({ + documentId, + targetLang, + }: { + documentId: string; + targetLang: LanguageInput; + }): Promise { + const newPericopiesTr: PericopiesTextsWithTranslationConnection = + await this.getPericopiesTextsWithTranslationConnection( + { + documentId, + targetLang, + }, + PAGE_SIZE, + null, + ); + this.pubSub.publish(SubscriptionToken.pericopiesRecommendedHasChanged, { + [SubscriptionToken.pericopiesRecommendedHasChanged]: newPericopiesTr, + }); + } } diff --git a/api/src/components/pericopies/pericopies.module.ts b/api/src/components/pericopies/pericopies.module.ts index e11b60bb..8a5caa54 100644 --- a/api/src/components/pericopies/pericopies.module.ts +++ b/api/src/components/pericopies/pericopies.module.ts @@ -8,12 +8,14 @@ import { PericopiesResolver } from './pericopies.resolver'; import { PericopeVotesService } from './pericope-votes.service'; import { PericopiesService } from './pericopies.service'; import { AuthorizationModule } from '../authorization/authorization.module'; +import { PericopeTrModule } from '../pericope-translations/pericope-tr.module'; @Module({ imports: [ forwardRef(() => CoreModule), forwardRef(() => DocumentsModule), forwardRef(() => AuthorizationModule), + forwardRef(() => PericopeTrModule), ], providers: [PericopiesService, PericopeVotesService, PericopiesResolver], exports: [PericopiesService, PericopeVotesService], diff --git a/api/src/components/pericopies/pericopies.resolver.ts b/api/src/components/pericopies/pericopies.resolver.ts index 402f052f..566e87d5 100644 --- a/api/src/components/pericopies/pericopies.resolver.ts +++ b/api/src/components/pericopies/pericopies.resolver.ts @@ -26,6 +26,7 @@ import { PericopeTextWithDescription, PericopeDeleteOutput, } from './types'; +import { PericopeTrService } from '../pericope-translations/pericope-tr.service'; @Injectable() @Resolver() @@ -34,6 +35,7 @@ export class PericopiesResolver { @Inject(PUB_SUB) private readonly pubSub: PubSub, private pericopiesService: PericopiesService, private pericopeVotesService: PericopeVotesService, + private pericopeTrService: PericopeTrService, ) {} @Query(() => PericopiesOutput) @@ -103,6 +105,17 @@ export class PericopiesResolver { [SubscriptionToken.pericopiesAdded]: newPericopies, }); + if (newPericopies.pericopies[0]?.pericope_id) { + const dIdsAdnLangs = + await this.pericopiesService.getDocumentIdsAndLangsOfPericopeIds([ + newPericopies.pericopies[0]?.pericope_id, + ]); + this.pericopeTrService.publishNewRecommendedPericopiesTr({ + documentId: dIdsAdnLangs[0].documentId, + targetLang: dIdsAdnLangs[0].lang, + }); + } + return newPericopies; } diff --git a/api/src/components/pericopies/pericopies.service.ts b/api/src/components/pericopies/pericopies.service.ts index c7fc8a42..737bf02a 100644 --- a/api/src/components/pericopies/pericopies.service.ts +++ b/api/src/components/pericopies/pericopies.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger } from '@nestjs/common'; +import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; import { PoolClient } from 'pg'; import { calc_vote_weight, pgClientOrPool } from 'src/common/utility'; @@ -41,6 +41,7 @@ import { GetDocumentWordEntriesTotalPageSize, getDocumentWordEntriesTotalPageSize, } from '../documents/sql-string'; +import { LanguageInput } from '../common/types'; export const WORDS_JOINER = ' '; @@ -438,4 +439,37 @@ export class PericopiesService { }; } } + + async getDocumentIdsAndLangsOfPericopeIds( + pericope_ids: string[], + ): Promise> { + const res = await this.pg.pool.query<{ + document_id: string; + language_code: string; + dialect_code: string; + geo_code: string; + }>( + ` + select + d.document_id, + d.language_code, + d.dialect_code, + d.geo_code + from pericopies p + left join document_word_entries dwe on p.start_word = dwe.document_word_entry_id + left join documents d on dwe.document_id =d.document_id + where p.pericope_id = any($1) + `, + [pericope_ids], + ); + + return res.rows.map((row) => ({ + documentId: row.document_id, + lang: { + language_code: row.language_code, + dialect_code: row.dialect_code, + geo_code: row.geo_code, + }, + })); + } } diff --git a/api/src/schema.gql b/api/src/schema.gql index c233707a..3d153936 100644 --- a/api/src/schema.gql +++ b/api/src/schema.gql @@ -1532,6 +1532,7 @@ type Subscription { pericopeDeleted: PericopeDeleteOutput! pericopeVoteStatusToggled: PericopeVoteStatusOutput! pericopiesAdded: PericopiesOutput! + pericopiesRecommendedHasChanged: PericopiesTextsWithTranslationConnection! questionsAdded: QuestionsOutput! questionsOnWordRangeAdded: QuestionOnWordRangesOutput! wordRangeTagVoteStatusToggled: WordRangeTagVoteStatusOutput! diff --git a/frontend/graphql.schema.json b/frontend/graphql.schema.json index c59c36c5..03c5dbeb 100644 --- a/frontend/graphql.schema.json +++ b/frontend/graphql.schema.json @@ -20311,6 +20311,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "pericopiesRecommendedHasChanged", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "PericopiesTextsWithTranslationConnection", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "questionsAdded", "description": null, diff --git a/frontend/src/components/pericope-translations/PericopeTrPage.tsx b/frontend/src/components/pericope-translations/PericopeTrPage.tsx index 5777a5e9..24628eac 100644 --- a/frontend/src/components/pericope-translations/PericopeTrPage.tsx +++ b/frontend/src/components/pericope-translations/PericopeTrPage.tsx @@ -5,6 +5,8 @@ import { Caption } from '../common/Caption/Caption'; import { useTr } from '../../hooks/useTr'; import { LangSelector } from '../common/LangSelector/LangSelector'; import { Button } from '@mui/material'; +import { useSubscribeToPericopiesTrSubscription } from '../../hooks/useSubscribeToPericopiesTextsWithTranslation'; +import { useEffect } from 'react'; interface PericopeTrPageProps extends RouteComponentProps<{ @@ -33,6 +35,13 @@ export const PericopeTrPage: React.FC = ({ ); }; + const { data: pericopeTrSubsData, error: pericopeTrSubsError } = + useSubscribeToPericopiesTrSubscription(); + + useEffect(() => { + console.log(`PericopeTrPage`, pericopeTrSubsData, pericopeTrSubsError); + }, [pericopeTrSubsData, pericopeTrSubsError]); + return ( , best_translation_list: Array<{ __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } }> } }; +export type SubscribeToPericopiesTrSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type SubscribeToPericopiesTrSubscription = { __typename?: 'Subscription', pericopiesRecommendedHasChanged: { __typename?: 'PericopiesTextsWithTranslationConnection', edges: Array<{ __typename?: 'PericopiesTextsWithTranslationEdge', cursor: string, node: { __typename?: 'PericopeTextWithTranslationAndDescription', pericope_id?: string | null, pericope_text: string, pericope_description_text: string, translation?: { __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } } | null } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, totalEdges?: number | null } } }; + export type PericopeFragmentFragment = { __typename?: 'Pericope', pericope_id: string, start_word: string }; export type PericopeVoteStatusFragmentFragment = { __typename?: 'PericopeVoteStatus', pericope_id: string, upvotes: number, downvotes: number }; @@ -8524,6 +8530,41 @@ export function useTogglePericopeTrVoteStatusMutation(baseOptions?: Apollo.Mutat export type TogglePericopeTrVoteStatusMutationHookResult = ReturnType; export type TogglePericopeTrVoteStatusMutationResult = Apollo.MutationResult; export type TogglePericopeTrVoteStatusMutationOptions = Apollo.BaseMutationOptions; +export const SubscribeToPericopiesTrDocument = gql` + subscription SubscribeToPericopiesTr { + pericopiesRecommendedHasChanged { + edges { + ...PericopiesTextsWithTranslationEdgeFragment + } + pageInfo { + ...PageInfoFragment + } + } +} + ${PericopiesTextsWithTranslationEdgeFragmentFragmentDoc} +${PageInfoFragmentFragmentDoc}`; + +/** + * __useSubscribeToPericopiesTrSubscription__ + * + * To run a query within a React component, call `useSubscribeToPericopiesTrSubscription` and pass it any options that fit your needs. + * When your component renders, `useSubscribeToPericopiesTrSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useSubscribeToPericopiesTrSubscription({ + * variables: { + * }, + * }); + */ +export function useSubscribeToPericopiesTrSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(SubscribeToPericopiesTrDocument, options); + } +export type SubscribeToPericopiesTrSubscriptionHookResult = ReturnType; +export type SubscribeToPericopiesTrSubscriptionResult = Apollo.SubscriptionResult; export const GetPericopiesByDocumentIdDocument = gql` query GetPericopiesByDocumentId($document_id: ID!, $first: Int, $after: ID) { getPericopiesByDocumentId( @@ -11970,6 +12011,7 @@ export const namedOperations = { SubscribeToDataGenProgress: 'SubscribeToDataGenProgress', SubscribeToDocumentAdded: 'SubscribeToDocumentAdded', SubscribeToZipMap: 'SubscribeToZipMap', + SubscribeToPericopiesTr: 'SubscribeToPericopiesTr', SubscribeToPericopiesAdded: 'SubscribeToPericopiesAdded', SubscribeToPericopieDeleted: 'SubscribeToPericopieDeleted', SubscribeToPericopeVoteStatusToggled: 'SubscribeToPericopeVoteStatusToggled', From 0283321488f44594618f893ca56fcc182f8bfbbf Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Fri, 1 Dec 2023 19:44:26 +0100 Subject: [PATCH 02/18] add blueprint of hook --- ...bscribeToPericopiesTextsWithTranslation.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts diff --git a/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts b/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts new file mode 100644 index 00000000..2316bbd4 --- /dev/null +++ b/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts @@ -0,0 +1,19 @@ +import { useSubscribeToPericopiesTrSubscription as useGeneratedSubscribeToPericopiesTrSubscription } from '../generated/graphql'; + +export function useSubscribeToPericopiesTrSubscription() { + return useGeneratedSubscribeToPericopiesTrSubscription({ + onData(data) { + console.log(data); + // const { data, error } = result; + // if ( + // !error && + // data && + // data.pericopiesAdded.pericopies.length > 0 && + // data.pericopiesAdded.error === ErrorType.NoError + // ) { + // const newPericope = data.pericopiesAdded.pericopies[0]!; + + // updateCacheWithUpsertPericope(client.cache, newPericope); + }, + }); +} From 7a4227bc39dab2ab9bf72bb97692c32835bbadf2 Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Mon, 4 Dec 2023 21:00:52 +0100 Subject: [PATCH 03/18] feat: add subscription to periocopies list change --- api/src/common/subscription-token.ts | 2 +- .../pericope-tr.resolver.ts | 12 ---- .../pericope-tr.service.ts | 24 -------- .../components/pericope-translations/types.ts | 5 ++ .../pericopies/pericopies.resolver.ts | 37 +++++++++++-- api/src/schema.gql | 7 ++- frontend/graphql.schema.json | 55 +++++++++++++++++-- .../pericope-translations/PericopeTrPage.tsx | 9 --- .../PericopiesTrListPage/PericopiesTrList.tsx | 28 +++++++++- .../pericope-translations/gql.graphql | 11 +--- frontend/src/generated/graphql.tsx | 46 ++++++++-------- ...bscribeToPericopiesTextsWithTranslation.ts | 19 ------- 12 files changed, 144 insertions(+), 111 deletions(-) delete mode 100644 frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts diff --git a/api/src/common/subscription-token.ts b/api/src/common/subscription-token.ts index 568e2a66..bfb9121f 100644 --- a/api/src/common/subscription-token.ts +++ b/api/src/common/subscription-token.ts @@ -9,7 +9,7 @@ export class SubscriptionToken { static pericopiesAdded = 'pericopiesAdded'; static pericopeDeleted = 'pericopeDeleted'; static pericopeVoteStatusToggled = 'pericopeVoteStatusToggled'; - static pericopiesRecommendedHasChanged = 'pericopiesRecommendedHasChanged'; + static recommendedPericopiesChanged = 'recommendedPericopiesChanged'; static questionsAdded = 'questionsAdded'; static questionsOnWordRangeAdded = 'questionsOnWordRangeAdded'; static answersAdded = 'answersAdded'; diff --git a/api/src/components/pericope-translations/pericope-tr.resolver.ts b/api/src/components/pericope-translations/pericope-tr.resolver.ts index 75fdec25..1574e1d6 100644 --- a/api/src/components/pericope-translations/pericope-tr.resolver.ts +++ b/api/src/components/pericope-translations/pericope-tr.resolver.ts @@ -7,7 +7,6 @@ import { Mutation, Query, Resolver, - Subscription, } from '@nestjs/graphql'; import { PericopeTrService } from './pericope-tr.service'; import { @@ -22,7 +21,6 @@ import { import { BearerTokenAuthGuard } from '../../guards/bearer-token-auth.guard'; import { ErrorType } from '../../common/types'; import { LanguageInput } from '../common/types'; -import { SubscriptionToken } from '../../common/subscription-token'; import { PUB_SUB } from '../../pubSub.module'; import { PubSub } from 'graphql-subscriptions'; @@ -130,14 +128,4 @@ export class PericopeTrResolver { }; } } - - @Subscription(() => PericopiesTextsWithTranslationConnection, { - name: SubscriptionToken.pericopiesRecommendedHasChanged, - }) - async subscribeToPericopiesTextsWithTranslation() { - console.log('subscribeTo pericopiesRecommendedHasChanged'); - return this.pubSub.asyncIterator( - SubscriptionToken.pericopiesRecommendedHasChanged, - ); - } } diff --git a/api/src/components/pericope-translations/pericope-tr.service.ts b/api/src/components/pericope-translations/pericope-tr.service.ts index 0854b69b..39516043 100644 --- a/api/src/components/pericope-translations/pericope-tr.service.ts +++ b/api/src/components/pericope-translations/pericope-tr.service.ts @@ -36,7 +36,6 @@ import { PericopiesTextsWithTranslationConnection, PericopiesTextsWithTranslationEdge, } from './types'; -import { SubscriptionToken } from '../../common/subscription-token'; const errorishPageInfo = { hasNextPage: false, @@ -45,8 +44,6 @@ const errorishPageInfo = { endCursor: null, }; -const PAGE_SIZE = 30; // todo: same as at frontend, so maybe move it to common utils lib - @Injectable() export class PericopeTrService { constructor( @@ -451,25 +448,4 @@ export class PericopeTrService { }, })); } - - async publishNewRecommendedPericopiesTr({ - documentId, - targetLang, - }: { - documentId: string; - targetLang: LanguageInput; - }): Promise { - const newPericopiesTr: PericopiesTextsWithTranslationConnection = - await this.getPericopiesTextsWithTranslationConnection( - { - documentId, - targetLang, - }, - PAGE_SIZE, - null, - ); - this.pubSub.publish(SubscriptionToken.pericopiesRecommendedHasChanged, { - [SubscriptionToken.pericopiesRecommendedHasChanged]: newPericopiesTr, - }); - } } diff --git a/api/src/components/pericope-translations/types.ts b/api/src/components/pericope-translations/types.ts index 179fcca2..4fdaab0f 100644 --- a/api/src/components/pericope-translations/types.ts +++ b/api/src/components/pericope-translations/types.ts @@ -110,3 +110,8 @@ export class PericopeTrVoteStatusAndBestTrListOutput extends PericopeTrVoteStatu @Field(() => [PericopeTranslation]) best_translation_list: Array; } + +@ObjectType() +export class RecomendedPericopiesChangedAtDocumentId extends GenericOutput { + @Field(() => String) documentId: string; +} diff --git a/api/src/components/pericopies/pericopies.resolver.ts b/api/src/components/pericopies/pericopies.resolver.ts index 566e87d5..400eed9f 100644 --- a/api/src/components/pericopies/pericopies.resolver.ts +++ b/api/src/components/pericopies/pericopies.resolver.ts @@ -14,7 +14,10 @@ import { SubscriptionToken } from 'src/common/subscription-token'; import { PUB_SUB } from 'src/pubSub.module'; import { getBearer } from 'src/common/utility'; -import { GetPericopeTextInput } from '../pericope-translations/types'; +import { + GetPericopeTextInput, + RecomendedPericopiesChangedAtDocumentId, +} from '../pericope-translations/types'; import { PericopeVotesService } from './pericope-votes.service'; import { PericopiesService } from './pericopies.service'; @@ -106,19 +109,30 @@ export class PericopiesResolver { }); if (newPericopies.pericopies[0]?.pericope_id) { - const dIdsAdnLangs = + const documentsData = await this.pericopiesService.getDocumentIdsAndLangsOfPericopeIds([ newPericopies.pericopies[0]?.pericope_id, ]); - this.pericopeTrService.publishNewRecommendedPericopiesTr({ - documentId: dIdsAdnLangs[0].documentId, - targetLang: dIdsAdnLangs[0].lang, + this.pubSub.publish(SubscriptionToken.recommendedPericopiesChanged, { + [SubscriptionToken.recommendedPericopiesChanged]: { + documentId: documentsData[0].documentId, + }, }); } return newPericopies; } + @Subscription(() => RecomendedPericopiesChangedAtDocumentId, { + name: SubscriptionToken.recommendedPericopiesChanged, + }) + async subscribeToRecommendedPericopiesChanged() { + console.log('subscribeToRecommendedPericopiesChanged'); + return this.pubSub.asyncIterator( + SubscriptionToken.recommendedPericopiesChanged, + ); + } + @Subscription(() => PericopiesOutput, { name: SubscriptionToken.pericopiesAdded, }) @@ -134,6 +148,11 @@ export class PericopiesResolver { ): Promise { Logger.log('deletePericopies: ', pericope_id); + const documentsData = + await this.pericopiesService.getDocumentIdsAndLangsOfPericopeIds([ + pericope_id, + ]); + const deletedPericope = await this.pericopiesService.delete( +pericope_id, getBearer(req) || '', @@ -144,6 +163,14 @@ export class PericopiesResolver { [SubscriptionToken.pericopeDeleted]: deletedPericope, }); + if (documentsData[0].documentId) { + this.pubSub.publish(SubscriptionToken.recommendedPericopiesChanged, { + [SubscriptionToken.recommendedPericopiesChanged]: { + documentId: documentsData[0].documentId, + }, + }); + } + return deletedPericope; } diff --git a/api/src/schema.gql b/api/src/schema.gql index 3d153936..f77ba692 100644 --- a/api/src/schema.gql +++ b/api/src/schema.gql @@ -1371,6 +1371,11 @@ type QuestionsOutput { questions: [Question]! } +type RecomendedPericopiesChangedAtDocumentId { + documentId: String! + error: ErrorType! +} + input RegisterInput { avatar: String! email: String! @@ -1532,9 +1537,9 @@ type Subscription { pericopeDeleted: PericopeDeleteOutput! pericopeVoteStatusToggled: PericopeVoteStatusOutput! pericopiesAdded: PericopiesOutput! - pericopiesRecommendedHasChanged: PericopiesTextsWithTranslationConnection! questionsAdded: QuestionsOutput! questionsOnWordRangeAdded: QuestionOnWordRangesOutput! + recommendedPericopiesChanged: RecomendedPericopiesChangedAtDocumentId! wordRangeTagVoteStatusToggled: WordRangeTagVoteStatusOutput! wordRangeTagWithVoteAdded: WordRangeTagWithVotesOutput! } diff --git a/frontend/graphql.schema.json b/frontend/graphql.schema.json index 03c5dbeb..0c0dfdf3 100644 --- a/frontend/graphql.schema.json +++ b/frontend/graphql.schema.json @@ -18769,6 +18769,49 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "RecomendedPericopiesChangedAtDocumentId", + "description": null, + "fields": [ + { + "name": "documentId", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "error", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ErrorType", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "RegisterInput", @@ -20312,7 +20355,7 @@ "deprecationReason": null }, { - "name": "pericopiesRecommendedHasChanged", + "name": "questionsAdded", "description": null, "args": [], "type": { @@ -20320,7 +20363,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "PericopiesTextsWithTranslationConnection", + "name": "QuestionsOutput", "ofType": null } }, @@ -20328,7 +20371,7 @@ "deprecationReason": null }, { - "name": "questionsAdded", + "name": "questionsOnWordRangeAdded", "description": null, "args": [], "type": { @@ -20336,7 +20379,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "QuestionsOutput", + "name": "QuestionOnWordRangesOutput", "ofType": null } }, @@ -20344,7 +20387,7 @@ "deprecationReason": null }, { - "name": "questionsOnWordRangeAdded", + "name": "recommendedPericopiesChanged", "description": null, "args": [], "type": { @@ -20352,7 +20395,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "QuestionOnWordRangesOutput", + "name": "RecomendedPericopiesChangedAtDocumentId", "ofType": null } }, diff --git a/frontend/src/components/pericope-translations/PericopeTrPage.tsx b/frontend/src/components/pericope-translations/PericopeTrPage.tsx index 24628eac..5777a5e9 100644 --- a/frontend/src/components/pericope-translations/PericopeTrPage.tsx +++ b/frontend/src/components/pericope-translations/PericopeTrPage.tsx @@ -5,8 +5,6 @@ import { Caption } from '../common/Caption/Caption'; import { useTr } from '../../hooks/useTr'; import { LangSelector } from '../common/LangSelector/LangSelector'; import { Button } from '@mui/material'; -import { useSubscribeToPericopiesTrSubscription } from '../../hooks/useSubscribeToPericopiesTextsWithTranslation'; -import { useEffect } from 'react'; interface PericopeTrPageProps extends RouteComponentProps<{ @@ -35,13 +33,6 @@ export const PericopeTrPage: React.FC = ({ ); }; - const { data: pericopeTrSubsData, error: pericopeTrSubsError } = - useSubscribeToPericopiesTrSubscription(); - - useEffect(() => { - console.log(`PericopeTrPage`, pericopeTrSubsData, pericopeTrSubsError); - }, [pericopeTrSubsData, pericopeTrSubsError]); - return ( { + if ( + recomendedPericopiesChangedSubscriptionData?.recommendedPericopiesChanged + .documentId !== documentId + ) { + return; + } + refetchPericopiesTrQuery(); + }, [ + documentId, + recomendedPericopiesChangedSubscriptionData, + refetchPericopiesTrQuery, + ]); + useEffect(() => { if (!targetLang) { present({ diff --git a/frontend/src/components/pericope-translations/gql.graphql b/frontend/src/components/pericope-translations/gql.graphql index 0f2589d3..48d6d6c5 100644 --- a/frontend/src/components/pericope-translations/gql.graphql +++ b/frontend/src/components/pericope-translations/gql.graphql @@ -143,13 +143,8 @@ mutation TogglePericopeTrVoteStatus( } } -subscription SubscribeToPericopiesTr { - pericopiesRecommendedHasChanged { - edges { - ...PericopiesTextsWithTranslationEdgeFragment - } - pageInfo { - ...PageInfoFragment - } +subscription SubscribeToRecomendedPericopiesChanged { + recommendedPericopiesChanged { + documentId } } diff --git a/frontend/src/generated/graphql.tsx b/frontend/src/generated/graphql.tsx index 512d8e0c..bfd24fbc 100644 --- a/frontend/src/generated/graphql.tsx +++ b/frontend/src/generated/graphql.tsx @@ -2496,6 +2496,12 @@ export type QuestionsOutput = { questions: Array>; }; +export type RecomendedPericopiesChangedAtDocumentId = { + __typename?: 'RecomendedPericopiesChangedAtDocumentId'; + documentId: Scalars['String']['output']; + error: ErrorType; +}; + export type RegisterInput = { avatar: Scalars['String']['input']; email: Scalars['String']['input']; @@ -2676,9 +2682,9 @@ export type Subscription = { pericopeDeleted: PericopeDeleteOutput; pericopeVoteStatusToggled: PericopeVoteStatusOutput; pericopiesAdded: PericopiesOutput; - pericopiesRecommendedHasChanged: PericopiesTextsWithTranslationConnection; questionsAdded: QuestionsOutput; questionsOnWordRangeAdded: QuestionOnWordRangesOutput; + recommendedPericopiesChanged: RecomendedPericopiesChangedAtDocumentId; wordRangeTagVoteStatusToggled: WordRangeTagVoteStatusOutput; wordRangeTagWithVoteAdded: WordRangeTagWithVotesOutput; }; @@ -3966,10 +3972,10 @@ export type TogglePericopeTrVoteStatusMutationVariables = Exact<{ export type TogglePericopeTrVoteStatusMutation = { __typename?: 'Mutation', togglePericopeTrVoteStatus: { __typename?: 'PericopeTrVoteStatusAndBestTrListOutput', error: ErrorType, vote_status_list: Array<{ __typename?: 'PericopeTrVoteStatus', pericope_translation_id: string, upvotes: number, downvotes: number }>, best_translation_list: Array<{ __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } }> } }; -export type SubscribeToPericopiesTrSubscriptionVariables = Exact<{ [key: string]: never; }>; +export type SubscribeToRecomendedPericopiesChangedSubscriptionVariables = Exact<{ [key: string]: never; }>; -export type SubscribeToPericopiesTrSubscription = { __typename?: 'Subscription', pericopiesRecommendedHasChanged: { __typename?: 'PericopiesTextsWithTranslationConnection', edges: Array<{ __typename?: 'PericopiesTextsWithTranslationEdge', cursor: string, node: { __typename?: 'PericopeTextWithTranslationAndDescription', pericope_id?: string | null, pericope_text: string, pericope_description_text: string, translation?: { __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } } | null } }>, pageInfo: { __typename?: 'PageInfo', endCursor?: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: string | null, totalEdges?: number | null } } }; +export type SubscribeToRecomendedPericopiesChangedSubscription = { __typename?: 'Subscription', recommendedPericopiesChanged: { __typename?: 'RecomendedPericopiesChangedAtDocumentId', documentId: string } }; export type PericopeFragmentFragment = { __typename?: 'Pericope', pericope_id: string, start_word: string }; @@ -8530,41 +8536,35 @@ export function useTogglePericopeTrVoteStatusMutation(baseOptions?: Apollo.Mutat export type TogglePericopeTrVoteStatusMutationHookResult = ReturnType; export type TogglePericopeTrVoteStatusMutationResult = Apollo.MutationResult; export type TogglePericopeTrVoteStatusMutationOptions = Apollo.BaseMutationOptions; -export const SubscribeToPericopiesTrDocument = gql` - subscription SubscribeToPericopiesTr { - pericopiesRecommendedHasChanged { - edges { - ...PericopiesTextsWithTranslationEdgeFragment - } - pageInfo { - ...PageInfoFragment - } +export const SubscribeToRecomendedPericopiesChangedDocument = gql` + subscription SubscribeToRecomendedPericopiesChanged { + recommendedPericopiesChanged { + documentId } } - ${PericopiesTextsWithTranslationEdgeFragmentFragmentDoc} -${PageInfoFragmentFragmentDoc}`; + `; /** - * __useSubscribeToPericopiesTrSubscription__ + * __useSubscribeToRecomendedPericopiesChangedSubscription__ * - * To run a query within a React component, call `useSubscribeToPericopiesTrSubscription` and pass it any options that fit your needs. - * When your component renders, `useSubscribeToPericopiesTrSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useSubscribeToRecomendedPericopiesChangedSubscription` and pass it any options that fit your needs. + * When your component renders, `useSubscribeToRecomendedPericopiesChangedSubscription` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useSubscribeToPericopiesTrSubscription({ + * const { data, loading, error } = useSubscribeToRecomendedPericopiesChangedSubscription({ * variables: { * }, * }); */ -export function useSubscribeToPericopiesTrSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { +export function useSubscribeToRecomendedPericopiesChangedSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSubscription(SubscribeToPericopiesTrDocument, options); + return Apollo.useSubscription(SubscribeToRecomendedPericopiesChangedDocument, options); } -export type SubscribeToPericopiesTrSubscriptionHookResult = ReturnType; -export type SubscribeToPericopiesTrSubscriptionResult = Apollo.SubscriptionResult; +export type SubscribeToRecomendedPericopiesChangedSubscriptionHookResult = ReturnType; +export type SubscribeToRecomendedPericopiesChangedSubscriptionResult = Apollo.SubscriptionResult; export const GetPericopiesByDocumentIdDocument = gql` query GetPericopiesByDocumentId($document_id: ID!, $first: Int, $after: ID) { getPericopiesByDocumentId( @@ -12011,7 +12011,7 @@ export const namedOperations = { SubscribeToDataGenProgress: 'SubscribeToDataGenProgress', SubscribeToDocumentAdded: 'SubscribeToDocumentAdded', SubscribeToZipMap: 'SubscribeToZipMap', - SubscribeToPericopiesTr: 'SubscribeToPericopiesTr', + SubscribeToRecomendedPericopiesChanged: 'SubscribeToRecomendedPericopiesChanged', SubscribeToPericopiesAdded: 'SubscribeToPericopiesAdded', SubscribeToPericopieDeleted: 'SubscribeToPericopieDeleted', SubscribeToPericopeVoteStatusToggled: 'SubscribeToPericopeVoteStatusToggled', diff --git a/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts b/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts deleted file mode 100644 index 2316bbd4..00000000 --- a/frontend/src/hooks/useSubscribeToPericopiesTextsWithTranslation.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { useSubscribeToPericopiesTrSubscription as useGeneratedSubscribeToPericopiesTrSubscription } from '../generated/graphql'; - -export function useSubscribeToPericopiesTrSubscription() { - return useGeneratedSubscribeToPericopiesTrSubscription({ - onData(data) { - console.log(data); - // const { data, error } = result; - // if ( - // !error && - // data && - // data.pericopiesAdded.pericopies.length > 0 && - // data.pericopiesAdded.error === ErrorType.NoError - // ) { - // const newPericope = data.pericopiesAdded.pericopies[0]!; - - // updateCacheWithUpsertPericope(client.cache, newPericope); - }, - }); -} From 9dbee455aed99e3b3f71e6da1cf9562d6b15baab Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Mon, 4 Dec 2023 21:22:36 +0100 Subject: [PATCH 04/18] fix: issue with pericopies being cutted --- .../components/pericope-translations/pericope-tr.service.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/src/components/pericope-translations/pericope-tr.service.ts b/api/src/components/pericope-translations/pericope-tr.service.ts index 27b34596..62e924f7 100644 --- a/api/src/components/pericope-translations/pericope-tr.service.ts +++ b/api/src/components/pericope-translations/pericope-tr.service.ts @@ -190,14 +190,13 @@ export class PericopeTrService { currPericopeid = word.pericope_id; currPericopeCursor++; } - // it's better to make ordered_pericopies plain zero-based array - ordered_pericopies[currPericopeCursor - 1] = { + ordered_pericopies[currPericopeCursor] = { pericopeCursor: currPericopeCursor, pericopeId: currPericopeid, words: [...(ordered_pericopies[currPericopeCursor]?.words || []), word], }; }); - return ordered_pericopies; + return ordered_pericopies.slice(1); } async getPericopeDescription( From 85ac9f24a3f3ccbc6e5134240d9180939e0e0e6b Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Tue, 5 Dec 2023 12:49:33 +0100 Subject: [PATCH 05/18] feat: update pericope translations on new pericope --- .../PericopiesTrListPage/PericopiesTrList.tsx | 98 ++++++------------- .../SuperDocumentViewer.tsx | 1 + .../SuperDocumentViewerPage.tsx | 4 +- ...mSubscribeToRecomendedPericopiesChanged.ts | 15 +++ 4 files changed, 47 insertions(+), 71 deletions(-) create mode 100644 frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts diff --git a/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx b/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx index 00e99eb7..f6f13877 100644 --- a/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx +++ b/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx @@ -9,14 +9,12 @@ import { } from '@ionic/react'; import { useTr } from '../../../hooks/useTr'; import { FilterKind } from '../../super-tool/SuperDocumentViewerPage/ToolBox'; -import { - useGetPericopiesTrLazyQuery, - useSubscribeToRecomendedPericopiesChangedSubscription, -} from '../../../generated/graphql'; +import { useGetPericopiesTrQuery } from '../../../generated/graphql'; import { useAppContext } from '../../../hooks/useAppContext'; -import { useCallback, useEffect } from 'react'; +import { useCallback } from 'react'; import { langInfo2langInput } from '../../../../../utils'; import { PAGE_SIZE } from '../../../const/commonConst'; +import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useCusomSubscribeToRecomendedPericopiesChanged'; export type PericopiesTrListProps = { documentId: string; @@ -31,75 +29,35 @@ export function PericopiesTrList({ }: PericopiesTrListProps) { const { tr } = useTr(); const [present] = useIonToast(); - const [ - getPericopiesTr, - { data: pericopies, fetchMore, loading, refetch: refetchPericopiesTrQuery }, - ] = useGetPericopiesTrLazyQuery(); - - const { data: recomendedPericopiesChangedSubscriptionData } = - useSubscribeToRecomendedPericopiesChangedSubscription({}); const { states: { global: { - langauges: { sourceLang, targetLang }, + langauges: { + documentPage: { source: sourceLang, target: targetLang }, + }, }, }, } = useAppContext(); - useEffect(() => { - if ( - recomendedPericopiesChangedSubscriptionData?.recommendedPericopiesChanged - .documentId !== documentId - ) { - return; - } - refetchPericopiesTrQuery(); - }, [ - documentId, - recomendedPericopiesChangedSubscriptionData, - refetchPericopiesTrQuery, - ]); + const { data: pericopies, fetchMore } = useGetPericopiesTrQuery({ + variables: { + documentId, + targetLang: langInfo2langInput(targetLang || { lang: { tag: '' } }), + filter: stringFilter, + onlyNotTranslatedTo: + filterKind === FilterKind.NotTranslated && targetLang + ? langInfo2langInput(targetLang) + : null, + onlyTranslatedTo: + filterKind === FilterKind.Translated && targetLang + ? langInfo2langInput(targetLang) + : null, + first: PAGE_SIZE, + }, + }); - useEffect(() => { - if (!targetLang) { - present({ - message: tr('Target language is not defined'), - duration: 1500, - position: 'top', - color: 'danger', - }); - return; - } - if (!loading) { - getPericopiesTr({ - variables: { - documentId, - targetLang: langInfo2langInput(targetLang), - filter: stringFilter, - onlyNotTranslatedTo: - filterKind === FilterKind.NotTranslated && targetLang - ? langInfo2langInput(targetLang) - : null, - onlyTranslatedTo: - filterKind === FilterKind.Translated && targetLang - ? langInfo2langInput(targetLang) - : null, - first: PAGE_SIZE, - }, - }); - } - }, [ - getPericopiesTr, - targetLang, - loading, - sourceLang, - present, - tr, - documentId, - stringFilter, - filterKind, - ]); + useSubscribeToRecomendedPericopiesChangedSubscription(); const handleInfinite = useCallback( async (ev: IonInfiniteScrollCustomEvent) => { @@ -150,10 +108,7 @@ export function PericopiesTrList({ return ( <> -
- {loading && } -
- {pericopies && + {pericopies ? ( pericopies.getPericopiesTr.edges.map( (pericopeTr) => pericopeTr.node && ( @@ -172,7 +127,10 @@ export function PericopiesTrList({ }} /> ), - )} + ) + ) : ( +
{}
+ )}
diff --git a/frontend/src/components/super-tool/SuperDocumentViewer/SuperDocumentViewer.tsx b/frontend/src/components/super-tool/SuperDocumentViewer/SuperDocumentViewer.tsx index 60b8c18c..b062a2cf 100644 --- a/frontend/src/components/super-tool/SuperDocumentViewer/SuperDocumentViewer.tsx +++ b/frontend/src/components/super-tool/SuperDocumentViewer/SuperDocumentViewer.tsx @@ -43,4 +43,5 @@ export function SuperDocumentViewer({ /> ); } + return null; } diff --git a/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx b/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx index 01ae09ea..56bd8013 100644 --- a/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx +++ b/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx @@ -23,6 +23,7 @@ import { NavArrowDown } from '../../common/icons/NavArrowDown'; import { NavArrowUp } from '../../common/icons/NavArrowUp'; import { SuperDocumentViewer } from '../SuperDocumentViewer/SuperDocumentViewer'; import { SuperPericopiesTranslator } from '../SuperPericopiesTranslator'; +import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useCusomSubscribeToRecomendedPericopiesChanged'; export function SuperDocumentViewerPage() { const { tr } = useTr(); @@ -55,7 +56,6 @@ export function SuperDocumentViewerPage() { document_id, }, }); - useIonViewDidEnter(() => { setPageStatus('shown'); }); @@ -64,6 +64,8 @@ export function SuperDocumentViewerPage() { setPageStatus('hidden'); }); + useSubscribeToRecomendedPericopiesChangedSubscription(); + const handleToggleMode = useCallback(() => { setMode((mode) => { if (mode === 'view') { diff --git a/frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts b/frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts new file mode 100644 index 00000000..e35d4ee5 --- /dev/null +++ b/frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts @@ -0,0 +1,15 @@ +import { + GetPericopiesTrDocument, + useSubscribeToRecomendedPericopiesChangedSubscription as useGenSubscribeToRecomendedPericopiesChangedSubscription, +} from '../generated/graphql'; + +export function useSubscribeToRecomendedPericopiesChangedSubscription() { + return useGenSubscribeToRecomendedPericopiesChangedSubscription({ + onData: ({ data, client }) => { + client.refetchQueries({ + include: [GetPericopiesTrDocument], + }); + console.log(data); + }, + }); +} From d15c2ba84b4fe90a61c2806f029b86c15a812da0 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 09:43:16 -0500 Subject: [PATCH 06/18] feat: add cache bursting --- .github/workflows/dev.yml | 8 +++ frontend/.eslintrc.cjs | 2 +- frontend/package.json | 2 +- frontend/src/App.tsx | 48 ++++++++----- frontend/src/hooks/useCacheBuster.ts | 103 +++++++++++++++++++++++++++ package.json | 1 + 6 files changed, 145 insertions(+), 19 deletions(-) create mode 100644 frontend/src/hooks/useCacheBuster.ts diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 9a90cd1d..8ac64278 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -15,6 +15,14 @@ jobs: - name: Checkout uses: actions/checkout@v1 + - name: "Automated Version Bump" + id: version-bump + uses: "phips28/gh-action-bump-version@master" + with: + tag-prefix: "v" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Log in to Docker Hub uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 6ff974f9..591c3078 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -11,7 +11,7 @@ module.exports = { 'plugin:prettier/recommended', ], plugins: ['react', 'react-hooks'], - ignorePatterns: ['src/generated/graphql.tsx'], + ignorePatterns: ['src/generated/graphql.tsx', 'generate-build-version.js'], parserOptions: { ecmaVersion: 2020, }, diff --git a/frontend/package.json b/frontend/package.json index a1cedb31..79e344ff 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,7 @@ "dev": "vite", "build:test": "tsc && vite build --mode test", "build:local": "tsc && vite build --mode local-dev", - "build:staging": "tsc && vite build --mode staging", + "build:staging": "node generate-build-version && tsc && vite build --mode staging", "build:prod": "tsc && vite build", "format": "prettier --write \"src/**/*.{ts,tsx,md,mdx,js,jsx}\"", "preview": "vite preview", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 283e50ad..bb5f453d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react'; import { Route } from 'react-router-dom'; import { IonApp, IonRouterOutlet, setupIonicReact } from '@ionic/react'; import { IonReactRouter } from '@ionic/react-router'; @@ -49,6 +50,8 @@ import { createUploadLink } from 'apollo-upload-client'; import { typePolicies } from './cacheTypePolicies'; import { createClient } from 'graphql-ws'; +import { useCacheBuster } from './hooks/useCacheBuster'; + console.info('Runninig in environment: ' + import.meta.env.MODE); const server_url = `${import.meta.env.VITE_APP_SERVER_URL}/graphql`; @@ -112,23 +115,34 @@ export const apollo_client = new ApolloClient({ (window as any).cacheApollo = apollo_client; const App: React.FC = () => { - return ( - - - - - - - - - - - - - - - - ); + const { loading, isLatestVersion, refreshCacheAndReload, latestVersion } = + useCacheBuster(); + + useEffect(() => { + if (!loading && !isLatestVersion) refreshCacheAndReload(latestVersion); + }, [loading, isLatestVersion, refreshCacheAndReload, latestVersion]); + + if (loading || !isLatestVersion) { + return null; + } else { + return ( + + + + + + + + + + + + + + + + ); + } }; export default App; diff --git a/frontend/src/hooks/useCacheBuster.ts b/frontend/src/hooks/useCacheBuster.ts new file mode 100644 index 00000000..b843b3f7 --- /dev/null +++ b/frontend/src/hooks/useCacheBuster.ts @@ -0,0 +1,103 @@ +import { useEffect, useState, useCallback } from 'react'; + +import packageJson from '../../../package.json'; +const appVersion = packageJson.version; + +const semverGreaterThan = (versionA: string, versionB: string) => { + const versionsA = versionA.split(/\./g); + + const versionsB = versionB.split(/\./g); + while (versionsA.length || versionsB.length) { + const a = Number(versionsA.shift()); + + const b = Number(versionsB.shift()); + // eslint-disable-next-line no-continue + if (a === b) continue; + // eslint-disable-next-line no-restricted-globals + return a > b || isNaN(b); + } + return false; +}; + +export const useCacheBuster = () => { + const [state, setState] = useState<{ + loading: boolean; + isLatestVersion: boolean; + latestVersion: string; + }>({ + loading: true, + isLatestVersion: false, + latestVersion: '', + }); + + const refreshCacheAndReload = useCallback(async (version: string) => { + try { + if (caches) { + // Service worker cache should be cleared with caches.delete() + caches.keys().then(function (names) { + for (const name of names) caches.delete(name); + }); + } + localStorage.clear(); + localStorage.setItem('APP_VERSION', version); + + window.location.reload(); + } catch (err) { + console.error(err); + } + }, []); + + useEffect(() => { + fetch('/meta.json') + .then((response) => response.json()) + .then((meta) => { + const latestVersion = meta.version; + const currentVersion = appVersion; + const localStorageAppVersion = localStorage.getItem('APP_VERSION'); + + const shouldForceRefresh = semverGreaterThan( + latestVersion, + currentVersion, + ); + + let invalidPersistedData = false; + if ( + !localStorageAppVersion || + semverGreaterThan(latestVersion, localStorageAppVersion as string) + ) { + invalidPersistedData = true; + } + if (shouldForceRefresh || invalidPersistedData) { + if (shouldForceRefresh) + console.info( + 'info:::: ', + `We have a new version - ${latestVersion}. Should force refresh`, + ); + if (invalidPersistedData) + console.info( + 'info:::: ', + `You have invalid persisted data - ${latestVersion}. Should force refresh`, + ); + console.error( + `We have a new version - ${latestVersion}. Should force refresh`, + ); + setState({ loading: false, isLatestVersion: false, latestVersion }); + } else { + console.info( + 'info:::: ', + `You already have the latest version - ${latestVersion}. No cache refresh needed.`, + ); + console.error( + `You already have the latest version - ${latestVersion}. No cache refresh needed.`, + ); + setState({ loading: false, isLatestVersion: true, latestVersion }); + } + }); + }, []); + return { + loading: state.loading, + isLatestVersion: state.isLatestVersion, + latestVersion: state.latestVersion, + refreshCacheAndReload, + }; +}; diff --git a/package.json b/package.json index 0a2a8832..fd3effcb 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,5 @@ { + "version": "0.0.1", "devDependencies": { "@playwright/test": "^1.40.0" } From dbeb3bcd04138c32f943a6cb1171e75e4785fbca Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 09:53:02 -0500 Subject: [PATCH 07/18] chore: update dockerfile --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c1d49227..768246a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ WORKDIR /usr/src/etenlab/crowd-rocks COPY frontend /frontend/ COPY api /api/ COPY utils /utils/ +COPY ./package.json ./package.json ARG BUILD_MODE From 2e7e9ddda4ebb7f06ffa382a7c39371aa3f93927 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 09:59:07 -0500 Subject: [PATCH 08/18] update dockerfile --- Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 768246a8..524f1683 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,10 +3,7 @@ FROM node:16 # Create app directory WORKDIR /usr/src/etenlab/crowd-rocks -COPY frontend /frontend/ -COPY api /api/ -COPY utils /utils/ -COPY ./package.json ./package.json +COPY . / ARG BUILD_MODE From e5108e8f4974f63123602cdcdfe1d58fbc8e9cf4 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 10:30:46 -0500 Subject: [PATCH 09/18] change package.json --- frontend/.gitignore | 1 + frontend/package.json | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/.gitignore b/frontend/.gitignore index 68eba805..071a04d7 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -32,3 +32,4 @@ dist/ /test-results/ /playwright-report/ /playwright/.cache/ +/public/meta.json diff --git a/frontend/package.json b/frontend/package.json index 79e344ff..f7a82a98 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,10 +5,10 @@ "type": "module", "scripts": { "dev": "vite", - "build:test": "tsc && vite build --mode test", - "build:local": "tsc && vite build --mode local-dev", + "build:test": "node generate-build-version && tsc && vite build --mode test", + "build:local": "node generate-build-version && tsc && vite build --mode local-dev", "build:staging": "node generate-build-version && tsc && vite build --mode staging", - "build:prod": "tsc && vite build", + "build:prod": "node generate-build-version && tsc && vite build", "format": "prettier --write \"src/**/*.{ts,tsx,md,mdx,js,jsx}\"", "preview": "vite preview", "test.e2e": "cypress run", From 288b7f33501653a7da15d512a6e0d92bcad7281c Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 10:37:19 -0500 Subject: [PATCH 10/18] udpate package.json --- frontend/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index f7a82a98..7256cbfe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,10 +5,10 @@ "type": "module", "scripts": { "dev": "vite", - "build:test": "node generate-build-version && tsc && vite build --mode test", - "build:local": "node generate-build-version && tsc && vite build --mode local-dev", - "build:staging": "node generate-build-version && tsc && vite build --mode staging", - "build:prod": "node generate-build-version && tsc && vite build", + "build:test": "node ./generate-build-version.js && tsc && vite build --mode test", + "build:local": "node ./generate-build-version.js && tsc && vite build --mode local-dev", + "build:staging": "node ./generate-build-version.js && tsc && vite build --mode staging", + "build:prod": "node ./generate-build-version.js && tsc && vite build", "format": "prettier --write \"src/**/*.{ts,tsx,md,mdx,js,jsx}\"", "preview": "vite preview", "test.e2e": "cypress run", From dec8ca38480ca125006faae99c9a5b92bbf324e1 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 10:52:46 -0500 Subject: [PATCH 11/18] change: package.json --- frontend/package.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 7256cbfe..b709711d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,10 +5,12 @@ "type": "module", "scripts": { "dev": "vite", - "build:test": "node ./generate-build-version.js && tsc && vite build --mode test", - "build:local": "node ./generate-build-version.js && tsc && vite build --mode local-dev", - "build:staging": "node ./generate-build-version.js && tsc && vite build --mode staging", - "build:prod": "node ./generate-build-version.js && tsc && vite build", + "generate-build-version": "node generate-build-version", + "prebuild": "npm run generate-build-version", + "build:test": "tsc && vite build --mode test", + "build:local": "tsc && vite build --mode local-dev", + "build:staging": "tsc && vite build --mode staging", + "build:prod": "tsc && vite build", "format": "prettier --write \"src/**/*.{ts,tsx,md,mdx,js,jsx}\"", "preview": "vite preview", "test.e2e": "cypress run", From 400113876a765adc803990470748541753612b72 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 11:15:02 -0500 Subject: [PATCH 12/18] change package.json --- frontend/.eslintrc.cjs | 2 +- frontend/generate-build-version.cjs | 22 ++++++++++++++++++++++ frontend/package.json | 10 +++++----- 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 frontend/generate-build-version.cjs diff --git a/frontend/.eslintrc.cjs b/frontend/.eslintrc.cjs index 591c3078..2a9e49ec 100644 --- a/frontend/.eslintrc.cjs +++ b/frontend/.eslintrc.cjs @@ -11,7 +11,7 @@ module.exports = { 'plugin:prettier/recommended', ], plugins: ['react', 'react-hooks'], - ignorePatterns: ['src/generated/graphql.tsx', 'generate-build-version.js'], + ignorePatterns: ['src/generated/graphql.tsx', 'generate-build-version.cjs'], parserOptions: { ecmaVersion: 2020, }, diff --git a/frontend/generate-build-version.cjs b/frontend/generate-build-version.cjs new file mode 100644 index 00000000..5c634d38 --- /dev/null +++ b/frontend/generate-build-version.cjs @@ -0,0 +1,22 @@ +/* generate-build-version.js */ + +var fs = require('fs'); + +var packageJson = fs.readFileSync('../package.json', 'utf8'); + +var appVersion = JSON.parse(packageJson).version; + +var jsonData = { + version: appVersion, +}; + +var jsonContent = JSON.stringify(jsonData); + +fs.writeFile('./public/meta.json', jsonContent, 'utf8', function (err) { + if (err) { + console.log('An error occured while writing JSON Object to meta.json'); + return console.log(err); + } + + console.log('meta.json file has been saved with latest version number'); +}); diff --git a/frontend/package.json b/frontend/package.json index b709711d..173d7059 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,12 +5,12 @@ "type": "module", "scripts": { "dev": "vite", - "generate-build-version": "node generate-build-version", + "generate-build-version": "node ./generate-build-version.cjs", "prebuild": "npm run generate-build-version", - "build:test": "tsc && vite build --mode test", - "build:local": "tsc && vite build --mode local-dev", - "build:staging": "tsc && vite build --mode staging", - "build:prod": "tsc && vite build", + "build:test": "npm run generate-build-version && tsc && vite build --mode test", + "build:local": "npm run generate-build-version && tsc && vite build --mode local-dev", + "build:staging": "npm run generate-build-version && tsc && vite build --mode staging", + "build:prod": "npm run generate-build-version && tsc && vite build", "format": "prettier --write \"src/**/*.{ts,tsx,md,mdx,js,jsx}\"", "preview": "vite preview", "test.e2e": "cypress run", From 21937d132fc59c3529dfc75b0c662215bfb1bc39 Mon Sep 17 00:00:00 2001 From: Ihor_S Date: Tue, 5 Dec 2023 17:51:56 +0100 Subject: [PATCH 13/18] feat: subscription for best pericope translation --- api/src/common/subscription-token.ts | 1 + .../pericope-tr.resolver.ts | 59 +++++++--- .../pericope-tr.service.ts | 48 +++----- .../components/pericope-translations/types.ts | 19 ++-- .../pericopies/pericopies.module.ts | 2 - .../pericopies/pericopies.resolver.ts | 9 +- api/src/components/pericopies/types.ts | 4 + api/src/schema.gql | 15 ++- frontend/graphql.schema.json | 103 +++++++++++++----- .../PericopeTranslationsList.tsx | 3 + .../PericopiesTrListPage/PericopiesTrList.tsx | 2 +- .../pericope-translations/gql.graphql | 15 ++- .../SuperDocumentViewerPage.tsx | 4 +- frontend/src/generated/graphql.tsx | 65 +++++++++-- .../useSubscribeToRecomendedPericopies.ts | 21 ++++ ...SubscribeToRecomendedPericopiesChanged.ts} | 0 .../useTogglePericopeTrVoteStatusMutation.ts | 27 +---- 17 files changed, 266 insertions(+), 131 deletions(-) create mode 100644 frontend/src/hooks/useSubscribeToRecomendedPericopies.ts rename frontend/src/hooks/{useCusomSubscribeToRecomendedPericopiesChanged.ts => useSubscribeToRecomendedPericopiesChanged.ts} (100%) diff --git a/api/src/common/subscription-token.ts b/api/src/common/subscription-token.ts index bfb9121f..b326ec51 100644 --- a/api/src/common/subscription-token.ts +++ b/api/src/common/subscription-token.ts @@ -9,6 +9,7 @@ export class SubscriptionToken { static pericopiesAdded = 'pericopiesAdded'; static pericopeDeleted = 'pericopeDeleted'; static pericopeVoteStatusToggled = 'pericopeVoteStatusToggled'; + static bestPericopeTrChanged = 'bestPericopeTrChanged'; static recommendedPericopiesChanged = 'recommendedPericopiesChanged'; static questionsAdded = 'questionsAdded'; static questionsOnWordRangeAdded = 'questionsOnWordRangeAdded'; diff --git a/api/src/components/pericope-translations/pericope-tr.resolver.ts b/api/src/components/pericope-translations/pericope-tr.resolver.ts index 1574e1d6..723e9d4d 100644 --- a/api/src/components/pericope-translations/pericope-tr.resolver.ts +++ b/api/src/components/pericope-translations/pericope-tr.resolver.ts @@ -7,22 +7,24 @@ import { Mutation, Query, Resolver, + Subscription, } from '@nestjs/graphql'; import { PericopeTrService } from './pericope-tr.service'; import { AddPericopeTranslationInput, + BestPericopeTrChanged, GetPericopeTranslationsInput, GetPericopiesTrInput, PericopeTranslation, PericopeTranslationsOutput, - PericopeTrVoteStatusAndBestTrListOutput, + PericopeTrVoteStatusAndBestTrOutput, PericopiesTextsWithTranslationConnection, } from './types'; import { BearerTokenAuthGuard } from '../../guards/bearer-token-auth.guard'; import { ErrorType } from '../../common/types'; -import { LanguageInput } from '../common/types'; import { PUB_SUB } from '../../pubSub.module'; import { PubSub } from 'graphql-subscriptions'; +import { SubscriptionToken } from '../../common/subscription-token'; @Injectable() @Resolver() @@ -61,40 +63,57 @@ export class PericopeTrResolver { } @UseGuards(BearerTokenAuthGuard) - @Mutation(() => PericopeTrVoteStatusAndBestTrListOutput) + @Mutation(() => PericopeTrVoteStatusAndBestTrOutput) async togglePericopeTrVoteStatus( @Args('pericope_translation_id', { type: () => ID }) pericope_translation_id: string, @Args('vote', { type: () => Boolean }) vote: boolean, @Context() req: any, - ): Promise { + ): Promise { Logger.log( `${JSON.stringify(pericope_translation_id)}`, `PericopeTrResolver#togglePericopeTrVoteStatus`, ); - const vote_status_list = await this.pericopeTrService.toggleVoteStatus( + const { pericopeId, lang } = ( + await this.pericopeTrService.getPericopeIdsAndLangsOfTranslationIds([ + pericope_translation_id, + ]) + )[0]; + + const oldBestTr = + await this.pericopeTrService.getRecomendedPericopeTranslation( + pericopeId, + lang, + ); + + const vote_status = await this.pericopeTrService.toggleVoteStatus( pericope_translation_id, vote, req.req.token as string, ); - const pIdsLangs: { pericopeId: string; lang: LanguageInput }[] = - await this.pericopeTrService.getPericopeIdsAndLangsOfTranslationIds( - vote_status_list.vote_status_list.map((v) => v.pericope_translation_id), + const best_translation = + await this.pericopeTrService.getRecomendedPericopeTranslation( + pericopeId, + lang, ); - const bestTrListPromises: Promise[] = - pIdsLangs.map((pIdLang) => { - return this.pericopeTrService.getRecomendedPericopeTranslation( - pIdLang.pericopeId, - pIdLang.lang, - ); + if ( + best_translation?.pericope_translation_id !== + oldBestTr?.pericope_translation_id + ) { + this.pubSub.publish(SubscriptionToken.bestPericopeTrChanged, { + [SubscriptionToken.bestPericopeTrChanged]: { + newPericopeTr: best_translation, + newVoteStatus: vote_status.vote_status, + } as BestPericopeTrChanged, }); + } return { - ...vote_status_list, - best_translation_list: await Promise.all(bestTrListPromises), + ...vote_status, + best_translation, }; } @@ -128,4 +147,12 @@ export class PericopeTrResolver { }; } } + + @Subscription(() => BestPericopeTrChanged, { + name: SubscriptionToken.bestPericopeTrChanged, + }) + async bestPericopeTrChanged() { + console.log('PericopeTrResolver#bestPericopeTrChanged'); + return this.pubSub.asyncIterator(SubscriptionToken.bestPericopeTrChanged); + } } diff --git a/api/src/components/pericope-translations/pericope-tr.service.ts b/api/src/components/pericope-translations/pericope-tr.service.ts index 609a7ffb..6ee58fbc 100644 --- a/api/src/components/pericope-translations/pericope-tr.service.ts +++ b/api/src/components/pericope-translations/pericope-tr.service.ts @@ -1,9 +1,7 @@ -import { Inject, Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { ErrorType } from '../../common/types'; import { calc_vote_weight } from '../../common/utility'; import { PostgresService } from '../../core/postgres.service'; -import { PUB_SUB } from '../../pubSub.module'; -import { PubSub } from 'graphql-subscriptions'; import { LanguageInput } from '../common/types'; import { PericopiesService, @@ -31,8 +29,7 @@ import { GetPericopiesTrInput, PericopeTranslation, PericopeTranslationWithVotes, - PericopeTrVoteStatus, - PericopeTrVoteStatusListOutput, + PericopeTrVoteStatusOutput, PericopiesTextsWithTranslationConnection, PericopiesTextsWithTranslationEdge, } from './types'; @@ -49,7 +46,6 @@ export class PericopeTrService { constructor( private pg: PostgresService, private pericopiesService: PericopiesService, - @Inject(PUB_SUB) private readonly pubSub: PubSub, ) {} async getPericopiesTextsWithTranslationConnection( @@ -345,7 +341,7 @@ export class PericopeTrService { pericope_translation_id: string, vote: boolean, token: string, - ): Promise { + ): Promise { try { const res = await this.pg.pool.query( ...togglePericopeTrVoteStatusSql({ @@ -365,55 +361,43 @@ export class PericopeTrService { ) { return { error: creatingError, - vote_status_list: [], + vote_status: null, }; } - return this.getVoteStatusFromIds([pericope_translation_id]); + return this.getVoteStatusOfPericopeTrId(pericope_translation_id); } catch (e) { console.error(e); } return { error: ErrorType.UnknownError, - vote_status_list: [], + vote_status: null, }; } - async getVoteStatusFromIds( - pericopeTrIds: string[], - ): Promise { + async getVoteStatusOfPericopeTrId( + pericopeTrId: string, + ): Promise { try { const res = await this.pg.pool.query( - ...getPericopeTrVoteStatusFromPericopeIdsSql(pericopeTrIds), - ); - - const voteStatusMap = new Map(); - - res.rows.forEach((row) => - voteStatusMap.set(row.pericope_translation_id, row), + ...getPericopeTrVoteStatusFromPericopeIdsSql([pericopeTrId]), ); return { error: ErrorType.NoError, - vote_status_list: pericopeTrIds.map((pericope_translation_id) => { - const voteStatus = voteStatusMap.get(pericope_translation_id + ''); - - return voteStatus - ? voteStatus - : { - pericope_translation_id: pericope_translation_id + '', - upvotes: 0, - downvotes: 0, - }; - }), + vote_status: { + pericope_translation_id: res.rows[0].pericope_translation_id, + upvotes: res.rows[0].upvotes || 0, + downvotes: res.rows[0].downvotes || 0, + }, }; } catch (e) { Logger.error(e); } return { error: ErrorType.UnknownError, - vote_status_list: [], + vote_status: null, }; } diff --git a/api/src/components/pericope-translations/types.ts b/api/src/components/pericope-translations/types.ts index 4fdaab0f..0741e23d 100644 --- a/api/src/components/pericope-translations/types.ts +++ b/api/src/components/pericope-translations/types.ts @@ -101,17 +101,20 @@ export class PericopeTrVoteStatus { } @ObjectType() -export class PericopeTrVoteStatusListOutput extends GenericOutput { - @Field(() => [PericopeTrVoteStatus]) - vote_status_list: PericopeTrVoteStatus[]; +export class PericopeTrVoteStatusOutput extends GenericOutput { + @Field(() => PericopeTrVoteStatus) + vote_status: PericopeTrVoteStatus | null; } @ObjectType() -export class PericopeTrVoteStatusAndBestTrListOutput extends PericopeTrVoteStatusListOutput { - @Field(() => [PericopeTranslation]) - best_translation_list: Array; +export class PericopeTrVoteStatusAndBestTrOutput extends PericopeTrVoteStatusOutput { + @Field(() => PericopeTranslation) + best_translation: PericopeTranslation | null; } @ObjectType() -export class RecomendedPericopiesChangedAtDocumentId extends GenericOutput { - @Field(() => String) documentId: string; +export class BestPericopeTrChanged extends GenericOutput { + @Field(() => PericopeTranslation, { nullable: true }) + newPericopeTr: PericopeTranslation | null; + @Field(() => PericopeTrVoteStatus, { nullable: true }) + newVoteStatus: PericopeTrVoteStatus | null; } diff --git a/api/src/components/pericopies/pericopies.module.ts b/api/src/components/pericopies/pericopies.module.ts index 8a5caa54..e11b60bb 100644 --- a/api/src/components/pericopies/pericopies.module.ts +++ b/api/src/components/pericopies/pericopies.module.ts @@ -8,14 +8,12 @@ import { PericopiesResolver } from './pericopies.resolver'; import { PericopeVotesService } from './pericope-votes.service'; import { PericopiesService } from './pericopies.service'; import { AuthorizationModule } from '../authorization/authorization.module'; -import { PericopeTrModule } from '../pericope-translations/pericope-tr.module'; @Module({ imports: [ forwardRef(() => CoreModule), forwardRef(() => DocumentsModule), forwardRef(() => AuthorizationModule), - forwardRef(() => PericopeTrModule), ], providers: [PericopiesService, PericopeVotesService, PericopiesResolver], exports: [PericopiesService, PericopeVotesService], diff --git a/api/src/components/pericopies/pericopies.resolver.ts b/api/src/components/pericopies/pericopies.resolver.ts index 400eed9f..8294203c 100644 --- a/api/src/components/pericopies/pericopies.resolver.ts +++ b/api/src/components/pericopies/pericopies.resolver.ts @@ -14,10 +14,7 @@ import { SubscriptionToken } from 'src/common/subscription-token'; import { PUB_SUB } from 'src/pubSub.module'; import { getBearer } from 'src/common/utility'; -import { - GetPericopeTextInput, - RecomendedPericopiesChangedAtDocumentId, -} from '../pericope-translations/types'; +import { GetPericopeTextInput } from '../pericope-translations/types'; import { PericopeVotesService } from './pericope-votes.service'; import { PericopiesService } from './pericopies.service'; @@ -28,8 +25,8 @@ import { PericopeWithVotesListConnection, PericopeTextWithDescription, PericopeDeleteOutput, + RecomendedPericopiesChangedAtDocumentId, } from './types'; -import { PericopeTrService } from '../pericope-translations/pericope-tr.service'; @Injectable() @Resolver() @@ -38,7 +35,6 @@ export class PericopiesResolver { @Inject(PUB_SUB) private readonly pubSub: PubSub, private pericopiesService: PericopiesService, private pericopeVotesService: PericopeVotesService, - private pericopeTrService: PericopeTrService, ) {} @Query(() => PericopiesOutput) @@ -127,7 +123,6 @@ export class PericopiesResolver { name: SubscriptionToken.recommendedPericopiesChanged, }) async subscribeToRecommendedPericopiesChanged() { - console.log('subscribeToRecommendedPericopiesChanged'); return this.pubSub.asyncIterator( SubscriptionToken.recommendedPericopiesChanged, ); diff --git a/api/src/components/pericopies/types.ts b/api/src/components/pericopies/types.ts index 8a82b008..f4250a7a 100644 --- a/api/src/components/pericopies/types.ts +++ b/api/src/components/pericopies/types.ts @@ -93,3 +93,7 @@ export class PericopeTextWithDescription extends GenericOutput { @Field(() => String) pericope_text: string; @Field(() => String) pericope_description_text: string; } +@ObjectType() +export class RecomendedPericopiesChangedAtDocumentId extends GenericOutput { + @Field(() => String) documentId: string; +} diff --git a/api/src/schema.gql b/api/src/schema.gql index f77ba692..f4c1f989 100644 --- a/api/src/schema.gql +++ b/api/src/schema.gql @@ -48,6 +48,12 @@ type AvatarUpdateOutput { user: User } +type BestPericopeTrChanged { + error: ErrorType! + newPericopeTr: PericopeTranslation + newVoteStatus: PericopeTrVoteStatus +} + input BotTranslateDocumentInput { botType: BotType! documentId: String! @@ -706,7 +712,7 @@ type Mutation { threadUpsert(input: ThreadUpsertInput!): ThreadOutput! toggleFlagWithRef(name: String!, parent_id: String!, parent_table: TableNameType!): FlagsOutput! toggleMapVoteStatus(is_original: Boolean!, map_id: ID!, vote: Boolean!): MapVoteStatusOutputRow! - togglePericopeTrVoteStatus(pericope_translation_id: ID!, vote: Boolean!): PericopeTrVoteStatusAndBestTrListOutput! + togglePericopeTrVoteStatus(pericope_translation_id: ID!, vote: Boolean!): PericopeTrVoteStatusAndBestTrOutput! togglePericopeVoteStatus(pericope_id: ID!, vote: Boolean!): PericopeVoteStatusOutput! togglePhraseDefinitionVoteStatus(phrase_definition_id: ID!, vote: Boolean!): DefinitionVoteStatusOutputRow! togglePhraseToPhraseTrVoteStatus(phrase_to_phrase_translation_id: ID!, vote: Boolean!): PhraseToPhraseTranslationVoteStatusOutputRow! @@ -829,10 +835,10 @@ type PericopeTrVoteStatus { upvotes: Int! } -type PericopeTrVoteStatusAndBestTrListOutput { - best_translation_list: [PericopeTranslation!]! +type PericopeTrVoteStatusAndBestTrOutput { + best_translation: PericopeTranslation! error: ErrorType! - vote_status_list: [PericopeTrVoteStatus!]! + vote_status: PericopeTrVoteStatus! } type PericopeTranslation { @@ -1533,6 +1539,7 @@ type Subscription { TranslationReport: TranslateAllWordsAndPhrasesByBotResult! ZipMapReport: ZipMapResult! answersAdded: AnswersOutput! + bestPericopeTrChanged: BestPericopeTrChanged! documentAdded: DocumentUploadOutput! pericopeDeleted: PericopeDeleteOutput! pericopeVoteStatusToggled: PericopeVoteStatusOutput! diff --git a/frontend/graphql.schema.json b/frontend/graphql.schema.json index 0c0dfdf3..79c6cca6 100644 --- a/frontend/graphql.schema.json +++ b/frontend/graphql.schema.json @@ -458,6 +458,57 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "BestPericopeTrChanged", + "description": null, + "fields": [ + { + "name": "error", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "ErrorType", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newPericopeTr", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PericopeTranslation", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "newVoteStatus", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "PericopeTrVoteStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "SCALAR", "name": "Boolean", @@ -7405,7 +7456,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "PericopeTrVoteStatusAndBestTrListOutput", + "name": "PericopeTrVoteStatusAndBestTrOutput", "ofType": null } }, @@ -10253,28 +10304,20 @@ }, { "kind": "OBJECT", - "name": "PericopeTrVoteStatusAndBestTrListOutput", + "name": "PericopeTrVoteStatusAndBestTrOutput", "description": null, "fields": [ { - "name": "best_translation_list", + "name": "best_translation", "description": null, "args": [], "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "PericopeTranslation", - "ofType": null - } - } + "kind": "OBJECT", + "name": "PericopeTranslation", + "ofType": null } }, "isDeprecated": false, @@ -10297,24 +10340,16 @@ "deprecationReason": null }, { - "name": "vote_status_list", + "name": "vote_status", "description": null, "args": [], "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "PericopeTrVoteStatus", - "ofType": null - } - } + "kind": "OBJECT", + "name": "PericopeTrVoteStatus", + "ofType": null } }, "isDeprecated": false, @@ -20290,6 +20325,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "bestPericopeTrChanged", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "BestPericopeTrChanged", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "documentAdded", "description": null, diff --git a/frontend/src/components/pericope-translations/PericopeTranslationPage/PericopeTranslationsList.tsx b/frontend/src/components/pericope-translations/PericopeTranslationPage/PericopeTranslationsList.tsx index d31de16d..0e00d0c4 100644 --- a/frontend/src/components/pericope-translations/PericopeTranslationPage/PericopeTranslationsList.tsx +++ b/frontend/src/components/pericope-translations/PericopeTranslationPage/PericopeTranslationsList.tsx @@ -9,6 +9,7 @@ import { TextCard } from '../../common/TextCard'; import { useCallback, useEffect } from 'react'; import { useIonToast } from '@ionic/react'; import { useTogglePericopeTrVoteStatusMutation } from '../../../hooks/useTogglePericopeTrVoteStatusMutation'; +import { useBestPericopeTrChangedSubscription } from '../../../hooks/useSubscribeToRecomendedPericopies'; export type PericopeTranslationListProps = { translations: PericopeTranslationWithVotes[]; @@ -22,6 +23,8 @@ export function PericopeTranslationList({ const [toggleTrVoteStatus, { data: voteData, loading: voteLoading }] = useTogglePericopeTrVoteStatusMutation(); + useBestPericopeTrChangedSubscription(); + useEffect(() => { if (voteLoading) return; if ( diff --git a/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx b/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx index f6f13877..035b80de 100644 --- a/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx +++ b/frontend/src/components/pericope-translations/PericopiesTrListPage/PericopiesTrList.tsx @@ -14,7 +14,7 @@ import { useAppContext } from '../../../hooks/useAppContext'; import { useCallback } from 'react'; import { langInfo2langInput } from '../../../../../utils'; import { PAGE_SIZE } from '../../../const/commonConst'; -import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useCusomSubscribeToRecomendedPericopiesChanged'; +import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useSubscribeToRecomendedPericopiesChanged'; export type PericopiesTrListProps = { documentId: string; diff --git a/frontend/src/components/pericope-translations/gql.graphql b/frontend/src/components/pericope-translations/gql.graphql index 48d6d6c5..7d4062a6 100644 --- a/frontend/src/components/pericope-translations/gql.graphql +++ b/frontend/src/components/pericope-translations/gql.graphql @@ -134,10 +134,10 @@ mutation TogglePericopeTrVoteStatus( vote: $vote ) { error - vote_status_list { + vote_status { ...PericopeTrVoteStatusFragment } - best_translation_list { + best_translation { ...PericopeTranslationFragment } } @@ -148,3 +148,14 @@ subscription SubscribeToRecomendedPericopiesChanged { documentId } } + +subscription BestPericopeTrChanged { + bestPericopeTrChanged { + newPericopeTr { + ...PericopeTranslationFragment + } + newVoteStatus { + ...PericopeTrVoteStatusFragment + } + } +} diff --git a/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx b/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx index 56bd8013..2b9532dd 100644 --- a/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx +++ b/frontend/src/components/super-tool/SuperDocumentViewerPage/SuperDocumentViewerPage.tsx @@ -23,7 +23,8 @@ import { NavArrowDown } from '../../common/icons/NavArrowDown'; import { NavArrowUp } from '../../common/icons/NavArrowUp'; import { SuperDocumentViewer } from '../SuperDocumentViewer/SuperDocumentViewer'; import { SuperPericopiesTranslator } from '../SuperPericopiesTranslator'; -import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useCusomSubscribeToRecomendedPericopiesChanged'; +import { useSubscribeToRecomendedPericopiesChangedSubscription } from '../../../hooks/useSubscribeToRecomendedPericopiesChanged'; +import { useBestPericopeTrChangedSubscription } from '../../../hooks/useSubscribeToRecomendedPericopies'; export function SuperDocumentViewerPage() { const { tr } = useTr(); @@ -65,6 +66,7 @@ export function SuperDocumentViewerPage() { }); useSubscribeToRecomendedPericopiesChangedSubscription(); + useBestPericopeTrChangedSubscription(); const handleToggleMode = useCallback(() => { setMode((mode) => { diff --git a/frontend/src/generated/graphql.tsx b/frontend/src/generated/graphql.tsx index bfd24fbc..708a459a 100644 --- a/frontend/src/generated/graphql.tsx +++ b/frontend/src/generated/graphql.tsx @@ -71,6 +71,13 @@ export type AvatarUpdateOutput = { user?: Maybe; }; +export type BestPericopeTrChanged = { + __typename?: 'BestPericopeTrChanged'; + error: ErrorType; + newPericopeTr?: Maybe; + newVoteStatus?: Maybe; +}; + export type BotTranslateDocumentInput = { botType: BotType; documentId: Scalars['String']['input']; @@ -778,7 +785,7 @@ export type Mutation = { threadUpsert: ThreadOutput; toggleFlagWithRef: FlagsOutput; toggleMapVoteStatus: MapVoteStatusOutputRow; - togglePericopeTrVoteStatus: PericopeTrVoteStatusAndBestTrListOutput; + togglePericopeTrVoteStatus: PericopeTrVoteStatusAndBestTrOutput; togglePericopeVoteStatus: PericopeVoteStatusOutput; togglePhraseDefinitionVoteStatus: DefinitionVoteStatusOutputRow; togglePhraseToPhraseTrVoteStatus: PhraseToPhraseTranslationVoteStatusOutputRow; @@ -1399,11 +1406,11 @@ export type PericopeTrVoteStatus = { upvotes: Scalars['Int']['output']; }; -export type PericopeTrVoteStatusAndBestTrListOutput = { - __typename?: 'PericopeTrVoteStatusAndBestTrListOutput'; - best_translation_list: Array; +export type PericopeTrVoteStatusAndBestTrOutput = { + __typename?: 'PericopeTrVoteStatusAndBestTrOutput'; + best_translation: PericopeTranslation; error: ErrorType; - vote_status_list: Array; + vote_status: PericopeTrVoteStatus; }; export type PericopeTranslation = { @@ -2678,6 +2685,7 @@ export type Subscription = { TranslationReport: TranslateAllWordsAndPhrasesByBotResult; ZipMapReport: ZipMapResult; answersAdded: AnswersOutput; + bestPericopeTrChanged: BestPericopeTrChanged; documentAdded: DocumentUploadOutput; pericopeDeleted: PericopeDeleteOutput; pericopeVoteStatusToggled: PericopeVoteStatusOutput; @@ -3970,13 +3978,18 @@ export type TogglePericopeTrVoteStatusMutationVariables = Exact<{ }>; -export type TogglePericopeTrVoteStatusMutation = { __typename?: 'Mutation', togglePericopeTrVoteStatus: { __typename?: 'PericopeTrVoteStatusAndBestTrListOutput', error: ErrorType, vote_status_list: Array<{ __typename?: 'PericopeTrVoteStatus', pericope_translation_id: string, upvotes: number, downvotes: number }>, best_translation_list: Array<{ __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } }> } }; +export type TogglePericopeTrVoteStatusMutation = { __typename?: 'Mutation', togglePericopeTrVoteStatus: { __typename?: 'PericopeTrVoteStatusAndBestTrOutput', error: ErrorType, vote_status: { __typename?: 'PericopeTrVoteStatus', pericope_translation_id: string, upvotes: number, downvotes: number }, best_translation: { __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } } } }; export type SubscribeToRecomendedPericopiesChangedSubscriptionVariables = Exact<{ [key: string]: never; }>; export type SubscribeToRecomendedPericopiesChangedSubscription = { __typename?: 'Subscription', recommendedPericopiesChanged: { __typename?: 'RecomendedPericopiesChangedAtDocumentId', documentId: string } }; +export type BestPericopeTrChangedSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type BestPericopeTrChangedSubscription = { __typename?: 'Subscription', bestPericopeTrChanged: { __typename?: 'BestPericopeTrChanged', newPericopeTr?: { __typename?: 'PericopeTranslation', pericope_translation_id: string, pericope_id: string, translation: string, translation_description?: string | null, created_at: string, created_by_user: { __typename?: 'User', user_id: string, avatar: string, avatar_url?: string | null, is_bot: boolean }, language: { __typename?: 'LanguageOutput', language_code: string, dialect_code?: string | null, geo_code?: string | null } } | null, newVoteStatus?: { __typename?: 'PericopeTrVoteStatus', pericope_translation_id: string, upvotes: number, downvotes: number } | null } }; + export type PericopeFragmentFragment = { __typename?: 'Pericope', pericope_id: string, start_word: string }; export type PericopeVoteStatusFragmentFragment = { __typename?: 'PericopeVoteStatus', pericope_id: string, upvotes: number, downvotes: number }; @@ -8499,10 +8512,10 @@ export const TogglePericopeTrVoteStatusDocument = gql` vote: $vote ) { error - vote_status_list { + vote_status { ...PericopeTrVoteStatusFragment } - best_translation_list { + best_translation { ...PericopeTranslationFragment } } @@ -8565,6 +8578,41 @@ export function useSubscribeToRecomendedPericopiesChangedSubscription(baseOption } export type SubscribeToRecomendedPericopiesChangedSubscriptionHookResult = ReturnType; export type SubscribeToRecomendedPericopiesChangedSubscriptionResult = Apollo.SubscriptionResult; +export const BestPericopeTrChangedDocument = gql` + subscription BestPericopeTrChanged { + bestPericopeTrChanged { + newPericopeTr { + ...PericopeTranslationFragment + } + newVoteStatus { + ...PericopeTrVoteStatusFragment + } + } +} + ${PericopeTranslationFragmentFragmentDoc} +${PericopeTrVoteStatusFragmentFragmentDoc}`; + +/** + * __useBestPericopeTrChangedSubscription__ + * + * To run a query within a React component, call `useBestPericopeTrChangedSubscription` and pass it any options that fit your needs. + * When your component renders, `useBestPericopeTrChangedSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useBestPericopeTrChangedSubscription({ + * variables: { + * }, + * }); + */ +export function useBestPericopeTrChangedSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(BestPericopeTrChangedDocument, options); + } +export type BestPericopeTrChangedSubscriptionHookResult = ReturnType; +export type BestPericopeTrChangedSubscriptionResult = Apollo.SubscriptionResult; export const GetPericopiesByDocumentIdDocument = gql` query GetPericopiesByDocumentId($document_id: ID!, $first: Int, $after: ID) { getPericopiesByDocumentId( @@ -12012,6 +12060,7 @@ export const namedOperations = { SubscribeToDocumentAdded: 'SubscribeToDocumentAdded', SubscribeToZipMap: 'SubscribeToZipMap', SubscribeToRecomendedPericopiesChanged: 'SubscribeToRecomendedPericopiesChanged', + BestPericopeTrChanged: 'BestPericopeTrChanged', SubscribeToPericopiesAdded: 'SubscribeToPericopiesAdded', SubscribeToPericopieDeleted: 'SubscribeToPericopieDeleted', SubscribeToPericopeVoteStatusToggled: 'SubscribeToPericopeVoteStatusToggled', diff --git a/frontend/src/hooks/useSubscribeToRecomendedPericopies.ts b/frontend/src/hooks/useSubscribeToRecomendedPericopies.ts new file mode 100644 index 00000000..84e156e7 --- /dev/null +++ b/frontend/src/hooks/useSubscribeToRecomendedPericopies.ts @@ -0,0 +1,21 @@ +import { updateCacheWithTogglePericopeTrVoteStatus } from '../cacheUpdators/togglePericopeTrVoteStatus'; +import { useBestPericopeTrChangedSubscription as useGenBestPericopeTrChangedSubscription } from '../generated/graphql'; + +export function useBestPericopeTrChangedSubscription() { + return useGenBestPericopeTrChangedSubscription({ + onData: ({ data, client }) => { + if ( + !data.data?.bestPericopeTrChanged.newPericopeTr || + !data.data.bestPericopeTrChanged.newVoteStatus + ) + return; + updateCacheWithTogglePericopeTrVoteStatus( + client.cache, + data.data.bestPericopeTrChanged.newVoteStatus, + data.data.bestPericopeTrChanged.newPericopeTr, + ); + client.cache; + console.log(data); + }, + }); +} diff --git a/frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts b/frontend/src/hooks/useSubscribeToRecomendedPericopiesChanged.ts similarity index 100% rename from frontend/src/hooks/useCusomSubscribeToRecomendedPericopiesChanged.ts rename to frontend/src/hooks/useSubscribeToRecomendedPericopiesChanged.ts diff --git a/frontend/src/hooks/useTogglePericopeTrVoteStatusMutation.ts b/frontend/src/hooks/useTogglePericopeTrVoteStatusMutation.ts index bd58a62e..e0e5d065 100644 --- a/frontend/src/hooks/useTogglePericopeTrVoteStatusMutation.ts +++ b/frontend/src/hooks/useTogglePericopeTrVoteStatusMutation.ts @@ -21,15 +21,12 @@ export function useTogglePericopeTrVoteStatusMutation() { if ( !errors && data && - data.togglePericopeTrVoteStatus.vote_status_list[0] && + data.togglePericopeTrVoteStatus.vote_status && data.togglePericopeTrVoteStatus.error === ErrorType.NoError ) { - // note: index [0] is because we are toggling single vote related to one definite pericope_translaion_id - // so we're expecting only single row. - const newVoteStatus = - data.togglePericopeTrVoteStatus.vote_status_list[0]; + const newVoteStatus = data.togglePericopeTrVoteStatus.vote_status; const newBestTranslation = - data.togglePericopeTrVoteStatus.best_translation_list[0]; + data.togglePericopeTrVoteStatus.best_translation; updateCacheWithTogglePericopeTrVoteStatus( cache, @@ -49,21 +46,3 @@ export function useTogglePericopeTrVoteStatusMutation() { }, }); } - -// export function useSubscribeToPericopeVoteStatusToggledSubscription() { -// return useGeneratedSubscribeToPericopeVoteStatusToggledSubscription({ -// onData({ client, data: result }) { -// const { data, error } = result; -// if ( -// !error && -// data && -// data.pericopeVoteStatusToggled.vote_status && -// data.pericopeVoteStatusToggled.error === ErrorType.NoError -// ) { -// const newVoteStatus = data.pericopeVoteStatusToggled.vote_status; - -// updateCacheWithTogglePericopeVoteStatus(client.cache, newVoteStatus); -// } -// }, -// }); -// } From 91470c4149ce121c0a6e23799b876b00c7c77d01 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 11:56:07 -0500 Subject: [PATCH 14/18] update workflow --- .github/workflows/dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 8ac64278..b813b187 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -21,7 +21,7 @@ jobs: with: tag-prefix: "v" env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.ADMIN_GITHUB_TOKEN }} - name: Log in to Docker Hub uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 From 6917a3f334fc0a32cf9e6c41e3272b7e0799ff02 Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 12:41:46 -0500 Subject: [PATCH 15/18] change for test --- frontend/src/App.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bb5f453d..bcd9e8b1 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -146,3 +146,4 @@ const App: React.FC = () => { }; export default App; +// test From 15f5926ba6bb3546231dd40da95669a12dfd7e9d Mon Sep 17 00:00:00 2001 From: hiroshi Date: Tue, 5 Dec 2023 12:43:57 -0500 Subject: [PATCH 16/18] update cache --- frontend/src/App.tsx | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bcd9e8b1..1a3502fc 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -146,4 +146,4 @@ const App: React.FC = () => { }; export default App; -// test +// test 1 diff --git a/package.json b/package.json index fd3effcb..654d7504 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.0.1", + "version": "0.0.3", "devDependencies": { "@playwright/test": "^1.40.0" } From 442b0e449ae1c740446413fdcb4cafd08e42e1ce Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Tue, 5 Dec 2023 17:47:11 +0000 Subject: [PATCH 17/18] ci: version bump to v0.0.4 --- package-lock.json | 6 ++++-- package.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index eefb11cf..8f5e2c1f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,8 @@ "": { "devDependencies": { "@playwright/test": "^1.40.0" - } + }, + "version": "0.0.4" }, "node_modules/@playwright/test": { "version": "1.40.0", @@ -67,5 +68,6 @@ "node": ">=16" } } - } + }, + "version": "0.0.4" } diff --git a/package.json b/package.json index 654d7504..92bef4af 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.0.3", + "version": "0.0.4", "devDependencies": { "@playwright/test": "^1.40.0" } From 0cc5ec47a894533ddae503595cd9a5116629bb24 Mon Sep 17 00:00:00 2001 From: Automated Version Bump Date: Tue, 5 Dec 2023 18:51:19 +0000 Subject: [PATCH 18/18] ci: version bump to v0.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f5e2c1f..d55d25cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "devDependencies": { "@playwright/test": "^1.40.0" }, - "version": "0.0.4" + "version": "0.1.0" }, "node_modules/@playwright/test": { "version": "1.40.0", @@ -69,5 +69,5 @@ } } }, - "version": "0.0.4" + "version": "0.1.0" } diff --git a/package.json b/package.json index 92bef4af..8eceb916 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.0.4", + "version": "0.1.0", "devDependencies": { "@playwright/test": "^1.40.0" }