File
creationDate
|
creationDate: Date | null
|
Type : Date | null
|
label
|
label: string | null
|
Type : string | null
|
paused
|
paused: boolean | null
|
Type : boolean | null
|
reminder
|
reminder: string | null
|
Type : string | null
|
import { Item } from '../item.class'
import {
Schedule,
ScheduleConfig
} from '../schedules'
import { Subject } from 'rxjs'
import {
SymptomCheckConfig,
QuestionScheduleConfig,
isSymptomCheckConfig,
assertSymptomCheckConfig,
isQuestionScheduleConfig,
defaultSymptomCheckConfig
} from './symptom-checks.commons'
// Is there duplication with the interfaces in interfaces.ts?
// Answer: No. The following interfaces are NOT Configs! they make
// use of Classes like Date or Schedule.
export interface SymptomCheckMeta {
label : string | null
paused : boolean | null
defaultSchedule : Schedule | null
creationDate : Date | null
reminder : string | null //HH:MM
}
export interface QuestionSchedule {
questionId : string,
schedule : Schedule
}
export class SymptomCheck extends Item<SymptomCheckConfig> {
declare public id : string
public meta! : SymptomCheckMeta
public questionSchedules! : QuestionSchedule[]
protected updateSubject = new Subject<string>()
public update$ = this.updateSubject.asObservable()
public static acceptsAsConfig = isSymptomCheckConfig
constructor(config: SymptomCheckConfig = defaultSymptomCheckConfig){ super(config) }
set config(config: SymptomCheckConfig){
assertSymptomCheckConfig(config)
this.meta = {
label: config.meta.label || null,
paused: config.meta.paused || false,
reminder: config.meta.reminder || null,
creationDate: config.meta.creationDate
? new Date(config.meta.creationDate)
: null,
defaultSchedule: new Schedule(config.meta.defaultSchedule)
}
this.questionSchedules = []
config.questions.forEach( (q: string | QuestionScheduleConfig) => {
return isQuestionScheduleConfig(q)
? this.addQuestionId(q.id, q.schedule)
: this.addQuestionId(q)
})
this.id = config.id
this.update('set config')
}
get config(): SymptomCheckConfig {
const meta = {
label: this.meta.label || null,
creationDate: this.meta.creationDate && this.meta.creationDate.toISOString() || null,
reminder: this.meta.reminder,
paused: this.meta.paused ? true : false,
defaultSchedule: this.meta.defaultSchedule && this.meta.defaultSchedule.config || null
}
//Remove empty keys:
for(const key in meta) if(meta[key as keyof typeof meta ] === null) delete meta[key as keyof typeof meta ]
const questions = this.questionSchedules.map( item => {
return item.schedule && !item.schedule.matches(meta.defaultSchedule)
? {id: item.questionId, schedule: item.schedule.config}
: item.questionId
})
const id = this.id
return { meta, questions, id }
}
/**
* Trigger emit message on .update$ observable.
*/
public update(message?: string) : void {
// update() may be called from the constructor
// this.updateSubject will then not yet exist.
if(this.updateSubject) this.updateSubject.next(message)
}
public addQuestionId(id: string, config?: ScheduleConfig): void {
const schedule = config && !this.meta.defaultSchedule.matches(config)
? new Schedule(config)
: this.meta.defaultSchedule
this.questionSchedules.push({questionId: id, schedule })
}
public togglePause(force?: boolean) : void {
this.meta.paused = typeof force == 'boolean'
? force
: !this.meta.paused
this.update('meta.paused')
}
public coversQuestionIds(ids: string[]) : boolean {
return this.questionSchedules
.map( questionSchedule => questionSchedule.questionId )
.some( id => ids.includes(id) )
}
public getDueQuestionIds(date: Date): string[] {
return this.questionSchedules
.filter( qs => qs.schedule.matches(date) )
.map( qs => qs.questionId )
}
get questionIds(): string[] { return this.questionSchedules.map( item => item.questionId) }
}