]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
fcfbf34f1d3ef23375a711646667a4e299d39025
[ceph-ci.git] /
1 import { Component, Input, OnChanges, OnInit } from '@angular/core';
2 import { FormControl, ValidatorFn } from '@angular/forms';
3
4 import { I18n } from '@ngx-translate/i18n-polyfill';
5 import * as _ from 'lodash';
6
7 import { CdFormGroup } from '../../forms/cd-form-group';
8 import { SelectBadgesMessages } from './select-badges-messages.model';
9 import { SelectBadgesOption } from './select-badges-option.model';
10
11 @Component({
12   selector: 'cd-select-badges',
13   templateUrl: './select-badges.component.html',
14   styleUrls: ['./select-badges.component.scss']
15 })
16 export class SelectBadgesComponent implements OnInit, OnChanges {
17   @Input()
18   data: Array<string> = [];
19   @Input()
20   options: Array<SelectBadgesOption> = [];
21   @Input()
22   messages = new SelectBadgesMessages({}, this.i18n);
23   @Input()
24   selectionLimit: number;
25   @Input()
26   customBadges = false;
27   @Input()
28   customBadgeValidators: ValidatorFn[] = [];
29   form: CdFormGroup;
30   filter: FormControl;
31   Object = Object;
32   filteredOptions: Array<SelectBadgesOption> = [];
33
34   constructor(private i18n: I18n) {}
35
36   ngOnInit() {
37     this.initFilter();
38     if (this.data.length > 0) {
39       this.initMissingOptions();
40     }
41     this.options = _.sortBy(this.options, ['name']);
42     this.updateOptions();
43   }
44
45   private initFilter() {
46     this.filter = new FormControl('', { validators: this.customBadgeValidators });
47     this.form = new CdFormGroup({ filter: this.filter });
48     this.filteredOptions = [...this.options];
49   }
50
51   private initMissingOptions() {
52     const options = this.options.map((option) => option.name);
53     const needToCreate = this.data.filter((option) => options.indexOf(option) === -1);
54     needToCreate.forEach((option) => this.addOption(option));
55     this.forceOptionsToReflectData();
56   }
57
58   private addOption(name: string) {
59     this.options.push(new SelectBadgesOption(false, name, ''));
60     this.options = _.sortBy(this.options, ['name']);
61     this.triggerSelection(this.options.find((option) => option.name === name));
62   }
63
64   triggerSelection(option: SelectBadgesOption) {
65     if (
66       !option ||
67       (this.selectionLimit && !option.selected && this.data.length >= this.selectionLimit)
68     ) {
69       return;
70     }
71     option.selected = !option.selected;
72     this.updateOptions();
73   }
74
75   private updateOptions() {
76     this.data.splice(0, this.data.length);
77     this.options.forEach((option: SelectBadgesOption) => {
78       if (option.selected) {
79         this.data.push(option.name);
80       }
81     });
82     this.updateFilter();
83   }
84
85   updateFilter() {
86     this.filteredOptions = this.options.filter((option) => option.name.includes(this.filter.value));
87   }
88
89   private forceOptionsToReflectData() {
90     this.options.forEach((option) => {
91       if (this.data.indexOf(option.name) !== -1) {
92         option.selected = true;
93       }
94     });
95   }
96
97   ngOnChanges() {
98     if (!this.options || !this.data || this.data.length === 0) {
99       return;
100     }
101     this.forceOptionsToReflectData();
102   }
103
104   selectOption() {
105     if (this.filteredOptions.length === 0) {
106       this.addCustomOption();
107     } else {
108       this.triggerSelection(this.filteredOptions[0]);
109       this.resetFilter();
110     }
111   }
112
113   addCustomOption() {
114     if (!this.isCreatable()) {
115       return;
116     }
117     this.addOption(this.filter.value);
118     this.resetFilter();
119   }
120
121   isCreatable() {
122     return (
123       this.customBadges &&
124       this.filter.valid &&
125       this.filter.value.length > 0 &&
126       this.filteredOptions.every((option) => option.name !== this.filter.value)
127     );
128   }
129
130   private resetFilter() {
131     this.filter.setValue('');
132     this.updateFilter();
133   }
134
135   removeItem(item: string) {
136     this.triggerSelection(
137       this.options.find((option: SelectBadgesOption) => option.name === item && option.selected)
138     );
139   }
140 }