Added interceptor 401 and refactor commands
parent
9226dd50d6
commit
011094b232
|
@ -2,7 +2,7 @@
|
|||
font-size: 24px;
|
||||
}
|
||||
|
||||
.images-button-row {
|
||||
.calendar-button-row {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 16px;
|
||||
|
@ -16,31 +16,11 @@
|
|||
padding: 16px;
|
||||
}
|
||||
|
||||
.imagesLists-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card.unidad-card {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid rgba(122, 122, 122, 0.555);
|
||||
}
|
||||
|
||||
.image-container h4 {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.image-name{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
margin-top: 50px;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar calendarios</h2>
|
||||
<div class="images-button-row">
|
||||
<div class="calendar-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addImage()">Añadir calendario</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,7 +26,6 @@
|
|||
<ng-container *ngIf="column.columnDef !== 'isDefault' && column.columnDef !== 'installed' && column.columnDef !== 'downloadUrl'">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -1,49 +1,33 @@
|
|||
.commands-list {
|
||||
margin-bottom: 20px;
|
||||
.title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.command-item {
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background-color: #f9f9f9;
|
||||
.calendar-button-row {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.command-item:hover {
|
||||
background-color: #e9e9e9;
|
||||
.divider {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.command-details {
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f4f4f4;
|
||||
border-radius: 4px;
|
||||
.lists-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.script-display {
|
||||
margin-top: 20px;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
.imagesLists-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 0;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
.card.unidad-card {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mat-elevation-z8{
|
||||
margin-top: 20px;
|
||||
}
|
||||
tr:hover {
|
||||
background-color: rgba(219, 219, 219, 0.219);
|
||||
}
|
||||
|
||||
.detailBtn{
|
||||
cursor: pointer;
|
||||
table {
|
||||
width: 100%;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
|
@ -65,6 +49,30 @@ tr:hover {
|
|||
padding: 5px;
|
||||
}
|
||||
|
||||
.command-button-row{
|
||||
margin-bottom: 10px;
|
||||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.mat-elevation-z8 {
|
||||
box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.paginator-container {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.mat-chip-readonly-true {
|
||||
background-color: #4CAF50 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.mat-chip-readonly-false {
|
||||
background-color: #F44336 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,46 +14,28 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<table mat-table [dataSource]="commands" class="mat-elevation-z8">
|
||||
<!-- Nombre columna -->
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> Nombre </th>
|
||||
<td mat-cell *matCellDef="let command"> {{ command.name }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Creado por columna -->
|
||||
<ng-container matColumnDef="createdBy">
|
||||
<th mat-header-cell *matHeaderCellDef> Creado por </th>
|
||||
<td mat-cell *matCellDef="let command"> {{ command.createdBy }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Fecha de creación columna -->
|
||||
<ng-container matColumnDef="createdAt">
|
||||
<th mat-header-cell *matHeaderCellDef> Fecha de creación </th>
|
||||
<td mat-cell *matCellDef="let command"> {{ command.createdAt | date:'short' }} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Columna para el menú de acciones -->
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> Acciones </th>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let command" >
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
<ng-container *ngIf="column.columnDef !== 'readOnly'">
|
||||
{{ column.cell(command) }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'readOnly'" >
|
||||
<mat-chip *ngIf="command.readOnly" class="mat-chip-readonly-true"><mat-icon style="color:white;">check</mat-icon></mat-chip>
|
||||
<mat-chip *ngIf="!command.readOnly" class="mat-chip-readonly-false"> <mat-icon style="color:white;">close</mat-icon></mat-chip>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<button mat-icon-button color="info" (click)="viewDetails($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editCommand($event, client)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteCommand($event, client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="viewDetails(command)">
|
||||
<mat-icon>info</mat-icon>
|
||||
<span>Detalles</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="editCommand(command)">
|
||||
<mat-icon>edit</mat-icon>
|
||||
<span>Editar</span>
|
||||
</button>
|
||||
<button mat-menu-item (click)="deleteCommand(command)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
<span>Eliminar</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import { ToastrService } from 'ngx-toastr';
|
|||
import { CommandDetailComponent } from './detail-command/command-detail.component';
|
||||
import { CreateCommandComponent } from './create-command/create-command.component';
|
||||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
import {DatePipe} from "@angular/common";
|
||||
|
||||
@Component({
|
||||
selector: 'app-commands',
|
||||
|
@ -13,13 +15,36 @@ import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/
|
|||
})
|
||||
export class CommandsComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
commands: any[] = [];
|
||||
dataSource = new MatTableDataSource<any>();
|
||||
filters: { [key: string]: string | boolean } = {};
|
||||
length: number = 0;
|
||||
itemsPerPage: number = 20;
|
||||
page: number = 1;
|
||||
page: number = 0;
|
||||
pageSizeOptions: number[] = [10, 20, 40, 100];
|
||||
displayedColumns: string[] = ['name', 'createdBy', 'createdAt', 'actions'];
|
||||
datePipe: DatePipe = new DatePipe('es-ES');
|
||||
columns = [
|
||||
{
|
||||
columnDef: 'id',
|
||||
header: 'ID',
|
||||
cell: (command: any) => `${command.id}`,
|
||||
},
|
||||
{
|
||||
columnDef: 'name',
|
||||
header: 'Nombre',
|
||||
cell: (command: any) => `${command.name}`
|
||||
},
|
||||
{
|
||||
columnDef: 'readOnly',
|
||||
header: 'Solo Lectura',
|
||||
cell: (command: any) => `${command.readOnly}`
|
||||
},
|
||||
{
|
||||
columnDef: 'createdAt',
|
||||
header: 'Fecha de creación',
|
||||
cell: (command: any) => `${this.datePipe.transform(command.createdAt, 'dd/MM/yyyy hh:mm:ss')}`,
|
||||
}
|
||||
];
|
||||
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
|
||||
private apiUrl = `${this.baseUrl}/commands`;
|
||||
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {}
|
||||
|
@ -29,9 +54,9 @@ export class CommandsComponent implements OnInit {
|
|||
}
|
||||
|
||||
search(): void {
|
||||
this.http.get<any>(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
|
||||
this.http.get<any>(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
|
||||
(data) => {
|
||||
this.commands = data['hydra:member'];
|
||||
this.dataSource.data = data['hydra:member'];
|
||||
this.length = data['hydra:totalItems'];
|
||||
},
|
||||
(error) => {
|
||||
|
@ -40,7 +65,8 @@ export class CommandsComponent implements OnInit {
|
|||
);
|
||||
}
|
||||
|
||||
viewDetails(command: any): void {
|
||||
viewDetails(event: MouseEvent, command: any): void {
|
||||
event.stopPropagation();
|
||||
this.dialog.open(CommandDetailComponent, {
|
||||
width: '800px',
|
||||
data: command,
|
||||
|
@ -53,14 +79,16 @@ export class CommandsComponent implements OnInit {
|
|||
}).afterClosed().subscribe(() => this.search());
|
||||
}
|
||||
|
||||
editCommand(command: any): void {
|
||||
editCommand(event: MouseEvent, command: any): void {
|
||||
event.stopPropagation();
|
||||
this.dialog.open(CreateCommandComponent, {
|
||||
width: '600px',
|
||||
data: { command },
|
||||
data: command['@id']
|
||||
}).afterClosed().subscribe(() => this.search());
|
||||
}
|
||||
|
||||
deleteCommand(command: any): void {
|
||||
deleteCommand(event: MouseEvent,command: any): void {
|
||||
event.stopPropagation();
|
||||
this.dialog.open(DeleteModalComponent, {
|
||||
width: '300px',
|
||||
data: { name: command.name },
|
||||
|
@ -80,8 +108,9 @@ export class CommandsComponent implements OnInit {
|
|||
}
|
||||
|
||||
onPageChange(event: any): void {
|
||||
this.page = event.pageIndex === 0 ? 1 : event.pageIndex;
|
||||
this.page = event.pageIndex;
|
||||
this.itemsPerPage = event.pageSize;
|
||||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +1,60 @@
|
|||
.dialog-title {
|
||||
font-size: 1.5em;
|
||||
color: #343a40;
|
||||
margin: 0;
|
||||
border-bottom: 2px solid #007bff;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.command-form {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
.full-width {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-container {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 26px;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.additional-form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.checkbox-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20px;
|
||||
margin: 15px 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
.time-fields {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
margin-right: 10px;
|
||||
color: #dc3545;
|
||||
.time-field {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
.list-item-content {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.submit-button:hover {
|
||||
background-color: #0056b3;
|
||||
.text-content {
|
||||
flex-grow: 1;
|
||||
margin-right: 16px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.icon-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.right-icon {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<h2 mat-dialog-title class="dialog-title">{{ isEditMode ? 'Editar Comando' : 'Añadir Comando' }}</h2>
|
||||
|
||||
<h2 mat-dialog-title>{{ commandId ? 'Editar' : 'Crear' }} Comando</h2>
|
||||
<mat-dialog-content class="form-container">
|
||||
<form [formGroup]="createCommandForm" (ngSubmit)="onSubmit()" class="command-form">
|
||||
<mat-form-field appearance="fill" class="form-field">
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Nombre</mat-label>
|
||||
<input matInput formControlName="name" placeholder="Nombre del comando" required>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="form-field">
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Script</mat-label>
|
||||
<textarea matInput formControlName="script" placeholder="Script del comando" required></textarea>
|
||||
<textarea matInput formControlName="script" placeholder="Script del comando"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="checkbox-group">
|
||||
|
@ -16,13 +16,15 @@
|
|||
<mat-checkbox formControlName="enabled">Habilitado</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="fill" class="form-field">
|
||||
<mat-form-field appearance="fill" class="full-width">
|
||||
<mat-label>Comentarios</mat-label>
|
||||
<textarea matInput formControlName="comments" placeholder="Comentarios"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div mat-dialog-actions class="action-buttons">
|
||||
<button mat-button (click)="onCancel($event)" class="cancel-button">Cancelar</button>
|
||||
<button mat-flat-button color="primary" type="submit" class="submit-button">{{ isEditMode ? 'Guardar' : 'Añadir' }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button (click)="onCancel($event)">Cancelar</button>
|
||||
<button mat-button (click)="onSubmit()" cdkFocusInitial> Guardar </button>
|
||||
</mat-dialog-actions>
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import {DataService} from "../data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-command',
|
||||
|
@ -11,27 +12,49 @@ import { ToastrService } from 'ngx-toastr';
|
|||
})
|
||||
export class CreateCommandComponent {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
createCommandForm!: FormGroup;
|
||||
isEditMode: boolean;
|
||||
createCommandForm: FormGroup<any>;
|
||||
private apiUrl = `${this.baseUrl}/commands`;
|
||||
commandId: string | null = null;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private http: HttpClient,
|
||||
public dialogRef: MatDialogRef<CreateCommandComponent>,
|
||||
private toastService: ToastrService,
|
||||
private dataService: DataService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) {
|
||||
this.isEditMode = data && data.command;
|
||||
this.createCommandForm = this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
script: [''],
|
||||
readOnly: [false],
|
||||
enabled: [true],
|
||||
comments: [''],
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.data) {
|
||||
this.load()
|
||||
}
|
||||
}
|
||||
|
||||
load(): void {
|
||||
this.dataService.getCommand(this.data).subscribe({
|
||||
next: (response) => {
|
||||
console.log(response);
|
||||
this.createCommandForm = this.fb.group({
|
||||
name: [this.isEditMode ? this.data.command.name : '', Validators.required],
|
||||
script: [this.isEditMode ? this.data.command.script : '', Validators.required],
|
||||
readOnly: [this.isEditMode ? this.data.command.readOnly : false],
|
||||
enabled: [this.isEditMode ? this.data.command.enabled : true],
|
||||
comments: [this.isEditMode ? this.data.command.comments : '']
|
||||
name: [response.name, Validators.required],
|
||||
notes: [response.notes],
|
||||
script: [response.script],
|
||||
readOnly: [response.readOnly],
|
||||
enabled: [response.enabled],
|
||||
});
|
||||
this.commandId = response['@id'];
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error fetching remote calendar:', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,24 +65,35 @@ export class CreateCommandComponent {
|
|||
|
||||
onSubmit(): void {
|
||||
if (this.createCommandForm.valid) {
|
||||
const commandData = this.createCommandForm.value;
|
||||
if (this.isEditMode) {
|
||||
this.http.patch(`${this.apiUrl}/${this.data.command.uuid}`, commandData).subscribe(
|
||||
response => {
|
||||
this.toastService.success('Comando creado con éxito');
|
||||
this.dialogRef.close(commandData);
|
||||
|
||||
const payload = {
|
||||
name: this.createCommandForm.value.name,
|
||||
script: this.createCommandForm.value.script,
|
||||
readOnly: this.createCommandForm.value.readOnly,
|
||||
enabled: this.createCommandForm.value.enabled,
|
||||
comments: this.createCommandForm.value.comments,
|
||||
};
|
||||
|
||||
if (this.commandId) {
|
||||
this.http.put(`${this.baseUrl}${this.commandId}`, payload).subscribe(
|
||||
(response) => {
|
||||
this.toastService.success('Comando editado correctamente');
|
||||
this.dialogRef.close();
|
||||
},
|
||||
error => {
|
||||
console.error('Error editing command', error);
|
||||
(error) => {
|
||||
this.toastService.error(error['error']['hydra:description']);
|
||||
console.error('Error al editar el comando', error);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.http.post(this.apiUrl, commandData).subscribe(
|
||||
response => {
|
||||
this.dialogRef.close(true);
|
||||
this.http.post(`${this.baseUrl}/commands`, payload).subscribe(
|
||||
(response) => {
|
||||
this.toastService.success('Comando añadido correctamente');
|
||||
this.dialogRef.close();
|
||||
},
|
||||
error => {
|
||||
console.error('Error adding command', error);
|
||||
(error) => {
|
||||
this.toastService.error(error['error']['hydra:description']);
|
||||
console.error('Error al añadir comando', error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
import { Injectable } from '@angular/core';
|
||||
import {HttpClient, HttpParams} from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DataService {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
private apiUrl = `${this.baseUrl}/commands?page=1&itemsPerPage=1000`;
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
getCommands(filters: { [key: string]: string }): Observable<{ totalItems: any; data: any }> {
|
||||
const params = new HttpParams({ fromObject: filters });
|
||||
|
||||
return this.http.get<any>(this.apiUrl, { params }).pipe(
|
||||
map(response => {
|
||||
if (response['hydra:member'] && Array.isArray(response['hydra:member'])) {
|
||||
return {
|
||||
data: response['hydra:member'],
|
||||
totalItems: response['hydra:totalItems']
|
||||
}
|
||||
} else {
|
||||
throw new Error('Unexpected response format');
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
console.error('Error fetching commands', error);
|
||||
return throwError(error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getCommand(id: string): Observable<any> {
|
||||
return this.http.get<any>(`${this.baseUrl}${id}`).pipe(
|
||||
map(response => {
|
||||
if (response.name) {
|
||||
return response;
|
||||
} else {
|
||||
throw new Error('Unexpected response format');
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
console.error('Error fetching user group', error);
|
||||
return throwError(error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
.modal-container {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
border-radius: 10px;
|
||||
width: calc(100% - 40px);
|
||||
max-width: 800px;
|
||||
|
@ -73,12 +72,6 @@
|
|||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.primary-button:hover,
|
||||
.accent-button:hover,
|
||||
.cancel-button:hover {
|
||||
|
|
|
@ -26,21 +26,6 @@
|
|||
Debes seleccionar al menos un cliente.
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<!-- <mat-checkbox formControlName="scheduleExecution" (change)="onScheduleChange($event)">
|
||||
Programar ejecución
|
||||
</mat-checkbox>
|
||||
<div *ngIf="showDatePicker" class="schedule-container">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Fecha</mat-label>
|
||||
<input matInput [matDatepicker]="picker" formControlName="scheduleDate">
|
||||
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Hora</mat-label>
|
||||
<input matInput type="time" formControlName="scheduleTime">
|
||||
</mat-form-field>
|
||||
</div> -->
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -48,7 +33,6 @@
|
|||
<button mat-button color="primary" class="primary-button" [disabled]="false" (click)="execute()" >
|
||||
{{ showClientSelect ? 'Ejecutar' : 'Configurar ejecución' }}
|
||||
</button>
|
||||
<!-- <button mat-button color="accent" class="accent-button" (click)="edit()">Editar</button> -->
|
||||
<button mat-button class="cancel-button" (click)="cancel()">Cancelar</button>
|
||||
<button mat-button (click)="cancel()">Cancelar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Injectable()
|
||||
export class CustomInterceptor implements HttpInterceptor {
|
||||
constructor() { }
|
||||
constructor(private router: Router) { }
|
||||
|
||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||
const token = localStorage.getItem('loginToken');
|
||||
|
@ -24,6 +26,15 @@ export class CustomInterceptor implements HttpInterceptor {
|
|||
});
|
||||
}
|
||||
|
||||
return next.handle(newCloneRequest);
|
||||
return next.handle(newCloneRequest).pipe(
|
||||
catchError((error: HttpErrorResponse) => {
|
||||
if (error.status === 401) {
|
||||
this.router.navigate(['/auth/login']).then(r => {
|
||||
console.error('Error 401, redirect to login page');
|
||||
});
|
||||
}
|
||||
return throwError(() => error);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue