File

projects/netgrif-components-core/src/lib/side-menu/content-components/new-case/abstract-new-case.component.ts

Index

Properties

Properties

value
value: string
Type : string
version
version: string
Type : string
Optional
viewValue
viewValue: string
Type : string
import {Component, Inject, OnDestroy, ViewChild} from '@angular/core';
import {FormBuilder, FormControl, Validators} from '@angular/forms';
import {StepperSelectionEvent} from '@angular/cdk/stepper';
import {map, startWith, tap} from 'rxjs/operators';
import {BehaviorSubject, combineLatest, Observable, ReplaySubject, Subscription} from 'rxjs';
import {SnackBarService} from '../../../snack-bar/services/snack-bar.service';
import {NAE_SIDE_MENU_CONTROL} from '../../side-menu-injection-token';
import {SideMenuControl} from '../../models/side-menu-control';
import {CaseResourceService} from '../../../resources/engine-endpoint/case-resource.service';
import {NewCaseInjectionData} from './model/new-case-injection-data';
import {TranslateService} from '@ngx-translate/core';
import {Hotkey, HotkeysService} from 'angular2-hotkeys';
import {MatToolbar} from '@angular/material/toolbar';
import semver from 'semver';
import {CreateCaseEventOutcome} from '../../../event/model/event-outcomes/case-outcomes/create-case-event-outcome';
import {EventOutcomeMessageResource} from '../../../resources/interface/message-resource';
import {MatOption} from '@angular/material/core';
import {LoadingEmitter} from '../../../utility/loading-emitter';

interface Form {
    value: string;
    viewValue: string;
    version?: string;
}

@Component({
    selector: 'ncc-abstract-new-case',
    template: ''
})
export abstract class AbstractNewCaseComponent implements OnDestroy {

    processFormControl = new FormControl('', Validators.required);
    titleFormControl = new FormControl('', Validators.required);
    netVersion: string;

    options: Array<Form> = [];
    colors: Array<Form> = [
        {value: 'panel-primary-icon', viewValue: 'Primary'},
        {value: 'panel-accent-icon', viewValue: 'Accent'},
    ];
    filteredOptions$: Observable<Array<Form>>;
    @ViewChild('toolbar') toolbar: MatToolbar;

    @ViewChild('stepper1') stepper1;
    @ViewChild('stepper2') stepper2;

    public loadingSubmit: LoadingEmitter;
    protected _options$: ReplaySubject<Array<Form>>;
    protected _injectedData: NewCaseInjectionData;
    protected _hasMultipleNets$: ReplaySubject<boolean>;
    protected _notInitialized$: BehaviorSubject<boolean>;
    private _allowedNetsSubscription: Subscription;

    protected constructor(@Inject(NAE_SIDE_MENU_CONTROL) protected _sideMenuControl: SideMenuControl,
                          protected _formBuilder: FormBuilder,
                          protected _snackBarService: SnackBarService,
                          protected _caseResourceService: CaseResourceService,
                          protected _hotkeysService: HotkeysService,
                          protected _translate: TranslateService) {
        if (this._sideMenuControl.data) {
            this._injectedData = this._sideMenuControl.data as NewCaseInjectionData;
        }
        if (!this._injectedData) {
            this.closeNoNets();
        }
        this._hotkeysService.add(new Hotkey('enter', (event: KeyboardEvent): boolean => {
            this.nextStep();
            return false;
        }));

        this._hasMultipleNets$ = new ReplaySubject(1);
        this._notInitialized$ = new BehaviorSubject<boolean>(true);
        this._options$ = new ReplaySubject(1);
        this.loadingSubmit = new LoadingEmitter(false);

        this._allowedNetsSubscription = this._injectedData.allowedNets$.pipe(
            map(nets => nets.map(petriNet => ({
                value: petriNet.stringId,
                viewValue: petriNet.title,
                version: petriNet.version
            }))),
            map(nets => {
                if (!this._sideMenuControl.allVersionEnabled) {
                    return this.removeOldVersions(nets);
                } else {
                    return nets;
                }
            }),
            tap(options => {
                if (options.length === 0) {
                    this.closeNoNets();
                }
                this.options = options;
                this._hasMultipleNets$.next(options.length > 1);
            })
        ).subscribe(options => {
            this._options$.next(options);
            if (!this._notInitialized$.closed) {
                this._notInitialized$.next(false);
                this._notInitialized$.complete();
            }
        });

        this.filteredOptions$ = combineLatest([this._options$, this.processFormControl.valueChanges.pipe(startWith(''))]).pipe(
            map(sources => {
                const options = sources[0];
                const input = typeof sources[1] === 'string' || sources[1] === null ? sources[1] : sources[1].viewValue;
                return input ? this._filter(input, options) : options.slice();
            }),
            tap(filteredOptions => {
                if (filteredOptions.length === 1) {
                    this.processFormControl.setValue(filteredOptions[0], {emitEvent: false});
                }
            })
        );
    }

    ngOnDestroy(): void {
        this._hasMultipleNets$.complete();
        this.loadingSubmit.complete();
        this._allowedNetsSubscription.unsubscribe();
    }

    public get hasMultipleNets$(): Observable<boolean> {
        return this._hasMultipleNets$.asObservable();
    }

    public get notInitialized$(): Observable<boolean> {
        return this._notInitialized$.asObservable();
    }

