|
|
@@ -1,261 +1,481 @@
|
|
|
<div class="preview-excel-container">
|
|
|
+ <div
|
|
|
+ class="preview-header"
|
|
|
+ style="
|
|
|
+ padding: 16px;
|
|
|
+ border-bottom: 1px solid #e0e0e0;
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ background: white;
|
|
|
+ z-index: 100;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="header-top"
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ width: 50%;
|
|
|
+ "
|
|
|
+ ></div>
|
|
|
|
|
|
- <div class="preview-header" style="padding: 16px; border-bottom: 1px solid #e0e0e0; position: sticky; top: 0; background: white; z-index: 100;">
|
|
|
- <div class="header-top" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; width: 50%;">
|
|
|
-
|
|
|
- @if (hasUnsavedChanges) {
|
|
|
- <div class="changes-indicator"
|
|
|
- style="display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: #fff3cd; border-radius: 20px; font-size: 12px; color: #856404; border: 1px solid #ffeaa7;">
|
|
|
- <mat-icon style="font-size: 14px;">edit</mat-icon>
|
|
|
- <span>Cambios sin guardar</span>
|
|
|
- </div>
|
|
|
- }
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="header-controls" style="display: flex; gap: 16px; width: 100%; justify-content: end; align-items: center;">
|
|
|
- <div class="docu">
|
|
|
- <h2 mat-dialog-title style="margin: 0; font-size: 18px; display: flex; align-items: center; gap: 8px; color: #424242; margin-bottom: 13px;" >
|
|
|
- <mat-icon style="color: #19d241;">table_chart</mat-icon>
|
|
|
+ <div
|
|
|
+ class="header-controls"
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ gap: 16px;
|
|
|
+ width: 100%;
|
|
|
+ justify-content: end;
|
|
|
+ align-items: center;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div class="docu" style="margin-right: 100 !important">
|
|
|
+ <h2
|
|
|
+ mat-dialog-title
|
|
|
+ class="dialog-title"
|
|
|
+ style="
|
|
|
+ font-size: 18px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ color: #424242;
|
|
|
+ margin-bottom: 13px;
|
|
|
+ margin-right: 80px;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <mat-icon style="color: #17752b">table_chart</mat-icon>
|
|
|
{{ fileName }}
|
|
|
</h2>
|
|
|
</div>
|
|
|
|
|
|
- @if (sheetNames.length > 1) {
|
|
|
- <div class="sheet-selector">
|
|
|
- <mat-form-field appearance="outline" style="width: 200px;">
|
|
|
- <mat-label>Hoja</mat-label>
|
|
|
- <mat-select [(value)]="selectedSheet" (selectionChange)="onSheetChange($event.value)">
|
|
|
- @for (sheet of sheetNames; track $index) {
|
|
|
- <mat-option [value]="sheet">
|
|
|
- {{ sheet }}
|
|
|
- </mat-option>
|
|
|
- }
|
|
|
- </mat-select>
|
|
|
- </mat-form-field>
|
|
|
- </div>
|
|
|
- }
|
|
|
-
|
|
|
- <div class="edit-controls" style="display: flex; align-items: center; gap: 8px;">
|
|
|
- <button mat-icon-button
|
|
|
- (click)="toggleEditMode()"
|
|
|
- [color]="editMode ? 'warn' : 'primary'"
|
|
|
- [matTooltip]="editMode ? 'Salir del modo edición' : 'Activar modo edición'"
|
|
|
- style="border-radius: 10px; margin-bottom: 20px;"
|
|
|
- [ngClass]="editMode ? 'pink_primary_background white_font' : 'orange_primary_background white_font'">
|
|
|
- <mat-icon>{{ editMode ? 'visibility' : 'edit' }}</mat-icon>
|
|
|
+ <div class="sheet-selector" *ngIf="sheetNames.length > 1">
|
|
|
+ <mat-form-field appearance="outline" style="width: 200px">
|
|
|
+ <mat-label>Hoja</mat-label>
|
|
|
+ <mat-select
|
|
|
+ [(value)]="selectedSheet"
|
|
|
+ (selectionChange)="onSheetChange($event.value)"
|
|
|
+ >
|
|
|
+ <mat-option *ngFor="let sheet of sheetNames" [value]="sheet">
|
|
|
+ {{ sheet }}
|
|
|
+ </mat-option>
|
|
|
+ </mat-select>
|
|
|
+ </mat-form-field>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ class="edit-controls"
|
|
|
+ style="display: flex; align-items: center; gap: 8px; margin-right: 20px"
|
|
|
+ >
|
|
|
+ <button
|
|
|
+ mat-icon-button
|
|
|
+ (click)="toggleEditMode()"
|
|
|
+ [color]="editMode ? 'warn' : 'primary'"
|
|
|
+ [matTooltip]="
|
|
|
+ editMode ? 'Salir del modo edición' : 'Activar modo edición'
|
|
|
+ "
|
|
|
+ style="border-radius: 10px; margin-bottom: 20px"
|
|
|
+ [ngClass]="
|
|
|
+ editMode
|
|
|
+ ? 'pink_primary_background white_font'
|
|
|
+ : 'orange_primary_background white_font'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <mat-icon>{{ editMode ? "visibility" : "edit" }}</mat-icon>
|
|
|
</button>
|
|
|
-
|
|
|
- @if (editMode) {
|
|
|
- <ng-container>
|
|
|
- <button mat-icon-button
|
|
|
- (click)="addRow()"
|
|
|
- matTooltip="Agregar fila"
|
|
|
- color="primary"
|
|
|
- style="border-radius: 8px;">
|
|
|
- <mat-icon>table_rows</mat-icon>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button mat-icon-button
|
|
|
- (click)="addColumn()"
|
|
|
- matTooltip="Agregar columna"
|
|
|
- color="primary"
|
|
|
- style="border-radius: 8px;">
|
|
|
- <mat-icon>view_column</mat-icon>
|
|
|
- </button>
|
|
|
- </ng-container>
|
|
|
- }
|
|
|
-
|
|
|
- @if (hasUnsavedChanges) {
|
|
|
- <ng-container>
|
|
|
- <button mat-raised-button
|
|
|
- (click)="saveChanges()"
|
|
|
- color="primary"
|
|
|
- style="margin-left: 8px; border-radius: 8px;">
|
|
|
- <mat-icon>save</mat-icon>
|
|
|
- Guardar
|
|
|
- </button>
|
|
|
-
|
|
|
- <button mat-stroked-button
|
|
|
- (click)="discardChanges()"
|
|
|
- color="warn"
|
|
|
- style="border-radius: 8px;">
|
|
|
- <mat-icon>undo</mat-icon>
|
|
|
- Descartar
|
|
|
- </button>
|
|
|
|
|
|
- </ng-container>
|
|
|
- }
|
|
|
+ <ng-container *ngIf="editMode" style="margin-bottom: 20px !important">
|
|
|
+ <button
|
|
|
+ mat-icon-button
|
|
|
+ (click)="addRow()"
|
|
|
+ matTooltip="Agregar fila"
|
|
|
+ style="border-radius: 8px"
|
|
|
+ >
|
|
|
+ <object data="assets/img/agregarfila.svg" width="40"></object>
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <!-- <button mat-icon-button
|
|
|
+ disabled
|
|
|
+ (click)="addColumn()"
|
|
|
+ matTooltip="Agregar columna"
|
|
|
+ color="primary"
|
|
|
+ style="border-radius: 8px;">
|
|
|
+ <mat-icon>view_column</mat-icon>
|
|
|
+ </button> -->
|
|
|
+ </ng-container>
|
|
|
+
|
|
|
+ <ng-container *ngIf="hasUnsavedChanges">
|
|
|
+ <button
|
|
|
+ mat-button
|
|
|
+ class="raised-button-background"
|
|
|
+ (click)="saveChanges()"
|
|
|
+ color="primary"
|
|
|
+ style="margin-left: 8px; border-radius: 8px"
|
|
|
+ >
|
|
|
+ <mat-icon>save</mat-icon>
|
|
|
+ Guardar Cambios
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <button
|
|
|
+ mat-button
|
|
|
+ (click)="discardChanges()"
|
|
|
+ color="warn"
|
|
|
+ style="border-radius: 8px"
|
|
|
+ >
|
|
|
+ <mat-icon>undo</mat-icon>
|
|
|
+ Descartar
|
|
|
+ </button>
|
|
|
+ </ng-container>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="table-container" style="overflow: auto; background: #fafafa; position: relative;">
|
|
|
- @if (currentSheetData.length > 0) {
|
|
|
- <table class="excel-table"
|
|
|
- style="width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; background: white; margin: 16px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
|
|
|
-
|
|
|
- <thead>
|
|
|
- <tr style="background: linear-gradient(to bottom, #f8f9fa, #e9ecef); border-radius: 8px 8px 0 0;">
|
|
|
- <th class="row-header"
|
|
|
- style="width: 60px; padding: 12px 8px; border-right: 1px solid #dee2e6; text-align: center; font-weight: 600; color: #495057; font-size: 12px; border-radius: 8px 0 0 0;">
|
|
|
- #
|
|
|
- </th>
|
|
|
-
|
|
|
- @for (header of getTableHeaders(); track $index; let colIndex = $index, isLast = $last) {
|
|
|
- <th
|
|
|
- class="column-header"
|
|
|
- [style.border-radius]="isLast ? '0 8px 0 0' : '0'"
|
|
|
- style="min-width: 140px; padding: 12px 16px; border-right: 1px solid #dee2e6; text-align: left; font-weight: 600; color: #495057; font-size: 12px; position: relative;">
|
|
|
- <div style="display: flex; align-items: center; justify-content: space-between;">
|
|
|
- <span>{{ header }}</span>
|
|
|
- @if (editMode && getTableHeaders().length > 1) {
|
|
|
- <button
|
|
|
- mat-icon-button
|
|
|
- (click)="deleteColumn(colIndex)"
|
|
|
- style="width: 24px; height: 24px; color: #dc3545; opacity: 0.7;"
|
|
|
- matTooltip="Eliminar columna">
|
|
|
- <mat-icon style="font-size: 16px;">close</mat-icon>
|
|
|
- </button>
|
|
|
- }
|
|
|
- </div>
|
|
|
- </th>
|
|
|
- }
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
-
|
|
|
- <tbody>
|
|
|
- @for (row of currentSheetData; track $index; let rowIndex = $index, isLast = $last) {
|
|
|
- <tr
|
|
|
- [style.background]="rowIndex % 2 === 0 ? '#ffffff' : '#f8f9fa'"
|
|
|
- [style.border-radius]="isLast ? '0 0 8px 8px' : '0'"
|
|
|
- style="transition: all 0.2s ease; border-bottom: 1px solid #e9ecef;">
|
|
|
-
|
|
|
- <td class="row-number"
|
|
|
- [style.border-radius]="isLast ? '0 0 0 8px' : '0'"
|
|
|
- style="width: 60px; padding: 12px 8px; border-right: 1px solid #dee2e6; text-align: center; font-weight: 500; color: #6c757d; font-size: 12px; background: #f8f9fa !important;">
|
|
|
- <div style="display: flex; align-items: center; justify-content: center; gap: 4px;">
|
|
|
- <span>{{ getRowNumber(rowIndex) }}</span>
|
|
|
- @if (editMode && currentSheetData.length > 1) {
|
|
|
- <button
|
|
|
- mat-icon-button
|
|
|
- (click)="deleteRow(rowIndex)"
|
|
|
- style="width: 20px; height: 20px; color: #dc3545;"
|
|
|
- matTooltip="Eliminar fila">
|
|
|
- <mat-icon style="font-size: 14px;">close</mat-icon>
|
|
|
- </button>
|
|
|
- }
|
|
|
- </div>
|
|
|
- </td>
|
|
|
-
|
|
|
- @for (cell of row; track $index; let colIndex = $index, isLastCol = $last) {
|
|
|
- <td
|
|
|
- class="data-cell"
|
|
|
- [style.border-radius]="isLast && isLastCol ? '0 0 8px 0' : '0'"
|
|
|
- style="min-width: 140px; max-width: 250px; padding: 12px 16px; border-right: 1px solid #dee2e6; vertical-align: top; position: relative;">
|
|
|
-
|
|
|
- @if (!editMode) {
|
|
|
- <div
|
|
|
- class="cell-content"
|
|
|
- style="min-height: 20px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Roboto', sans-serif; color: #424242; line-height: 1.4;">
|
|
|
- {{ getCellValue(row, colIndex) }}
|
|
|
- </div>
|
|
|
- }
|
|
|
+ <div
|
|
|
+ class="table-container"
|
|
|
+ style="overflow: auto; background: #fafafa; position: relative"
|
|
|
+ >
|
|
|
+ <table
|
|
|
+ class="excel-table"
|
|
|
+ *ngIf="currentSheetData.length > 0"
|
|
|
+ style="
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: separate;
|
|
|
+ border-spacing: 0;
|
|
|
+ font-size: 13px;
|
|
|
+ background: white;
|
|
|
+ margin: 16px;
|
|
|
+ border-radius: 10px;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <thead>
|
|
|
+ <tr
|
|
|
+ style="
|
|
|
+ background: linear-gradient(to bottom, #f8f9fa, #e9ecef);
|
|
|
+ border-radius: 8px 8px 0 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <th
|
|
|
+ class="row-header"
|
|
|
+ style="
|
|
|
+ width: 60px;
|
|
|
+ padding: 12px 8px;
|
|
|
+ border-right: 1px solid #dee2e6;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #495057;
|
|
|
+ font-size: 12px;
|
|
|
+ border-radius: 8px 0 0 0;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ #
|
|
|
+ </th>
|
|
|
+
|
|
|
+ <th
|
|
|
+ *ngFor="
|
|
|
+ let header of getTableHeaders();
|
|
|
+ let colIndex = index;
|
|
|
+ let isLast = last;
|
|
|
+ trackBy: trackByIndex
|
|
|
+ "
|
|
|
+ class="column-header"
|
|
|
+ [class.id-column-header]="isIdColumn(colIndex, selectedSheet)"
|
|
|
+ [style.border-radius]="isLast ? '0 8px 0 0' : '0'"
|
|
|
+ [style.background]="
|
|
|
+ isIdColumn(colIndex, selectedSheet)
|
|
|
+ ? 'linear-gradient(to bottom, #e3f2fd, #bbdefb)'
|
|
|
+ : 'linear-gradient(to bottom, #f8f9fa, #e9ecef)'
|
|
|
+ "
|
|
|
+ [matTooltip]="
|
|
|
+ isIdColumn(colIndex, selectedSheet)
|
|
|
+ ? 'Columna de ID - Generada automáticamente'
|
|
|
+ : ''
|
|
|
+ "
|
|
|
+ style="
|
|
|
+ min-width: 140px;
|
|
|
+ padding: 12px 16px;
|
|
|
+ border-right: 1px solid #dee2e6;
|
|
|
+ text-align: left;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #495057;
|
|
|
+ font-size: 12px;
|
|
|
+ position: relative;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <span style="display: flex; align-items: center; gap: 4px">
|
|
|
+ {{ header }}
|
|
|
+ </span>
|
|
|
+ <button
|
|
|
+ *ngIf="
|
|
|
+ editMode &&
|
|
|
+ getTableHeaders().length > 1 &&
|
|
|
+ !isIdColumn(colIndex, selectedSheet)
|
|
|
+ "
|
|
|
+ mat-icon-button
|
|
|
+ (click)="deleteColumn(colIndex)"
|
|
|
+ style="width: 24px; height: 24px; color: #dc3545; opacity: 0.7"
|
|
|
+ matTooltip="Eliminar columna"
|
|
|
+ >
|
|
|
+ <mat-icon style="font-size: 16px">close</mat-icon>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+
|
|
|
+ <tbody>
|
|
|
+ <tr
|
|
|
+ *ngFor="
|
|
|
+ let row of currentSheetData;
|
|
|
+ let rowIndex = index;
|
|
|
+ let isLast = last;
|
|
|
+ trackBy: trackByRowData
|
|
|
+ "
|
|
|
+ [style.background]="rowIndex % 2 === 0 ? '#ffffff' : '#f8f9fa'"
|
|
|
+ [style.border-radius]="isLast ? '0 0 8px 8px' : '0'"
|
|
|
+ style="transition: all 0.2s ease; border-bottom: 1px solid #e9ecef"
|
|
|
+ >
|
|
|
+ <td
|
|
|
+ class="row-number"
|
|
|
+ [style.border-radius]="isLast ? '0 0 0 8px' : '0'"
|
|
|
+ style="
|
|
|
+ width: 60px;
|
|
|
+ padding: 12px 8px;
|
|
|
+ border-right: 1px solid #dee2e6;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #6c757d;
|
|
|
+ font-size: 12px;
|
|
|
+ background: #f8f9fa !important;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 4px;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <span>{{ getRowNumber(rowIndex) }}</span>
|
|
|
+ <button
|
|
|
+ *ngIf="editMode && currentSheetData.length > 1"
|
|
|
+ mat-icon-button
|
|
|
+ (click)="deleteRow(rowIndex)"
|
|
|
+ style="width: 20px; height: 20px; color: #dc3545"
|
|
|
+ matTooltip="Eliminar fila"
|
|
|
+ >
|
|
|
+ <mat-icon style="font-size: 14px">close</mat-icon>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+
|
|
|
+ <td
|
|
|
+ *ngFor="
|
|
|
+ let cell of row;
|
|
|
+ let colIndex = index;
|
|
|
+ let isLastCol = last;
|
|
|
+ trackBy: trackByIndex
|
|
|
+ "
|
|
|
+ class="data-cell"
|
|
|
+ [style.border-radius]="isLast && isLastCol ? '0 0 8px 0' : '0'"
|
|
|
+ style="
|
|
|
+ min-width: 140px;
|
|
|
+ max-width: 250px;
|
|
|
+ padding: 12px 16px;
|
|
|
+ border-right: 1px solid #dee2e6;
|
|
|
+ vertical-align: top;
|
|
|
+ position: relative;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ *ngIf="!isCellBeingEdited(rowIndex, colIndex)"
|
|
|
+ class="cell-content"
|
|
|
+ (click)="startEdit(rowIndex, colIndex)"
|
|
|
+ style="
|
|
|
+ min-height: 20px;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ word-wrap: break-word;
|
|
|
+ font-family: 'Roboto', sans-serif;
|
|
|
+ color: #424242;
|
|
|
+ line-height: 1.4;
|
|
|
+ cursor: pointer;
|
|
|
+ "
|
|
|
+ [class.disabled-cell]="isCellDisabled(rowIndex, colIndex)"
|
|
|
+ >
|
|
|
+ {{ getDisplayCellValue(row, colIndex) }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <input
|
|
|
+ *ngIf="isCellBeingEdited(rowIndex, colIndex)"
|
|
|
+ s
|
|
|
+ type="text"
|
|
|
+ class="cell-input"
|
|
|
+ (input)="onCellInputChange()"
|
|
|
+ [value]="getDisplayCellValue(row, colIndex)"
|
|
|
+ [attr.title]="
|
|
|
+ isCellDisabled(rowIndex, colIndex)
|
|
|
+ ? 'Campo ID generado automáticamente'
|
|
|
+ : ''
|
|
|
+ "
|
|
|
+ style="
|
|
|
+ width: 100%;
|
|
|
+ border: 1px solid #aabaca;
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 8px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-family: 'Roboto', sans-serif;
|
|
|
+ background: white;
|
|
|
+ outline: none;
|
|
|
+ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
|
|
+ "
|
|
|
+ (blur)="saveCellValue(rowIndex, colIndex, $event)"
|
|
|
+ (keyup.enter)="saveCellValue(rowIndex, colIndex, $event)"
|
|
|
+ autofocus
|
|
|
+ />
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
|
|
|
- @if (editMode) {
|
|
|
- <input
|
|
|
- type="text"
|
|
|
- class="cell-input"
|
|
|
- [value]="getCellValue(row, colIndex)"
|
|
|
- (input)="onCellInput(rowIndex, colIndex, $event)"
|
|
|
- (blur)="onCellBlur(rowIndex, colIndex, $event)"
|
|
|
- [attr.data-row]="rowIndex"
|
|
|
- [attr.data-col]="colIndex"
|
|
|
- style="width: 100%; border: 1px solid #ced4da; border-radius: 4px; padding: 8px; font-size: 13px; font-family: 'Roboto', sans-serif; background: white; transition: border-color 0.2s ease; outline: none;"
|
|
|
- onfocus="this.style.borderColor='#007bff'; this.style.boxShadow='0 0 0 2px rgba(0, 123, 255, 0.25)'"
|
|
|
- onblur="this.style.borderColor='#ced4da'; this.style.boxShadow='none'">
|
|
|
- }
|
|
|
- </td>
|
|
|
- }
|
|
|
- </tr>
|
|
|
- }
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
- }
|
|
|
-
|
|
|
@if (currentSheetData.length === 0) {
|
|
|
- <div
|
|
|
- class="no-data-message"
|
|
|
- style="padding: 60px 20px; text-align: center; color: #6c757d; background: white; margin: 16px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
|
|
|
- <mat-icon style="font-size: 64px; color: #dee2e6; margin-bottom: 16px;">table_chart</mat-icon>
|
|
|
- <p style="margin: 0 0 16px 0; font-size: 16px;">No hay datos disponibles en la hoja "{{ selectedSheet }}"</p>
|
|
|
- @if (editMode) {
|
|
|
- <button
|
|
|
- mat-raised-button
|
|
|
- color="primary"
|
|
|
- (click)="addRow()"
|
|
|
- style="border-radius: 8px;">
|
|
|
- <mat-icon>add</mat-icon>
|
|
|
- Agregar primera fila
|
|
|
- </button>
|
|
|
- }
|
|
|
- </div>
|
|
|
+ <div
|
|
|
+ class="no-data-message"
|
|
|
+ style="
|
|
|
+ padding: 60px 20px;
|
|
|
+ text-align: center;
|
|
|
+ color: #6c757d;
|
|
|
+ background: white;
|
|
|
+ margin: 16px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <mat-icon style="font-size: 64px; color: #dee2e6; margin-bottom: 16px"
|
|
|
+ >table_chart</mat-icon
|
|
|
+ >
|
|
|
+ <p style="margin: 0 0 16px 0; font-size: 16px">
|
|
|
+ No hay datos disponibles en la hoja "{{ selectedSheet }}"
|
|
|
+ </p>
|
|
|
+ @if (editMode) {
|
|
|
+ <button
|
|
|
+ mat-raised-button
|
|
|
+ color="primary"
|
|
|
+ (click)="addRow()"
|
|
|
+ style="border-radius: 8px"
|
|
|
+ >
|
|
|
+ <mat-icon>add</mat-icon>
|
|
|
+ Agregar primera fila
|
|
|
+ </button>
|
|
|
+ }
|
|
|
+ </div>
|
|
|
}
|
|
|
</div>
|
|
|
|
|
|
- <div class="table-summary">
|
|
|
- <div class="summary-info" style="display: flex; gap: 24px;">
|
|
|
- <div style="display: flex; align-items: center; gap: 6px;">
|
|
|
- <mat-hint style="color: #1976d2;">INFORMACIÓN:</mat-hint>
|
|
|
- <mat-icon style="font-size: 16px;">layers</mat-icon>
|
|
|
- <span>{{ sheetNames.length }} {{ sheetNames.length === 1 ? 'hoja' : 'hojas' }}</span>
|
|
|
+ <div
|
|
|
+ class="table-summary"
|
|
|
+ style="
|
|
|
+ padding: 16px;
|
|
|
+ border-top: 1px solid #e0e0e0;
|
|
|
+ background: #f8f9fa;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div class="summary-info" style="display: flex; gap: 24px">
|
|
|
+ <div style="display: flex; align-items: center; gap: 6px">
|
|
|
+ <mat-hint style="color: #1976d2">INFORMACIÓN:</mat-hint>
|
|
|
+ <mat-icon style="font-size: 16px">layers</mat-icon>
|
|
|
+ <span
|
|
|
+ >{{ sheetNames.length }}
|
|
|
+ {{ sheetNames.length === 1 ? "hoja" : "hojas" }}</span
|
|
|
+ >
|
|
|
</div>
|
|
|
- <div style="display: flex; align-items: center; gap: 6px;">
|
|
|
- <mat-icon style="font-size: 16px;">table_rows</mat-icon>
|
|
|
+ <div style="display: flex; align-items: center; gap: 6px">
|
|
|
+ <mat-icon style="font-size: 16px">table_rows</mat-icon>
|
|
|
<span>{{ currentSheetData.length }} filas</span>
|
|
|
</div>
|
|
|
- <div style="display: flex; align-items: center; gap: 6px;">
|
|
|
- <mat-icon style="font-size: 16px;">view_column</mat-icon>
|
|
|
+ <div style="display: flex; align-items: center; gap: 6px">
|
|
|
+ <mat-icon style="font-size: 16px">view_column</mat-icon>
|
|
|
<span>{{ getTableHeaders().length }} columnas</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
+
|
|
|
<div class="summary-actions">
|
|
|
@if (editMode) {
|
|
|
- <div style="display: flex; align-items: center; gap: 6px; color: #28a745;">
|
|
|
- <mat-icon style="font-size: 16px;">edit</mat-icon>
|
|
|
- <span>Edición habilitada</span>
|
|
|
- </div>
|
|
|
- }
|
|
|
- @if (!editMode) {
|
|
|
- <div style="display: flex; align-items: center; gap: 6px; color: #6c757d;">
|
|
|
- <mat-icon style="font-size: 16px;">visibility</mat-icon>
|
|
|
- <span>Solo lectura</span>
|
|
|
- </div>
|
|
|
+ <div style="display: flex; align-items: center; gap: 6px; color: #28a745">
|
|
|
+ <mat-icon style="font-size: 16px">edit</mat-icon>
|
|
|
+ <span>Edición habilitada</span>
|
|
|
+ </div>
|
|
|
+ } @if (!editMode) {
|
|
|
+ <div style="display: flex; align-items: center; gap: 6px; color: #6c757d">
|
|
|
+ <mat-icon style="font-size: 16px">visibility</mat-icon>
|
|
|
+ <span>Solo lectura</span>
|
|
|
+ </div>
|
|
|
}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <mat-dialog-actions align="end"
|
|
|
- class="dialog-actions"
|
|
|
- style="padding: 16px; border-top: 1px solid #e0e0e0; background: white; gap: 12px;">
|
|
|
-
|
|
|
- <div class="status-info" style="margin-right: auto; display: flex; align-items: center; gap: 8px; font-size: 13px; color: #6c757d;">
|
|
|
- <mat-icon style="font-size: 16px; color: #1976d2;">info</mat-icon>
|
|
|
- <span>{{ selectedSheet }} • {{ editMode ? 'Modo edición' : 'Solo lectura' }}</span>
|
|
|
+ <mat-dialog-actions
|
|
|
+ align="end"
|
|
|
+ class="dialog-actions"
|
|
|
+ style="
|
|
|
+ padding: 16px;
|
|
|
+ border-top: 1px solid #e0e0e0;
|
|
|
+ background: white;
|
|
|
+ gap: 12px;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="status-info"
|
|
|
+ style="
|
|
|
+ margin-right: auto;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ font-size: 13px;
|
|
|
+ color: #6c757d;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <mat-icon style="font-size: 16px; color: #1976d2">info</mat-icon>
|
|
|
+ <span
|
|
|
+ >{{ selectedSheet }} •
|
|
|
+ {{ editMode ? "Modo edición" : "Solo lectura" }}</span
|
|
|
+ >
|
|
|
+ <span *ngIf="hasUnsavedChanges" style="color: #ff9800; margin-left: 8px"
|
|
|
+ >• Cambios pendientes</span
|
|
|
+ >
|
|
|
</div>
|
|
|
-
|
|
|
- <div class="action-buttons" style="display: flex; gap: 12px;">
|
|
|
- <button mat-button
|
|
|
- (click)="closeDialog()">
|
|
|
- <mat-icon>close</mat-icon>
|
|
|
+
|
|
|
+ <div class="action-buttons" style="display: flex; gap: 12px">
|
|
|
+ <button mat-button (click)="closeDialog()">
|
|
|
+ <mat-icon style="margin-top: 5px">close</mat-icon>
|
|
|
Cancelar
|
|
|
</button>
|
|
|
-
|
|
|
- <button mat-stroked-button
|
|
|
- (click)="ValidateExcel()"
|
|
|
- class="white_font blue_send_background">
|
|
|
- <mat-icon>check</mat-icon>
|
|
|
- Validar documento
|
|
|
+
|
|
|
+ <button
|
|
|
+ mat-button
|
|
|
+ class="raised-button-background"
|
|
|
+ color="primary"
|
|
|
+ (click)="ValidateExcel()"
|
|
|
+ [disabled]="isLoading"
|
|
|
+ >
|
|
|
+ <mat-icon *ngIf="!isLoading">check</mat-icon>
|
|
|
+ <mat-spinner
|
|
|
+ *ngIf="isLoading"
|
|
|
+ diameter="20"
|
|
|
+ style="margin-right: 8px"
|
|
|
+ ></mat-spinner>
|
|
|
+ {{ isLoading ? "Procesando..." : "Procesar equipamientos" }}
|
|
|
</button>
|
|
|
</div>
|
|
|
</mat-dialog-actions>
|