refs #2467. Create tag component
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
0248067d14
commit
0a14bbd486
|
@ -159,6 +159,7 @@ import { ClientPendingTasksComponent } from './components/task-logs/client-pendi
|
|||
import { QueueConfirmationModalComponent } from './shared/queue-confirmation-modal/queue-confirmation-modal.component';
|
||||
import { ModalOverlayComponent } from './shared/modal-overlay/modal-overlay.component';
|
||||
import { ScrollToTopComponent } from './shared/scroll-to-top/scroll-to-top.component';
|
||||
import { CreateTagModalComponent } from './components/repositories/show-git-images/create-tag-modal/create-tag-modal.component';
|
||||
|
||||
export function HttpLoaderFactory(http: HttpClient) {
|
||||
return new TranslateHttpLoader(http, './locale/', '.json');
|
||||
|
@ -274,7 +275,8 @@ registerLocaleData(localeEs, 'es-ES');
|
|||
SoftwareProfilePartitionComponent,
|
||||
ClientPendingTasksComponent,
|
||||
ModalOverlayComponent,
|
||||
ScrollToTopComponent
|
||||
ScrollToTopComponent,
|
||||
CreateTagModalComponent
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [BrowserModule,
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
.dialog-content {
|
||||
min-width: 400px;
|
||||
max-width: 500px;
|
||||
padding: 0 24px 24px 24px;
|
||||
}
|
||||
|
||||
h2[mat-dialog-title] {
|
||||
padding: 24px 24px 0 24px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.commit-info {
|
||||
background-color: #f5f5f5;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
border-left: 4px solid #3f51b5;
|
||||
}
|
||||
|
||||
.commit-info p {
|
||||
margin: 5px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.commit-info strong {
|
||||
color: #3f51b5;
|
||||
}
|
||||
|
||||
.tag-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
padding: 0 24px 24px 24px;
|
||||
}
|
||||
|
||||
.ordinary-button {
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ordinary-button:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #3f51b5;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.submit-button:hover:not(:disabled) {
|
||||
background-color: #303f9f;
|
||||
}
|
||||
|
||||
.submit-button:disabled {
|
||||
background-color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<app-loading [isLoading]="loading"></app-loading>
|
||||
|
||||
<h2 mat-dialog-title>Crear Tag para Commit</h2>
|
||||
|
||||
<mat-dialog-content class="dialog-content">
|
||||
<div class="commit-info">
|
||||
<p><strong>Commit ID:</strong> {{ data.commit.hexsha }}</p>
|
||||
<p><strong>Mensaje:</strong> {{ data.commit.message }}</p>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="tagForm" (ngSubmit)="createTag()" class="tag-form">
|
||||
<mat-form-field appearance="fill" class="form-field">
|
||||
<mat-label>Nombre del tag</mat-label>
|
||||
<input matInput formControlName="name" placeholder="ej: v1.0.0" required>
|
||||
<mat-error *ngIf="tagForm.get('name')?.hasError('required')">
|
||||
El nombre del tag es obligatorio
|
||||
</mat-error>
|
||||
<mat-error *ngIf="tagForm.get('name')?.hasError('pattern')">
|
||||
El nombre del tag solo puede contener letras, números, puntos, guiones y guiones bajos
|
||||
</mat-error>
|
||||
<mat-hint>Ejemplo: v1.0.0, release-2024-01, hotfix-bug-123</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="form-field">
|
||||
<mat-label>Mensaje del tag</mat-label>
|
||||
<textarea matInput formControlName="message" placeholder="Descripción del tag" required rows="3"></textarea>
|
||||
<mat-error *ngIf="tagForm.get('message')?.hasError('required')">
|
||||
El mensaje del tag es obligatorio
|
||||
</mat-error>
|
||||
<mat-hint>Descripción del tag (ej: "Release estable de la versión 1.0")</mat-hint>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<div mat-dialog-actions class="action-container">
|
||||
<button class="ordinary-button" (click)="close()">Cancelar</button>
|
||||
<button class="submit-button" (click)="createTag()" [disabled]="tagForm.invalid || loading">
|
||||
Crear Tag
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,63 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CreateTagModalComponent } from './create-tag-modal.component';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
describe('CreateTagModalComponent', () => {
|
||||
let component: CreateTagModalComponent;
|
||||
let fixture: ComponentFixture<CreateTagModalComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [CreateTagModalComponent],
|
||||
imports: [
|
||||
MatDialogModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
NoopAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
FormBuilder,
|
||||
HttpClient,
|
||||
ToastrService,
|
||||
ConfigService,
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting(),
|
||||
{
|
||||
provide: MatDialogRef,
|
||||
useValue: {}
|
||||
},
|
||||
{
|
||||
provide: MAT_DIALOG_DATA,
|
||||
useValue: {
|
||||
commit: {
|
||||
hexsha: 'test-commit-id',
|
||||
message: 'Test commit message'
|
||||
},
|
||||
repositoryName: 'test-repo'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CreateTagModalComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,64 @@
|
|||
import { Component, Inject } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-tag-modal',
|
||||
templateUrl: './create-tag-modal.component.html',
|
||||
styleUrl: './create-tag-modal.component.css'
|
||||
})
|
||||
export class CreateTagModalComponent {
|
||||
tagForm: FormGroup;
|
||||
loading: boolean = false;
|
||||
baseUrl: string;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private http: HttpClient,
|
||||
public dialogRef: MatDialogRef<CreateTagModalComponent>,
|
||||
private toastService: ToastrService,
|
||||
private configService: ConfigService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { commit: any, repositoryName: string, repositoryUuid: string }
|
||||
) {
|
||||
this.baseUrl = this.configService.apiUrl;
|
||||
this.tagForm = this.fb.group({
|
||||
name: ['', [Validators.required, Validators.pattern(/^[a-zA-Z0-9._-]+$/)]],
|
||||
message: ['', Validators.required]
|
||||
});
|
||||
}
|
||||
|
||||
createTag(): void {
|
||||
if (this.tagForm.valid) {
|
||||
this.loading = true;
|
||||
const payload = {
|
||||
commit: this.data.commit.hexsha,
|
||||
name: this.tagForm.value.name,
|
||||
message: this.tagForm.value.message,
|
||||
repository: this.data.repositoryName
|
||||
};
|
||||
|
||||
const url = `${this.baseUrl}/image-repositories/server/git/${this.data.repositoryUuid}/create-tag`;
|
||||
|
||||
this.http.post(url, payload).subscribe({
|
||||
next: (response) => {
|
||||
this.toastService.success('Tag creado correctamente');
|
||||
this.dialogRef.close(response);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error creating tag:', error);
|
||||
this.toastService.error(error.error?.message || 'Error al crear el tag');
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.toastService.error('Por favor, complete todos los campos requeridos');
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
|
@ -95,6 +95,10 @@
|
|||
<button mat-icon-button color="primary" (click)="toggleAction(commit, 'view-details')" matTooltip="Ver detalles">
|
||||
<mat-icon>info</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-icon-button color="accent" (click)="toggleAction(commit, 'create-tag')" matTooltip="Crear tag">
|
||||
<mat-icon>local_offer</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, Inject, Input, isDevMode, OnInit} from '@angular/core';
|
||||
import {Component, Inject, isDevMode, OnInit} from '@angular/core';
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
import {DatePipe} from "@angular/common";
|
||||
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
|
||||
|
@ -7,13 +7,8 @@ import {ToastrService} from "ngx-toastr";
|
|||
import {JoyrideService} from "ngx-joyride";
|
||||
import {ConfigService} from "@services/config.service";
|
||||
import {Router} from "@angular/router";
|
||||
import {Observable} from "rxjs";
|
||||
import {ServerInfoDialogComponent} from "../../ogdhcp/server-info-dialog/server-info-dialog.component";
|
||||
import {ImportImageComponent} from "../import-image/import-image.component";
|
||||
import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
import {ExportImageComponent} from "../../images/export-image/export-image.component";
|
||||
import {BackupImageComponent} from "../backup-image/backup-image.component";
|
||||
import {EditImageComponent} from "../edit-image/edit-image.component";
|
||||
import {CreateTagModalComponent} from "./create-tag-modal/create-tag-modal.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-show-git-commits',
|
||||
|
@ -212,6 +207,9 @@ export class ShowGitCommitsComponent implements OnInit{
|
|||
this.toastService.success('Commit ID copiado al portapapeles');
|
||||
});
|
||||
break;
|
||||
case 'create-tag':
|
||||
this.openCreateTagDialog(commit);
|
||||
break;
|
||||
default:
|
||||
console.error('Acción no soportada:', action);
|
||||
break;
|
||||
|
@ -253,6 +251,24 @@ export class ShowGitCommitsComponent implements OnInit{
|
|||
});
|
||||
}
|
||||
|
||||
openCreateTagDialog(commit: any) {
|
||||
const dialogRef = this.dialog.open(CreateTagModalComponent, {
|
||||
width: '500px',
|
||||
data: {
|
||||
commit: commit,
|
||||
repositoryName: this.selectedRepository,
|
||||
repositoryUuid: this.data.repositoryUuid
|
||||
}
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(result => {
|
||||
if (result) {
|
||||
// Recargar los datos para mostrar el nuevo tag
|
||||
this.loadData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
goToPage(commit: any) {
|
||||
window.open(`http://localhost:3100/oggit/${this.selectedRepository}/commit/${commit.hexsha}`, '_blank');
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue