All files / app/codeCharta/ui/filePanel fileSelectionMode.service.ts

100% Statements 30/30
87.5% Branches 14/16
100% Functions 11/11
100% Lines 25/25

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 54 55 56 57 58 595x 5x 5x   5x 5x 5x 5x     5x 6x   6x       9x   6x           6x 6x       3x                   6x 6x 4x 4x   4x 4x 4x 4x   2x         4x      
import { Injectable, OnDestroy } from "@angular/core"
import { Store, State } from "@ngrx/store"
import { pairwise, tap, filter } from "rxjs"
import { CcState } from "../../codeCharta.model"
import { FileSelectionState, FileState } from "../../model/files/files"
import { isDeltaState, isEqual } from "../../model/files/files.helper"
import { setDelta, setFiles } from "../../state/store/files/files.actions"
import { filesSelector } from "../../state/store/files/files.selector"
 
@Injectable({ providedIn: "root" })
export class FileSelectionModeService implements OnDestroy {
    lastSetFilesOfPreviousMode: FileState[] = []
 
    private subscription = this.store
        .select(filesSelector)
        .pipe(
            pairwise(),
            filter(([oldFiles, newFiles]) => isDeltaState(oldFiles) !== isDeltaState(newFiles) || newFiles.length === 0),
            tap(([oldFiles, newFiles]) => {
                this.lastSetFilesOfPreviousMode = newFiles.length === 0 ? newFiles : oldFiles
            })
        )
        .subscribe()
 
    constructor(
        private store: Store<CcState>,
        private state: State<CcState>
    ) {}
 
    ngOnDestroy(): void {
        this.subscription.unsubscribe()
    }
 
    /** Toggles selection mode between "Standard" and "Delta".
     * If available it restores the last set selected files of new mode.
     * When it switches to delta mode and there is no reference
     * file selected, it sets the first selected file as reference as there
     * must be a reference file for anything being rendered at all.
     */
    toggle() {
        const isCurrentlyStandardMode = this.lastSetFilesOfPreviousMode.length === 0 || isDeltaState(this.lastSetFilesOfPreviousMode)
        if (isCurrentlyStandardMode) {
            const existingFiles = filesSelector(this.state.getValue())
            this.lastSetFilesOfPreviousMode = this.filterNoneExisting(existingFiles, this.lastSetFilesOfPreviousMode)
            const referenceFile =
                this.lastSetFilesOfPreviousMode.find(file => file.selectedAs === FileSelectionState.Reference) ??
                existingFiles.find(file => file.selectedAs === FileSelectionState.Partial)
            const comparisonFile = this.lastSetFilesOfPreviousMode.find(file => file.selectedAs === FileSelectionState.Comparison)
            this.store.dispatch(setDelta({ referenceFile: referenceFile.file, comparisonFile: comparisonFile?.file }))
        } else {
            this.store.dispatch(setFiles({ value: this.lastSetFilesOfPreviousMode }))
        }
    }
 
    private filterNoneExisting(existingFileStates: FileState[], fileStates: FileState[]) {
        return fileStates.filter(fileState => existingFileStates.find(existingFileState => isEqual(existingFileState.file, fileState.file)))
    }
}