-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cobbler-Frontend: Add UI for distro overview and detail view
- Loading branch information
Showing
20 changed files
with
476 additions
and
436 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
projects/cobbler-frontend/src/app/items/distro/edit/distro-edit.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<div class="title-table"> | ||
<div class="title-row"> | ||
<h1 class="title title-cell-text">Name: {{ name }}</h1> | ||
<span class="title-cell-button"> | ||
<button | ||
mat-icon-button | ||
(click)="this.refreshData()" | ||
matTooltip="Refresh data" | ||
><mat-icon>refresh</mat-icon></button> | ||
</span> | ||
<span class="title-cell-button"> | ||
<button | ||
mat-icon-button | ||
(click)="this.copyDistro()" | ||
matTooltip="Copy" | ||
><mat-icon>content_copy</mat-icon></button> | ||
</span> | ||
<span class="title-cell-button"> | ||
<button | ||
mat-icon-button | ||
(click)="this.editDistro()" | ||
matTooltip="Edit" | ||
><mat-icon>edit</mat-icon></button> | ||
</span> | ||
<span class="title-cell-button"> | ||
<button | ||
mat-icon-button | ||
(click)="this.removeDistro()" | ||
matTooltip="Delete" | ||
><mat-icon>delete</mat-icon></button> | ||
</span> | ||
</div> | ||
</div> | ||
|
||
<form class="form-replicate" [formGroup]="distroFormGroup"> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Name</mat-label> | ||
<input matInput type="text" formControlName="name"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>UID</mat-label> | ||
<input matInput type="text" formControlName="uid"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Last modified time</mat-label> | ||
<input matInput type="text" formControlName="mtime"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Creation time</mat-label> | ||
<input matInput type="text" formControlName="ctime"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Depth</mat-label> | ||
<input matInput type="number" formControlName="depth"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Architecture</mat-label> | ||
<input matInput type="text" formControlName="arch"/> | ||
</mat-form-field> | ||
<mat-checkbox class="form-field-full-width" formControlName="is_subobject">Is Subobject?</mat-checkbox> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Tree Build Time</mat-label> | ||
<input matInput type="text" formControlName="tree_build_time"/> | ||
</mat-form-field> | ||
<!-- TODO: autoinstall_meta --> | ||
<!-- TODO: boot_files --> | ||
<ng-container class="form-field-full-width"> | ||
<mat-form-field> | ||
<mat-label>Boot Loaders</mat-label> | ||
<mat-select formControlName="boot_loaders" multiple> | ||
@for (boot_loader of ["ipxe", "grub", "pxe"]; track boot_loader) { | ||
<mat-option [value]="boot_loader">{{boot_loader}}</mat-option> | ||
} | ||
</mat-select> | ||
</mat-form-field> | ||
<mat-checkbox formControlName="bootloader_inherited">Inherited</mat-checkbox> | ||
</ng-container> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Breed</mat-label> | ||
<input matInput type="text" formControlName="breed"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Comment</mat-label> | ||
<input matInput type="text" formControlName="comment"/> | ||
</mat-form-field> | ||
<!-- TODO: fetchable_files --> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>kernel</mat-label> | ||
<input matInput type="text" formControlName="kernel"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>initrd</mat-label> | ||
<input matInput type="text" formControlName="initrd"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Remote Boot Initrd</mat-label> | ||
<input matInput type="text" formControlName="remote_boot_initrd"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Remote Boot Kernel</mat-label> | ||
<input matInput type="text" formControlName="remote_boot_kernel"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Remote GRUB Initrd</mat-label> | ||
<input matInput type="text" formControlName="remote_grub_initrd"/> | ||
</mat-form-field> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Remote GRUB Kernel</mat-label> | ||
<input matInput type="text" formControlName="remote_grub_kernel"/> | ||
</mat-form-field> | ||
<!-- TODO: kernel_options --> | ||
<!-- TODO: kernel_options_post --> | ||
<!-- TODO: mgmt_classes --> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>Operating System Version</mat-label> | ||
<input matInput type="text" formControlName="os_version"/> | ||
</mat-form-field> | ||
<!-- TODO: owners --> | ||
<mat-form-field class="form-field-full-width"> | ||
<mat-label>RedHat Management Key</mat-label> | ||
<input matInput type="text" formControlName="redhat_management_key"/> | ||
</mat-form-field> | ||
<!-- TODO: template_files --> | ||
@if (isEditMode) { | ||
<button mat-button (click)="saveDistro()">Save Distro</button> | ||
} | ||
</form> |
30 changes: 30 additions & 0 deletions
30
projects/cobbler-frontend/src/app/items/distro/edit/distro-edit.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
.title-table { | ||
display: table; | ||
width: 100%; | ||
} | ||
|
||
.title-row { | ||
display: table-cell; | ||
width: 100%; | ||
} | ||
|
||
.title-cell-text { | ||
display: table-cell; | ||
width: 100%; | ||
vertical-align: middle; | ||
} | ||
|
||
.title-cell-button { | ||
display: table-cell; | ||
} | ||
|
||
.form-replicate { | ||
min-width: 150px; | ||
max-width: 600px; | ||
width: 100%; | ||
} | ||
|
||
.form-field-full-width { | ||
width: 100%; | ||
} | ||
|
23 changes: 23 additions & 0 deletions
23
projects/cobbler-frontend/src/app/items/distro/edit/distro-edit.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { DistroEditComponent } from './distro-edit.component'; | ||
|
||
describe('EditComponent', () => { | ||
let component: DistroEditComponent; | ||
let fixture: ComponentFixture<DistroEditComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [DistroEditComponent] | ||
}) | ||
.compileComponents(); | ||
|
||
fixture = TestBed.createComponent(DistroEditComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
146 changes: 146 additions & 0 deletions
146
projects/cobbler-frontend/src/app/items/distro/edit/distro-edit.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import {Component, inject, OnInit} from '@angular/core'; | ||
import {FormBuilder, FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms'; | ||
import {MatButton, MatIconButton} from '@angular/material/button'; | ||
import {MatCheckbox} from '@angular/material/checkbox'; | ||
import {MatFormField, MatLabel} from '@angular/material/form-field'; | ||
import {MatIcon} from '@angular/material/icon'; | ||
import {MatInput} from '@angular/material/input'; | ||
import {MatOption, MatSelect} from '@angular/material/select'; | ||
import {MatSnackBar} from '@angular/material/snack-bar'; | ||
import {MatTooltip} from '@angular/material/tooltip'; | ||
import {ActivatedRoute, Router} from '@angular/router'; | ||
import {CobblerApiService, Distro} from 'cobbler-api'; | ||
import {UserService} from '../../../services/user.service'; | ||
|
||
@Component({ | ||
selector: 'cobbler-edit', | ||
standalone: true, | ||
imports: [ | ||
MatIcon, | ||
MatIconButton, | ||
ReactiveFormsModule, | ||
MatFormField, | ||
MatInput, | ||
MatLabel, | ||
FormsModule, | ||
MatTooltip, | ||
MatButton, | ||
MatCheckbox, | ||
MatSelect, | ||
MatOption, | ||
], | ||
templateUrl: './distro-edit.component.html', | ||
styleUrl: './distro-edit.component.scss' | ||
}) | ||
export class DistroEditComponent implements OnInit{ | ||
name: string; | ||
distro: Distro; | ||
private readonly _formBuilder = inject(FormBuilder); | ||
distroFormGroup = this._formBuilder.group({ | ||
name: new FormControl({value: "", disabled: true}), | ||
uid: new FormControl({value: "", disabled: true}), | ||
mtime: new FormControl({value: "", disabled: true}), | ||
ctime: new FormControl({value: "", disabled: true}), | ||
depth: new FormControl({value: 0, disabled: true}), | ||
arch: new FormControl({value: "", disabled: true}), | ||
is_subobject: new FormControl({value: false, disabled: true}), | ||
tree_build_time: new FormControl({value: "", disabled: true}), | ||
breed: new FormControl({value: "", disabled: true}), | ||
comment: new FormControl({value: "", disabled: true}), | ||
kernel: new FormControl({value: "", disabled: true}), | ||
initrd: new FormControl({value: "", disabled: true}), | ||
remote_boot_initrd: new FormControl({value: "", disabled: true}), | ||
remote_boot_kernel: new FormControl({value: "", disabled: true}), | ||
remote_grub_initrd: new FormControl({value: "", disabled: true}), | ||
remote_grub_kernel: new FormControl({value: "", disabled: true}), | ||
os_version: new FormControl({value: "", disabled: true}), | ||
redhat_management_key: new FormControl({value: "", disabled: true}), | ||
boot_loaders: new FormControl({value: [], disabled: true}), | ||
bootloader_inherited: new FormControl({value: false, disabled: true}), | ||
}); | ||
isEditMode: boolean = false; | ||
|
||
constructor( | ||
private route: ActivatedRoute, | ||
private userService: UserService, | ||
private cobblerApiService: CobblerApiService, | ||
private _snackBar: MatSnackBar, | ||
private router: Router, | ||
) { | ||
this.name = this.route.snapshot.paramMap.get("name"); | ||
} | ||
|
||
ngOnInit(): void { | ||
this.refreshData() | ||
} | ||
|
||
refreshData(): void { | ||
this.cobblerApiService.get_distro(this.name, false, false, this.userService.token).subscribe(value => { | ||
this.distro = value | ||
this.distroFormGroup.controls.name.setValue(this.distro.name) | ||
this.distroFormGroup.controls.uid.setValue(this.distro.uid) | ||
this.distroFormGroup.controls.mtime.setValue(new Date(this.distro.mtime * 1000).toString()) | ||
this.distroFormGroup.controls.ctime.setValue(new Date(this.distro.ctime * 1000).toString()) | ||
this.distroFormGroup.controls.depth.setValue(this.distro.depth) | ||
this.distroFormGroup.controls.arch.setValue(this.distro.arch) | ||
this.distroFormGroup.controls.is_subobject.setValue(this.distro.is_subobject) | ||
this.distroFormGroup.controls.tree_build_time.setValue(new Date(this.distro.tree_build_time * 1000).toString()) | ||
this.distroFormGroup.controls.breed.setValue(this.distro.breed) | ||
this.distroFormGroup.controls.comment.setValue(this.distro.comment) | ||
this.distroFormGroup.controls.kernel.setValue(this.distro.kernel) | ||
this.distroFormGroup.controls.initrd.setValue(this.distro.initrd) | ||
this.distroFormGroup.controls.remote_boot_initrd.setValue(this.distro.remote_boot_initrd) | ||
this.distroFormGroup.controls.remote_boot_kernel.setValue(this.distro.remote_boot_kernel) | ||
this.distroFormGroup.controls.remote_grub_initrd.setValue(this.distro.remote_grub_initrd) | ||
this.distroFormGroup.controls.remote_grub_kernel.setValue(this.distro.remote_grub_kernel) | ||
this.distroFormGroup.controls.os_version.setValue(this.distro.os_version) | ||
this.distroFormGroup.controls.redhat_management_key.setValue(this.distro.redhat_management_key) | ||
if (typeof this.distro.boot_loaders === "string") { | ||
this.distroFormGroup.controls.bootloader_inherited.setValue(true) | ||
} else { | ||
this.distroFormGroup.controls.bootloader_inherited.setValue(false) | ||
this.distroFormGroup.controls.boot_loaders.setValue(this.distro.boot_loaders) | ||
} | ||
}, error => { | ||
// HTML encode the error message since it originates from XML | ||
this._snackBar.open(this.toHTML(error.message), 'Close'); | ||
}) | ||
} | ||
|
||
removeDistro(): void { | ||
this.cobblerApiService.remove_distro(this.name, this.userService.token, false).subscribe(value => { | ||
if (value) { | ||
this.router.navigate(["/distro"]) | ||
} | ||
// HTML encode the error message since it originates from XML | ||
this._snackBar.open("Delete failed! Check server logs for more information.", 'Close'); | ||
}, error => { | ||
// HTML encode the error message since it originates from XML | ||
this._snackBar.open(this.toHTML(error.message), 'Close'); | ||
}) | ||
} | ||
|
||
editDistro(): void { | ||
// TODO | ||
this._snackBar.open("Not implemented at the moment!", "Close") | ||
} | ||
|
||
copyDistro(): void { | ||
this.cobblerApiService.copy_distro("", "", this.userService.token) | ||
.subscribe(value => { | ||
// TODO | ||
}, error => { | ||
// HTML encode the error message since it originates from XML | ||
this._snackBar.open(this.toHTML(error.message), 'Close'); | ||
}) | ||
} | ||
|
||
saveDistro(): void { | ||
// TODO | ||
} | ||
|
||
toHTML(input: string): any { | ||
// FIXME: Deduplicate method | ||
return new DOMParser().parseFromString(input, 'text/html').documentElement.textContent; | ||
} | ||
} |
File renamed without changes.
Oops, something went wrong.