refactor: scan-table refactoring, running version

This commit is contained in:
2025-01-27 17:32:46 +01:00
parent 27061b24e9
commit d3481d68bf
6 changed files with 195 additions and 88 deletions

View File

@ -0,0 +1,3 @@
export interface ScanCountResponse {
count: number;
}

View File

@ -15,6 +15,10 @@ export interface ScanDataResponse {
info?: { [key: string]: any };
timestamp?: number;
user_data?: { [key: string]: any };
name?: string;
user_rating?: number;
system_rating?: number;
user_comments?: string;
system_comments?: string;
}

View File

@ -4,6 +4,7 @@ import { ServerSettingsService } from '../server-settings.service';
import { ScanDataResponse } from './model/scan-data';
import { Realm } from './model/realm';
import { Deployment } from './model/deployment';
import { ScanCountResponse } from './model/scan-count';
@Injectable({
providedIn: 'root',
@ -41,7 +42,7 @@ export class RemoteDataService {
*/
protected get<T>(
path: string,
params: { [key: string]: string },
params: { [key: string]: string | number },
headers: HttpHeaders
) {
return this.httpClient.get<T>(
@ -153,3 +154,38 @@ export class DeploymentDataService extends RemoteDataService {
);
}
}
@Injectable({
providedIn: 'root',
})
export class ScanCountService extends RemoteDataService {
/**
* Method for getting the scan count
* @param sessionId Unique identifier for the session (Optional)
* @param scanName Name of the scan (Optional)
* @param datasetNumber Dataset number (Optional)
* @returns response from the server with the scan count
* @throws HttpErrorResponse if the request fails
* @throws TimeoutError if the request takes too long
* @throws Error if the response is not a number
*/
getScanCount(
sessionId: string | null = null,
scanName: string | null = null,
datasetNumber: number | null = null
) {
let headers = new HttpHeaders();
let filters: { [key: string]: string | number } = {};
headers = headers.set('Content-Type', 'application/json; charset=utf-8');
if (sessionId !== null) {
filters['session_id'] = sessionId;
}
if (scanName !== null) {
filters['scan_name'] = scanName;
}
if (datasetNumber !== null) {
filters['dataset_number'] = datasetNumber;
}
return this.get<ScanCountResponse>('scans/count', filters, headers);
}
}

View File

@ -1,31 +1,35 @@
<div class = "button-container">
<button mat-raised-button (click)="ngOnInit()">Refresh</button>
</div>
<div class="table-container">
<mat-card>
<mat-toolbar color="primary"> ScanData Table </mat-toolbar>
<!-- <table mat-table *ngIf="tableData | async as data" [dataSource]="data" class="mat-elevation-z8"> -->
<table mat-table *ngIf="tableData() as data" [dataSource]="data" class="mat-elevation-z8">
<mat-toolbar color="primary">
Table with Scan Data
<span class="spacer"></span>
<button mat-icon-button (click)="ngOnInit()">
<mat-icon>search</mat-icon>
</button>
<button mat-icon-button (click)="ngOnInit()">
<mat-icon>refresh</mat-icon>
</button>
<button mat-icon-button (click)="ngOnInit()">
<mat-icon>settings</mat-icon>
</button>
</mat-toolbar>
<table mat-table *ngIf="tableData() as data" [dataSource]="data" class="mat-elevation-z8">
<!-- Create table data dynamically -->
<ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef> {{ column | titlecase }} </th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="column === 'timestamp'; else userRating">
{{ element[column] * 1000| date :'HH:mm:ss'}}
<td mat-cell *matCellDef="let element">
@if (column === 'timestamp') {
{{ element[column] * 1000 | date :'HH:mm:ss'}}
<br>
{{ element[column] * 1000 | date :'dd/MM/yyyy'}}
</ng-container>
<ng-template #userRating>
<div *ngIf="column === 'user_rating'; else showData">
<star-rating [starType]="'svg'" [rating]="element[column]"></star-rating>
</div>
</ng-template>
<ng-template #showData>
{{ element[column] * 1000 | date :'dd/MM/yyyy'}}
}
@else if (column === 'user_rating') {
<star-rating [starType]="'svg'" [rating]="element[column]"></star-rating>
}
@else{
<p> {{ element[column] }}</p>
</ng-template>
}
</ng-container>
<!-- Header Row -->
@ -35,5 +39,15 @@
</table>
</mat-card>
<mat-paginator [pageSize]=10 [pageSizeOptions]="[5, 10, 25, 100]" aria-label="Select page"></mat-paginator>
<mat-paginator
#paginator
class="table-paginator"
(page) = "handlePageEvent($event)"
[length]="totalScanCount"
[pageSize]= "limit"
[showFirstLastButtons]="true"
[pageSizeOptions]="[5, 10, 25, 100]"
[pageIndex]="page"
aria-label="Select page">
</mat-paginator>
</div>

View File

@ -10,4 +10,8 @@
}
.mat-mdc-row:hover {
background-color: var(--mat-sys-secondary-container);
}
.spacer {
flex: 1 1 auto;
}

View File

@ -1,91 +1,137 @@
import { ChangeDetectionStrategy, Component, WritableSignal, signal, ViewChild } from '@angular/core';
import { ScanDataService } from '../core/remote-data.service';
import {
ChangeDetectionStrategy,
Component,
WritableSignal,
signal,
ViewChild,
} from '@angular/core';
import { ScanCountService, ScanDataService } from '../core/remote-data.service';
import { ScanDataResponse } from '../core/model/scan-data';
import { firstValueFrom } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { MatTableModule } from '@angular/material/table';
import { MatIconModule } from '@angular/material/icon';
import { MatCardModule } from '@angular/material/card';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatButtonModule } from '@angular/material/button';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
import {
MatPaginator,
MatPaginatorModule,
PageEvent,
} from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { StarRatingModule } from 'angular-star-rating';
import { MatSort } from '@angular/material/sort';
@Component({
selector: 'app-scan-table',
standalone: true,
imports: [CommonModule, MatPaginator, MatTableModule, MatIconModule, MatToolbarModule, MatCardModule, MatButtonModule, MatPaginatorModule, StarRatingModule],
imports: [
CommonModule,
MatPaginator,
MatTableModule,
MatIconModule,
MatToolbarModule,
MatCardModule,
MatButtonModule,
MatPaginatorModule,
StarRatingModule,
MatProgressSpinnerModule,
],
templateUrl: './scan-table.component.html',
styleUrl: './scan-table.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ScanTableComponent {
tableData: WritableSignal<ScanDataResponse[]> = signal([]); // Initialize as empty array
limit: number = 100;
// private tableData: new MatTableDataSource<ScanDataResponse[]>(); // Initialize as empty array
// tableData: ScanDataResponse[] = [];
tableData: WritableSignal<ScanDataResponse[]> = signal([]);
limit: number = 10;
offset: number = 0;
displayedColumns: string[] = ['scan_number', 'status', 'num_points', 'scan_name', 'scan_type', 'dataset_number', 'timestamp', 'user_rating'];
ignoredEntries: string[] = ['scan_report_devices', 'user_metadata', 'readout_priority', 'scan_parameters', 'request_inputs', 'info'];
totalScanCount: number = 0;
page: number = this.offset / this.limit;
pageEvent: PageEvent = new PageEvent();
sessionId: string = '';
sorting: number = -1;
displayedColumns: string[] = [
'scan_number',
'status',
'num_points',
'scan_name',
'scan_type',
'dataset_number',
'timestamp',
'user_rating',
];
ignoredEntries: string[] = [
'scan_report_devices',
'user_metadata',
'readout_priority',
'scan_parameters',
'request_inputs',
'info',
];
@ViewChild(MatPaginatorModule) paginator!: MatPaginatorModule;
constructor(
private scanData: ScanDataService,
private scanCount: ScanCountService
) {}
constructor(private scanData: ScanDataService) {}
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort!: MatSort;
ngOnInit(): void {
let sessionId = '6793628df62026a414d9338e';
this.updateTableData(sessionId);
this.sessionId = '6793628df62026a414d9338e';
this.updateUI();
}
async updateTableData(sessionId: string) {
let data = await firstValueFrom(
this.scanData.getScanData(sessionId, this.offset, this.limit, this.displayedColumns, false, { scan_number: -1 })
);
console.log('Received data: ', data);
for (const entry of data) {
if (entry.user_data && entry.user_data['user_rating'])
{
entry.user_rating = entry.user_data['user_rating'];
}
}
console.log('Received data: ', data);
this.tableData.set(data); // Update the signal value
handlePageEvent(event: PageEvent) {
this.pageEvent = event;
this.offset = event.pageIndex * event.pageSize;
this.limit = event.pageSize;
this.page = this.offset / this.limit;
this.updateUI();
}
updateUI() {
this.updateTotalScanCount(this.sessionId);
this.updateTableData(this.sessionId);
}
updateTableData(sessionId: string) {
this.scanData
.getScanData(
sessionId,
this.offset,
this.limit,
this.displayedColumns,
false,
{ scan_number: this.sorting }
)
.subscribe({
next: (data) => {
console.log('Received data: ', data);
for (const entry of data) {
if (entry.user_data && entry.user_data['user_rating']) {
entry.user_rating = entry.user_data['user_rating'];
}
}
this.tableData.set(data);
},
error: (error) => {
console.error('Error fetching data: ', error);
},
});
}
updateTotalScanCount(sessionId: string) {
this.scanCount.getScanCount(sessionId).subscribe({
next: (data) => {
console.log('Received data: ', data);
this.totalScanCount = data.count;
},
error: (error) => {
console.error('Error fetching data: ', error);
},
});
}
}
// @Component({
// selector: 'app-scan-table',
// standalone: true,
// imports: [CommonModule, MatPaginator, MatTableModule, MatIconModule, MatToolbarModule, MatCardModule, MatButtonModule, MatPaginatorModule],
// templateUrl: './scan-table.component.html',
// styleUrl: './scan-table.component.scss',
// changeDetection: ChangeDetectionStrategy.OnPush,
// })
// export class ScanTableComponent {
// tableData!: Promise<ScanDataResponse[]>;
// limit: number = 100;
// offset: number = 0;
// displayedColumns: string[] = ['scan_number', 'status', "num_points", "scan_name", "scan_type", "dataset_number", "timestamp", "user_rating"];
// ignoredEntries: string[] = ["scan_report_devices", "user_metadata", "readout_priority", "scan_parameters", "request_inputs", "info"];
// // , "scan_name", "scan_type"];
// @ViewChild(MatPaginatorModule) paginator!: MatPaginatorModule;
// constructor( private scanData: ScanDataService) {
// }
// ngOnInit(): void {
// let sessionId = "6793628df62026a414d9338e";
// this.tableData = this.updateTableData(sessionId = "6793628df62026a414d9338e");
// // this.tableData = this.scanData.getScanData(sessionId = "6793628df62026a414d9338e");
// }
// async updateTableData(sessionId: string, offset: number = 0, limit: number = 100) {
// const data = await firstValueFrom(this.scanData.getScanData(sessionId=sessionId, offset=this.offset, limit=this.limit, this.displayedColumns, false, {"scan_number": -1}));
// console.log("Received data: ", data);
// // this.tableData = data;
// return data;
// }
// }