diff options
author | Chocobozzz <me@florianbigard.com> | 2021-02-09 16:35:48 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-02-10 11:36:40 +0100 |
commit | ead64cdf8d917fa0d6a20271e42378f38e5f2407 (patch) | |
tree | 681e9dba853107edab45d8185688dadde4850efb /client/src/app | |
parent | b9c9fefe820fb0b3aaa3c2b5af73bafb29d890d0 (diff) | |
download | PeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.tar.gz PeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.tar.zst PeerTube-ead64cdf8d917fa0d6a20271e42378f38e5f2407.zip |
Support custom value in ng-select
Diffstat (limited to 'client/src/app')
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 | ||
45 | ng-select, | 45 | my-select-options, |
46 | my-select-custom-value, | ||
46 | my-select-checkbox { | 47 | my-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 @@ | |||
1 | export * from './select-channel.component' | 1 | export * from './select-channel.component' |
2 | export * from './select-checkbox.component' | ||
3 | export * from './select-custom-value.component' | ||
2 | export * from './select-options.component' | 4 | export * from './select-options.component' |
3 | export * from './select-tags.component' | 5 | export * from './select-tags.component' |
4 | export * 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 @@ | |||
1 | import { Component, forwardRef, Input } from '@angular/core' | ||
2 | import { 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 | }) | ||
16 | export 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 @@ | |||
1 | import { Component, forwardRef, Input, OnChanges } from '@angular/core' | ||
2 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' | ||
3 | import { 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 | }) | ||
17 | export 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 | |||
42 | input[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' | |||
7 | import { SharedMainModule } from '../shared-main/shared-main.module' | 7 | import { SharedMainModule } from '../shared-main/shared-main.module' |
8 | import { DynamicFormFieldComponent } from './dynamic-form-field.component' | 8 | import { DynamicFormFieldComponent } from './dynamic-form-field.component' |
9 | import { FormValidatorService } from './form-validator.service' | 9 | import { FormValidatorService } from './form-validator.service' |
10 | import { InputToggleHiddenComponent } from './input-toggle-hidden.component' | ||
11 | import { InputSwitchComponent } from './input-switch.component' | 10 | import { InputSwitchComponent } from './input-switch.component' |
11 | import { InputToggleHiddenComponent } from './input-toggle-hidden.component' | ||
12 | import { MarkdownTextareaComponent } from './markdown-textarea.component' | 12 | import { MarkdownTextareaComponent } from './markdown-textarea.component' |
13 | import { PeertubeCheckboxComponent } from './peertube-checkbox.component' | 13 | import { PeertubeCheckboxComponent } from './peertube-checkbox.component' |
14 | import { PreviewUploadComponent } from './preview-upload.component' | 14 | import { PreviewUploadComponent } from './preview-upload.component' |
15 | import { ReactiveFileComponent } from './reactive-file.component' | 15 | import { ReactiveFileComponent } from './reactive-file.component' |
16 | import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select' | 16 | import { |
17 | SelectChannelComponent, | ||
18 | SelectCheckboxComponent, | ||
19 | SelectCustomValueComponent, | ||
20 | SelectOptionsComponent, | ||
21 | SelectTagsComponent | ||
22 | } from './select' | ||
17 | import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' | 23 | import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' |
18 | import { TimestampInputComponent } from './timestamp-input.component' | 24 | import { 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 | ], |