    public stepChange($event: StepperSelectionEvent): void {
        this._sideMenuControl.publish({
            opened: true,
            message: 'Active step has changed',
            data: $event
        });
    }

    displayFn(process: Form): string {
        return process && process.viewValue ? process.viewValue : '';
    }

    public createNewCase(): void {
        if (this.loadingSubmit.value) {
            return
        }

        if (!this._sideMenuControl.isOpened()) {
            return
        }

        if (this.titleFormControl.valid || !this.isCaseTitleRequired()) {
            const newCase = {
                title: this.titleFormControl.value === '' ? null : this.titleFormControl.value,
                color: 'panel-primary-icon',
                netId: this.options.length === 1 ? this.options[0].value : this.processFormControl.value.value
            };
            this.loadingSubmit.on();
            this._caseResourceService.createCase(newCase)
                .subscribe(
                    (response: EventOutcomeMessageResource) => {
                        this.loadingSubmit.off();
                        if (!!response.outcome) {
                            this._snackBarService.openSuccessSnackBar(response.outcome.message === undefined
                                ? this._translate.instant('side-menu.new-case.createCase') + ' ' + newCase.title
                                : response.outcome.message);
                            this._sideMenuControl.close({
                                opened: false,
                                message: response.outcome.message === undefined
                                    ? 'Confirm new case setup'
                                    : response.outcome.message
                                ,
                                data: (response.outcome as CreateCaseEventOutcome).aCase
                            });
                        } else if (!!response.error) {
                            this._snackBarService.openWarningSnackBar(this._translate.instant('side-menu.new-case.createCaseError') + ' ' + newCase.title);
                            this._sideMenuControl.close({
                                opened: false,
                                message: response.error === undefined
                                    ? 'Confirm new case setup'
                                    : response.error
                            });
                        }
                        this.titleFormControl.markAsUntouched();
                        this.titleFormControl.setValue(null);
                    },
                    error => {
                        this.loadingSubmit.off();
                        this._snackBarService.openErrorSnackBar(error.message ? error.message : error);
                    }
                );
        }
    }

    /**
     * Function to filter out matchless options without accent and case-sensitive differences
     * @param value to compare matching options
     * @param options that should be filtered
     * @return  return matched options
     */
    protected _filter(value: string, options: Array<Form>): Array<Form> {
        const filterValue = value.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');

        return options.filter(option => option.viewValue.toLowerCase().normalize('NFD')
            .replace(/[\u0300-\u036f]/g, '').indexOf(filterValue) === 0);
    }

    protected closeNoNets() {
        this._snackBarService.openErrorSnackBar(this._translate.instant('side-menu.new-case.noNets'));
        this._sideMenuControl.close({
            opened: false
        });
    }

    nextStep() {
        if (this.stepper1) {
            if (this.stepper1.selectedIndex === 1) {
                this.createNewCase();
            } else {
                this.stepper1.next();
            }
        }
        if (this.stepper2) {
            if (this.stepper2.selectedIndex === 0) {
                this.createNewCase();
            } else {
                this.stepper2.next();
            }
        }
    }

    titleShortening() {
        let size;
        if (this.toolbar && this.toolbar._elementRef && this.toolbar._elementRef.nativeElement &&
            this.toolbar._elementRef.nativeElement.offsetWidth) {
            switch (this.toolbar._elementRef.nativeElement.offsetWidth) {
                case 296:
                    size = 22;
                    break;
                case 496:
                    size = 42;
                    break;
                case 246:
                    size = 18;
                    break;
                default:
                    size = 32;
                    break;
            }
        } else {
            size = 32;
        }

        const caze = this._translate.instant('side-menu.new-case.case');
        const name = typeof this.processFormControl.value === 'string' || this.processFormControl.value === null ?
            undefined : this.processFormControl.value.viewValue;
        const title = name === undefined ? caze : caze + ' - ' + name;
        if (title.length > size) {
            const tmp = title.slice(0, size);
            return tmp + '...';
        }
        return title;
    }

    private removeOldVersions(options: Array<Form>): Array<Form> {
        const tempNets = Object.assign([], options);
        const petriNetIds = new Set(options.map(form => form.value));
        const newestNets = new Array<Form>();

        for (const value of petriNetIds) {
            let current: Form = {value, version: '1.0.0', viewValue: ''};
            for (const net of tempNets) {
                if (value === net.value && !semver.lt(net.version, current.version)) {
                    current = net;
                }
            }
            newestNets.push(current);
        }
        return newestNets;
    }

    isCaseTitleEnabled(): boolean {
        return !!(this._injectedData?.newCaseCreationConfiguration?.enableCaseTitle ?? true);
    }

    isCaseTitleRequired(): boolean {
        return this.isCaseTitleEnabled() && !!(this._injectedData?.newCaseCreationConfiguration?.isCaseTitleRequired ?? true);
    }

    showVersion(option: MatOption): void {
        if (option !== undefined && option.value !== undefined && option.value.version !== undefined)
            this.netVersion = option.value.version;
    }

    checkVersion(viewValue: any): void {
        const currentOption = typeof viewValue === 'string' || viewValue === null ? undefined : viewValue.version;
        if (currentOption === undefined) {
            this.netVersion = '';
        }
    }

    toNextStep(viewValue: any): void {
        if (viewValue !== null && viewValue.value !== undefined) {
            this.stepper1.next();
        }
    }
}

result-matching ""

    No results matching ""