From 81d6419f57f8f0393013b026f1e07590234e2eae Mon Sep 17 00:00:00 2001 From: cv5ch <176032962+cv5ch@users.noreply.github.com> Date: Mon, 11 Aug 2025 13:03:06 +0200 Subject: [PATCH 1/2] Make the "Reset chunk" action in the "Chunk activity" page do an actual backend request and made the functionality a service to avoid code duplication --- .../chunks-table/chunks-table.component.html | 1 + .../chunks-table/chunks-table.component.ts | 20 ++++++++- .../tasks-chunks-table.component.ts | 40 +++++------------- .../actions/chunk-actions.service.ts | 42 +++++++++++++++++++ 4 files changed, 72 insertions(+), 31 deletions(-) create mode 100644 src/app/core/_services/actions/chunk-actions.service.ts diff --git a/src/app/core/_components/tables/chunks-table/chunks-table.component.html b/src/app/core/_components/tables/chunks-table/chunks-table.component.html index b8d90477..42c83aba 100644 --- a/src/app/core/_components/tables/chunks-table/chunks-table.component.html +++ b/src/app/core/_components/tables/chunks-table/chunks-table.component.html @@ -6,6 +6,7 @@ [dataSource]="dataSource" [tableColumns]="tableColumns" [contextMenuService]="contextMenuService" + (rowActionClicked)="rowActionClicked($event)" [isFilterable]="true" diff --git a/src/app/core/_components/tables/chunks-table/chunks-table.component.ts b/src/app/core/_components/tables/chunks-table/chunks-table.component.ts index 2d57e636..723cb202 100644 --- a/src/app/core/_components/tables/chunks-table/chunks-table.component.ts +++ b/src/app/core/_components/tables/chunks-table/chunks-table.component.ts @@ -1,10 +1,13 @@ -import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnInit, inject } from '@angular/core'; import { SafeHtml } from '@angular/platform-browser'; import { JChunk } from '@models/chunk.model'; +import { ChunkActionsService } from '@services/actions/chunk-actions.service'; import { ChunkContextMenuService } from '@services/context-menu/chunk-menu.service'; +import { ActionMenuEvent } from '@components/menus/action-menu/action-menu.model'; +import { RowActionMenuAction } from '@components/menus/row-action-menu/row-action-menu.constants'; import { BaseTableComponent } from '@components/tables/base-table/base-table.component'; import { ChunksTableCol, ChunksTableColumnLabel } from '@components/tables/chunks-table/chunks-table.constants'; import { HTTableColumn } from '@components/tables/ht-table/ht-table.models'; @@ -29,6 +32,8 @@ export class ChunksTableComponent extends BaseTableComponent implements OnInit { dataSource: ChunksDataSource; selectedFilterColumn: string = 'all'; + private readonly chunkActions = inject(ChunkActionsService); + ngOnInit(): void { this.setColumnLabels(ChunksTableColumnLabel); this.tableColumns = this.getColumns(); @@ -197,4 +202,17 @@ export class ChunksTableComponent extends BaseTableComponent implements OnInit { return this.sanitize(`${chunk.solveTime}`); } + + rowActionClicked(event: ActionMenuEvent): void { + switch (event.menuItem.action) { + case RowActionMenuAction.RESET: + this.subscriptions.push( + this.chunkActions.resetChunk(event.data).subscribe(() => { + this.alertService.showSuccessMessage('Successfully reseted chunk!'); + this.reload(); + }) + ); + break; + } + } } diff --git a/src/app/core/_components/tables/tasks-chunks-table/tasks-chunks-table.component.ts b/src/app/core/_components/tables/tasks-chunks-table/tasks-chunks-table.component.ts index 2641bbff..ab08cc40 100644 --- a/src/app/core/_components/tables/tasks-chunks-table/tasks-chunks-table.component.ts +++ b/src/app/core/_components/tables/tasks-chunks-table/tasks-chunks-table.component.ts @@ -1,12 +1,10 @@ -import { catchError } from 'rxjs'; - -import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; import { SafeHtml } from '@angular/platform-browser'; import { JChunk } from '@models/chunk.model'; +import { ChunkActionsService } from '@services/actions/chunk-actions.service'; import { ChunkContextMenuService } from '@services/context-menu/chunk-menu.service'; -import { SERV } from '@services/main.config'; import { ActionMenuEvent } from '@components/menus/action-menu/action-menu.model'; import { RowActionMenuAction } from '@components/menus/row-action-menu/row-action-menu.constants'; @@ -42,6 +40,8 @@ export class TasksChunksTableComponent extends BaseTableComponent implements OnI // Track initialization private isInitialized = false; + private readonly chunkActions = inject(ChunkActionsService); + ngOnInit(): void { this.setColumnLabels(TasksChunksTableColumnLabel); this.tableColumns = this.getColumns(); @@ -221,36 +221,16 @@ export class TasksChunksTableComponent extends BaseTableComponent implements OnI return this.sanitize(`${chunk.solveTime}`); } - // --- Action functions --- rowActionClicked(event: ActionMenuEvent): void { switch (event.menuItem.action) { case RowActionMenuAction.RESET: - this.rowActionReset(event.data); + this.subscriptions.push( + this.chunkActions.resetChunk(event.data).subscribe(() => { + this.alertService.showSuccessMessage('Successfully reseted chunk!'); + this.reload(); + }) + ); break; } } - - /** - * @todo Implement error handling. - */ - private rowActionReset(chunks: JChunk): void { - const path = chunks.state === 2 ? 'abortChunk' : 'resetChunk'; - const payload = { chunkId: chunks.id }; - this.subscriptions.push( - this.gs - .chelper(SERV.HELPER, path, payload) - .pipe( - catchError((error) => { - const errorMessage = 'Error during resetting'; - console.error(errorMessage, error); - this.alertService.showErrorMessage(errorMessage); - return []; - }) - ) - .subscribe(() => { - this.alertService.showSuccessMessage('Successfully reseted chunk!'); - this.reload(); - }) - ); - } } diff --git a/src/app/core/_services/actions/chunk-actions.service.ts b/src/app/core/_services/actions/chunk-actions.service.ts new file mode 100644 index 00000000..406b0750 --- /dev/null +++ b/src/app/core/_services/actions/chunk-actions.service.ts @@ -0,0 +1,42 @@ +import { EMPTY, Observable, catchError } from 'rxjs'; + +import { Injectable } from '@angular/core'; + +import { JChunk } from '@models/chunk.model'; + +import { SERV } from '@services/main.config'; +import { GlobalService } from '@services/main.service'; +import { AlertService } from '@services/shared/alert.service'; + +@Injectable({ providedIn: 'root' }) +export class ChunkActionsService { + constructor( + private gs: GlobalService, + private alertService: AlertService + ) {} + + /** + * Resets or aborts a chunk based on its current state. + * + * If the chunk's state is `2` (in-progress), the request will abort it. + * Otherwise, the request will reset it to its initial state. + * + * @param chunk The chunk to reset or abort. + * @returns An Observable that completes when the operation finishes. + * Emits no value. Handles errors internally by logging and showing + * an error message via AlertService. + */ + resetChunk(chunk: JChunk): Observable { + const path = chunk.state === 2 ? 'abortChunk' : 'resetChunk'; + const payload = { chunkId: chunk.id }; + + return this.gs.chelper(SERV.HELPER, path, payload).pipe( + catchError((error) => { + const errorMessage = 'Error during resetting'; + console.error(errorMessage, error); + this.alertService.showErrorMessage(errorMessage); + return EMPTY; + }) + ); + } +} From 1f492422e7ed7abb5762954553b34743311af4ff Mon Sep 17 00:00:00 2001 From: cv5ch <176032962+cv5ch@users.noreply.github.com> Date: Mon, 11 Aug 2025 13:48:43 +0200 Subject: [PATCH 2/2] Fix error in test --- .../settings/acc-settings/acc-settings.component.spec.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/app/account/settings/acc-settings/acc-settings.component.spec.ts b/src/app/account/settings/acc-settings/acc-settings.component.spec.ts index 6a11d735..8cedd294 100644 --- a/src/app/account/settings/acc-settings/acc-settings.component.spec.ts +++ b/src/app/account/settings/acc-settings/acc-settings.component.spec.ts @@ -122,7 +122,13 @@ describe('AccountSettingsComponent', () => { describe('Main form tests', () => { it('initializes the form with default values', async () => { + component.ngOnInit(); + fixture.detectChanges(); + + // Wait for async observable subscription and form patching to complete await fixture.whenStable(); + + // Trigger change detection after async updates fixture.detectChanges(); const formValue = component.form.getRawValue();