aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin/config
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/+admin/config')
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html135
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss9
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts68
3 files changed, 175 insertions, 37 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 ec6f879d7..50df8a8ac 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
@@ -2,12 +2,13 @@
2 2
3 <ngb-tabset class="root-tabset bootstrap"> 3 <ngb-tabset class="root-tabset bootstrap">
4 4
5 <ngb-tab i18n-title title="Basic configuration"> 5 <ngb-tab i18n-title title="Instance information">
6 <ng-template ngbTabContent> 6 <ng-template ngbTabContent>
7 7
8 <div i18n class="inner-form-title">Instance</div>
9
10 <ng-container formGroupName="instance"> 8 <ng-container formGroupName="instance">
9
10 <div i18n class="inner-form-title">Instance</div>
11
11 <div class="form-group"> 12 <div class="form-group">
12 <label i18n for="instanceName">Name</label> 13 <label i18n for="instanceName">Name</label>
13 <input 14 <input
@@ -36,37 +37,41 @@
36 </div> 37 </div>
37 38
38 <div class="form-group"> 39 <div class="form-group">
39 <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> 40 <label i18n for="instanceCategories">Main instance categories</label>
40 <my-markdown-textarea 41
41 id="instanceTerms" formControlName="terms" textareaWidth="500px" [previewColumn]="true" 42 <div>
42 [ngClass]="{ 'input-error': formErrors['instance.terms'] }" 43 <p-multiSelect
43 ></my-markdown-textarea> 44 inputId="instanceCategories" [options]="categoryItems" formControlName="categories" showToggleAll="false"
44 <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div> 45 [defaultLabel]="getDefaultCategoryLabel()" [selectedItemsLabel]="getSelectedCategoryLabel()"
46 emptyFilterMessage="No results found" i18n-emptyFilterMessage
47 ></p-multiSelect>
48 </div>
45 </div> 49 </div>
46 50
47 <div class="form-group"> 51 <div class="form-group">
52 <label i18n for="instanceLanguages">Main languages you/your moderators speak</label>
53
54 <div>
55 <p-multiSelect
56 inputId="instanceLanguages" [options]="languageItems" formControlName="languages" showToggleAll="false"
57 [defaultLabel]="getDefaultLanguageLabel()" [selectedItemsLabel]="getSelectedLanguageLabel()"
58 emptyFilterMessage="No results found" i18n-emptyFilterMessage
59 ></p-multiSelect>
60 </div>
61 </div>
62
63 <div i18n class="inner-form-title">Moderation & NSFW</div>
64
65 <div class="form-group">
48 <my-peertube-checkbox 66 <my-peertube-checkbox
49 inputName="instanceIsNSFW" formControlName="isNSFW" 67 inputName="instanceIsNSFW" formControlName="isNSFW"
50 i18n-labelText labelText="Dedicated to sensitive or NSFW content" 68 i18n-labelText labelText="This instance is dedicated to sensitive or NSFW content"
51 i18n-helpHtml helpHtml="Enabling it will allow other administrators to know that you are mainly federating sensitive content.<br /><br /> 69 i18n-helpHtml helpHtml="Enabling it will allow other administrators to know that you are mainly federating sensitive content.<br /><br />
52 Moreover, the NSFW checkbox on video upload will be automatically checked by default." 70 Moreover, the NSFW checkbox on video upload will be automatically checked by default."
53 ></my-peertube-checkbox> 71 ></my-peertube-checkbox>
54 </div> 72 </div>
55 73
56 <div class="form-group"> 74 <div class="form-group">
57 <label i18n for="instanceDefaultClientRoute">Default client route</label>
58 <div class="peertube-select-container">
59 <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute">
60 <option i18n value="/videos/overview">Videos Overview</option>
61 <option i18n value="/videos/trending">Videos Trending</option>
62 <option i18n value="/videos/recently-added">Videos Recently Added</option>
63 <option i18n value="/videos/local">Local videos</option>
64 </select>
65 </div>
66 <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div>
67 </div>
68
69 <div class="form-group">
70 <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> 75 <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
71 <my-help 76 <my-help
72 helpType="custom" i18n-customHtml 77 helpType="custom" i18n-customHtml
@@ -82,10 +87,79 @@
82 </div> 87 </div>
83 <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div> 88 <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div>
84 </div> 89 </div>
90
91 <div class="form-group">
92 <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help>
93 <my-markdown-textarea
94 id="instanceTerms" formControlName="terms" textareaWidth="500px" [previewColumn]="true"
95 [ngClass]="{ 'input-error': formErrors['instance.terms'] }"
96 ></my-markdown-textarea>
97 <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div>
98 </div>
99
100 <div class="form-group">
101 <label i18n for="instanceCodeOfConduct">Code of conduct</label><my-help helpType="markdownText"></my-help>
102 <my-markdown-textarea
103 id="instanceCodeOfConduct" formControlName="codeOfConduct" textareaWidth="500px" [previewColumn]="true"
104 [ngClass]="{ 'input-error': formErrors['instance.codeOfConduct'] }"
105 ></my-markdown-textarea>
106 <div *ngIf="formErrors.instance.codeOfConduct" class="form-error">{{ formErrors.instance.codeOfConduct }}</div>
107 </div>
108
109 <div class="form-group">
110 <label i18n for="instanceModerationInformation">Moderation information</label><my-help helpType="markdownText"></my-help>
111 <div class="label-small-info">Who moderates the instance? What is the policy regarding NSFW videos? Political videos? etc</div>
112
113 <my-markdown-textarea
114 id="instanceModerationInformation" formControlName="moderationInformation" textareaWidth="500px" [previewColumn]="true"
115 [ngClass]="{ 'input-error': formErrors['instance.moderationInformation'] }"
116 ></my-markdown-textarea>
117 <div *ngIf="formErrors.instance.moderationInformation" class="form-error">{{ formErrors.instance.moderationInformation }}</div>
118 </div>
119
120 <div i18n class="inner-form-title">You and your instance</div>
121
122 <div class="form-group">
123 <label i18n for="instanceAdministrator">Who is behind the instance? </label>
124 <div class="label-small-info">A single person? A non profit? A company?</div>
125
126 <textarea
127 id="instanceAdministrator" formControlName="administrator"
128 [ngClass]="{ 'input-error': formErrors['instance.administrator'] }"
129 ></textarea>
130 <div *ngIf="formErrors.instance.administrator" class="form-error">{{ formErrors.instance.administrator }}</div>
131 </div>
132
133 <div class="form-group">
134 <label i18n for="instanceMaintenanceLifetime">How long do you plan to maintain this instance?</label>
135 <div class="label-small-info">It's important to know for users who want to register on your instance</div>
136
137 <textarea
138 id="instanceMaintenanceLifetime" formControlName="maintenanceLifetime"
139 [ngClass]="{ 'input-error': formErrors['instance.maintenanceLifetime'] }"
140 ></textarea>
141 <div *ngIf="formErrors.instance.maintenanceLifetime" class="form-error">{{ formErrors.instance.maintenanceLifetime }}</div>
142 </div>
143
144 <div class="form-group">
145 <label i18n for="instanceBusinessModel">How will you pay the PeerTube instance server?</label>
146 <div class="label-small-info">With you own funds? With users donations? Advertising?</div>
147
148 <textarea
149 id="instanceBusinessModel" formControlName="businessModel"
150 [ngClass]="{ 'input-error': formErrors['instance.businessModel'] }"
151 ></textarea>
152 <div *ngIf="formErrors.instance.businessModel" class="form-error">{{ formErrors.instance.businessModel }}</div>
153 </div>
154
85 </ng-container> 155 </ng-container>
156 </ng-template>
157 </ngb-tab>
86 158
159 <ngb-tab i18n-title title="Basic configuration">
160 <ng-template ngbTabContent>
87 161
88 <div i18n class="inner-form-title">Theme</div> 162 <div i18n class="inner-form-title">Theme & Default route</div>
89 163
90 <ng-container formGroupName="theme"> 164 <ng-container formGroupName="theme">
91 <div class="form-group"> 165 <div class="form-group">
@@ -102,6 +176,19 @@
102 </ng-container> 176 </ng-container>
103 177
104 178
179 <div class="form-group" formGroupName="instance">
180 <label i18n for="instanceDefaultClientRoute">Default client route</label>
181 <div class="peertube-select-container">
182 <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute">
183 <option i18n value="/videos/overview">Videos Discover</option>
184 <option i18n value="/videos/trending">Videos Trending</option>
185 <option i18n value="/videos/recently-added">Videos Recently Added</option>
186 <option i18n value="/videos/local">Local videos</option>
187 </select>
188 </div>
189 <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div>
190 </div>
191
105 <div i18n class="inner-form-title">Signup</div> 192 <div i18n class="inner-form-title">Signup</div>
106 193
107 <ng-container formGroupName="signup"> 194 <ng-container formGroupName="signup">
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 c90bd5141..68f1b01b7 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
@@ -1,6 +1,10 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.form-group {
5 margin-bottom: 25px;
6}
7
4input[type=text] { 8input[type=text] {
5 @include peertube-input-text(340px); 9 @include peertube-input-text(340px);
6 display: block; 10 display: block;
@@ -44,3 +48,8 @@ textarea {
44 height: 100px; 48 height: 100px;
45 } 49 }
46} 50}
51
52.label-small-info {
53 font-style: italic;
54 margin-bottom: 10px;
55}
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 d51104569..3119ab040 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
@@ -6,6 +6,9 @@ import { Notifier } from '@app/core'
6import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' 6import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 8import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
9import { SelectItem } from 'primeng/api'
10import { forkJoin } from 'rxjs'
11import { first } from 'rxjs/operators'
9 12
10@Component({ 13@Component({
11 selector: 'my-edit-custom-config', 14 selector: 'my-edit-custom-config',
@@ -18,6 +21,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
18 resolutions: { id: string, label: string }[] = [] 21 resolutions: { id: string, label: string }[] = []
19 transcodingThreadOptions: { label: string, value: number }[] = [] 22 transcodingThreadOptions: { label: string, value: number }[] = []
20 23
24 languageItems: SelectItem[] = []
25 categoryItems: SelectItem[] = []
26
21 constructor ( 27 constructor (
22 protected formValidatorService: FormValidatorService, 28 protected formValidatorService: FormValidatorService,
23 private customConfigValidatorsService: CustomConfigValidatorsService, 29 private customConfigValidatorsService: CustomConfigValidatorsService,
@@ -88,10 +94,22 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
88 name: this.customConfigValidatorsService.INSTANCE_NAME, 94 name: this.customConfigValidatorsService.INSTANCE_NAME,
89 shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION, 95 shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION,
90 description: null, 96 description: null,
91 terms: null, 97
92 defaultClientRoute: null,
93 isNSFW: false, 98 isNSFW: false,
94 defaultNSFWPolicy: null, 99 defaultNSFWPolicy: null,
100
101 terms: null,
102 codeOfConduct: null,
103 moderationInformation: null,
104 administrator: null,
105 maintenanceLifetime: null,
106 businessModel: null,
107
108 categories: null,
109 languages: null,
110
111 defaultClientRoute: null,
112
95 customizations: { 113 customizations: {
96 javascript: null, 114 javascript: null,
97 css: null 115 css: null
@@ -184,18 +202,27 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
184 202
185 this.buildForm(formGroupData) 203 this.buildForm(formGroupData)
186 204
187 this.configService.getCustomConfig() 205 forkJoin([
188 .subscribe( 206 this.configService.getCustomConfig(),
189 res => { 207 this.serverService.videoLanguagesLoaded.pipe(first()), // First so the observable completes
190 this.customConfig = res 208 this.serverService.videoCategoriesLoaded.pipe(first())
209 ]).subscribe(
210 ([ config ]) => {
211 this.customConfig = config
191 212
192 this.updateForm() 213 const languages = this.serverService.getVideoLanguages()
193 // Force form validation 214 this.languageItems = languages.map(l => ({ label: l.label, value: l.id }))
194 this.forceCheck()
195 },
196 215
197 err => this.notifier.error(err.message) 216 const categories = this.serverService.getVideoCategories()
198 ) 217 this.categoryItems = categories.map(l => ({ label: l.label, value: l.id }))
218
219 this.updateForm()
220 // Force form validation
221 this.forceCheck()
222 },
223
224 err => this.notifier.error(err.message)
225 )
199 } 226 }
200 227
201 isTranscodingEnabled () { 228 isTranscodingEnabled () {
@@ -224,8 +251,23 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
224 ) 251 )
225 } 252 }
226 253
254 getSelectedLanguageLabel () {
255 return this.i18n('{{\'{0} languages selected')
256 }
257
258 getDefaultLanguageLabel () {
259 return this.i18n('No language')
260 }
261
262 getSelectedCategoryLabel () {
263 return this.i18n('{{\'{0} categories selected')
264 }
265
266 getDefaultCategoryLabel () {
267 return this.i18n('No category')
268 }
269
227 private updateForm () { 270 private updateForm () {
228 this.form.patchValue(this.customConfig) 271 this.form.patchValue(this.customConfig)
229 } 272 }
230
231} 273}