aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-02-09 16:35:48 +0100
committerChocobozzz <me@florianbigard.com>2021-02-10 11:36:40 +0100
commitead64cdf8d917fa0d6a20271e42378f38e5f2407 (patch)
tree681e9dba853107edab45d8185688dadde4850efb
parentb9c9fefe820fb0b3aaa3c2b5af73bafb29d890d0 (diff)
downloadPeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.tar.gz
PeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.tar.zst
PeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.zip
Support custom value in ng-select
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html61
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss3
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts42
-rw-r--r--client/src/app/shared/shared-forms/select/index.ts3
-rw-r--r--client/src/app/shared/shared-forms/select/select-custom-input.component.html14
-rw-r--r--client/src/app/shared/shared-forms/select/select-custom-input.component.scss0
-rw-r--r--client/src/app/shared/shared-forms/select/select-custom-input.component.ts44
-rw-r--r--client/src/app/shared/shared-forms/select/select-custom-value.component.html14
-rw-r--r--client/src/app/shared/shared-forms/select/select-custom-value.component.ts76
-rw-r--r--client/src/app/shared/shared-forms/select/select-options.component.html1
-rw-r--r--client/src/app/shared/shared-forms/select/select-options.component.ts1
-rw-r--r--client/src/app/shared/shared-forms/select/select-shared.component.scss15
-rw-r--r--client/src/app/shared/shared-forms/shared-form.module.ts12
13 files changed, 168 insertions, 118 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index 5f0a5ff6c..844620ca2 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -445,13 +445,11 @@
445 <span i18n>allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.</span> 445 <span i18n>allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.</span>
446 </span> 446 </span>
447 447
448 <div class="peertube-select-container"> 448 <div class="number-with-unit">
449 <select id="importConcurrency" formControlName="concurrency" class="form-control"> 449 <input type="number" name="importConcurrency" formControlName="concurrency" />
450 <option *ngFor="let option of concurrencyOptions" [value]="option"> 450 <span i18n>jobs in parallel</span>
451 {{ option }}
452 </option>
453 </select>
454 </div> 451 </div>
452
455 <div *ngIf="formErrors.import.concurrency" class="form-error">{{ formErrors.import.concurrency }}</div> 453 <div *ngIf="formErrors.import.concurrency" class="form-error">{{ formErrors.import.concurrency }}</div>
456 </div> 454 </div>
457 455
@@ -892,13 +890,13 @@
892 <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding</ng-container> 890 <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding</ng-container>
893 </span> 891 </span>
894 892
895 <div class="peertube-select-container"> 893 <my-select-custom-value
896 <select id="transcodingThreads" formControlName="threads" class="form-control"> 894 id="transcodingThreads"
897 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> 895 [items]="transcodingThreadOptions"
898 {{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}} 896 formControlName="threads"
899 </option> 897 [clearable]="false"
900 </select> 898 ></my-select-custom-value>
901 </div> 899
902 <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div> 900 <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div>
903 </div> 901 </div>
904 902
@@ -908,13 +906,11 @@
908 <span i18n>allows to transcode multiple files in parallel. ⚠️ Requires a PeerTube restart.</span> 906 <span i18n>allows to transcode multiple files in parallel. ⚠️ Requires a PeerTube restart.</span>
909 </span> 907 </span>
910 908
911 <div class="peertube-select-container"> 909 <div class="number-with-unit">
912 <select id="transcodingConcurrency" formControlName="concurrency" class="form-control"> 910 <input type="number" name="transcodingConcurrency" formControlName="concurrency" />
913 <option *ngFor="let option of concurrencyOptions" [value]="option"> 911 <span i18n>jobs in parallel</span>
914 {{ option }}
915 </option>
916 </select>
917 </div> 912 </div>
913
918 <div *ngIf="formErrors.transcoding.concurrency" class="form-error">{{ formErrors.transcoding.concurrency }}</div> 914 <div *ngIf="formErrors.transcoding.concurrency" class="form-error">{{ formErrors.transcoding.concurrency }}</div>
919 </div> 915 </div>
920 916
@@ -922,7 +918,7 @@
922 <label i18n for="transcodingProfile">Transcoding profile</label> 918 <label i18n for="transcodingProfile">Transcoding profile</label>
923 <span class="text-muted ml-1" i18n>new transcoding profiles can be added by PeerTube plugins</span> 919 <span class="text-muted ml-1" i18n>new transcoding profiles can be added by PeerTube plugins</span>
924 920
925 <ng-select 921 <my-select-options
926 id="transcodingProfile" 922 id="transcodingProfile"
927 formControlName="profile" 923 formControlName="profile"
928 [items]="getAvailableTranscodingProfile('vod')" 924 [items]="getAvailableTranscodingProfile('vod')"
@@ -935,7 +931,7 @@
935 <span class="text-muted" i18n>x264, targeting maximum device compatibility</span> 931 <span class="text-muted" i18n>x264, targeting maximum device compatibility</span>
936 </ng-container> 932 </ng-container>
937 </ng-template> 933 </ng-template>
938 </ng-select> 934 </my-select-options>
939 <div *ngIf="formErrors.transcoding.profile" class="form-error">{{ formErrors.transcoding.profile }}</div> 935 <div *ngIf="formErrors.transcoding.profile" class="form-error">{{ formErrors.transcoding.profile }}</div>
940 </div> 936 </div>
941 937
@@ -1007,10 +1003,10 @@
1007 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> 1003 <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }">
1008 <label i18n for="liveMaxDuration">Max live duration</label> 1004 <label i18n for="liveMaxDuration">Max live duration</label>
1009 1005
1010 <ng-select 1006 <my-select-options
1011 labelForId="liveMaxDuration" [items]="liveMaxDurationOptions" formControlName="maxDuration" 1007 labelForId="liveMaxDuration" [items]="liveMaxDurationOptions" formControlName="maxDuration"
1012 bindLabel="label" bindValue="value" [clearable]="false" [searchable]="false" 1008 bindLabel="label" bindValue="value" [clearable]="false" [searchable]="true"
1013 ></ng-select> 1009 ></my-select-options>
1014 </div> 1010 </div>
1015 1011
1016 </ng-container> 1012 </ng-container>
@@ -1069,13 +1065,12 @@
1069 <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding</ng-container> 1065 <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding</ng-container>
1070 </span> 1066 </span>
1071 1067
1072 <div class="peertube-select-container"> 1068 <my-select-custom-value
1073 <select id="liveTranscodingThreads" formControlName="threads" class="form-control"> 1069 id="liveTranscodingThreads"
1074 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> 1070 [items]="transcodingThreadOptions"
1075 {{ transcodingThreadOption.label }} {transcodingThreadOption.value, plural, =0 {} =1 {thread} other {threads}} 1071 formControlName="threads"
1076 </option> 1072 [clearable]="false"
1077 </select> 1073 ></my-select-custom-value>
1078 </div>
1079 <div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div> 1074 <div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div>
1080 </div> 1075 </div>
1081 1076
@@ -1083,7 +1078,7 @@
1083 <label i18n for="liveTranscodingProfile">Live transcoding profile</label> 1078 <label i18n for="liveTranscodingProfile">Live transcoding profile</label>
1084 <span class="text-muted ml-1" i18n>new live transcoding profiles can be added by PeerTube plugins</span> 1079 <span class="text-muted ml-1" i18n>new live transcoding profiles can be added by PeerTube plugins</span>
1085 1080
1086 <ng-select 1081 <my-select-options
1087 id="liveTranscodingProfile" 1082 id="liveTranscodingProfile"
1088 formControlName="profile" 1083 formControlName="profile"
1089 [items]="getAvailableTranscodingProfile('live')" 1084 [items]="getAvailableTranscodingProfile('live')"
@@ -1096,7 +1091,7 @@
1096 <span class="text-muted" i18n>x264, targeting maximum device compatibility</span> 1091 <span class="text-muted" i18n>x264, targeting maximum device compatibility</span>
1097 </ng-container> 1092 </ng-container>
1098 </ng-template> 1093 </ng-template>
1099 </ng-select> 1094 </my-select-options>
1100 <div *ngIf="formErrors.live.transcoding.profile" class="form-error">{{ formErrors.live.transcoding.profile }}</div> 1095 <div *ngIf="formErrors.live.transcoding.profile" class="form-error">{{ formErrors.live.transcoding.profile }}</div>
1101 </div> 1096 </div>
1102 1097
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
index 665247368..c12465d45 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss
@@ -42,7 +42,8 @@ input[type=checkbox] {
42 @include peertube-select-container($form-base-input-width); 42 @include peertube-select-container($form-base-input-width);
43} 43}
44 44
45ng-select, 45my-select-options,
46my-select-custom-value,
46my-select-checkbox { 47my-select-checkbox {
47 @include responsive-width($form-base-input-width); 48 @include responsive-width($form-base-input-width);
48 49
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
index 48fb86968..a9f72d7db 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
@@ -37,12 +37,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A
37 37
38 resolutions: { id: string, label: string, description?: string }[] = [] 38 resolutions: { id: string, label: string, description?: string }[] = []
39 liveResolutions: { id: string, label: string, description?: string }[] = [] 39 liveResolutions: { id: string, label: string, description?: string }[] = []
40 concurrencyOptions: number[] = []
41 transcodingThreadOptions: { label: string, value: number }[] = []
42 liveMaxDurationOptions: { label: string, value: number }[] = []
43 40
44 vodTranscodingProfileOptions: string[] = [] 41 transcodingThreadOptions: SelectOptionsItem[] = []
45 liveTranscodingProfileOptions: string[] = [] 42 liveMaxDurationOptions: SelectOptionsItem[] = []
46 43
47 languageItems: SelectOptionsItem[] = [] 44 languageItems: SelectOptionsItem[] = []
48 categoryItems: SelectOptionsItem[] = [] 45 categoryItems: SelectOptionsItem[] = []
@@ -99,23 +96,22 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A
99 this.liveResolutions = this.resolutions.filter(r => r.id !== '0p') 96 this.liveResolutions = this.resolutions.filter(r => r.id !== '0p')
100 97
101 this.transcodingThreadOptions = [ 98 this.transcodingThreadOptions = [
102 { value: 0, label: $localize`Auto (via ffmpeg)` }, 99 { id: 0, label: $localize`Auto (via ffmpeg)` },
103 { value: 1, label: '1' }, 100 { id: 1, label: '1' },
104 { value: 2, label: '2' }, 101 { id: 2, label: '2' },
105 { value: 4, label: '4' }, 102 { id: 4, label: '4' },
106 { value: 8, label: '8' } 103 { id: 8, label: '8' },
104 { id: 12, label: '12' },
105 { id: 16, label: '16' },
106 { id: 32, label: '32' }
107 ] 107 ]
108 this.concurrencyOptions = [ 1, 2, 3, 4, 5, 6 ]
109
110 this.vodTranscodingProfileOptions = [ 'default' ]
111 this.liveTranscodingProfileOptions = [ 'default' ]
112 108
113 this.liveMaxDurationOptions = [ 109 this.liveMaxDurationOptions = [
114 { value: -1, label: $localize`No limit` }, 110 { id: -1, label: $localize`No limit` },
115 { value: 1000 * 3600, label: $localize`1 hour` }, 111 { id: 1000 * 3600, label: $localize`1 hour` },
116 { value: 1000 * 3600 * 3, label: $localize`3 hours` }, 112 { id: 1000 * 3600 * 3, label: $localize`3 hours` },
117 { value: 1000 * 3600 * 5, label: $localize`5 hours` }, 113 { id: 1000 * 3600 * 5, label: $localize`5 hours` },
118 { value: 1000 * 3600 * 10, label: $localize`10 hours` } 114 { id: 1000 * 3600 * 10, label: $localize`10 hours` }
119 ] 115 ]
120 } 116 }
121 117
@@ -137,11 +133,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A
137 } 133 }
138 134
139 getAvailableTranscodingProfile (type: 'live' | 'vod') { 135 getAvailableTranscodingProfile (type: 'live' | 'vod') {
140 if (type === 'live') { 136 const profiles = type === 'live'
141 return this.serverConfig.live.transcoding.availableProfiles 137 ? this.serverConfig.live.transcoding.availableProfiles
142 } 138 : this.serverConfig.transcoding.availableProfiles
143 139
144 return this.serverConfig.transcoding.availableProfiles 140 return profiles.map(p => ({ id: p, label: p }))
145 } 141 }
146 142
147 getTotalTranscodingThreads () { 143 getTotalTranscodingThreads () {
diff --git a/client/src/app/shared/shared-forms/select/index.ts b/client/src/app/shared/shared-forms/select/index.ts
index 33459b23b..e387e1f48 100644
--- a/client/src/app/shared/shared-forms/select/index.ts
+++ b/client/src/app/shared/shared-forms/select/index.ts
@@ -1,4 +1,5 @@
1export * from './select-channel.component' 1export * from './select-channel.component'
2export * from './select-checkbox.component'
3export * from './select-custom-value.component'
2export * from './select-options.component' 4export * from './select-options.component'
3export * from './select-tags.component' 5export * from './select-tags.component'
4export * from './select-checkbox.component'
diff --git a/client/src/app/shared/shared-forms/select/select-custom-input.component.html b/client/src/app/shared/shared-forms/select/select-custom-input.component.html
deleted file mode 100644
index 84fa15c3d..000000000
--- a/client/src/app/shared/shared-forms/select/select-custom-input.component.html
+++ /dev/null
@@ -1,14 +0,0 @@
1<ng-select
2 [(ngModel)]="selectedId"
3 (ngModelChange)="onModelChange()"
4 [bindLabel]="bindLabel"
5 [bindValue]="bindValue"
6 [clearable]="clearable"
7 [searchable]="searchable"
8>
9 <ng-option *ngFor="let item of items" [value]="item.id">
10 {{ channel.label }}
11 </ng-option>
12
13 <ng-content></ng-content>
14</ng-select>
diff --git a/client/src/app/shared/shared-forms/select/select-custom-input.component.scss b/client/src/app/shared/shared-forms/select/select-custom-input.component.scss
deleted file mode 100644
index e69de29bb..000000000
--- a/client/src/app/shared/shared-forms/select/select-custom-input.component.scss
+++ /dev/null
diff --git a/client/src/app/shared/shared-forms/select/select-custom-input.component.ts b/client/src/app/shared/shared-forms/select/select-custom-input.component.ts
deleted file mode 100644
index ba6fef8ad..000000000
--- a/client/src/app/shared/shared-forms/select/select-custom-input.component.ts
+++ /dev/null
@@ -1,44 +0,0 @@
1import { Component, forwardRef, Input } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3
4@Component({
5 selector: 'my-select-custom-input',
6 styleUrls: [ './select-custom-input.component.scss' ],
7 templateUrl: './select-custom-input.component.html',
8 providers: [
9 {
10 provide: NG_VALUE_ACCESSOR,
11 useExisting: forwardRef(() => SelectCustomInputComponent),
12 multi: true
13 }
14 ]
15})
16export class SelectCustomInputComponent implements ControlValueAccessor {
17 @Input() items: any[] = []
18
19 selectedId: number
20
21 // ng-select options
22 bindLabel = 'label'
23 bindValue = 'id'
24 clearable = false
25 searchable = false
26
27 propagateChange = (_: any) => { /* empty */ }
28
29 writeValue (id: number) {
30 this.selectedId = id
31 }
32
33 registerOnChange (fn: (_: any) => void) {
34 this.propagateChange = fn
35 }
36
37 registerOnTouched () {
38 // Unused
39 }
40
41 onModelChange () {
42 this.propagateChange(this.selectedId)
43 }
44}
diff --git a/client/src/app/shared/shared-forms/select/select-custom-value.component.html b/client/src/app/shared/shared-forms/select/select-custom-value.component.html
new file mode 100644
index 000000000..5fdf432ff
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-custom-value.component.html
@@ -0,0 +1,14 @@
1<div class="root">
2 <my-select-options
3 [items]="itemsWithCustom"
4 [clearable]="clearable"
5 [searchable]="searchable"
6 [groupBy]="groupBy"
7 [labelForId]="labelForId"
8
9 [(ngModel)]="selectedId"
10 (ngModelChange)="onModelChange()"
11 ></my-select-options>
12
13 <input *ngIf="isCustomValue()" [(ngModel)]="customValue" (ngModelChange)="onModelChange()" type="text" class="form-control" />
14</div>
diff --git a/client/src/app/shared/shared-forms/select/select-custom-value.component.ts b/client/src/app/shared/shared-forms/select/select-custom-value.component.ts
new file mode 100644
index 000000000..a8e5ad0d3
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-custom-value.component.ts
@@ -0,0 +1,76 @@
1import { Component, forwardRef, Input, OnChanges } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import { SelectOptionsItem } from './select-options.component'
4
5@Component({
6 selector: 'my-select-custom-value',
7 styleUrls: [ './select-shared.component.scss' ],
8 templateUrl: './select-custom-value.component.html',
9 providers: [
10 {
11 provide: NG_VALUE_ACCESSOR,
12 useExisting: forwardRef(() => SelectCustomValueComponent),
13 multi: true
14 }
15 ]
16})
17export class SelectCustomValueComponent implements ControlValueAccessor, OnChanges {
18 @Input() items: SelectOptionsItem[] = []
19 @Input() clearable = false
20 @Input() searchable = false
21 @Input() groupBy: string
22 @Input() labelForId: string
23
24 customValue: number | string = ''
25 selectedId: number | string
26
27 itemsWithCustom: SelectOptionsItem[] = []
28
29 ngOnChanges () {
30 this.itemsWithCustom = this.getItems()
31 }
32
33 propagateChange = (_: any) => { /* empty */ }
34
35 writeValue (id: number | string) {
36 this.selectedId = id
37
38 if (this.isSelectedIdInItems() !== true) {
39 this.selectedId = 'other'
40 this.customValue = id
41 }
42 }
43
44 registerOnChange (fn: (_: any) => void) {
45 this.propagateChange = fn
46 }
47
48 registerOnTouched () {
49 // Unused
50 }
51
52 onModelChange () {
53 if (this.selectedId === 'other') {
54 return this.propagateChange(this.customValue)
55 }
56
57 return this.propagateChange(this.selectedId)
58 }
59
60 isSelectedIdInItems () {
61 return !!this.items.find(i => i.id === this.selectedId)
62 }
63
64 getItems () {
65 const other: SelectOptionsItem = {
66 id: 'other',
67 label: $localize`Custom value...`
68 }
69
70 return this.items.concat([ other ])
71 }
72
73 isCustomValue () {
74 return this.selectedId === 'other'
75 }
76}
diff --git a/client/src/app/shared/shared-forms/select/select-options.component.html b/client/src/app/shared/shared-forms/select/select-options.component.html
index 6d0d7e925..3b1761255 100644
--- a/client/src/app/shared/shared-forms/select/select-options.component.html
+++ b/client/src/app/shared/shared-forms/select/select-options.component.html
@@ -6,6 +6,7 @@
6 [clearable]="clearable" 6 [clearable]="clearable"
7 [labelForId]="labelForId" 7 [labelForId]="labelForId"
8 [searchable]="searchable" 8 [searchable]="searchable"
9 [searchFn]="searchFn"
9 10
10 bindLabel="label" 11 bindLabel="label"
11 bindValue="id" 12 bindValue="id"
diff --git a/client/src/app/shared/shared-forms/select/select-options.component.ts b/client/src/app/shared/shared-forms/select/select-options.component.ts
index f0abd1a68..51a3f515d 100644
--- a/client/src/app/shared/shared-forms/select/select-options.component.ts
+++ b/client/src/app/shared/shared-forms/select/select-options.component.ts
@@ -27,6 +27,7 @@ export class SelectOptionsComponent implements ControlValueAccessor {
27 @Input() searchable = false 27 @Input() searchable = false
28 @Input() groupBy: string 28 @Input() groupBy: string
29 @Input() labelForId: string 29 @Input() labelForId: string
30 @Input() searchFn: any
30 31
31 selectedId: number | string 32 selectedId: number | string
32 33
diff --git a/client/src/app/shared/shared-forms/select/select-shared.component.scss b/client/src/app/shared/shared-forms/select/select-shared.component.scss
index 0b4c6b784..1a4192b55 100644
--- a/client/src/app/shared/shared-forms/select/select-shared.component.scss
+++ b/client/src/app/shared/shared-forms/select/select-shared.component.scss
@@ -30,3 +30,18 @@ ng-select ::ng-deep {
30 width: 20px; 30 width: 20px;
31 } 31 }
32} 32}
33
34.root {
35 display:flex;
36
37 > my-select-options {
38 flex-grow: 1;
39 }
40}
41
42input[type=text] {
43 margin-left: 5px;
44
45 @include peertube-input-text($form-base-input-width);
46 display: block;
47}
diff --git a/client/src/app/shared/shared-forms/shared-form.module.ts b/client/src/app/shared/shared-forms/shared-form.module.ts
index 22e8dd05a..9bdd138a1 100644
--- a/client/src/app/shared/shared-forms/shared-form.module.ts
+++ b/client/src/app/shared/shared-forms/shared-form.module.ts
@@ -7,13 +7,19 @@ import { SharedGlobalIconModule } from '../shared-icons'
7import { SharedMainModule } from '../shared-main/shared-main.module' 7import { SharedMainModule } from '../shared-main/shared-main.module'
8import { DynamicFormFieldComponent } from './dynamic-form-field.component' 8import { DynamicFormFieldComponent } from './dynamic-form-field.component'
9import { FormValidatorService } from './form-validator.service' 9import { FormValidatorService } from './form-validator.service'
10import { InputToggleHiddenComponent } from './input-toggle-hidden.component'
11import { InputSwitchComponent } from './input-switch.component' 10import { InputSwitchComponent } from './input-switch.component'
11import { InputToggleHiddenComponent } from './input-toggle-hidden.component'
12import { MarkdownTextareaComponent } from './markdown-textarea.component' 12import { MarkdownTextareaComponent } from './markdown-textarea.component'
13import { PeertubeCheckboxComponent } from './peertube-checkbox.component' 13import { PeertubeCheckboxComponent } from './peertube-checkbox.component'
14import { PreviewUploadComponent } from './preview-upload.component' 14import { PreviewUploadComponent } from './preview-upload.component'
15import { ReactiveFileComponent } from './reactive-file.component' 15import { ReactiveFileComponent } from './reactive-file.component'
16import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select' 16import {
17 SelectChannelComponent,
18 SelectCheckboxComponent,
19 SelectCustomValueComponent,
20 SelectOptionsComponent,
21 SelectTagsComponent
22} from './select'
17import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' 23import { TextareaAutoResizeDirective } from './textarea-autoresize.directive'
18import { TimestampInputComponent } from './timestamp-input.component' 24import { TimestampInputComponent } from './timestamp-input.component'
19 25
@@ -44,6 +50,7 @@ import { TimestampInputComponent } from './timestamp-input.component'
44 SelectOptionsComponent, 50 SelectOptionsComponent,
45 SelectTagsComponent, 51 SelectTagsComponent,
46 SelectCheckboxComponent, 52 SelectCheckboxComponent,
53 SelectCustomValueComponent,
47 54
48 DynamicFormFieldComponent 55 DynamicFormFieldComponent
49 ], 56 ],
@@ -69,6 +76,7 @@ import { TimestampInputComponent } from './timestamp-input.component'
69 SelectOptionsComponent, 76 SelectOptionsComponent,
70 SelectTagsComponent, 77 SelectTagsComponent,
71 SelectCheckboxComponent, 78 SelectCheckboxComponent,
79 SelectCustomValueComponent,
72 80
73 DynamicFormFieldComponent 81 DynamicFormFieldComponent
74 ], 82 ],