Skip to content

Commit

Permalink
Cobbler-Frontend: Implement viewer for rendered auto-installations
Browse files Browse the repository at this point in the history
  • Loading branch information
SchoolGuy committed Nov 13, 2024
1 parent af6ee94 commit a814b5a
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 44 deletions.
11 changes: 11 additions & 0 deletions projects/cobbler-frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SyncComponent } from './actions/sync/sync.component';
import { ValidateAutoinstallsComponent } from './actions/validate-autoinstalls/validate-autoinstalls.component';
import { AppEventsComponent } from './app-events/app-events.component';
import { AppManageComponent } from './appManage';
import { ViewAutoinstallComponent } from './common/view-autoinstall/view-autoinstall.component';
import { DistroEditComponent } from './items/distro/edit/distro-edit.component';
import { DistrosOverviewComponent } from './items/distro/overview/distros-overview.component';
import { FileEditComponent } from './items/file/edit/file-edit.component';
Expand Down Expand Up @@ -72,6 +73,11 @@ export const routes: Routes = [
component: ProfileEditComponent,
canActivate: [AuthGuardService],
},
{
path: 'profile/:name/autoinstall',
component: ViewAutoinstallComponent,
canActivate: [AuthGuardService],
},
{
path: 'system',
component: SystemOverviewComponent,
Expand All @@ -82,6 +88,11 @@ export const routes: Routes = [
component: SystemEditComponent,
canActivate: [AuthGuardService],
},
{
path: 'system/:name/autoinstall',
component: ViewAutoinstallComponent,
canActivate: [AuthGuardService],
},
{
path: 'repository',
component: RepositoryOverviewComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<h1>Rendered auto-installation template</h1>

<p>This is the rendered template for {{ name }}.</p>

<form class="full-width full-height" (window:resize)="triggerResize()">
<mat-form-field class="full-width full-height">
<mat-label>Auto-installation content</mat-label>
<textarea
matInput
[formControl]="autoinstallFormControl"
readonly
class="content"
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="10"
cdkAutosizeMaxRows="40"
></textarea>
</mat-form-field>
</form>

<div>
<button
mat-fab
class="fab-positioning"
color="primary"
matTooltip="Back to {{ name }}"
(click)="backToItem()"
>
<mat-icon>arrow_back</mat-icon>
</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.full-width {
width: 100%;
}

.content {
white-space: pre-line;
width: 100%;
}

.fab-positioning {
position: fixed;
right: 1%;
bottom: 1%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute, provideRouter } from '@angular/router';
import { COBBLER_URL } from 'cobbler-api';
import { routes } from '../../app-routing.module';

import { ViewAutoinstallComponent } from './view-autoinstall.component';

describe('ViewAutoinstallComponent', () => {
let component: ViewAutoinstallComponent;
let fixture: ComponentFixture<ViewAutoinstallComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ViewAutoinstallComponent, NoopAnimationsModule],
providers: [
provideRouter(routes),
provideHttpClient(),
provideHttpClientTesting(),
{
provide: COBBLER_URL,
useValue: new URL('http://localhost/cobbler_api'),
},
{
provide: ActivatedRoute,
useValue: {
snapshot: {
url: [{ path: 'profile' }],
paramMap: {
get: () => 'testprof',
},
},
},
},
],
}).compileComponents();

fixture = TestBed.createComponent(ViewAutoinstallComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { CdkTextareaAutosize } from '@angular/cdk/text-field';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatTooltipModule } from '@angular/material/tooltip';
import { ActivatedRoute, Router } from '@angular/router';
import { CobblerApiService } from 'cobbler-api';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
selector: 'cobbler-view-autoinstall',
standalone: true,
imports: [
MatFormFieldModule,
MatInputModule,
ReactiveFormsModule,
MatIconModule,
MatButtonModule,
MatTooltipModule,
],
templateUrl: './view-autoinstall.component.html',
styleUrl: './view-autoinstall.component.scss',
})
export class ViewAutoinstallComponent implements OnInit, OnDestroy {
// Unsubscribe
private ngUnsubscribe = new Subject<void>();

// Data
type: string;
name: string;
autoinstallFormControl = new FormControl('');
@ViewChild('autosize') autosize: CdkTextareaAutosize;

constructor(
private router: Router,
private route: ActivatedRoute,
private cobblerApiService: CobblerApiService,
) {
this.type = this.route.snapshot.url[0].path;
this.name = this.route.snapshot.paramMap.get('name');
}

ngOnInit(): void {
if (this.type === 'profile') {
this.cobblerApiService
.generate_autoinstall(this.name, '')
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe((value) => {
this.autoinstallFormControl.setValue(value);
this.autosize.resizeToFitContent(true);
});
} else if (this.type === 'system') {
this.cobblerApiService
.generate_autoinstall('', this.name)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe((value) => {
this.autoinstallFormControl.setValue(value);
this.autosize.resizeToFitContent(true);
});
} else {
throw new Error('Object type was neither profile nor system!');
}
}

ngOnDestroy(): void {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}

triggerResize() {
this.autosize.resizeToFitContent(true);
}

backToItem() {
this.router.navigate(['/items', this.type, this.name]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ <h1 class="title title-cell-text">Name: {{ name }}</h1>
<mat-icon>refresh</mat-icon>
</button>
</span>
<span class="title-cell-button">
<button
mat-icon-button
[disabled]="isEditMode"
(click)="this.goToAutoinstall()"
matTooltip="Rendered auto-install template"
>
<mat-icon>task</mat-icon>
</button>
</span>
<span class="title-cell-button">
<button
mat-icon-button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { MatButton, MatIconButton } from '@angular/material/button';
import { MatCheckbox } from '@angular/material/checkbox';
import { MatDialog } from '@angular/material/dialog';
import { MatFormField, MatLabel } from '@angular/material/form-field';
import { MatIcon } from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import { MatInput } from '@angular/material/input';
import { MatSelect } from '@angular/material/select';
import { MatSnackBar } from '@angular/material/snack-bar';
Expand All @@ -30,11 +30,11 @@ import Utils from '../../../utils';
selector: 'cobbler-edit',
standalone: true,
imports: [
MatIcon,
MatIconButton,
MatTooltip,
FormsModule,
MatButton,
MatIconModule,
MatCheckbox,
MatFormField,
MatInput,
Expand Down Expand Up @@ -184,6 +184,10 @@ export class ProfileEditComponent implements OnInit, OnDestroy {
};
}

goToAutoinstall() {
this.router.navigate(['/items', 'profile', this.name, 'autoinstall']);
}

refreshData(): void {
this.cobblerApiService
.get_profile(this.name, false, false, this.userService.token)
Expand Down Expand Up @@ -449,26 +453,26 @@ export class ProfileEditComponent implements OnInit, OnDestroy {
this.cobblerApiService
.get_profile_handle(name, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(
(profileHandle) => {
.subscribe({
next: (profileHandle) => {
this.cobblerApiService
.copy_profile(profileHandle, newItemName, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(
(value) => {
.subscribe({
next: (value) => {
this.router.navigate(['/items', 'profile', newItemName]);
},
(error) => {
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(Utils.toHTML(error.message), 'Close');
},
);
});
},
(error) => {
error: (error) => {
// HTML encode the error message since it originates from XML
this._snackBar.open(Utils.toHTML(error.message), 'Close');
},
);
});
});
}

Expand All @@ -480,8 +484,8 @@ export class ProfileEditComponent implements OnInit, OnDestroy {
this.cobblerApiService
.get_profile_handle(this.name, this.userService.token)
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(
(profileHandle) => {
.subscribe({
next: (profileHandle) => {
let modifyObservables: Observable<boolean>[] = [];
dirtyValues.forEach((value, key) => {
modifyObservables.push(
Expand All @@ -493,29 +497,29 @@ export class ProfileEditComponent implements OnInit, OnDestroy {
),
);
});
combineLatest(modifyObservables).subscribe(
(value) => {
combineLatest(modifyObservables).subscribe({
next: (value) => {
this.cobblerApiService
.save_profile(profileHandle, this.userService.token)
.subscribe(
(value1) => {
.subscribe({
next: (value1) => {
this.isEditMode = false;
this.profileFormGroup.disable();
this.refreshData();
},
(error) => {
error: (error) => {
this._snackBar.open(Utils.toHTML(error.message), 'Close');
},
);
});
},
(error) => {
error: (error) => {
this._snackBar.open(Utils.toHTML(error.message), 'Close');
},
);
});
},
(error) => {
error: (error) => {
this._snackBar.open(Utils.toHTML(error.message), 'Close');
},
);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ <h1 class="title title-cell-text">Name: {{ name }}</h1>
<mat-icon>refresh</mat-icon>
</button>
</span>
<span class="title-cell-button">
<button
mat-icon-button
[disabled]="isEditMode"
(click)="this.goToAutoinstall()"
matTooltip="Rendered auto-install template"
>
<mat-icon>task</mat-icon>
</button>
</span>
<span class="title-cell-button">
<button
mat-icon-button
Expand Down
Loading

0 comments on commit a814b5a

Please sign in to comment.