Skip to content
This repository was archived by the owner on Mar 25, 2023. It is now read-only.

Commit 4713f7e

Browse files
author
wowshakhov
authored
Merge pull request #252 from bwsw/224-vm-group-modal-dialog
(closes #224) Improve change VM group modal dialog
2 parents 11c76ef + 36aef6a commit 4713f7e

20 files changed

+420
-296
lines changed

src/app/dialog/dialog-module/dialog.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export class DialogService {
110110

111111
this.translateService.get(translationParams.translationTokens, translationParams.interpolateParams)
112112
.subscribe(translations => {
113-
let newConfig = this.getMergedConfig(config);
113+
const newConfig = this.getMergedConfig(config);
114114

115115
newConfig.message = translations[translationParams.message];
116116
newConfig.actions = newConfig.actions.map(action => ({
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<h3
2+
*ngIf="title"
3+
class="mdl-dialog__title"
4+
>
5+
{{ title | translate }}
6+
</h3>
7+
8+
<form
9+
(ngSubmit)="submit()"
10+
#form="ngForm"
11+
novalidate
12+
>
13+
<div class="mdl-dialog__content">
14+
<mdl-radio
15+
*ngIf="enableAssign"
16+
name="assignExistingRadio"
17+
[value]="modes.assign"
18+
[ngModel]="mode"
19+
(ngModelChange)="setMode($event)"
20+
mdl-ripple
21+
>
22+
{{ assignLabel | translate }}
23+
</mdl-radio>
24+
25+
<mdl-radio
26+
*ngIf="enableCreate"
27+
name="createNewRadio"
28+
[value]="modes.create"
29+
[ngModel]="mode"
30+
(ngModelChange)="setMode($event)"
31+
mdl-ripple
32+
>
33+
{{ createLabel | translate }}
34+
</mdl-radio>
35+
36+
<mdl-radio
37+
*ngIf="defaultValue && enableRemove"
38+
name="removeRadio"
39+
mdl-ripple
40+
[value]="modes.remove"
41+
[ngModel]="mode"
42+
(ngModelChange)="setMode($event)"
43+
>
44+
<div>
45+
{{ removeLabel | translate:{ value: defaultValue } }}
46+
</div>
47+
</mdl-radio>
48+
49+
<mdl-textfield
50+
*ngIf="mode === modes.create"
51+
type="text"
52+
name="textValue"
53+
floating-label
54+
autofocus
55+
required
56+
[(ngModel)]="newValue"
57+
#textField
58+
#textFieldModel="ngModel"
59+
[class.is-invalid]="textFieldModel.invalid && !textFieldModel.pristine"
60+
[style.width]="'100%'"
61+
[placeholder]="textFieldPlaceholder | translate"
62+
[maxlength]="maxLength"
63+
></mdl-textfield>
64+
65+
<mdl-select
66+
name="selectValue"
67+
*ngIf="mode === modes.assign"
68+
[(ngModel)]="newValue"
69+
[placeholder]="selectPlaceholder | translate"
70+
>
71+
<mdl-option
72+
*ngFor="let option of options"
73+
[value]="option"
74+
>
75+
{{ option }}
76+
</mdl-option>
77+
</mdl-select>
78+
</div>
79+
80+
<div class="mdl-dialog__actions">
81+
<button
82+
*ngIf="mode !== modes.remove"
83+
mdl-colored="primary"
84+
mdl-button
85+
mdl-ripple
86+
type="submit"
87+
[disabled]="!valueChanged || !form.valid"
88+
>
89+
{{ 'ASSIGN' | translate }}
90+
</button>
91+
<button
92+
*ngIf="mode === modes.remove"
93+
mdl-colored="primary"
94+
mdl-button
95+
mdl-ripple
96+
type="submit"
97+
>
98+
{{ 'REMOVE' | translate }}
99+
</button>
100+
<button
101+
mdl-colored="primary"
102+
mdl-button
103+
mdl-ripple
104+
type="button"
105+
(click)="cancel()"
106+
>
107+
{{ 'CANCEL' | translate }}
108+
</button>
109+
</div>
110+
</form>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
mdl-radio {
2+
width: 100%;
3+
}
4+
5+
/deep/ mdl-radio div {
6+
text-overflow: ellipsis;
7+
overflow: hidden;
8+
white-space: nowrap;
9+
}
10+
11+
.mdl-dialog__content {
12+
padding-bottom: 0;
13+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { MdlTextFieldComponent } from '@angular-mdl/core';
2+
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
3+
4+
5+
export enum Mode {
6+
assign,
7+
create,
8+
remove
9+
}
10+
11+
@Component({
12+
selector: 'cs-create-update-delete-dialog',
13+
templateUrl: 'create-update-delete-dialog.component.html',
14+
styleUrls: ['create-update-delete-dialog.component.scss']
15+
})
16+
export class CreateUpdateDeleteDialogComponent implements OnInit {
17+
@Input() public defaultValue: string;
18+
@Input() public options: Array<string>;
19+
20+
@Input() public enableAssign = true;
21+
@Input() public enableCreate = true;
22+
@Input() public enableRemove = true;
23+
24+
@Input() public assignLabel: string;
25+
@Input() public createLabel: string;
26+
@Input() public removeLabel: string;
27+
28+
@Input() public maxLength: number;
29+
30+
@Input() public selectPlaceholder: string;
31+
@Input() public textFieldPlaceholder: string;
32+
33+
@Input() public title: string;
34+
35+
@Output() public onAssigned: EventEmitter<string>;
36+
@Output() public onCancel: EventEmitter<void>;
37+
@Output() public onCreated: EventEmitter<string>;
38+
@Output() public onRemoved: EventEmitter<void>;
39+
@ViewChild('textField') public textField: MdlTextFieldComponent;
40+
41+
public loading: boolean;
42+
public newValue: string;
43+
44+
private _mode: Mode;
45+
public modes = Mode;
46+
47+
constructor() {
48+
this.onAssigned = new EventEmitter<string>();
49+
this.onCancel = new EventEmitter<void>();
50+
this.onCreated = new EventEmitter<string>();
51+
this.onRemoved = new EventEmitter<void>();
52+
}
53+
54+
public ngOnInit(): void {
55+
this.setDefaultMode();
56+
}
57+
58+
public get valueChanged(): boolean {
59+
const groupWasEmpty = !this.defaultValue && !!this.newValue;
60+
const groupChanged = this.defaultValue !== this.newValue;
61+
return groupWasEmpty || groupChanged;
62+
}
63+
64+
public get mode(): Mode {
65+
return this._mode;
66+
}
67+
68+
public setMode(mode: Mode) {
69+
if (this.mode !== mode) {
70+
this._mode = mode;
71+
this.setDefaultValue();
72+
}
73+
}
74+
75+
public cancel(): void {
76+
this.onCancel.emit();
77+
}
78+
79+
public submit(): void {
80+
switch (this.mode) {
81+
case Mode.assign:
82+
this.onAssigned.emit(this.newValue);
83+
break;
84+
case Mode.create:
85+
this.onCreated.emit(this.newValue);
86+
break;
87+
case Mode.remove:
88+
this.onRemoved.emit();
89+
break;
90+
default: break;
91+
}
92+
}
93+
94+
private setDefaultValue(): void {
95+
switch (this.mode) {
96+
case Mode.assign:
97+
this.newValue = this.defaultValue || this.options[0];
98+
break;
99+
case Mode.create:
100+
this.newValue = undefined;
101+
setTimeout(() => this.textField.setFocus());
102+
break;
103+
default: break;
104+
}
105+
}
106+
107+
private setDefaultMode(): void {
108+
const defaultMode = this.options.length ? Mode.assign : Mode.create;
109+
this.setMode(defaultMode);
110+
}
111+
}

src/app/shared/models/affinity-group.model.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { BaseModel } from './base.model';
22
import { FieldMapper } from '../decorators';
33

44

5-
export interface AffinityGroupType {
6-
type: string;
7-
}
5+
export type AffinityGroupType = string;
6+
export const AffinityGroupTypes = {
7+
hostAntiAffinity: 'host anti-affinity' as AffinityGroupType
8+
};
89

910
@FieldMapper({
1011
virtualmachineIds: 'virtualMachineIds'

src/app/shared/services/affinity-group.service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ export class AffinityGroupService extends BaseBackendCachedService<AffinityGroup
3535
.switchMap(job => this.asyncJob.queryJob(job.jobid, this.entity, this.entityModel));
3636
}
3737

38-
public updateForVm(vm: VirtualMachine, groupId: string): Observable<VirtualMachine> {
38+
public updateForVm(vm: VirtualMachine, affinityGroup?: AffinityGroup): Observable<VirtualMachine> {
3939
return this.sendCommand('updateVM', {
4040
id: vm.id,
41-
affinityGroupIds: groupId
41+
affinityGroupIds: affinityGroup && affinityGroup.id || ''
4242
})
4343
.switchMap(job => this.asyncJob.queryJob(job.jobid, 'virtualmachine', VirtualMachine));
4444
}
45+
46+
public removeForVm(vm: VirtualMachine): Observable<VirtualMachine> {
47+
return this.updateForVm(vm);
48+
}
4549
}

src/app/shared/shared.module.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ import { ReloadComponent } from './components/reload/reload.component';
8989
import {
9090
CharacterCountTextfieldComponent
9191
} from './components/character-count-textfield/character-count-textfield.component';
92+
import {
93+
CreateUpdateDeleteDialogComponent
94+
} from './components/create-update-delete-dialog/create-update-delete-dialog.component';
9295

9396

9497
@NgModule({
@@ -105,6 +108,7 @@ import {
105108
exports: [
106109
CharacterCountTextfieldComponent,
107110
ColorPickerComponent,
111+
CreateUpdateDeleteDialogComponent,
108112
DatePickerComponent,
109113
DescriptionComponent,
110114
DiskOfferingComponent,
@@ -145,6 +149,7 @@ import {
145149
CalendarMonthComponent,
146150
CalendarYearComponent,
147151
ColorPickerComponent,
152+
CreateUpdateDeleteDialogComponent,
148153
DateDisplayComponent,
149154
DatePickerComponent,
150155
DatePickerDialogComponent,

src/app/vm/vm-creation/vm-creation.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ export class VmCreationComponent implements OnInit {
224224
if (shouldCreateAffinityGroup) {
225225
affinityGroupsObservable = this.affinityGroupService.create({
226226
name: this.vmCreationData.affinityGroupName,
227-
type: this.vmCreationData.affinityGroupTypes[0].type
227+
type: this.vmCreationData.affinityGroupTypes[0]
228228
})
229229
.map(affinityGroup => {
230230
this.vmCreationData.affinityGroups.push(affinityGroup);

src/app/vm/vm-sidebar/affinity-group-dialog.component.html

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/app/vm/vm-sidebar/affinity-group-dialog.component.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

0 commit comments

Comments
 (0)