refs #1288. Added Menu CRUD
testing/ogGui-multibranch/pipeline/head This commit looks good Details

pull/10/head
Manuel Aranda Rosales 2024-12-20 08:02:10 +01:00
parent 4c45e51493
commit 369e09ee86
5 changed files with 112 additions and 94 deletions

View File

@ -43,49 +43,47 @@ import {EnvVarsComponent} from "./components/admin/env-vars/env-vars.component";
import {MenusComponent} from "./components/menus/menus.component";
const routes: Routes = [
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' },
{
path: '',
component: MainLayoutComponent,
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'admin', component: AdminComponent },
{ path: 'users', component: UsersComponent },
{ path: 'env-vars', component: EnvVarsComponent },
{ path: 'user-groups', component: RolesComponent },
{ path: 'groups', component: GroupsComponent },
{ path: 'pxe-images', component: PXEimagesComponent },
{ path: 'pxe', component: PxeComponent },
{ path: 'pxe-boot-file', component: PxeBootFilesComponent },
{ path: 'ogboot-status', component: OgbootStatusComponent },
{ path: 'dhcp', component: OgdhcpComponent },
{ path: 'subnets', component: OgDhcpSubnetsComponent },
{ path: 'ogdhcp-status', component: StatusComponent },
{ path: 'commands', component: CommandsComponent },
{ path: 'commands-groups', component: CommandsGroupsComponent },
{ path: 'commands-task', component: CommandsTaskComponent },
{ path: 'commands-logs', component: TaskLogsComponent },
{ path: 'calendars', component: CalendarComponent },
{ path: 'clients/:id', component: ClientMainViewComponent },
{ path: 'clients/:id/partition-assistant', component: PartitionAssistantComponent },
{ path: 'clients/:id/create-image', component: CreateImageComponent },
{ path: 'clients/:id/deploy-image', component: DeployImageComponent },
{ path: 'images', component: ImagesComponent },
{ path: 'repositories', component: RepositoriesComponent },
{ path: 'repository/:id', component: MainRepositoryViewComponent },
{ path: 'software', component: SoftwareComponent },
{ path: 'software-profiles', component: SoftwareProfileComponent },
{ path: 'operative-systems', component: OperativeSystemComponent },
{ path: 'menus', component: MenusComponent },
],
},
{
path: 'auth',
component: AuthLayoutComponent,
children: [
{ path: 'login', component: LoginComponent },
],
},
{ path: '**', component: PageNotFoundComponent },
{ path: '', component: MainLayoutComponent,
children: [
{ path: 'dashboard', component: DashboardComponent },
{ path: 'admin', component: AdminComponent },
{ path: 'users', component: UsersComponent },
{ path: 'env-vars', component: EnvVarsComponent },
{ path: 'user-groups', component: RolesComponent },
{ path: 'groups', component: GroupsComponent },
{ path: 'pxe-images', component: PXEimagesComponent },
{ path: 'pxe', component: PxeComponent },
{ path: 'pxe-boot-file', component: PxeBootFilesComponent },
{ path: 'ogboot-status', component: OgbootStatusComponent },
{ path: 'dhcp', component: OgdhcpComponent },
{ path: 'subnets', component: OgDhcpSubnetsComponent },
{ path: 'ogdhcp-status', component: StatusComponent },
{ path: 'commands', component: CommandsComponent },
{ path: 'commands-groups', component: CommandsGroupsComponent },
{ path: 'commands-task', component: CommandsTaskComponent },
{ path: 'commands-logs', component: TaskLogsComponent },
{ path: 'calendars', component: CalendarComponent },
{ path: 'clients/:id', component: ClientMainViewComponent },
{ path: 'clients/:id/partition-assistant', component: PartitionAssistantComponent },
{ path: 'clients/:id/create-image', component: CreateImageComponent },
{ path: 'clients/:id/deploy-image', component: DeployImageComponent },
{ path: 'images', component: ImagesComponent },
{ path: 'repositories', component: RepositoriesComponent },
{ path: 'repository/:id', component: MainRepositoryViewComponent },
{ path: 'software', component: SoftwareComponent },
{ path: 'software-profiles', component: SoftwareProfileComponent },
{ path: 'operative-systems', component: OperativeSystemComponent },
{ path: 'menus', component: MenusComponent },
],
},
{
path: 'auth',
component: AuthLayoutComponent,
children: [
{ path: 'login', component: LoginComponent },
],
},
{ path: '**', component: PageNotFoundComponent },
];
@NgModule({

View File

@ -2,42 +2,40 @@
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
}
.form-container {
display: flex;
flex-direction: row; /* Alinear elementos horizontalmente */
justify-content: space-between;
gap: 24px;
align-items: flex-start; /* Para alinear superiormente */
}
.menu-form {
flex: 1; /* El formulario ocupa el espacio restante */
display: flex;
flex-direction: column;
gap: 16px;
}
.menu-form {
width: 100%;
display: flex;
flex-direction: column;
}
.form-field {
width: 100%;
margin-bottom: 16px;
}
.dialog-actions {
.iframe-container {
flex: 1; /* El iframe ocupa la otra mitad del espacio */
display: flex;
justify-content: flex-end;
margin-top: 24px;
justify-content: center;
align-items: flex-start;
max-width: 50%; /* Limitar ancho máximo */
}
button {
margin-left: 8px;
}
@media (max-width: 600px) {
.form-field {
width: 100%;
}
.dialog-actions {
flex-direction: column;
align-items: stretch;
}
button {
width: 100%;
margin-left: 0;
margin-bottom: 8px;
}
.iframe {
width: 100%;
height: 600px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}

View File

@ -1,27 +1,36 @@
<h2 mat-dialog-title> {{ menuId ? 'Editar' : 'Añadir' }} menú</h2>
<h2 mat-dialog-title>{{ menuId ? 'Editar' : 'Añadir' }} menú</h2>
<mat-dialog-content class="dialog-content">
<form [formGroup]="menuForm" (ngSubmit)="save()" class="menu-form">
<mat-form-field appearance="fill" class="form-field">
<mat-label>Nombre del menú</mat-label>
<input matInput formControlName="name" required>
</mat-form-field>
<div class="form-container">
<!-- Formulario -->
<form [formGroup]="menuForm" (ngSubmit)="save()" class="menu-form">
<mat-form-field appearance="fill" class="form-field">
<mat-label>Nombre del menú</mat-label>
<input matInput formControlName="name" required>
</mat-form-field>
<mat-form-field appearance="fill" class="form-field">
<mat-label>Url pública</mat-label>
<input matInput formControlName="publicUrl" name="description">
</mat-form-field>
<mat-form-field appearance="fill" class="form-field">
<span matPrefix>{{baseUrl}}/menu/</span>
<mat-label>Url pública</mat-label>
<input matInput formControlName="publicUrl" name="description">
</mat-form-field>
<mat-form-field appearance="fill" class="form-field">
<mat-label>Resolución</mat-label>
<input matInput formControlName="resolution" name="comments">
</mat-form-field>
<mat-form-field appearance="fill" class="form-field">
<mat-label>Resolución</mat-label>
<input matInput formControlName="resolution" name="resolution">
</mat-form-field>
<mat-form-field appearance="fill" class="form-field">
<mat-label>Comentarios</mat-label>
<input matInput formControlName="comments" name="comments">
</mat-form-field>
</form>
<mat-form-field appearance="fill" class="form-field">
<mat-label>Comentarios</mat-label>
<input matInput formControlName="comments" name="comments">
</mat-form-field>
</form>
<!-- Iframe -->
<div class="iframe-container" *ngIf="safeUrl">
<iframe [src]="safeUrl" class="iframe"></iframe>
</div>
</div>
</mat-dialog-content>
<mat-dialog-actions align="end" class="dialog-actions">

View File

@ -4,6 +4,7 @@ import {HttpClient} from "@angular/common/http";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {ToastrService} from "ngx-toastr";
import {DataService} from "../../images/data.service";
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
@Component({
selector: 'app-create-menu',
@ -15,6 +16,7 @@ export class CreateMenuComponent {
menuForm: FormGroup<any>;
menuId: string | null = null;
softwareProfiles: any[] = [];
safeUrl: SafeResourceUrl | null = null;
constructor(
private fb: FormBuilder,
@ -22,6 +24,7 @@ export class CreateMenuComponent {
public dialogRef: MatDialogRef<CreateMenuComponent>,
private toastService: ToastrService,
private dataService: DataService,
private sanitizer: DomSanitizer,
@Inject(MAT_DIALOG_DATA) public data: any
) {
this.menuForm = this.fb.group({
@ -32,6 +35,15 @@ export class CreateMenuComponent {
});
}
updateSafeUrl(): void {
const url = `${this.baseUrl}/menu/${this.menuForm.get('publicUrl')?.value}`;
if (url) {
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
} else {
this.safeUrl = null;
}
}
ngOnInit() {
if (this.data) {
this.load()
@ -48,6 +60,7 @@ export class CreateMenuComponent {
comments: [response.comments],
});
this.menuId = response['@id'];
this.updateSafeUrl()
},
error: (err) => {
console.error('Error fetching remote calendar:', err);

View File

@ -37,7 +37,7 @@ export class MenusComponent {
{
columnDef: 'publicUrl',
header: 'Url pública',
cell: (repository: any) => `${repository.publicUrl}`
cell: (repository: any) => `${this.baseUrl}/menu/${repository.publicUrl}`
},
{
columnDef: 'resolution',
@ -68,7 +68,7 @@ export class MenusComponent {
addMenu(): void {
const dialogRef = this.dialog.open(CreateMenuComponent, {
width: '600px'
width: '1000px'
});
dialogRef.afterClosed().subscribe(() => {
@ -94,7 +94,7 @@ export class MenusComponent {
editMenu(event: MouseEvent, menu: any): void {
event.stopPropagation();
this.dialog.open(CreateMenuComponent, {
width: '800px',
width: '1200px',
data: menu['@id']
}).afterClosed().subscribe(() => this.search());
}