blob: 2c3226f686ff727a9e025df74fc16c199db37bde (
plain) (
blame)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
import { Component, forwardRef, Input } from '@angular/core'
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
import { Notifier } from '@app/core'
import { prepareIcu } from '@app/helpers'
import { SelectOptionsItem } from '../../../../types/select-options-item.model'
import { ItemSelectCheckboxValue } from './select-checkbox.component'
@Component({
selector: 'my-select-checkbox-all',
styleUrls: [ './select-shared.component.scss' ],
template: `
<my-select-checkbox
[(ngModel)]="selectedItems"
(ngModelChange)="onModelChange()"
[availableItems]="availableItems"
[selectableGroup]="true" [selectableGroupAsModel]="true"
[placeholder]="placeholder"
(focusout)="onBlur()"
>
</my-select-checkbox>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectCheckboxAllComponent),
multi: true
}
]
})
export class SelectCheckboxAllComponent implements ControlValueAccessor {
@Input() availableItems: SelectOptionsItem[] = []
@Input() allGroupLabel: string
@Input() placeholder: string
@Input() maxItems: number
selectedItems: ItemSelectCheckboxValue[]
constructor (
private notifier: Notifier
) {
}
propagateChange = (_: any) => { /* empty */ }
writeValue (items: string[]) {
this.selectedItems = items
? items.map(l => ({ id: l }))
: [ { group: this.allGroupLabel } ]
}
registerOnChange (fn: (_: any) => void) {
this.propagateChange = fn
}
registerOnTouched () {
// Unused
}
onModelChange () {
if (!this.isMaxConstraintValid()) return
this.propagateChange(this.buildOutputItems())
}
onBlur () {
// Automatically use "All languages" if the user did not select any language
if (Array.isArray(this.selectedItems) && this.selectedItems.length === 0) {
this.selectedItems = [ { group: this.allGroupLabel } ]
}
}
private isMaxConstraintValid () {
if (!this.maxItems) return true
const outputItems = this.buildOutputItems()
if (!outputItems) return true
if (outputItems.length >= this.maxItems) {
this.notifier.error(
prepareIcu($localize`You can't select more than {maxItems, plural, =1 {1 item} other {{maxItems} items}}`)(
{ maxItems: this.maxItems },
$localize`You can't select more than ${this.maxItems} items`
)
)
return false
}
return true
}
private buildOutputItems () {
if (!Array.isArray(this.selectedItems)) return undefined
// null means "All"
if (this.selectedItems.length === 0 || this.selectedItems.length === this.availableItems.length) {
return null
}
if (this.selectedItems.length === 1) {
const item = this.selectedItems[0]
const itemGroup = typeof item === 'string' || typeof item === 'number'
? item
: item.group
if (itemGroup === this.allGroupLabel) return null
}
return this.selectedItems.map(l => {
if (typeof l === 'string' || typeof l === 'number') return l
if (l.group) return l.group
return l.id + ''
})
}
}
|