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