All files / src/app/components/timetrack/work-time/break-tracker break.validator.ts

100% Statements 29/29
100% Branches 21/21
100% Functions 3/3
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53    4x 4x 4x 4x 4x         4x 13x 22x 22x 14x     8x 8x 10x     10x 1x   10x 1x     10x 1x     10x 1x     10x 1x     10x 1x   10x 6x   4x   8x    
import { AbstractControl, ValidationErrors, ValidatorFn } from "@angular/forms";
 
export enum FieldErrors {
    REQUIRED = "required",
    OUT_OF_WORKTIME = "outofworktime",
    OVERLAP = "overlap",
    FLIPPED = "flipped"
}
 
export type ErrorValues = Partial<Record<"start"|"end", FieldErrors>>;
 
export function validateBreaks (start?: number, end?: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        const workBreaks = control.value;
        if(!workBreaks || !workBreaks.length)
            return null;
 
        let lastBreak;
        const invalidBreaks = [];
        for(const [index, workBreak] of workBreaks.entries()) {
            const errors: ErrorValues = {};
 
            //No Start time defined
            if(!workBreak.start)
                errors.start = FieldErrors.REQUIRED;
            //No End time defined
            if(!workBreak.end)
                errors["end"] = FieldErrors.REQUIRED;
 
            // Break start should be before break end
            if(workBreak.start > workBreak.end)
                errors["end"] = FieldErrors.FLIPPED;
 
            // Break start after Workstart
            if(start && start > workBreak.start)
                errors["start"] = FieldErrors.OUT_OF_WORKTIME;
 
            // Break end after Workend
            if(end && end < workBreak.end)
                errors["end"] = FieldErrors.OUT_OF_WORKTIME;
 
            // Start should be after end of break before
            if(lastBreak && lastBreak.end! > workBreak.start)
                errors["start"] = FieldErrors.OVERLAP;
 
            if(Object.keys(errors).length)
                invalidBreaks[index] = errors;
            else
                lastBreak = workBreak;
        }
        return invalidBreaks.length ? {invalidBreaks} : null;
    };
}