refs #2505. Update GIT image
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details

pull/33/head
Manuel Aranda Rosales 2025-08-05 10:28:06 +02:00
parent 229ff86c5b
commit 9969ab303a
3 changed files with 722 additions and 142 deletions

View File

@ -675,3 +675,340 @@ mat-form-field {
}
}
@media (max-width: 768px) {
.scroll-to-top-button {
right: 16px;
bottom: 16px;
}
}
/* Estilos para el selector de ramas */
.branch-selector-header {
display: flex;
gap: 16px;
align-items: flex-end;
width: 100%;
}
.create-branch-button {
background: #4caf50;
color: white;
border: none;
padding: 12px 20px;
border-radius: 8px;
font-weight: 500;
transition: all 0.3s ease;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
white-space: nowrap;
height: 56px;
}
.create-branch-button:hover:not(:disabled) {
background: #45a049;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
}
.create-branch-button:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.create-branch-button mat-icon {
font-size: 18px;
width: 18px;
height: 18px;
}
/* Estilos para la sección de commits */
.commits-section {
margin-top: 24px;
padding: 24px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border: 1px solid #e0e0e0;
}
.search-container {
margin-bottom: 20px;
}
.search-string {
width: 100%;
}
.commits-table-container {
margin-top: 20px;
overflow-x: auto;
}
.commit-id {
font-family: 'Courier New', monospace;
background: #f5f5f5;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: #333;
}
.commit-message {
max-width: 300px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.commit-stats {
font-size: 12px;
color: #666;
}
.commit-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
}
.commit-tags mat-chip {
font-size: 10px;
height: 20px;
}
.no-tags {
color: #999;
font-size: 12px;
font-style: italic;
}
.action-buttons {
display: flex;
gap: 8px;
justify-content: center;
}
.action-buttons button {
transition: all 0.2s ease;
}
.action-buttons button:hover {
transform: scale(1.1);
}
.paginator-container {
margin-top: 20px;
}
/* Responsive para ramas y commits */
@media (max-width: 768px) {
.branch-selector-header {
flex-direction: column;
align-items: stretch;
}
.create-branch-button {
height: auto;
padding: 12px 16px;
}
.commits-section {
padding: 16px;
}
.commit-message {
max-width: 200px;
}
.action-buttons {
flex-direction: column;
gap: 4px;
}
}
.git-info-container {
margin-bottom: 20px;
}
.git-info-card {
background: #f8f9fa;
border-radius: 8px;
padding: 20px;
color: #495057;
border: 1px solid #e9ecef;
animation: fadeInUp 0.5s ease-out;
}
.git-info-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.git-info-icon {
font-size: 20px;
width: 20px;
height: 20px;
color: #6c757d;
}
.git-info-title {
font-size: 16px;
font-weight: 600;
flex-grow: 1;
color: #495057;
}
.git-loading-spinner {
margin-left: auto;
}
.git-info-content {
background: #ffffff;
border-radius: 6px;
padding: 16px;
margin-top: 12px;
border: 1px solid #dee2e6;
}
.git-info-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
}
.git-info-item {
display: flex;
flex-direction: column;
}
.git-form-field {
width: 100%;
}
.git-item-icon {
font-size: 16px;
width: 16px;
height: 16px;
color: #495057;
margin-right: 4px;
}
.git-data-display {
background: #f8f9fa;
border-radius: 4px;
padding: 12px;
margin: 0;
font-family: 'Courier New', monospace;
font-size: 12px;
color: #495057;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
border: 1px solid #e9ecef;
}
.git-info-loading {
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
font-size: 14px;
color: #6c757d;
}
.git-info-empty {
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
font-size: 14px;
color: #6c757d;
font-style: italic;
}
/* Estilos para la advertencia de repositorio no encontrado */
.repository-warning {
display: flex;
align-items: flex-start;
gap: 12px;
margin-top: 16px;
padding: 16px;
background: #fff3cd;
border: 1px solid #ffeaa7;
border-radius: 8px;
color: #856404;
}
.warning-icon {
font-size: 20px;
width: 20px;
height: 20px;
color: #f39c12;
flex-shrink: 0;
margin-top: 2px;
}
.warning-content {
flex-grow: 1;
}
.warning-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 4px;
color: #e67e22;
}
.warning-message {
font-size: 13px;
line-height: 1.4;
color: #856404;
}
/* Responsive para el cuadro informativo de Git */
@media (max-width: 768px) {
.git-info-card {
padding: 16px;
}
.git-info-header {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.git-loading-spinner {
margin-left: 0;
align-self: flex-end;
}
.git-data-display {
font-size: 11px;
max-height: 200px;
}
.git-info-grid {
grid-template-columns: 1fr;
gap: 12px;
}
.git-info-item {
padding: 10px;
}
.git-info-value {
font-size: 13px;
}
}

View File

@ -1,4 +1,5 @@
<!-- Overlay de carga para creación de repositorio -->
<app-loading [isLoading]="loading"></app-loading>
<app-modal-overlay
[isVisible]="creatingRepository"
message="Creando repositorio...">
@ -20,12 +21,11 @@
</div>
</div>
<div class="button-row">
<button class="action-button" id="execute-button" [disabled]="!selectedPartition" (click)="save()">Ejecutar</button>
<button class="action-button" id="execute-button" [disabled]="!selectedPartition || loading" (click)="save()">Ejecutar</button>
</div>
</div>
<div class="select-container">
<!-- Sección: Configuración de tipo de imagen -->
<div class="form-section">
<div class="form-section-title">
<mat-icon>settings</mat-icon>
@ -43,15 +43,81 @@
</div>
</div>
<!-- Sección: Configuración Git (solo para tipo git) -->
<div class="form-section" *ngIf="imageType === 'git'">
<div class="form-section-title">
<mat-icon>code</mat-icon>
Configuración Git
</div>
<div class="git-repository-section">
<div class="repository-header">
<div class="git-info-container" *ngIf="selectedPartition && imageType === 'git' && (hasValidGitData || loadingGitData)">
<div class="git-info-card">
<div class="git-info-header">
<mat-icon class="git-info-icon">info</mat-icon>
<span class="git-info-title">La imagen en caché a actualizar es:</span>
<mat-spinner *ngIf="loadingGitData" diameter="20" class="git-loading-spinner"></mat-spinner>
</div>
<div class="" *ngIf="!loadingGitData && hasValidGitData">
<div class="git-info-grid">
<div class="git-info-item">
<mat-form-field appearance="outline" class="git-form-field">
<mat-label>
<mat-icon class="git-item-icon">folder</mat-icon>
Repositorio
</mat-label>
<input matInput [value]="gitData.repo" readonly>
</mat-form-field>
</div>
<div class="git-info-item">
<mat-form-field appearance="outline" class="git-form-field">
<mat-label>
<mat-icon class="git-item-icon">account_tree</mat-icon>
Rama origen
</mat-label>
<input matInput [value]="gitData.branch" readonly>
</mat-form-field>
</div>
<div class="git-info-item">
<mat-form-field appearance="outline" class="git-form-field">
<mat-label>
<mat-icon class="git-item-icon">call_split</mat-icon>
Rama destino
</mat-label>
<input matInput
[(ngModel)]="destinationBranch"
[readonly]="!isDestinationBranchEditable"
placeholder="Nombre de la rama destino"
[matTooltip]="isDestinationBranchEditable ? 'Guardar cambios' : 'Editar nombre de la rama destino'">
<button mat-icon-button
matSuffix
[matTooltip]="isDestinationBranchEditable ? 'Guardar' : 'Editar rama destino'"
(click)="toggleDestinationBranchEdit()">
<mat-icon>{{ isDestinationBranchEditable ? 'save' : 'edit' }}</mat-icon>
</button>
</mat-form-field>
</div>
</div>
<div class="repository-warning" *ngIf="repositoryNotFound">
<mat-icon class="warning-icon">warning</mat-icon>
<div class="warning-content">
<div class="warning-title">Repositorio no encontrado</div>
<div class="warning-message">
El repositorio "{{ gitData.repo }}" no existe en el listado de repositorios disponibles.
Es posible que necesites crearlo primero.
</div>
</div>
</div>
</div>
<div class="git-info-loading" *ngIf="loadingGitData">
<span>Cargando información de Git...</span>
</div>
<div class="git-info-empty" *ngIf="!loadingGitData && !hasValidGitData">
<span>No se encontró información de Git para esta partición</span>
</div>
</div>
</div>
<div class="repository-header" *ngIf="!hasValidGitData">
<button *ngIf="imageType === 'git'"
class="create-repository-button"
(click)="openCreateRepositoryModal()"
@ -61,95 +127,82 @@
</button>
</div>
<div class="selector">
<mat-form-field appearance="fill" class="full-width">
<mat-label>Seleccionar repositorio Git</mat-label>
<mat-select [(ngModel)]="selectedGitRepository" (selectionChange)="onGitRepositorySelected($event.value)" required>
<mat-option [value]="null">Seleccionar repositorio git / SO</mat-option>
<mat-option *ngFor="let repo of gitRepositories" [value]="repo">{{ repo.name }}</mat-option>
</mat-select>
<mat-spinner *ngIf="loadingGitRepositories" matSuffix diameter="20"></mat-spinner>
<mat-hint>
<mat-icon>info</mat-icon>
Selecciona el repositorio git para obtener las imágenes disponibles.
<span *ngIf="gitRepositories.length === 0" class="no-repositories-hint">
No hay repositorios disponibles. Crea uno nuevo para continuar.
</span>
</mat-hint>
</mat-form-field>
</div>
</div>
<div class="selector" *ngIf="!hasValidGitData">
<mat-form-field appearance="fill" class="half-width">
<mat-label>Seleccionar repositorio Git</mat-label>
<mat-select [(ngModel)]="selectedGitRepository" (selectionChange)="onGitRepositorySelected($event.value)" required>
<mat-option [value]="null">Seleccionar repositorio git / SO</mat-option>
<mat-option *ngFor="let repo of gitRepositories" [value]="repo">{{ repo.name }}</mat-option>
</mat-select>
<mat-spinner *ngIf="loadingGitRepositories" matSuffix diameter="20"></mat-spinner>
<mat-hint>
<mat-icon>info</mat-icon>
Selecciona el repositorio git para obtener las imágenes disponibles.
<span *ngIf="gitRepositories.length === 0" class="no-repositories-hint">
No hay repositorios disponibles. Crea uno nuevo para continuar.
</span>
</mat-hint>
</mat-form-field>
<!-- Opciones de acción Git -->
<div class="git-action-selector">
<div class="action-chips-container">
<mat-chip-listbox [(ngModel)]="gitAction" required class="action-chip-listbox">
<mat-chip-option value="create" class="action-chip create-chip firmware-chip" (click)="onGitActionSelected({value: 'create'})">
<span>Crear imagen</span>
</mat-chip-option>
<mat-chip-option value="update" class="action-chip update-chip firmware-chip" (click)="onGitActionSelected({value: 'update'})">
<span>Actualizar imagen</span>
</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="action-hint">
<mat-icon>info</mat-icon>
<span *ngIf="gitAction === 'create'">Crea una nueva imagen con el nombre especificado</span>
<span *ngIf="gitAction === 'update'">Actualiza una imagen existente seleccionada</span>
</div>
</div>
</div>
<!-- Sección: Configuración general -->
<div class="form-section" *ngIf="imageType !== 'git'">
<div class="form-section-title">
<mat-icon>image</mat-icon>
Configuración de imagen
<button class="create-branch-button"
*ngIf="selectedGitRepository"
(click)="openCreateBranchModal()"
[disabled]="loadingBranches"
matTooltip="Crear nueva rama"
style="display: none;">
<mat-icon>add</mat-icon>
<span>Crear rama</span>
</button>
</div>
<!-- Opciones de acción para imágenes monolíticas -->
<div class="action-chips-container">
<mat-chip-listbox [(ngModel)]="monolithicAction" required class="action-chip-listbox">
<mat-chip-option value="create" class="action-chip create-chip firmware-chip" (click)="onMonolithicActionSelected({value: 'create'})">
<span>Crear imagen</span>
</mat-chip-option>
<mat-chip-option value="update" class="action-chip update-chip firmware-chip" (click)="onMonolithicActionSelected({value: 'update'})">
<span>Actualizar imagen</span>
</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="action-hint">
<mat-icon>info</mat-icon>
<span *ngIf="monolithicAction === 'create'">Crea una nueva imagen con el nombre especificado</span>
<span *ngIf="monolithicAction === 'update'">Actualiza una imagen existente seleccionada</span>
</div>
<div class="selector" *ngIf="monolithicAction === 'create'">
<mat-form-field appearance="fill" class="half-width">
<mat-label>Nombre canónico</mat-label>
<input matInput [(ngModel)]="name" placeholder="Nombre canónico. En minúscula y sin espacios" required>
<mat-hint>Introduce el nombre para la nueva imagen que se creará.</mat-hint>
</mat-form-field>
</div>
<div class="selector" *ngIf="monolithicAction === 'update'">
<mat-form-field appearance="fill" class="half-width">
<mat-label>Seleccione imagen</mat-label>
<mat-select [(ngModel)]="selectedImage" name="selectedImage" (selectionChange)="resetCanonicalName()" required>
<mat-option [value]="null">Seleccionar imagen para actualizar</mat-option>
<mat-option *ngFor="let image of images" [value]="image">{{ image?.name }}</mat-option>
</mat-select>
<button *ngIf="selectedImage" mat-icon-button matSuffix aria-label="Clear client search"
(click)="selectedImage = null; resetCanonicalName()">
<mat-icon>close</mat-icon>
</button>
<mat-hint>Selecciona la imagen existente que quieres actualizar.</mat-hint>
</mat-form-field>
</div>
</div>
<!-- Sección: Selección de partición -->
<div class="form-section" *ngIf="imageType === 'monolithic'">
<div class="form-section-title">
<mat-icon>image</mat-icon>
Configuración de imagen monolítica
</div>
<div class="action-chips-container">
<mat-chip-listbox [(ngModel)]="monolithicAction" required class="action-chip-listbox">
<mat-chip-option value="create" class="action-chip create-chip firmware-chip" (click)="onMonolithicActionSelected({value: 'create'})">
<span>Crear imagen</span>
</mat-chip-option>
<mat-chip-option value="update" class="action-chip update-chip firmware-chip" (click)="onMonolithicActionSelected({value: 'update'})">
<span>Actualizar imagen</span>
</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="action-hint">
<mat-icon>info</mat-icon>
<span *ngIf="monolithicAction === 'create'">Crea una nueva imagen con el nombre especificado</span>
<span *ngIf="monolithicAction === 'update'">Actualiza una imagen existente seleccionada</span>
</div>
<div class="selector" *ngIf="monolithicAction === 'create'">
<mat-form-field appearance="fill" class="half-width">
<mat-label>Nombre canónico</mat-label>
<input matInput [(ngModel)]="name" placeholder="Nombre canónico. En minúscula y sin espacios" required>
<mat-hint>Introduce el nombre para la nueva imagen que se creará.</mat-hint>
</mat-form-field>
</div>
<div class="selector" *ngIf="monolithicAction === 'update'">
<mat-form-field appearance="fill" class="half-width">
<mat-label>Seleccione imagen</mat-label>
<mat-select [(ngModel)]="selectedImage" name="selectedImage" (selectionChange)="resetCanonicalName()" required>
<mat-option [value]="null">Seleccionar imagen para actualizar</mat-option>
<mat-option *ngFor="let image of images" [value]="image">{{ image?.name }}</mat-option>
</mat-select>
<button *ngIf="selectedImage" mat-icon-button matSuffix aria-label="Clear client search"
(click)="selectedImage = null; resetCanonicalName()">
<mat-icon>close</mat-icon>
</button>
<mat-hint>Selecciona la imagen existente que quieres actualizar.</mat-hint>
</mat-form-field>
</div>
</div>
<div class="form-section" #partitionSection id="partition-selection">
<div class="form-section-title">
<mat-icon>storage</mat-icon>

View File

@ -8,6 +8,7 @@ import { ConfigService } from '@services/config.service';
import {MatDialog} from "@angular/material/dialog";
import {QueueConfirmationModalComponent} from "../../../../../shared/queue-confirmation-modal/queue-confirmation-modal.component";
import {CreateRepositoryModalComponent} from "./create-repository-modal/create-repository-modal.component";
import {CreateBranchModalComponent} from "../../../../repositories/show-git-images/create-branch-modal/create-branch-modal.component";
@Component({
selector: 'app-create-image',
@ -38,12 +39,27 @@ export class CreateClientImageComponent implements OnInit{
loadingGitRepositories: boolean = false;
loadingGitImageRepositories: boolean = false;
creatingRepository: boolean = false;
gitAction: string = 'create';
monolithicAction: string = 'create';
existingImages: any[] = [];
selectedExistingImage: any = null;
loadingExistingImages: boolean = false;
dataSource = new MatTableDataSource<any>();
branches: string[] = [];
selectedBranch: string = '';
loadingBranches: boolean = false;
gitData: any = null;
loadingGitData: boolean = false;
destinationBranch: string = '';
isDestinationBranchEditable: boolean = false;
repositoryNotFound: boolean = false;
newlyCreatedRepository: any = null;
get hasValidGitData(): boolean {
return this.gitData && this.gitData.repo && this.gitData.branch;
}
columns = [
{
columnDef: 'diskNumber',
@ -107,9 +123,19 @@ export class CreateClientImageComponent implements OnInit{
this.clientName = response.name;
this.selectedRepository = response.repository;
this.dataSource.data = response.partitions.filter((partition: any) => {
const validPartitions = response.partitions.filter((partition: any) => {
return partition.partitionNumber !== 0;
});
this.dataSource.data = validPartitions;
const firstValidPartition = validPartitions.find((partition: any) => {
return partition.operativeSystem;
});
if (firstValidPartition) {
this.selectedPartition = firstValidPartition;
}
}
},
(error) => {
@ -141,6 +167,23 @@ export class CreateClientImageComponent implements OnInit{
(response: any) => {
this.gitRepositories = response['hydra:member'];
this.loadingGitRepositories = false;
if (this.newlyCreatedRepository) {
const newRepo = this.gitRepositories.find(repo =>
repo.name === this.newlyCreatedRepository.name
);
if (newRepo) {
this.selectedGitRepository = newRepo;
this.onGitRepositorySelected(newRepo);
this.toastService.success(`Repositorio "${newRepo.name}" preseleccionado`);
}
this.newlyCreatedRepository = null;
}
this.checkRepositoryExists();
},
(error) => {
console.error('Error al cargar los repositorios git:', error);
@ -151,7 +194,7 @@ export class CreateClientImageComponent implements OnInit{
loadGitImageRepositories(gitRepository: any) {
this.loadingGitImageRepositories = true;
const url = `${this.baseUrl}/git-image-repositories?gitRepository.id=${gitRepository.id}&page=1&itemsPerPage=100`;
const url = `${this.baseUrl}/git-image-repositories?gitRepository.uuid=${gitRepository.uuid}&page=1&itemsPerPage=100`;
this.http.get(url).subscribe(
(response: any) => {
this.gitImageRepositories = response['hydra:member'];
@ -168,47 +211,97 @@ export class CreateClientImageComponent implements OnInit{
this.selectedGitRepository = gitRepository;
this.selectedExistingImage = null;
this.existingImages = [];
this.selectedBranch = '';
this.branches = [];
if (gitRepository) {
this.loadGitImageRepositories(gitRepository);
this.loadBranches();
} else {
this.gitImageRepositories = [];
}
}
onGitActionSelected(event: any) {
console.log('onGitActionSelected llamado con:', event);
this.gitAction = event.value;
this.selectedExistingImage = null;
this.gitImageName = '';
// Si se selecciona 'update' y ya hay un repositorio Git seleccionado, cargar los repositorios de imágenes
if (event.value === 'update' && this.selectedGitRepository) {
this.loadGitImageRepositories(this.selectedGitRepository);
loadBranches(): void {
if (!this.selectedGitRepository) {
return;
}
console.log('Antes del setTimeout');
// Hacer scroll hacia la sección de partición después de un delay más largo
setTimeout(() => {
console.log('Dentro del setTimeout, llamando a scrollToPartitionSection');
this.scrollToPartitionSection();
}, 300);
this.loadingBranches = true;
const url = `${this.baseUrl}/image-repositories/server/git/${this.selectedRepository.uuid}/branches`;
this.http.post<any>(url, { repositoryName: this.selectedGitRepository.name }).subscribe(
data => {
this.branches = data.branches || [];
this.loadingBranches = false;
if (this.branches.length > 0) {
this.selectedBranch = this.branches[0];
}
},
error => {
console.error('Error fetching branches', error);
this.toastService.error('Error al cargar las ramas del repositorio');
this.loadingBranches = false;
}
);
}
onBranchChange(): void {
// La rama ha sido seleccionada, no necesitamos hacer nada más
}
openCreateBranchModal(): void {
if (this.hasValidGitData) {
const dialogRef = this.dialog.open(CreateBranchModalComponent, {
width: '500px',
data: {
commit: this.gitData.branch,
repositoryName: this.gitData.repo,
repositoryUuid: this.selectedRepository.uuid
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.toastService.success('Rama creada correctamente');
this.destinationBranch = result.branchName || result;
this.loadBranches();
}
});
return;
}
if (!this.selectedGitRepository) {
this.toastService.error('Debe seleccionar un repositorio primero');
return;
}
const dialogRef = this.dialog.open(CreateBranchModalComponent, {
width: '500px',
data: {
commit: this.selectedBranch || 'master',
repositoryName: this.selectedGitRepository.name,
repositoryUuid: this.selectedRepository.uuid
}
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.toastService.success('Rama creada correctamente');
this.destinationBranch = result.branchName || result;
this.loadBranches();
}
});
}
onMonolithicActionSelected(event: any) {
console.log('onMonolithicActionSelected llamado con:', event);
this.monolithicAction = event.value;
this.selectedImage = null;
this.name = '';
// Si se selecciona 'update', cargar las imágenes existentes
if (event.value === 'update') {
this.loadImages();
}
console.log('Antes del setTimeout (monolithic)');
// Hacer scroll hacia la sección de partición después de un delay más largo
setTimeout(() => {
console.log('Dentro del setTimeout (monolithic), llamando a scrollToPartitionSection');
this.scrollToPartitionSection();
}, 300);
}
@ -217,8 +310,7 @@ export class CreateClientImageComponent implements OnInit{
if (!this.selectedExistingImage) return;
this.loadingExistingImages = true;
// Aquí deberías hacer el GET al endpoint externo
// Por ahora uso un endpoint de ejemplo, ajusta según tu API
const url = `${this.baseUrl}/images?gitImageRepository.id=${this.selectedExistingImage.id}&page=1&itemsPerPage=100`;
this.http.get(url).subscribe(
@ -238,14 +330,15 @@ export class CreateClientImageComponent implements OnInit{
this.selectedGitRepository = null;
this.selectedExistingImage = null;
this.gitImageName = '';
this.gitAction = 'create';
this.monolithicAction = 'create';
this.existingImages = [];
this.gitRepositories = [];
this.gitImageRepositories = [];
this.selectedBranch = '';
this.branches = [];
this.selectedImage = null;
this.name = '';
this.monolithicAction = 'create';
}
resetCanonicalName() {
@ -258,12 +351,6 @@ export class CreateClientImageComponent implements OnInit{
return;
}
if (this.imageType === 'git') {
if (!this.selectedGitRepository) {
this.toastService.error('Debes seleccionar un repositorio Git');
return;
}
}
if (this.imageType === 'monolithic') {
if (this.monolithicAction === 'create' && !this.name) {
@ -295,25 +382,32 @@ export class CreateClientImageComponent implements OnInit{
let payload: any;
if (this.imageType === 'git') {
if (this.gitAction === 'update') {
endpoint = `${this.baseUrl}/git-repositories/update-image`;
payload = {
client: `/clients/${this.clientId}`,
partition: this.selectedPartition['@id'],
gitRepository: this.selectedGitRepository.name,
queue: result
};
} else {
const gitRepoName = this.hasValidGitData ? this.gitData.repo : this.selectedGitRepository?.name;
const originBranch = this.hasValidGitData ? this.gitData.branch : this.selectedBranch;
if (this.branches.length === 0) {
endpoint = `${this.baseUrl}/images`;
payload = {
client: `/clients/${this.clientId}`,
partition: this.selectedPartition['@id'],
type: this.imageType,
gitRepository: this.selectedGitRepository.name,
name: this.selectedGitRepository.name,
gitRepository: gitRepoName,
name: gitRepoName,
originalBranch: originBranch,
destinationBranch: this.destinationBranch,
action: 'create',
queue: result
};
} else {
endpoint = `${this.baseUrl}/git-repositories/update-image`;
payload = {
client: `/clients/${this.clientId}`,
partition: this.selectedPartition['@id'],
gitRepository: gitRepoName,
originalBranch: originBranch,
destinationBranch: this.destinationBranch,
queue: result
};
}
} else {
endpoint = `${this.baseUrl}/images`;
@ -337,9 +431,9 @@ export class CreateClientImageComponent implements OnInit{
.subscribe({
next: (response) => {
let actionText = 'creación';
if (this.imageType === 'git' && this.gitAction === 'update') {
if (this.imageType === 'monolithic' && this.monolithicAction === 'update') {
actionText = 'actualización';
} else if (this.imageType === 'monolithic' && this.monolithicAction === 'update') {
} else if (this.imageType === 'git' && this.branches.length > 0) {
actionText = 'actualización';
}
this.toastService.success(`Petición de ${actionText} de imagen enviada`);
@ -370,14 +464,28 @@ export class CreateClientImageComponent implements OnInit{
dialogRef.afterClosed().subscribe(result => {
this.creatingRepository = false;
if (result) {
this.newlyCreatedRepository = result;
this.loadGitRepositories();
setTimeout(() => {
const newRepository = this.gitRepositories.find(repo => repo['@id'] === result['@id']);
if (newRepository) {
this.selectedGitRepository = newRepository;
this.onGitRepositorySelected(newRepository);
if (this.newlyCreatedRepository && !this.selectedGitRepository) {
const newRepo = this.gitRepositories.find(repo =>
repo.name === this.newlyCreatedRepository.name
);
if (newRepo) {
this.selectedGitRepository = newRepo;
this.onGitRepositorySelected(newRepo);
this.toastService.success(`Repositorio "${newRepo.name}" preseleccionado`);
}
this.newlyCreatedRepository = null;
}
}, 200);
}, 1000);
} else {
}
});
}
@ -394,8 +502,13 @@ export class CreateClientImageComponent implements OnInit{
this.selectedImage = null;
this.name = '';
this.monolithicAction = 'create';
if (this.selectedPartition) {
this.loadGitData(this.selectedPartition);
}
} else {
this.resetGitSelections();
this.gitData = null;
}
}
@ -425,5 +538,82 @@ export class CreateClientImageComponent implements OnInit{
set selectedPartition(value: any) {
this._selectedPartition = value;
if (value && this.imageType === 'git') {
this.loadGitData(value);
} else {
this.gitData = null;
}
}
loadGitData(partition: any): void {
this.loadingGitData = true;
this.gitData = null;
this.repositoryNotFound = false;
const payload = {
partition: partition['@id'],
client: `/clients/${this.clientId}`
};
this.http.post(`${this.baseUrl}/git-repositories/get-git-data`, payload).subscribe({
next: (response) => {
this.gitData = response;
if (this.gitData && this.gitData.branch) {
this.destinationBranch = this.gitData.branch;
}
this.loadingGitData = false;
this.checkRepositoryExists();
if (this.hasValidGitData) {
this.loadBranchesForGitData();
}
},
error: (error) => {
console.error('Error al cargar datos de Git:', error);
this.toastService.error('Error al cargar información de Git');
this.loadingGitData = false;
}
});
}
checkRepositoryExists(): void {
if (this.gitData && this.gitData.repo && this.gitRepositories.length > 0) {
const repoExists = this.gitRepositories.some((repo: any) =>
repo.name === this.gitData.repo
);
this.repositoryNotFound = !repoExists;
} else {
this.repositoryNotFound = false;
}
}
loadBranchesForGitData(): void {
if (!this.gitData || !this.gitData.repo) {
return;
}
this.loadingBranches = true;
const url = `${this.baseUrl}/image-repositories/server/git/${this.selectedRepository.uuid}/branches`;
this.http.post<any>(url, { repositoryName: this.gitData.repo }).subscribe(
data => {
this.branches = data.branches || [];
this.loadingBranches = false;
},
error => {
console.error('Error fetching branches for Git data', error);
this.loadingBranches = false;
}
);
}
toggleDestinationBranchEdit(): void {
this.isDestinationBranchEditable = !this.isDestinationBranchEditable;
if (!this.isDestinationBranchEditable) {
// Opcional: Aquí se pueden agregar validaciones adicionales
console.log('Rama destino guardada:', this.destinationBranch);
}
}
}