]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | <div class="col-sm-12 col-lg-6"> |
2 | <form name="targetForm" | |
3 | class="form-horizontal" | |
4 | #formDir="ngForm" | |
5 | [formGroup]="targetForm" | |
6 | novalidate | |
7 | *ngIf="targetForm"> | |
8 | <div class="panel panel-default"> | |
9 | <div class="panel-heading"> | |
10 | <h3 i18n="form title|Example: Create Pool@@formTitle" | |
11 | class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3> | |
12 | </div> | |
13 | ||
14 | <div class="panel-body"> | |
15 | <!-- Target IQN --> | |
16 | <div class="form-group" | |
17 | [ngClass]="{'has-error': targetForm.showError('target_iqn', formDir)}"> | |
18 | <label class="control-label col-sm-3" | |
19 | for="target_iqn"> | |
20 | <ng-container i18n>Target IQN</ng-container> | |
21 | <span class="required"></span> | |
22 | </label> | |
23 | <div class="col-sm-9"> | |
24 | <div class="input-group"> | |
25 | <input class="form-control" | |
26 | type="text" | |
27 | id="target_iqn" | |
28 | name="target_iqn" | |
29 | formControlName="target_iqn" /> | |
30 | <span class="input-group-btn"> | |
31 | <button class="btn btn-default" | |
32 | id="ecp-info-button" | |
33 | type="button" | |
34 | (click)="targetSettingsModal()"> | |
35 | <i class="fa fa-cogs fa-fw" | |
36 | aria-hidden="true"></i> | |
37 | </button> | |
38 | </span> | |
39 | </div> | |
40 | ||
41 | <span class="help-block" | |
42 | *ngIf="targetForm.showError('target_iqn', formDir, 'required')" | |
43 | i18n>This field is required.</span> | |
44 | ||
45 | <span class="help-block" | |
46 | *ngIf="targetForm.showError('target_iqn', formDir, 'pattern')" | |
47 | i18n>IQN has wrong pattern.</span> | |
48 | ||
49 | <span class="help-block" | |
50 | *ngIf="targetForm.showError('target_iqn', formDir, 'iqn')"> | |
51 | <ng-container i18n>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</ng-container> | |
52 | <br> | |
53 | <ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container> | |
54 | <br> | |
55 | <a target="_blank" | |
56 | href="https://en.wikipedia.org/wiki/ISCSI#Addressing" | |
57 | i18n>More information</a> | |
58 | </span> | |
59 | ||
60 | <span class="help-block" | |
61 | *ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))" | |
62 | i18n>This target has modified advanced settings.</span> | |
63 | <hr /> | |
64 | </div> | |
65 | </div> | |
66 | ||
67 | <!-- Portals --> | |
68 | <div class="form-group" | |
69 | [ngClass]="{'has-error': targetForm.showError('portals', formDir)}"> | |
70 | <label class="control-label col-sm-3" | |
71 | for="portals"> | |
72 | <ng-container i18n>Portals</ng-container> | |
73 | <span class="required"></span> | |
74 | </label> | |
75 | <div class="col-sm-9"> | |
76 | ||
77 | <ng-container *ngFor="let portal of portals.value; let i = index"> | |
78 | <div class="input-group cd-mb"> | |
79 | <input class="form-control" | |
80 | type="text" | |
81 | [value]="portal" | |
82 | disabled /> | |
83 | <span class="input-group-btn"> | |
84 | <button class="btn btn-default" | |
85 | type="button" | |
86 | (click)="removePortal(i, portal)"> | |
87 | <i class="fa fa-remove fa-fw" | |
88 | aria-hidden="true"></i> | |
89 | </button> | |
90 | </span> | |
91 | </div> | |
92 | </ng-container> | |
93 | ||
94 | <span class="help-block" | |
95 | *ngIf="targetForm.showError('portals', formDir, 'minGateways')" | |
96 | i18n>At least {{ minimum_gateways }} gateways are required.</span> | |
97 | ||
98 | <div class="row"> | |
99 | <div class="col-md-12"> | |
100 | <cd-select [data]="portals.value" | |
101 | [options]="portalsSelections" | |
102 | [messages]="messages.portals" | |
103 | (selection)="onPortalSelection($event)" | |
104 | elemClass="btn btn-default pull-right"> | |
105 | <i class="fa fa-fw fa-plus"></i> | |
106 | <ng-container i18n>Add portal</ng-container> | |
107 | </cd-select> | |
108 | </div> | |
109 | </div> | |
110 | ||
111 | <hr /> | |
112 | </div> | |
113 | </div> | |
114 | ||
115 | <!-- Images --> | |
116 | <div class="form-group" | |
117 | [ngClass]="{'has-error': targetForm.showError('disks', formDir)}"> | |
118 | <label class="control-label col-sm-3" | |
119 | for="disks" | |
120 | i18n>Images</label> | |
121 | <div class="col-sm-9"> | |
122 | <ng-container *ngFor="let image of targetForm.getValue('disks'); let i = index"> | |
123 | <div class="input-group cd-mb"> | |
124 | <input class="form-control" | |
125 | type="text" | |
126 | [value]="image" | |
127 | disabled /> | |
eafe8130 TL |
128 | <div class="input-group-addon" |
129 | *ngIf="api_version >= 1">lun: {{ imagesSettings[image]['lun'] }}</div> | |
11fdf7f2 TL |
130 | <span class="input-group-btn"> |
131 | <button class="btn btn-default" | |
132 | type="button" | |
133 | (click)="imageSettingsModal(image)"> | |
134 | <i class="fa fa-cogs fa-fw" | |
135 | aria-hidden="true"></i> | |
136 | </button> | |
137 | <button class="btn btn-default" | |
138 | type="button" | |
139 | (click)="removeImage(i, image)"> | |
140 | <i class="fa fa-remove fa-fw" | |
141 | aria-hidden="true"></i> | |
142 | </button> | |
143 | </span> | |
144 | ||
145 | </div> | |
146 | ||
147 | <span class="help-block"> | |
148 | <ng-container *ngIf="backstores.length > 1" | |
149 | i18n>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}. </ng-container> | |
150 | ||
151 | <ng-container *ngIf="hasAdvancedSettings(imagesSettings[image][imagesSettings[image].backstore])" | |
152 | i18n>This image has modified settings.</ng-container> | |
153 | </span> | |
154 | </ng-container> | |
155 | ||
eafe8130 TL |
156 | <input class="form-control" |
157 | type="hidden" | |
158 | id="disks" | |
159 | name="disks" | |
160 | formControlName="disks" /> | |
161 | ||
162 | <span class="help-block" | |
163 | *ngIf="targetForm.showError('disks', formDir, 'dupLunId')" | |
164 | i18n>Duplicated LUN numbers.</span> | |
165 | ||
11fdf7f2 | 166 | <span class="help-block" |
eafe8130 TL |
167 | *ngIf="targetForm.showError('disks', formDir, 'dupWwn')" |
168 | i18n>Duplicated WWN.</span> | |
11fdf7f2 TL |
169 | |
170 | <div class="row"> | |
171 | <div class="col-md-12"> | |
172 | <cd-select [data]="disks.value" | |
173 | [options]="imagesSelections" | |
174 | [messages]="messages.images" | |
175 | (selection)="onImageSelection($event)" | |
176 | elemClass="btn btn-default pull-right"> | |
177 | <i class="fa fa-fw fa-plus"></i> | |
178 | <ng-container i18n>Add image</ng-container> | |
179 | </cd-select> | |
180 | </div> | |
181 | </div> | |
182 | ||
183 | <hr /> | |
184 | </div> | |
185 | </div> | |
186 | ||
187 | <!-- acl_enabled --> | |
188 | <div class="form-group"> | |
189 | <div class="col-sm-offset-3 col-sm-9"> | |
190 | <div class="checkbox checkbox-primary"> | |
191 | <input type="checkbox" | |
192 | formControlName="acl_enabled" | |
193 | name="acl_enabled" | |
194 | id="acl_enabled"> | |
195 | <label for="acl_enabled" | |
196 | i18n>ACL authentication</label> | |
197 | </div> | |
198 | ||
199 | <hr /> | |
200 | </div> | |
201 | </div> | |
202 | ||
eafe8130 TL |
203 | <!-- Target level authentication was introduced in ceph-iscsi config v11 --> |
204 | <div formGroupName="auth" *ngIf="cephIscsiConfigVersion > 10 && !targetForm.getValue('acl_enabled')"> | |
205 | ||
206 | <!-- Target user --> | |
207 | <div class="form-group" | |
208 | [ngClass]="{'has-error': targetForm.showError('user', formDir)}"> | |
209 | <label class="control-label col-sm-3" | |
210 | for="target_user"> | |
211 | <ng-container i18n>User</ng-container> | |
212 | </label> | |
213 | <div class="col-sm-9"> | |
214 | <input class="form-control" | |
215 | type="text" | |
216 | id="target_user" | |
217 | name="target_user" | |
218 | formControlName="user" /> | |
219 | ||
220 | <span class="help-block" | |
221 | *ngIf="targetForm.showError('user', formDir, 'required')" | |
222 | i18n>This field is required.</span> | |
223 | ||
224 | <span class="help-block" | |
225 | *ngIf="targetForm.showError('user', formDir, 'pattern')" | |
226 | i18n>Usernames must have a length of 8 to 64 characters and | |
227 | can only contain letters, '.', '@', '-', '_' or ':'.</span> | |
228 | </div> | |
229 | </div> | |
230 | ||
231 | <!-- Target password --> | |
232 | <div class="form-group" | |
233 | [ngClass]="{'has-error': targetForm.showError('password', formDir)}"> | |
234 | <label class="control-label col-sm-3" | |
235 | for="target_password"> | |
236 | <ng-container i18n>Password</ng-container> | |
237 | </label> | |
238 | <div class="col-sm-9"> | |
239 | <div class="input-group"> | |
240 | <input class="form-control" | |
241 | type="password" | |
242 | autocomplete="new-password" | |
243 | id="target_password" | |
244 | name="target_password" | |
245 | formControlName="password" /> | |
246 | <span class="input-group-btn"> | |
247 | <button type="button" | |
248 | class="btn btn-default" | |
249 | cdPasswordButton="target_password"> | |
250 | </button> | |
251 | <button type="button" | |
252 | class="btn btn-default" | |
253 | cdCopy2ClipboardButton="target_password"> | |
254 | </button> | |
255 | </span> | |
256 | </div> | |
257 | ||
258 | <span class="help-block" | |
259 | *ngIf="targetForm.showError('password', formDir, 'required')" | |
260 | i18n>This field is required.</span> | |
261 | ||
262 | <span class="help-block" | |
263 | *ngIf="targetForm.showError('password', formDir, 'pattern')" | |
264 | i18n>Passwords must have a length of 12 to 16 characters | |
265 | and can only contain letters, '@', '-', '_' or '/'.</span> | |
266 | </div> | |
267 | </div> | |
268 | ||
269 | <!-- Target mutual_user --> | |
270 | <div class="form-group" | |
271 | [ngClass]="{'has-error': targetForm.showError('mutual_user', formDir)}"> | |
272 | <label class="control-label col-sm-3" | |
273 | for="target_mutual_user"> | |
274 | <ng-container i18n>Mutual User</ng-container> | |
275 | </label> | |
276 | <div class="col-sm-9"> | |
277 | <input class="form-control" | |
278 | type="text" | |
279 | id="target_mutual_user" | |
280 | name="target_mutual_user" | |
281 | formControlName="mutual_user" /> | |
282 | ||
283 | <span class="help-block" | |
284 | *ngIf="targetForm.showError('mutual_user', formDir, 'required')" | |
285 | i18n>This field is required.</span> | |
286 | ||
287 | <span class="help-block" | |
288 | *ngIf="targetForm.showError('mutual_user', formDir, 'pattern')" | |
289 | i18n>Usernames must have a length of 8 to 64 characters and | |
290 | can only contain letters, '.', '@', '-', '_' or ':'.</span> | |
291 | </div> | |
292 | </div> | |
293 | ||
294 | <!-- Target mutual_password --> | |
295 | <div class="form-group" | |
296 | [ngClass]="{'has-error': targetForm.showError('mutual_password', formDir)}"> | |
297 | <label class="control-label col-sm-3" | |
298 | for="target_mutual_password"> | |
299 | <ng-container i18n>Mutual Password</ng-container> | |
300 | </label> | |
301 | <div class="col-sm-9"> | |
302 | <div class="input-group"> | |
303 | <input class="form-control" | |
304 | type="password" | |
305 | autocomplete="new-password" | |
306 | id="target_mutual_password" | |
307 | name="target_mutual_password" | |
308 | formControlName="mutual_password" /> | |
309 | ||
310 | <span class="input-group-btn"> | |
311 | <button type="button" | |
312 | class="btn btn-default" | |
313 | cdPasswordButton="target_mutual_password"> | |
314 | </button> | |
315 | <button type="button" | |
316 | class="btn btn-default" | |
317 | cdCopy2ClipboardButton="target_mutual_password"> | |
318 | </button> | |
319 | </span> | |
320 | </div> | |
321 | ||
322 | <span class="help-block" | |
323 | *ngIf="targetForm.showError('mutual_password', formDir, 'required')" | |
324 | i18n>This field is required.</span> | |
325 | ||
326 | <span class="help-block" | |
327 | *ngIf="targetForm.showError('mutual_password', formDir, 'pattern')" | |
328 | i18n>Passwords must have a length of 12 to 16 characters | |
329 | and can only contain letters, '@', '-', '_' or '/'.</span> | |
330 | </div> | |
331 | </div> | |
332 | ||
333 | </div> | |
334 | ||
11fdf7f2 TL |
335 | <!-- Initiators --> |
336 | <div class="form-group" | |
337 | *ngIf="targetForm.getValue('acl_enabled')"> | |
338 | <label class="control-label col-sm-3" | |
339 | for="initiators" | |
340 | i18n>Initiators</label> | |
341 | <div class="col-sm-9" | |
342 | formArrayName="initiators"> | |
343 | <div class="panel panel-default" | |
344 | *ngFor="let initiator of initiators.controls; let ii = index" | |
345 | [formGroupName]="ii"> | |
346 | <div class="panel-heading"> | |
347 | <ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }} | |
348 | <button type="button" | |
349 | class="close" | |
350 | (click)="removeInitiator(ii)"> | |
351 | <i class="fa fa-remove fa-fw"></i> | |
352 | </button> | |
353 | </div> | |
354 | <div class="panel-body"> | |
355 | <!-- Initiator: Name --> | |
356 | <div class="form-group" | |
357 | [ngClass]="{'has-error': initiator.showError('client_iqn', formDir)}"> | |
358 | <label class="control-label col-sm-3" | |
359 | for="client_iqn"> | |
360 | <ng-container i18n>Client IQN</ng-container> | |
361 | <span class="required"></span> | |
362 | </label> | |
363 | <div class="col-sm-9"> | |
364 | <input class="form-control" | |
365 | type="text" | |
366 | formControlName="client_iqn" | |
367 | (blur)="updatedInitiatorSelector()"> | |
368 | ||
369 | <span class="help-block" | |
370 | *ngIf="initiator.showError('client_iqn', formDir, 'notUnique')" | |
371 | i18n>Initiator IQN needs to be unique.</span> | |
372 | ||
373 | <span class="help-block" | |
374 | *ngIf="initiator.showError('client_iqn', formDir, 'required')" | |
375 | i18n>This field is required.</span> | |
376 | ||
377 | <span class="help-block" | |
378 | *ngIf="initiator.showError('client_iqn', formDir, 'pattern')" | |
379 | i18n>IQN has wrong pattern.</span> | |
380 | </div> | |
381 | </div> | |
382 | ||
383 | <ng-container formGroupName="auth"> | |
384 | <!-- Initiator: User --> | |
385 | <div class="form-group" | |
386 | [ngClass]="{'has-error': initiator.showError('user', formDir)}"> | |
387 | <label class="control-label col-sm-3" | |
388 | for="user" | |
389 | i18n>User</label> | |
390 | <div class="col-sm-9"> | |
81eedcae | 391 | <input [id]="'user' + ii" |
11fdf7f2 TL |
392 | class="form-control" |
393 | formControlName="user" | |
394 | type="text"> | |
395 | <span class="help-block" | |
396 | *ngIf="initiator.showError('user', formDir, 'required')" | |
397 | i18n>This field is required.</span> | |
398 | ||
399 | <span class="help-block" | |
400 | *ngIf="initiator.showError('user', formDir, 'pattern')" | |
401 | i18n>Usernames must have a length of 8 to 64 characters and | |
402 | can only contain letters, '.', '@', '-', '_' or ':'.</span> | |
403 | </div> | |
404 | </div> | |
405 | ||
406 | <!-- Initiator: Password --> | |
407 | <div class="form-group" | |
408 | [ngClass]="{'has-error': initiator.showError('password', formDir)}"> | |
409 | <label class="control-label col-sm-3" | |
410 | for="password" | |
411 | i18n>Password</label> | |
412 | <div class="col-sm-9"> | |
413 | <div class="input-group"> | |
81eedcae | 414 | <input [id]="'password' + ii" |
11fdf7f2 TL |
415 | class="form-control" |
416 | formControlName="password" | |
417 | type="password"> | |
418 | ||
419 | <span class="input-group-btn"> | |
420 | <button type="button" | |
421 | class="btn btn-default" | |
81eedcae | 422 | [cdPasswordButton]="'password' + ii"> |
11fdf7f2 TL |
423 | </button> |
424 | <button type="button" | |
425 | class="btn btn-default" | |
81eedcae | 426 | [cdCopy2ClipboardButton]="'password' + ii"> |
11fdf7f2 TL |
427 | </button> |
428 | </span> | |
429 | </div> | |
430 | <span class="help-block" | |
431 | *ngIf="initiator.showError('password', formDir, 'required')" | |
432 | i18n>This field is required.</span> | |
433 | ||
434 | <span class="help-block" | |
435 | *ngIf="initiator.showError('password', formDir, 'pattern')" | |
436 | i18n>Passwords must have a length of 12 to 16 characters | |
437 | and can only contain letters, '@', '-', '_' or '/'.</span> | |
438 | </div> | |
439 | </div> | |
440 | ||
441 | ||
442 | <!-- Initiator: mutual_user --> | |
443 | <div class="form-group" | |
444 | [ngClass]="{'has-error': initiator.showError('mutual_user', formDir)}"> | |
445 | <label class="control-label col-sm-3" | |
446 | for="mutual_user"> | |
447 | <ng-container i18n>Mutual User</ng-container> | |
448 | </label> | |
449 | <div class="col-sm-9"> | |
81eedcae | 450 | <input [id]="'mutual_user' + ii" |
11fdf7f2 TL |
451 | class="form-control" |
452 | formControlName="mutual_user" | |
453 | type="text"> | |
454 | ||
455 | <span class="help-block" | |
456 | *ngIf="initiator.showError('mutual_user', formDir, 'required')" | |
457 | i18n>This field is required.</span> | |
458 | ||
459 | <span class="help-block" | |
460 | *ngIf="initiator.showError('mutual_user', formDir, 'pattern')" | |
461 | i18n>Usernames must have a length of 8 to 64 characters and | |
462 | can only contain letters, '.', '@', '-', '_' or ':'.</span> | |
463 | </div> | |
464 | </div> | |
465 | ||
466 | <!-- Initiator: mutual_password --> | |
467 | <div class="form-group" | |
468 | [ngClass]="{'has-error': initiator.showError('mutual_password', formDir)}"> | |
469 | <label class="control-label col-sm-3" | |
470 | for="mutual_password" | |
471 | i18n>Mutual Password</label> | |
472 | <div class="col-sm-9"> | |
473 | <div class="input-group"> | |
81eedcae | 474 | <input [id]="'mutual_password' + ii" |
11fdf7f2 TL |
475 | class="form-control" |
476 | formControlName="mutual_password" | |
477 | type="password"> | |
478 | ||
479 | <span class="input-group-btn"> | |
480 | <button type="button" | |
481 | class="btn btn-default" | |
81eedcae | 482 | [cdPasswordButton]="'mutual_password' + ii"> |
11fdf7f2 TL |
483 | </button> |
484 | <button type="button" | |
485 | class="btn btn-default" | |
81eedcae | 486 | [cdCopy2ClipboardButton]="'mutual_password' + ii"> |
11fdf7f2 TL |
487 | </button> |
488 | </span> | |
489 | </div> | |
490 | <span class="help-block" | |
491 | *ngIf="initiator.showError('mutual_password', formDir, 'required')" | |
492 | i18n>This field is required.</span> | |
493 | ||
494 | <span class="help-block" | |
495 | *ngIf="initiator.showError('mutual_password', formDir, 'pattern')" | |
496 | i18n>Passwords must have a length of 12 to 16 characters and | |
497 | can only contain letters, '@', '-', '_' or '/'.</span> | |
498 | </div> | |
499 | </div> | |
500 | </ng-container> | |
501 | ||
502 | <!-- Initiator: Images --> | |
503 | <div class="form-group" | |
504 | [ngClass]="{'has-error': initiator.showError('luns', formDir)}"> | |
505 | <label class="control-label col-sm-3" | |
506 | for="luns" | |
507 | i18n>Images</label> | |
508 | <div class="col-sm-9"> | |
509 | <ng-container *ngFor="let image of initiator.getValue('luns'); let li = index"> | |
510 | <div class="input-group cd-mb"> | |
511 | <input class="form-control" | |
512 | type="text" | |
513 | [value]="image" | |
514 | disabled /> | |
515 | <span class="input-group-btn"> | |
516 | <button class="btn btn-default" | |
517 | type="button" | |
518 | (click)="removeInitiatorImage(initiator, li, ii, image)"> | |
519 | <i class="fa fa-remove fa-fw" | |
520 | aria-hidden="true"></i> | |
521 | </button> | |
522 | </span> | |
523 | </div> | |
524 | </ng-container> | |
525 | ||
526 | <span *ngIf="initiator.getValue('cdIsInGroup')" | |
527 | i18n>Initiator belongs to a group. Images will be configure in the group.</span> | |
528 | ||
529 | <div class="row" | |
530 | *ngIf="!initiator.getValue('cdIsInGroup')"> | |
531 | <div class="col-md-12"> | |
532 | <cd-select [data]="initiator.getValue('luns')" | |
533 | [options]="imagesInitiatorSelections[ii]" | |
534 | [messages]="messages.initiatorImage" | |
535 | elemClass="btn btn-default pull-right"> | |
536 | <i class="fa fa-fw fa-plus"></i> | |
537 | <ng-container i18n>Add image</ng-container> | |
538 | </cd-select> | |
539 | </div> | |
540 | </div> | |
541 | </div> | |
542 | </div> | |
543 | </div> | |
544 | </div> | |
545 | ||
546 | <div class="row"> | |
547 | <div class="col-md-12"> | |
548 | <span class="text-muted" | |
549 | *ngIf="initiators.controls.length === 0" | |
550 | i18n>No items added.</span> | |
551 | ||
552 | <button (click)="addInitiator(); false" | |
553 | class="btn btn-default pull-right"> | |
554 | <i class="fa fa-fw fa-plus"></i> | |
555 | <ng-container i18n>Add initiator</ng-container> | |
556 | </button> | |
557 | </div> | |
558 | </div> | |
559 | ||
560 | <hr /> | |
561 | </div> | |
562 | </div> | |
563 | ||
564 | <!-- Groups --> | |
565 | <div class="form-group" | |
566 | *ngIf="targetForm.getValue('acl_enabled')" | |
567 | [ngClass]="{'has-error': targetForm.showError('groups', formDir)}"> | |
568 | <label class="control-label col-sm-3" | |
569 | for="initiators" | |
570 | i18n>Groups</label> | |
571 | <div class="col-sm-9" | |
572 | formArrayName="groups"> | |
573 | <div class="panel panel-default" | |
574 | *ngFor="let group of groups.controls; let gi = index" | |
575 | [formGroupName]="gi"> | |
576 | <div class="panel-heading"> | |
577 | <ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }} | |
578 | <button type="button" | |
579 | class="close" | |
580 | (click)="groups.removeAt(gi)"> | |
581 | <i class="fa fa-remove fa-fw"></i> | |
582 | </button> | |
583 | </div> | |
584 | <div class="panel-body"> | |
585 | <!-- Group: group_id --> | |
586 | <div class="form-group"> | |
587 | <label class="control-label col-sm-3" | |
588 | for="group_id"> | |
589 | <ng-container i18n>Name</ng-container> | |
590 | <span class="required"></span> | |
591 | </label> | |
592 | <div class="col-sm-9"> | |
593 | <input class="form-control" | |
594 | type="text" | |
595 | formControlName="group_id"> | |
596 | </div> | |
597 | </div> | |
598 | ||
599 | <!-- Group: members --> | |
600 | <div class="form-group" | |
601 | [ngClass]="{'has-error': group.showError('members', formDir)}"> | |
602 | <label class="control-label col-sm-3" | |
603 | for="members"> | |
604 | <ng-container i18n>Initiators</ng-container> | |
605 | </label> | |
606 | <div class="col-sm-9"> | |
607 | <ng-container *ngFor="let member of group.getValue('members'); let i = index"> | |
608 | <div class="input-group cd-mb"> | |
609 | <input class="form-control" | |
610 | type="text" | |
611 | [value]="member" | |
612 | disabled /> | |
613 | <span class="input-group-btn"> | |
614 | <button class="btn btn-default" | |
615 | type="button" | |
616 | (click)="removeGroupInitiator(group, i, gi)"> | |
617 | <i class="fa fa-remove fa-fw" | |
618 | aria-hidden="true"></i> | |
619 | </button> | |
620 | </span> | |
621 | </div> | |
622 | </ng-container> | |
623 | ||
624 | <div class="row"> | |
625 | <div class="col-md-12"> | |
626 | <cd-select [data]="group.getValue('members')" | |
627 | [options]="groupMembersSelections[gi]" | |
628 | [messages]="messages.groupInitiator" | |
629 | (selection)="onGroupMemberSelection($event)" | |
630 | elemClass="btn btn-default pull-right"> | |
631 | <i class="fa fa-fw fa-plus"></i> | |
632 | <ng-container i18n>Add initiator</ng-container> | |
633 | </cd-select> | |
634 | </div> | |
635 | </div> | |
636 | ||
637 | <hr /> | |
638 | </div> | |
639 | </div> | |
640 | ||
641 | <!-- Group: disks --> | |
642 | <div class="form-group" | |
643 | [ngClass]="{'has-error': group.showError('disks', formDir)}"> | |
644 | <label class="control-label col-sm-3" | |
645 | for="disks"> | |
646 | <ng-container i18n>Images</ng-container> | |
647 | </label> | |
648 | <div class="col-sm-9"> | |
649 | <ng-container *ngFor="let disk of group.getValue('disks'); let i = index"> | |
650 | <div class="input-group cd-mb"> | |
651 | <input class="form-control" | |
652 | type="text" | |
653 | [value]="disk" | |
654 | disabled /> | |
655 | <span class="input-group-btn"> | |
656 | <button class="btn btn-default" | |
657 | type="button" | |
658 | (click)="removeGroupDisk(group, i, gi)"> | |
659 | <i class="fa fa-remove fa-fw" | |
660 | aria-hidden="true"></i> | |
661 | </button> | |
662 | </span> | |
663 | </div> | |
664 | </ng-container> | |
665 | ||
666 | <div class="row"> | |
667 | <div class="col-md-12"> | |
668 | <cd-select [data]="group.getValue('disks')" | |
669 | [options]="groupDiskSelections[gi]" | |
670 | [messages]="messages.initiatorImage" | |
671 | elemClass="btn btn-default pull-right"> | |
672 | <i class="fa fa-fw fa-plus"></i> | |
673 | <ng-container i18n>Add image</ng-container> | |
674 | </cd-select> | |
675 | </div> | |
676 | </div> | |
677 | ||
678 | <hr /> | |
679 | </div> | |
680 | </div> | |
681 | </div> | |
682 | </div> | |
683 | ||
684 | <div class="row"> | |
685 | <div class="col-md-12"> | |
686 | <span class="text-muted" | |
687 | *ngIf="groups.controls.length === 0" | |
688 | i18n>No items added.</span> | |
689 | ||
690 | <button (click)="addGroup(); false" | |
691 | class="btn btn-default pull-right"> | |
692 | <i class="fa fa-fw fa-plus"></i> | |
693 | <ng-container i18n>Add group</ng-container> | |
694 | </button> | |
695 | </div> | |
696 | </div> | |
697 | </div> | |
698 | </div> | |
699 | ||
700 | </div> | |
701 | <div class="panel-footer"> | |
702 | <div class="button-group text-right"> | |
703 | <cd-submit-button | |
704 | [form]="formDir" | |
705 | (submitAction)="submit()" | |
706 | i18n="form action button|Example: Create Pool@@formActionButton" | |
707 | type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button> | |
708 | <cd-back-button></cd-back-button> | |
709 | </div> | |
710 | </div> | |
711 | </div> | |
712 | </form> | |
713 | </div> |