Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI] Allow single item deletion from multi-value fields #7084

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/apiserver-impl/ui/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ testem.log
Thumbs.db

/cypress/videos
/cypress/screenshots

.odo
.odo
282 changes: 270 additions & 12 deletions ui/cypress/e2e/spec.cy.ts

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions ui/cypress/fixtures/input/with-exec-command.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ commands:
hotReloadCapable: false
workingDir: /projects
id: command1
- exec:
commandLine: echo command2
component: container1
hotReloadCapable: true
workingDir: /projects
id: command2
- exec:
commandLine: echo command3
component: container1
hotReloadCapable: true
workingDir: /projects
id: command3
components:
- container:
args:
Expand Down
12 changes: 12 additions & 0 deletions ui/cypress/fixtures/input/with-volume.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
schemaVersion: 2.2.0
metadata: {}
components:
- name: volume1
volume: {}
- name: volume2
volume:
size: 2Gi
- name: volume3
volume:
ephemeral: true
size: 3G
15 changes: 15 additions & 0 deletions ui/src/app/controls/endpoints/endpoints.component.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
.mid-width { width: 50%; }
.quart-width { width: 25%; }

mat-card{
display:flex;
flex-direction: row;
margin-bottom: 16px;
}

mat-card-content{
flex-grow: 1;
overflow: auto;
}

button.adjust-position {
right: 6px;
}
88 changes: 47 additions & 41 deletions ui/src/app/controls/endpoints/endpoints.component.html
Original file line number Diff line number Diff line change
@@ -1,43 +1,49 @@
<div *ngFor="let control of form.controls; index as i">
<ng-container [formGroup]="control">
<mat-form-field class="mid-width" appearance="outline">
<mat-label><span>Name</span></mat-label>
<input [attr.data-cy]="'endpoint-name-'+i" matInput formControlName="name">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label><span>Target Port</span></mat-label>
<input [attr.data-cy]="'endpoint-targetPort-'+i" type="number" matInput formControlName="targetPort">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label>Exposure</mat-label>
<mat-select [attr.data-cy]="'endpoint-exposure-'+i" formControlName="exposure">
<mat-option value="">(default, public)</mat-option>
<mat-option value="public">public</mat-option>
<mat-option value="internal">internal</mat-option>
<mat-option value="none">none</mat-option>
</mat-select>
</mat-form-field>
<div class="group">
<mat-card *ngFor="let control of form.controls; index as i">
<mat-card-content [formGroup]="control">
<mat-form-field class="mid-width" appearance="outline">
<mat-label><span>Name</span></mat-label>
<input [attr.data-cy]="'endpoint-name-'+i" matInput formControlName="name">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label><span>Target Port</span></mat-label>
<input [attr.data-cy]="'endpoint-targetPort-'+i" type="number" matInput formControlName="targetPort">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label>Exposure</mat-label>
<mat-select [attr.data-cy]="'endpoint-exposure-'+i" formControlName="exposure">
<mat-option value="">(default, public)</mat-option>
<mat-option value="public">public</mat-option>
<mat-option value="internal">internal</mat-option>
<mat-option value="none">none</mat-option>
</mat-select>
</mat-form-field>

<mat-form-field class="mid-width" appearance="outline">
<mat-label><span>Path</span></mat-label>
<input [attr.data-cy]="'endpoint-path-'+i" matInput formControlName="path">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label>Protocol</mat-label>
<mat-select [attr.data-cy]="'endpoint-protocol-'+i" formControlName="protocol">
<mat-option value="">(default, http)</mat-option>
<mat-option value="http">http</mat-option>
<mat-option value="https">https</mat-option>
<mat-option value="ws">ws</mat-option>
<mat-option value="wss">wss</mat-option>
<mat-option value="tcp">tcp</mat-option>
<mat-option value="udp">udp</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox [attr.data-cy]="'endpoint-secure-'+i" formControlName="secure">Protocol Is Secure</mat-checkbox>
</ng-container>
<mat-form-field class="mid-width" appearance="outline">
<mat-label><span>Path</span></mat-label>
<input [attr.data-cy]="'endpoint-path-'+i" matInput formControlName="path">
</mat-form-field>
<mat-form-field class="quart-width" appearance="outline">
<mat-label>Protocol</mat-label>
<mat-select [attr.data-cy]="'endpoint-protocol-'+i" formControlName="protocol">
<mat-option value="">(default, http)</mat-option>
<mat-option value="http">http</mat-option>
<mat-option value="https">https</mat-option>
<mat-option value="ws">ws</mat-option>
<mat-option value="wss">wss</mat-option>
<mat-option value="tcp">tcp</mat-option>
<mat-option value="udp">udp</mat-option>
</mat-select>
</mat-form-field>
<mat-checkbox [attr.data-cy]="'endpoint-secure-'+i" formControlName="secure">Protocol Is Secure</mat-checkbox>
</mat-card-content>
<mat-card-actions>
<button [attr.data-cy]="'endpoint-minus-'+i" class="adjust-position" mat-icon-button matTooltip="Delete endpoint" (click)="removeEndpoint(i)">
<mat-icon class="tab-icon material-icons-outlined">delete_forever</mat-icon>
</button>
</mat-card-actions>
</mat-card>
<div>
<button data-cy="endpoints-add" mat-flat-button (click)="addEndpoint()">Add an Endpoint</button>
</div>
</div>
<button data-cy="endpoints-plus" *ngIf="form.value.length > 0" mat-icon-button (click)="addEndpoint()">
<mat-icon class="tab-icon material-icons-outlined">add</mat-icon>
</button>
<button data-cy="endpoints-add" *ngIf="form.value.length == 0" mat-flat-button (click)="addEndpoint()">Add an Endpoint</button>
4 changes: 4 additions & 0 deletions ui/src/app/controls/endpoints/endpoints.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ export class EndpointsComponent implements ControlValueAccessor, Validator {
}));
}

