import { AchievementsRepository } from '../services/achievement/achievements-repository.service' ; import { Achievement } from './achievement' ; import { AchievementStatus } from './achievement/achievement-status.type' ; export class VisualAchievement { readonly id : string ; readonly name : string ; readonly type : string ; readonly cardId : string ; readonly cardType : string ; readonly text : string ; readonly completionSteps : readonly CompletionStep [ ] ; public static create ( value ) { return Object . assign ( new VisualAchievement ( ) , value ) ; } public update ( value ) { if ( value . id !== this . id && this . completionSteps . map ( ( step ) => step . id ) . indexOf ( value . id ) === - 1 ) { return this ; } const completionStepsWithNewCompletions = this . updateCompletionSteps ( value ) ; const [ completionSteps , text ] = AchievementsRepository . buildCompletionSteps ( completionStepsWithNewCompletions , value , this . text ) ; return Object . assign ( new VisualAchievement ( ) , this , { completionSteps : completionSteps , text : text , } as VisualAchievement ) ; } public isFullyCompleted ( ) { return this . completionSteps . every ( ( step ) => step . numberOfCompletions > 0 ) ; } public achievementStatus ( ) { if ( this . completionSteps . every ( ( step ) => step . numberOfCompletions > 0 ) ) { return 'completed' ; } else if ( this . completionSteps . some ( ( step ) => step . numberOfCompletions > 0 ) ) { return 'partially-completed' ; } return 'missing' ; } public getFirstMissingStep ( ) { return this . completionSteps . find ( ( step ) => ! step . numberOfCompletions ) ; } private updateCompletionSteps ( value ) { return this . completionSteps . map ( ( step ) => { if ( step . id !== value . id ) { return step ; } return Object . assign ( step , { numberOfCompletions : value . numberOfCompletions || step . numberOfCompletions , progress : value . progress || step . progress , } as CompletionStep ) ; } ) ; } } export interface CompletionStep { readonly id : string ; readonly numberOfCompletions : number ; readonly icon : string ; readonly completedText : string ; readonly priority : number ; readonly progress ? : number ; text ( showTimes ? ) : string ; }