Skip to content

Commit

Permalink
fix: CommandHandlerService use signals
Browse files Browse the repository at this point in the history
  • Loading branch information
ralfaron committed Jun 16, 2024
1 parent 8ac8c5d commit 3e14728
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 58 deletions.
4 changes: 2 additions & 2 deletions projects/aas-portal/src/app/aas/aas.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@
</button>
</div>
<div class="btn-group me-2" [hidden]="readOnly()">
<button type="button" class="btn btn-primary" (click)="undo()" [disabled]="canUndo === false">
<button type="button" class="btn btn-primary" (click)="undo()" [disabled]="canUndo() === false">
<i class="bi bi-arrow-counterclockwise"></i>
</button>
<button type="button" class="btn btn-primary" (click)="redo()" [disabled]="canRedo === false">
<button type="button" class="btn btn-primary" (click)="redo()" [disabled]="canRedo() === false">
<i class="bi bi-arrow-clockwise"></i>
</button>
</div>
Expand Down
8 changes: 2 additions & 6 deletions projects/aas-portal/src/app/aas/aas.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,9 @@ export class AASComponent implements OnInit, OnDestroy, AfterViewInit {

public readonly selectedElements = signal<aas.Referable[]>([]);

public get canUndo(): boolean {
return this.commandHandler.canUndo;
}
public readonly canUndo = this.commandHandler.canUndo;

public get canRedo(): boolean {
return this.commandHandler.canRedo;
}
public readonly canRedo = this.commandHandler.canRedo;

public readonly canPlay = computed(() => {
const state = this.store.state();
Expand Down
34 changes: 15 additions & 19 deletions projects/aas-portal/src/app/aas/command-handler.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
*
*****************************************************************************/

import { Injectable } from '@angular/core';
import { Injectable, computed, signal } from '@angular/core';
import { NotifyService } from 'aas-lib';
import { Command } from '../types/command';

@Injectable({
providedIn: 'root',
})
export class CommandHandlerService {
private commands: Array<Command> = [];
private position = -1;
private readonly commands = signal<Command[]>([]);
private readonly position = signal(-1);

public constructor(private notify: NotifyService) {}

Expand All @@ -27,46 +27,42 @@ export class CommandHandlerService {
try {
command.execute();

if (this.commands.length > 0 && this.position < this.commands.length - 1) {
this.commands.splice(this.position + 1);
if (this.commands().length > 0 && this.position() < this.commands().length - 1) {
this.commands.update(values => values.filter((_, i) => i <= this.position()));
}

this.commands.push(command);
++this.position;
this.commands.update(values => [...values, command]);
this.position.update(value => value + 1);
} catch (error) {
command.abort();
throw error;
}
}

public get canUndo(): boolean {
return this.position >= 0;
}
public readonly canUndo = computed(() => this.position() >= 0);

public get canRedo(): boolean {
return this.position + 1 < this.commands.length;
}
public readonly canRedo = computed(() => this.position() + 1 < this.commands().length);

public undo(): void {
try {
this.commands[this.position].undo();
--this.position;
this.commands()[this.position()].undo();
this.position.update(value => value - 1);
} catch (error) {
this.notify.error(error);
}
}

public redo(): void {
try {
++this.position;
this.commands[this.position].redo();
this.position.update(value => value + 1);
this.commands()[this.position()].redo();
} catch (error) {
this.notify.error(error);
}
}

public clear(): void {
this.commands = [];
this.position = -1;
this.commands.set([]);
this.position.set(-1);
}
}
12 changes: 4 additions & 8 deletions projects/aas-portal/src/app/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit, Aft

public readonly selectionMode = this.dashboard.selectionMode.asReadonly();

public readonly canUndo = computed(() => this.editMode() && this.commandHandler.canUndo());

public readonly canRedo = computed(() => this.editMode() && this.commandHandler.canRedo());

public ngOnInit(): void {
this.commandHandler.clear();

Expand Down Expand Up @@ -455,20 +459,12 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit, Aft
}
}

public canUndo(): boolean {
return this.editMode() && this.commandHandler.canUndo;
}

public undo(): void {
if (this.canUndo()) {
this.commandHandler.undo();
}
}

public canRedo(): boolean {
return this.editMode() && this.commandHandler.canRedo;
}

public redo(): void {
if (this.canRedo()) {
this.commandHandler.redo();
Expand Down
17 changes: 6 additions & 11 deletions projects/aas-portal/src/test/aas/aas.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing';
import { DashboardPage, DashboardService } from '../../app/dashboard/dashboard.service';
import { DashboardChartType } from '../../app/dashboard/dashboard.service';
import { Router, provideRouter } from '@angular/router';
import { Component, Input, input, output, signal } from '@angular/core';
import { Component, input, output, signal } from '@angular/core';
import { AASApiService } from '../../app/aas/aas-api.service';
import { ToolbarService } from '../../app/toolbar.service';
import { AASStore } from '../../app/aas/aas.store';
Expand Down Expand Up @@ -58,16 +58,11 @@ class TestAASTreeComponent {
standalone: true,
})
class TestSecureImageComponent {
@Input()
public src = '';
@Input()
public alt?: string;
@Input()
public classname?: string;
@Input()
public width = -1;
@Input()
public height = -1;
public readonly src = input.required<string>();
public readonly alt = input<string | undefined>();
public readonly classname = input<string | undefined>();
public readonly width = input<number | undefined>();
public readonly height = input<number | undefined>();
}

describe('AASComponent', () => {
Expand Down
24 changes: 12 additions & 12 deletions projects/aas-portal/src/test/aas/command-handler.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,41 +88,41 @@ describe('CommandHandlerService', () => {
expect(service).toBeTruthy();
});

it('indicates that undo is not possible', function () {
expect(service.canUndo).toBeFalse();
it('indicates that undo is not possible', () => {
expect(service.canUndo()).toBeFalse();
});

it('indicates that redo is not possible', function () {
expect(service.canRedo).toBeFalse();
it('indicates that redo is not possible', () => {
expect(service.canRedo()).toBeFalse();
});

it('can execute a command', function () {
it('can execute a command', () => {
const spy = jasmine.createSpy('execute');
service.execute(new TestCommand(spy));
expect(spy).toHaveBeenCalled();
});

it('can undo/redo a command', function () {
it('can undo/redo a command', () => {
const undoSpy = jasmine.createSpy('undo');
const redoSpy = jasmine.createSpy('redo');
service.execute(new TestCommand(undefined, undoSpy, redoSpy));
expect(service.canUndo).toBeTrue();
expect(service.canUndo()).toBeTrue();
service.undo();
expect(undoSpy).toHaveBeenCalled();
expect(service.canRedo).toBeTrue();
expect(service.canRedo()).toBeTrue();
service.redo();
expect(redoSpy).toHaveBeenCalled();
});

it('clears the undo/redo stack', function () {
it('clears the undo/redo stack', () => {
service.execute(new TestCommand());
service.execute(new TestCommand());
service.clear();
expect(service.canUndo).toBeFalse();
expect(service.canRedo).toBeFalse();
expect(service.canUndo()).toBeFalse();
expect(service.canRedo()).toBeFalse();
});

it('aborts a failed command', function () {
it('aborts a failed command', () => {
const abortSpy = jasmine.createSpy('abort');
expect(() => service.execute(new FailCommand(abortSpy))).toThrowError();
expect(abortSpy).toHaveBeenCalled();
Expand Down

0 comments on commit 3e14728

Please sign in to comment.