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