]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/shared-forms/select/select-checkbox-all.component.ts
Support ICU in TS components
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-forms / select / select-checkbox-all.component.ts
CommitLineData
dd24f1bb
C
1import { Component, forwardRef, Input } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import { Notifier } from '@app/core'
eaa52952 4import { prepareIcu } from '@app/helpers'
dd24f1bb
C
5import { SelectOptionsItem } from '../../../../types/select-options-item.model'
6import { ItemSelectCheckboxValue } from './select-checkbox.component'
7
8@Component({
9 selector: 'my-select-checkbox-all',
10 styleUrls: [ './select-shared.component.scss' ],
11
12 template: `
13 <my-select-checkbox
14 [(ngModel)]="selectedItems"
15 (ngModelChange)="onModelChange()"
16 [availableItems]="availableItems"
17 [selectableGroup]="true" [selectableGroupAsModel]="true"
18 [placeholder]="placeholder"
19 (focusout)="onBlur()"
20 >
21 </my-select-checkbox>`,
22
23 providers: [
24 {
25 provide: NG_VALUE_ACCESSOR,
26 useExisting: forwardRef(() => SelectCheckboxAllComponent),
27 multi: true
28 }
29 ]
30})
31export class SelectCheckboxAllComponent implements ControlValueAccessor {
32 @Input() availableItems: SelectOptionsItem[] = []
33 @Input() allGroupLabel: string
34
35 @Input() placeholder: string
36 @Input() maxItems: number
37
38 selectedItems: ItemSelectCheckboxValue[]
39
40 constructor (
41 private notifier: Notifier
42 ) {
43
44 }
45
46 propagateChange = (_: any) => { /* empty */ }
47
48 writeValue (items: string[]) {
49 this.selectedItems = items
50 ? items.map(l => ({ id: l }))
51 : [ { group: this.allGroupLabel } ]
52 }
53
54 registerOnChange (fn: (_: any) => void) {
55 this.propagateChange = fn
56 }
57
58 registerOnTouched () {
59 // Unused
60 }
61
62 onModelChange () {
63 if (!this.isMaxConstraintValid()) return
64
65 this.propagateChange(this.buildOutputItems())
66 }
67
68 onBlur () {
69 // Automatically use "All languages" if the user did not select any language
70 if (Array.isArray(this.selectedItems) && this.selectedItems.length === 0) {
71 this.selectedItems = [ { group: this.allGroupLabel } ]
72 }
73 }
74
75 private isMaxConstraintValid () {
76 if (!this.maxItems) return true
77
78 const outputItems = this.buildOutputItems()
79 if (!outputItems) return true
80
81 if (outputItems.length >= this.maxItems) {
eaa52952
C
82 this.notifier.error(
83 prepareIcu($localize`You can't select more than {maxItems, plural, =1 {1 item} other {{maxItems} items}}`)(
84 { maxItems: this.maxItems },
85 $localize`You can't select more than ${this.maxItems} items`
86 )
87 )
dd24f1bb
C
88
89 return false
90 }
91
92 return true
93 }
94
95 private buildOutputItems () {
96 if (!Array.isArray(this.selectedItems)) return undefined
97
98 // null means "All"
99 if (this.selectedItems.length === 0 || this.selectedItems.length === this.availableItems.length) {
100 return null
101 }
102
103 if (this.selectedItems.length === 1) {
104 const item = this.selectedItems[0]
105
106 const itemGroup = typeof item === 'string' || typeof item === 'number'
107 ? item
108 : item.group
109
110 if (itemGroup === this.allGroupLabel) return null
111 }
112
113 return this.selectedItems.map(l => {
114 if (typeof l === 'string' || typeof l === 'number') return l
115
116 if (l.group) return l.group
117
118 return l.id + ''
119 })
120 }
121}