aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html471
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts14
-rw-r--r--client/src/app/shared/forms/form-validators/custom-config.ts7
3 files changed, 274 insertions, 218 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 021252456..252d43c8f 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
@@ -1,222 +1,259 @@
1<div class="form-sub-title">Update PeerTube configuration</div>
2
3<form role="form" [formGroup]="form"> 1<form role="form" [formGroup]="form">
4 2
5 <div class="inner-form-title">Instance</div> 3 <tabset class="root-tabset bootstrap">
6 4
7 <div class="form-group"> 5 <tab heading="Basic configuration">
8 <label for="instanceName">Name</label> 6
9 <input 7 <div class="inner-form-title">Instance</div>
10 type="text" id="instanceName" 8
11 formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }" 9 <div class="form-group">
12 > 10 <label for="instanceName">Name</label>
13 <div *ngIf="formErrors.instanceName" class="form-error"> 11 <input
14 {{ formErrors.instanceName }} 12 type="text" id="instanceName"
15 </div> 13 formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }"
16 </div> 14 >
17 15 <div *ngIf="formErrors.instanceName" class="form-error">
18 <div class="form-group"> 16 {{ formErrors.instanceName }}
19 <label for="instanceShortDescription">Short description</label> 17 </div>
20 <textarea 18 </div>
21 id="instanceShortDescription" formControlName="instanceShortDescription" 19
22 [ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }" 20 <div class="form-group">
23 ></textarea> 21 <label for="instanceShortDescription">Short description</label>
24 <div *ngIf="formErrors.instanceShortDescription" class="form-error"> 22 <textarea
25 {{ formErrors.instanceShortDescription }} 23 id="instanceShortDescription" formControlName="instanceShortDescription"
26 </div> 24 [ngClass]="{ 'input-error': formErrors['instanceShortDescription'] }"
27 </div> 25 ></textarea>
28 26 <div *ngIf="formErrors.instanceShortDescription" class="form-error">
29 <div class="form-group"> 27 {{ formErrors.instanceShortDescription }}
30 <label for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help> 28 </div>
31 <my-markdown-textarea 29 </div>
32 id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true" 30
33 [classes]="{ 'input-error': formErrors['instanceDescription'] }" 31 <div class="form-group">
34 ></my-markdown-textarea> 32 <label for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help>
35 <div *ngIf="formErrors.instanceDescription" class="form-error"> 33 <my-markdown-textarea
36 {{ formErrors.instanceDescription }} 34 id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true"
37 </div> 35 [classes]="{ 'input-error': formErrors['instanceDescription'] }"
38 </div> 36 ></my-markdown-textarea>
39 37 <div *ngIf="formErrors.instanceDescription" class="form-error">
40 <div class="form-group"> 38 {{ formErrors.instanceDescription }}
41 <label for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> 39 </div>
42 <my-markdown-textarea 40 </div>
43 id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true" 41
44 [ngClass]="{ 'input-error': formErrors['instanceTerms'] }" 42 <div class="form-group">
45 ></my-markdown-textarea> 43 <label for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help>
46 <div *ngIf="formErrors.instanceTerms" class="form-error"> 44 <my-markdown-textarea
47 {{ formErrors.instanceTerms }} 45 id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true"
48 </div> 46 [ngClass]="{ 'input-error': formErrors['instanceTerms'] }"
49 </div> 47 ></my-markdown-textarea>
50 48 <div *ngIf="formErrors.instanceTerms" class="form-error">
51 <div class="form-group"> 49 {{ formErrors.instanceTerms }}
52 <label for="instanceDefaultClientRoute">Default client route</label> 50 </div>
53 <div class="peertube-select-container"> 51 </div>
54 <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute"> 52
55 <option value="/videos/trending">Videos Trending</option> 53 <div class="form-group">
56 <option value="/videos/recently-added">Videos Recently Added</option> 54 <label for="instanceDefaultClientRoute">Default client route</label>
57 <option value="/videos/local">Local videos</option> 55 <div class="peertube-select-container">
58 </select> 56 <select id="instanceDefaultClientRoute" formControlName="instanceDefaultClientRoute">
59 </div> 57 <option value="/videos/trending">Videos Trending</option>
60 <div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error"> 58 <option value="/videos/recently-added">Videos Recently Added</option>
61 {{ formErrors.instanceDefaultClientRoute }} 59 <option value="/videos/local">Local videos</option>
62 </div> 60 </select>
63 </div> 61 </div>
64 62 <div *ngIf="formErrors.instanceDefaultClientRoute" class="form-error">
65 <div class="form-group"> 63 {{ formErrors.instanceDefaultClientRoute }}
66 <label for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> 64 </div>
67 <my-help helpType="custom" customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."></my-help> 65 </div>
68 66
69 <div class="peertube-select-container"> 67 <div class="form-group">
70 <select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy"> 68 <label for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label>
71 <option value="do_not_list">Do not list</option> 69 <my-help helpType="custom" customHtml="With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video."></my-help>
72 <option value="blur">Blur thumbnails</option> 70
73 <option value="display">Display</option> 71 <div class="peertube-select-container">
74 </select> 72 <select id="instanceDefaultNSFWPolicy" formControlName="instanceDefaultNSFWPolicy">
75 </div> 73 <option value="do_not_list">Do not list</option>
76 <div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error"> 74 <option value="blur">Blur thumbnails</option>
77 {{ formErrors.instanceDefaultNSFWPolicy }} 75 <option value="display">Display</option>
78 </div> 76 </select>
79 </div> 77 </div>
80 78 <div *ngIf="formErrors.instanceDefaultNSFWPolicy" class="form-error">
81 <div class="inner-form-title">Cache</div> 79 {{ formErrors.instanceDefaultNSFWPolicy }}
82 80 </div>
83 <div class="form-group"> 81 </div>
84 <label for="cachePreviewsSize">Preview cache size</label> 82
85 <input 83 <div class="inner-form-title">Signup</div>
86 type="text" id="cachePreviewsSize" 84
87 formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }" 85 <div class="form-group">
88 > 86 <input type="checkbox" id="signupEnabled" formControlName="signupEnabled">
89 <div *ngIf="formErrors.cachePreviewsSize" class="form-error"> 87
90 {{ formErrors.cachePreviewsSize }} 88 <label for="signupEnabled"></label>
91 </div> 89 <label for="signupEnabled">Signup enabled</label>
92 </div> 90 </div>
93 91
94 <div class="inner-form-title">Signup</div> 92 <div *ngIf="isSignupEnabled()" class="form-group">
95 93 <label for="signupLimit">Signup limit</label>
96 <div class="form-group"> 94 <input
97 <input type="checkbox" id="signupEnabled" formControlName="signupEnabled"> 95 type="text" id="signupLimit"
98 96 formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }"
99 <label for="signupEnabled"></label> 97 >
100 <label for="signupEnabled">Signup enabled</label> 98 <div *ngIf="formErrors.signupLimit" class="form-error">
101 </div> 99 {{ formErrors.signupLimit }}
102 100 </div>
103 <div *ngIf="isSignupEnabled()" class="form-group"> 101 </div>
104 <label for="signupLimit">Signup limit</label> 102
105 <input 103 <div class="inner-form-title">Administrator</div>
106 type="text" id="signupLimit" 104
107 formControlName="signupLimit" [ngClass]="{ 'input-error': formErrors['signupLimit'] }" 105 <div class="form-group">
108 > 106 <label for="adminEmail">Admin email</label>
109 <div *ngIf="formErrors.signupLimit" class="form-error"> 107 <input
110 {{ formErrors.signupLimit }} 108 type="text" id="adminEmail"
111 </div> 109 formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }"
112 </div> 110 >
113 111 <div *ngIf="formErrors.adminEmail" class="form-error">
114 <div class="inner-form-title">Administrator</div> 112 {{ formErrors.adminEmail }}
115 113 </div>
116 <div class="form-group"> 114 </div>
117 <label for="adminEmail">Admin email</label> 115
118 <input 116 <div class="inner-form-title">Users</div>
119 type="text" id="adminEmail" 117
120 formControlName="adminEmail" [ngClass]="{ 'input-error': formErrors['adminEmail'] }" 118 <div class="form-group">
121 > 119 <label for="userVideoQuota">User default video quota</label>
122 <div *ngIf="formErrors.adminEmail" class="form-error"> 120 <div class="peertube-select-container">
123 {{ formErrors.adminEmail }} 121 <select id="userVideoQuota" formControlName="userVideoQuota">
124 </div> 122 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value">
125 </div> 123 {{ videoQuotaOption.label }}
126 124 </option>
127 <div class="inner-form-title">Users</div> 125 </select>
128 126 </div>
129 <div class="form-group"> 127 <div *ngIf="formErrors.userVideoQuota" class="form-error">
130 <label for="userVideoQuota">User default video quota</label> 128 {{ formErrors.userVideoQuota }}
131 <div class="peertube-select-container"> 129 </div>
132 <select id="userVideoQuota" formControlName="userVideoQuota"> 130 </div>
133 <option *ngFor="let videoQuotaOption of videoQuotaOptions" [value]="videoQuotaOption.value"> 131 </tab>
134 {{ videoQuotaOption.label }} 132
135 </option> 133 <tab heading="Services">
136 </select> 134
137 </div> 135 <div class="inner-form-title">Twitter</div>
138 <div *ngIf="formErrors.userVideoQuota" class="form-error"> 136
139 {{ formErrors.userVideoQuota }} 137 <div class="form-group">
140 </div> 138 <label for="signupLimit">Your Twitter username</label>
141 </div> 139 <my-help helpType="custom" customHtml="The Twitter @username the cards (created by PeerTube video shares) should be attributed to."></my-help>
142 140 <input
143 <div class="inner-form-title">Transcoding</div> 141 type="text" id="servicesTwitterUsername"
144 142 formControlName="servicesTwitterUsername" [ngClass]="{ 'input-error': formErrors['servicesTwitterUsername'] }"
145 <div class="form-group"> 143 >
146 <input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled"> 144 <div *ngIf="formErrors.servicesTwitterUsername" class="form-error">
147 145 {{ formErrors.servicesTwitterUsername }}
148 <label for="transcodingEnabled"></label> 146 </div>
149 <label for="transcodingEnabled">Transcoding enabled</label> 147 </div>
150 </div> 148
151 149 <div class="form-group">
152 <ng-template [ngIf]="isTranscodingEnabled()"> 150 <input type="checkbox" id="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted">
153 151
154 <div class="form-group"> 152 <label for="servicesTwitterWhitelisted"></label>
155 <label for="transcodingThreads">Transcoding threads</label> 153 <label for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label>
156 <div class="peertube-select-container"> 154 <my-help helpType="custom" customHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
157 <select id="transcodingThreads" formControlName="transcodingThreads"> 155If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br />
158 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value"> 156Check this checkbox, save the configuration and test on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted."></my-help>
159 {{ transcodingThreadOption.label }} 157
160 </option> 158 </div>
161 </select> 159 </tab>
162 </div> 160
163 <div *ngIf="formErrors.transcodingThreads" class="form-error"> 161 <tab heading="Advanced configuration">
164 {{ formErrors.transcodingThreads }} 162
165 </div> 163 <div class="inner-form-title">Transcoding</div>
166 </div> 164
167 165 <div class="form-group">
168 <div class="form-group" *ngFor="let resolution of resolutions"> 166 <input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled">
169 <input 167
170 type="checkbox" [id]="getResolutionKey(resolution)" 168 <label for="transcodingEnabled"></label>
171 [formControlName]="getResolutionKey(resolution)" 169 <label for="transcodingEnabled">Transcoding enabled</label>
172 > 170 </div>
173 <label [for]="getResolutionKey(resolution)"></label> 171
174 <label [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label> 172 <ng-template [ngIf]="isTranscodingEnabled()">
175 </div> 173
176 </ng-template> 174 <div class="form-group">
177 175 <label for="transcodingThreads">Transcoding threads</label>
178 <div class="inner-form-title">Customizations</div> 176 <div class="peertube-select-container">
179 177 <select id="transcodingThreads" formControlName="transcodingThreads">
180 <div class="form-group"> 178 <option *ngFor="let transcodingThreadOption of transcodingThreadOptions" [value]="transcodingThreadOption.value">
181 <label for="customizationJavascript">JavaScript</label> 179 {{ transcodingThreadOption.label }}
182 <my-help helpType="custom" customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"></my-help> 180 </option>
183 <textarea 181 </select>
184 id="customizationJavascript" formControlName="customizationJavascript" 182 </div>
185 [ngClass]="{ 'input-error': formErrors['customizationJavascript'] }" 183 <div *ngIf="formErrors.transcodingThreads" class="form-error">
186 ></textarea> 184 {{ formErrors.transcodingThreads }}
187 <div *ngIf="formErrors.customizationJavascript" class="form-error"> 185 </div>
188 {{ formErrors.customizationJavascript }} 186 </div>
189 </div> 187
190 </div> 188 <div class="form-group" *ngFor="let resolution of resolutions">
191 189 <input
192 <div class="form-group"> 190 type="checkbox" [id]="getResolutionKey(resolution)"
193 <label for="customizationCSS">CSS</label> 191 [formControlName]="getResolutionKey(resolution)"
194 <my-help 192 >
195 helpType="custom" 193 <label [for]="getResolutionKey(resolution)"></label>
196 customHtml=" 194 <label [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label>
197 Write directly CSS code. Example:<br /> 195 </div>
198 <pre> 196 </ng-template>
199body { 197
200 background-color: red; 198 <div class="inner-form-title">Cache</div>
201} 199
202 </pre> 200 <div class="form-group">
203 201 <label for="cachePreviewsSize">Preview cache size</label>
204 Prepend with <em>#custom-css</em> to override styles. Example: 202 <my-help helpType="custom" customHtml="Previews are not federated. We fetch them directly from the origin instance and cache them."></my-help>
205 <pre> 203
206#custom-css .logged-in-email { 204 <input
207 color: red; 205 type="text" id="cachePreviewsSize"
208} 206 formControlName="cachePreviewsSize" [ngClass]="{ 'input-error': formErrors['cachePreviewsSize'] }"
209 </pre> 207 >
210 " 208 <div *ngIf="formErrors.cachePreviewsSize" class="form-error">
211 ></my-help> 209 {{ formErrors.cachePreviewsSize }}
212 <textarea 210 </div>
213 id="customizationCSS" formControlName="customizationCSS" 211 </div>
214 [ngClass]="{ 'input-error': formErrors['customizationCSS'] }" 212
215 ></textarea> 213 <div class="inner-form-title">Customizations</div>
216 <div *ngIf="formErrors.customizationCSS" class="form-error"> 214
217 {{ formErrors.customizationCSS }} 215 <div class="form-group">
218 </div> 216 <label for="customizationJavascript">JavaScript</label>
219 </div> 217 <my-help helpType="custom" customHtml="Write directly JavaScript code.<br />Example: <pre>console.log('my instance is amazing');</pre>"></my-help>
218 <textarea
219 id="customizationJavascript" formControlName="customizationJavascript"
220 [ngClass]="{ 'input-error': formErrors['customizationJavascript'] }"
221 ></textarea>
222 <div *ngIf="formErrors.customizationJavascript" class="form-error">
223 {{ formErrors.customizationJavascript }}
224 </div>
225 </div>
226
227 <div class="form-group">
228 <label for="customizationCSS">CSS</label>
229 <my-help
230 helpType="custom"
231 customHtml="
232 Write directly CSS code. Example:<br />
233 <pre>
234 body {
235 background-color: red;
236 }
237 </pre>
238
239 Prepend with <em>#custom-css</em> to override styles. Example:
240 <pre>
241 #custom-css .logged-in-email {
242 color: red;
243 }
244 </pre>
245 "
246 ></my-help>
247 <textarea
248 id="customizationCSS" formControlName="customizationCSS"
249 [ngClass]="{ 'input-error': formErrors['customizationCSS'] }"
250 ></textarea>
251 <div *ngIf="formErrors.customizationCSS" class="form-error">
252 {{ formErrors.customizationCSS }}
253 </div>
254 </div>
255 </tab>
256 </tabset>
220 257
221 <input (click)="formValidated()" type="submit" value="Update configuration" [disabled]="!form.valid"> 258 <input (click)="formValidated()" type="submit" value="Update configuration" [disabled]="!form.valid">
222</form> 259</form>
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 2ab371cbb..a1e334a74 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
@@ -8,7 +8,7 @@ import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared'
8import { 8import {
9 ADMIN_EMAIL, 9 ADMIN_EMAIL,
10 CACHE_PREVIEWS_SIZE, 10 CACHE_PREVIEWS_SIZE,
11 INSTANCE_NAME, INSTANCE_SHORT_DESCRIPTION, 11 INSTANCE_NAME, INSTANCE_SHORT_DESCRIPTION, SERVICES_TWITTER_USERNAME,
12 SIGNUP_LIMIT, 12 SIGNUP_LIMIT,
13 TRANSCODING_THREADS 13 TRANSCODING_THREADS
14} from '@app/shared/forms/form-validators/custom-config' 14} from '@app/shared/forms/form-validators/custom-config'
@@ -49,6 +49,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
49 instanceTerms: '', 49 instanceTerms: '',
50 instanceDefaultClientRoute: '', 50 instanceDefaultClientRoute: '',
51 instanceDefaultNSFWPolicy: '', 51 instanceDefaultNSFWPolicy: '',
52 servicesTwitterUsername: '',
52 cachePreviewsSize: '', 53 cachePreviewsSize: '',
53 signupLimit: '', 54 signupLimit: '',
54 adminEmail: '', 55 adminEmail: '',
@@ -60,6 +61,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
60 validationMessages = { 61 validationMessages = {
61 instanceShortDescription: INSTANCE_SHORT_DESCRIPTION.MESSAGES, 62 instanceShortDescription: INSTANCE_SHORT_DESCRIPTION.MESSAGES,
62 instanceName: INSTANCE_NAME.MESSAGES, 63 instanceName: INSTANCE_NAME.MESSAGES,
64 servicesTwitterUsername: SERVICES_TWITTER_USERNAME,
63 cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES, 65 cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES,
64 signupLimit: SIGNUP_LIMIT.MESSAGES, 66 signupLimit: SIGNUP_LIMIT.MESSAGES,
65 adminEmail: ADMIN_EMAIL.MESSAGES, 67 adminEmail: ADMIN_EMAIL.MESSAGES,
@@ -92,6 +94,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
92 instanceTerms: [ '' ], 94 instanceTerms: [ '' ],
93 instanceDefaultClientRoute: [ '' ], 95 instanceDefaultClientRoute: [ '' ],
94 instanceDefaultNSFWPolicy: [ '' ], 96 instanceDefaultNSFWPolicy: [ '' ],
97 servicesTwitterUsername: [ '', SERVICES_TWITTER_USERNAME.VALIDATORS ],
98 servicesTwitterWhitelisted: [ ],
95 cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ], 99 cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
96 signupEnabled: [ ], 100 signupEnabled: [ ],
97 signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ], 101 signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
@@ -175,6 +179,12 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
175 css: this.form.value['customizationCSS'] 179 css: this.form.value['customizationCSS']
176 } 180 }
177 }, 181 },
182 services: {
183 twitter: {
184 username: this.form.value['servicesTwitterUsername'],
185 whitelisted: this.form.value['servicesTwitterWhitelisted']
186 }
187 },
178 cache: { 188 cache: {
179 previews: { 189 previews: {
180 size: this.form.value['cachePreviewsSize'] 190 size: this.form.value['cachePreviewsSize']
@@ -228,6 +238,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
228 instanceTerms: this.customConfig.instance.terms, 238 instanceTerms: this.customConfig.instance.terms,
229 instanceDefaultClientRoute: this.customConfig.instance.defaultClientRoute, 239 instanceDefaultClientRoute: this.customConfig.instance.defaultClientRoute,
230 instanceDefaultNSFWPolicy: this.customConfig.instance.defaultNSFWPolicy, 240 instanceDefaultNSFWPolicy: this.customConfig.instance.defaultNSFWPolicy,
241 servicesTwitterUsername: this.customConfig.services.twitter.username,
242 servicesTwitterWhitelisted: this.customConfig.services.twitter.whitelisted,
231 cachePreviewsSize: this.customConfig.cache.previews.size, 243 cachePreviewsSize: this.customConfig.cache.previews.size,
232 signupEnabled: this.customConfig.signup.enabled, 244 signupEnabled: this.customConfig.signup.enabled,
233 signupLimit: this.customConfig.signup.limit, 245 signupLimit: this.customConfig.signup.limit,
diff --git a/client/src/app/shared/forms/form-validators/custom-config.ts b/client/src/app/shared/forms/form-validators/custom-config.ts
index c9cef2e09..e3d9a4c7b 100644
--- a/client/src/app/shared/forms/form-validators/custom-config.ts
+++ b/client/src/app/shared/forms/form-validators/custom-config.ts
@@ -14,6 +14,13 @@ export const INSTANCE_SHORT_DESCRIPTION = {
14 } 14 }
15} 15}
16 16
17export const SERVICES_TWITTER_USERNAME = {
18 VALIDATORS: [ Validators.required ],
19 MESSAGES: {
20 'required': 'Twitter username is required.'
21 }
22}
23
17export const CACHE_PREVIEWS_SIZE = { 24export const CACHE_PREVIEWS_SIZE = {
18 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ], 25 VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
19 MESSAGES: { 26 MESSAGES: {