removeEndpoint(index: number) {
this.form.removeAt(index);
}

/* ControlValueAccessor implementation */
writeValue(value: Endpoint[]) {
value.forEach(ep => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
h3 { margin-bottom: 0; }
div.group { margin-bottom: 16px; }
div.group { margin-bottom: 16px; }

button.adjust-position {
right: 6px;
}
12 changes: 7 additions & 5 deletions ui/src/app/controls/multi-command/multi-command.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ <h3>{{title}}</h3>
<span *ngFor="let control of form.controls; index as i">
<mat-form-field appearance="fill">
<mat-label><span>Command</span></mat-label>
<mat-select [formControl]="control">
<mat-select [attr.data-cy]="'command-selector-'+i" [formControl]="control">
<mat-option *ngFor="let commandElement of commandList" [value]="commandElement">{{commandElement}}</mat-option>
</mat-select>
</mat-form-field>
<button [attr.data-cy]="'command-minus-'+i" class="adjust-position" mat-icon-button matTooltip="Delete command" (click)="removeCommand(i)">
<mat-icon class="tab-icon material-icons-outlined">delete_forever</mat-icon>
</button>
</span>
<button *ngIf="form.controls.length > 0" mat-icon-button (click)="addCommand('')">
<mat-icon class="tab-icon material-icons-outlined">add</mat-icon>
</button>
<button *ngIf="form.controls.length == 0" mat-flat-button (click)="addCommand('')">{{addLabel}}</button>
<div>
<button [attr.data-cy]="'add-command'" mat-flat-button (click)="addCommand('')">{{addLabel}}</button>
</div>
</div>
4 changes: 4 additions & 0 deletions ui/src/app/controls/multi-command/multi-command.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export class MultiCommandComponent implements ControlValueAccessor, Validator {
this.form.push(this.newCommand(cmdName));
}

removeCommand(index: number) {
this.form.removeAt(index);
}

/* Validator implementation */
validate(control: AbstractControl): ValidationErrors | null {
if (!this.form.valid) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
div.group { margin-bottom: 16px; }
.mid-width { width: 50%; }
.kv-width { width: 45%; }

button.adjust-position {
right: 6px;
top: 6px;
}

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<div class="group">
<div *ngFor="let control of form.controls; index as i">
<ng-container [formGroup]="control">
<mat-form-field class="mid-width" appearance="outline">
<mat-form-field class="kv-width" appearance="outline">
<mat-label><span>Name</span></mat-label>
<input [attr.data-cy]="dataCyPrefix+'-name-'+i" matInput formControlName="name">
</mat-form-field>
<mat-form-field class="mid-width" appearance="outline">
<mat-form-field class="kv-width" appearance="outline">
<mat-label><span>Value</span></mat-label>
<input [attr.data-cy]="dataCyPrefix+'-value-'+i" matInput formControlName="value">
</mat-form-field>
<button [attr.data-cy]="dataCyPrefix+'-minus-'+i" class="adjust-position" mat-icon-button [matTooltip]="deleteLabel" (click)="removeEntry(i)">
<mat-icon class="tab-icon material-icons-outlined">delete_forever</mat-icon>
</button>
</ng-container>
</div>
<button [attr.data-cy]="dataCyPrefix+'-plus'" *ngIf="form.controls.length > 0" mat-icon-button (click)="addEntry('', '')">
<mat-icon class="tab-icon material-icons-outlined">add</mat-icon>
</button>
<button [attr.data-cy]="dataCyPrefix+'-add'" *ngIf="form.controls.length == 0" mat-flat-button (click)="addEntry('', '')">{{addLabel}}</button>
<button [attr.data-cy]="dataCyPrefix+'-add'" mat-flat-button (click)="addEntry('', '')">{{addLabel}}</button>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class MultiKeyValueComponent implements ControlValueAccessor, Validator {

@Input() dataCyPrefix: string = "";
@Input() addLabel: string = "";
@Input() deleteLabel: string = "";

form = new FormArray<FormGroup>([]);

Expand Down Expand Up @@ -71,6 +72,10 @@ export class MultiKeyValueComponent implements ControlValueAccessor, Validator {
this.form.push(this.newKeyValueForm({name, value}));
}

removeEntry(index: number) {
this.form.removeAt(index);
}

/* Validator implementation */
validate(control: AbstractControl): ValidationErrors | null {
if (!this.form.valid) {
Expand Down
7 changes: 6 additions & 1 deletion ui/src/app/controls/multi-text/multi-text.component.css
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
h3 { margin-bottom: 0; }
div.group { margin-bottom: 16px; }
div.group { margin-bottom: 16px; }

button.adjust-position {
right: 6px;
top: 6px;
}
27 changes: 17 additions & 10 deletions ui/src/app/controls/multi-text/multi-text.component.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
<h3 *ngIf="title">{{title}}</h3>
<div class="group">
<span *ngFor="let control of form.controls; index as i">
<mat-form-field class="inline" appearance="outline">
<mat-label><span>{{label}}</span></mat-label>
<input matInput [formControl]="control">
</mat-form-field>
</span>
<button *ngIf="form.controls.length > 0" mat-icon-button (click)="addText('')">
<mat-icon class="tab-icon material-icons-outlined">add</mat-icon>
</button>
<button *ngIf="form.controls.length == 0" mat-flat-button (click)="addText('')">{{addLabel}}</button>
<mat-card *ngIf="form.controls.length > 0">
<mat-card-content>
<span *ngFor="let control of form.controls; index as i">
<mat-form-field class="inline" appearance="outline">
<mat-label><span>{{label}}</span></mat-label>
<input [attr.data-cy]="dataCyPrefix+'-text-'+i" matInput [formControl]="control">
</mat-form-field>
<button [attr.data-cy]="dataCyPrefix+'-minus-'+i" class="adjust-position" mat-icon-button [matTooltip]="deleteLabel" (click)="removeText(i)">
<mat-icon class="tab-icon material-icons-outlined">delete_forever</mat-icon>
</button>
</span>
</mat-card-content>
<mat-card-actions>
<button [attr.data-cy]="'add-text'" mat-flat-button (click)="addText('')">{{addLabel}}</button>
</mat-card-actions>
</mat-card>
<button *ngIf="form.controls.length == 0" [attr.data-cy]="'add-text'" mat-flat-button (click)="addText('')">{{addLabel}}</button>
</div>
6 changes: 6 additions & 0 deletions ui/src/app/controls/multi-text/multi-text.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ import {
})
export class MultiTextComponent implements ControlValueAccessor, Validator {

@Input() dataCyPrefix: string = "";
@Input() label: string = "";
@Input() addLabel: string = "";
@Input() deleteLabel: string = "";
@Input() title: string = "";

onChange = (_: string[]) => {};
Expand Down Expand Up @@ -62,6 +64,10 @@ export class MultiTextComponent implements ControlValueAccessor, Validator {
this.form.push(this.newText(text));
}

removeText(index: number) {
this.form.removeAt(index);
}

/* Validator implementation */
validate(control: AbstractControl): ValidationErrors | null {
if (!this.form.valid) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
h3 { margin-bottom: 0; }
div.group { margin-bottom: 16px; }
div.group { margin-bottom: 16px; }

button.adjust-position {
right: 6px;
top: 6px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@
<input formControlName="path" [attr.data-cy]="'volume-mount-path-'+i" matInput>
</mat-form-field>

<button [attr.data-cy]="'volume-mount-minus-'+i" class="adjust-position" mat-icon-button matTooltip="Delete Volume Mount" (click)="remove(i)">
<mat-icon class="tab-icon material-icons-outlined">delete_forever</mat-icon>
</button>

<app-volume
*ngIf="showNewVolume[i]"
(created)="onNewVolumeCreated(i, $event)"
></app-volume>
</ng-container>
</div>
<button data-cy="volume-mount-add" *ngIf="form.controls.length > 0" mat-icon-button (click)="add('', '')">
<mat-icon class="tab-icon material-icons-outlined">add</mat-icon>
</button>
<button data-cy="volume-mount-add" *ngIf="form.controls.length == 0" mat-flat-button (click)="add('', '')">Add Volume Mount</button>
<button data-cy="volume-mount-add" mat-flat-button (click)="add('', '')">Add Volume Mount</button>
</div>

4 changes: 4 additions & 0 deletions ui/src/app/controls/volume-mounts/volume-mounts.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export class VolumeMountsComponent implements ControlValueAccessor, Validator {
this.form.push(this.newVolumeMount({name, path}));
}

remove(i: number) {
this.form.removeAt(i);
}

onNameChange(i: number, name: string) {
this.showNewVolume[i] = name == "!";
}
Expand Down
Loading