Skip to content

Commit

Permalink
fix: update aas-table, aas-tree
Browse files Browse the repository at this point in the history
  • Loading branch information
ralfaron committed Nov 19, 2023
1 parent 73bc6ac commit caf721f
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 165 deletions.
2 changes: 1 addition & 1 deletion projects/aas-lib/src/lib/aas-table/aas-table.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const collapseRow = createAction(

export const toggleSelected = createAction(
AASTableActionType.TOGGLE_SELECTED,
props<{ row: AASTableRow }>());
props<{ row: AASTableRow, altKey: boolean, shiftKey: boolean }>());

export const toggleSelections = createAction(
AASTableActionType.TOGGLE_SELECTIONS);
4 changes: 2 additions & 2 deletions projects/aas-lib/src/lib/aas-table/aas-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<thead>
<tr>
<th class="th-w-checkbox">
<input id="aas-table-checkbox" type="checkbox" class="form-check-input" (change)="toggleSelections()"
[checked]="someSelections | async">
<input type="checkbox" class="form-check-input" [indeterminate]="someSelected | async"
[checked]="everySelected | async" (change)="toggleSelections()">
</th>
<th scope="col" class="th-w-icon">
<i class="bi bi-tag"></i>
Expand Down
38 changes: 27 additions & 11 deletions projects/aas-lib/src/lib/aas-table/aas-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { AASDocument } from 'common';
import { Observable, Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';

import { ViewMode } from '../types/view-mode';
import { AASTableRow, AASTableFeatureState } from './aas-table.state';
import * as AASTableSelectors from './aas-table.selectors';
import * as AASTableActions from './aas-table.actions';
import { AASQuery } from '../types/aas-query-params';
import { NotifyService } from '../notify/notify.service';
import { ClipboardService } from '../clipboard.service';
import { AASTableApiService } from './aas-table-api.service';
import { WindowService } from '../window.service';

@Component({
selector: 'fhg-aas-table',
Expand All @@ -32,23 +30,27 @@ export class AASTableComponent implements OnInit, OnChanges, OnDestroy {
private readonly subscription: Subscription = new Subscription();
private _filter = '';
private _limit = 10;
private shiftKey = false;
private altKey = false;

constructor(
private readonly router: Router,
translate: TranslateService,
store: Store,
private readonly api: AASTableApiService,
private readonly notify: NotifyService,
private readonly clipboard: ClipboardService
private readonly clipboard: ClipboardService,
private readonly window: WindowService
) {
this.store = store as Store<AASTableFeatureState>;
this.someSelections = this.store.select(AASTableSelectors.selectSomeSelections);
this.rows = this.store.select(AASTableSelectors.selectRows);
this.isFirstPage = this.store.select(AASTableSelectors.selectIsFirstPage);
this.isLastPage = this.store.select(AASTableSelectors.selectIsLastPage);
this.everySelected = this.store.select(AASTableSelectors.selectEverySelected);
this.someSelected = this.store.select(AASTableSelectors.selectSomeSelected);

this.subscription.add(this.store.select(AASTableSelectors.selectSelectedDocuments).pipe()
.subscribe(documents => this.selectedChange.emit({ documents })));

this.window.addEventListener('keyup', this.keyup);
this.window.addEventListener('keydown', this.keydown);
}

@Input()
Expand All @@ -63,14 +65,16 @@ export class AASTableComponent implements OnInit, OnChanges, OnDestroy {
@Output()
public selectedChange = new EventEmitter<{ documents: AASDocument[] }>();

public someSelected: Observable<boolean>;

public everySelected: Observable<boolean>;

public readonly isFirstPage: Observable<boolean>;

public readonly isLastPage: Observable<boolean>;

public readonly rows: Observable<AASTableRow[]>;

public readonly someSelections: Observable<boolean>;

public ngOnInit(): void {
this.store.dispatch(AASTableActions.initialize());
}
Expand All @@ -97,6 +101,8 @@ export class AASTableComponent implements OnInit, OnChanges, OnDestroy {

public ngOnDestroy(): void {
this.subscription.unsubscribe();
this.window.removeEventListener('keyup', this.keyup);
this.window.removeEventListener('keydown', this.keydown);
}

public skipStart(): void {
Expand Down Expand Up @@ -146,10 +152,20 @@ export class AASTableComponent implements OnInit, OnChanges, OnDestroy {
}

public toggleSelected(row: AASTableRow): void {
this.store.dispatch(AASTableActions.toggleSelected({ row }));
this.store.dispatch(AASTableActions.toggleSelected({ row, altKey: this.altKey, shiftKey: this.shiftKey }));
}

public toggleSelections(): void {
this.store.dispatch(AASTableActions.toggleSelections());
}

private keyup = () => {
this.shiftKey = false;
this.altKey = false;
};

private keydown = (event: KeyboardEvent) => {
this.shiftKey = event.shiftKey;
this.altKey = event.altKey;
};
}
95 changes: 73 additions & 22 deletions projects/aas-lib/src/lib/aas-table/aas-table.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const aasTableReducer = createReducer(
),
on(
AASTableActions.toggleSelected,
(state, { row }) => toggleSelected(state, row)
(state, { row, altKey, shiftKey }) => toggleSelected(state, row, altKey, shiftKey)
),
on(
AASTableActions.toggleSelections,
Expand Down Expand Up @@ -219,37 +219,88 @@ function collapseRow(state: AASTableState, row: AASTableRow): AASTableState {
return { ...state, rows };
}

function toggleSelected(state: AASTableState, row: AASTableRow) {
const rows = [...state.rows];
const index = rows.indexOf(row);
rows[index] = new AASTableRow(
row.document,
!row.selected,
row.expanded,
row.isLeaf,
row.level,
row.firstChild,
row.nextSibling);
// function toggleSelected(state: AASTableState, row: AASTableRow) {
// const rows = [...state.rows];
// const index = rows.indexOf(row);
// rows[index] = new AASTableRow(
// row.document,
// !row.selected,
// row.expanded,
// row.isLeaf,
// row.level,
// row.firstChild,
// row.nextSibling);

return { ...state, rows }
// return { ...state, rows }
// }

function toggleSelected(
state: AASTableState,
row: AASTableRow,
altKey: boolean,
shiftKey: boolean,
): AASTableState {
let rows: AASTableRow[];
if (altKey) {
rows = state.rows.map(item =>
item === row ? clone(row, !row.selected) : (item.selected ? clone(item, false) : item)
);
} else if (shiftKey) {
const index = state.rows.indexOf(row);
let begin = index;
let end = index;
const selection = state.rows.map(row => row.selected);
const last = selection.lastIndexOf(true);
if (last >= 0) {
if (last > index) {
begin = index;
end = selection.indexOf(true);
} else if (last < index) {
begin = last;
end = index;
}
}

rows = [];
for (let i = 0, n = state.rows.length; i < n; i++) {
const row = state.rows[i];
if (i < begin || i > end) {
rows.push(row.selected ? clone(row, false) : row);
} else {
rows.push(row.selected ? row : clone(row, true));
}
}
} else {
const i = state.rows.indexOf(row);
rows = [...state.rows];
rows[i] = clone(row, !row.selected);
}

return { ...state, rows };
}

function toggleSelections(state: AASTableState) {
const value = !state.rows.some(row => row.selected);
const value = state.rows.length > 0 && state.rows.some(row => row.selected) &&
!state.rows.every(row => row.selected);

const rows = [...state.rows];
for (let index = 0; index < rows.length; ++index) {
const row = rows[index];
if (row.selected !== value) {
rows[index] = new AASTableRow(
row.document,
!row.selected,
row.expanded,
row.isLeaf,
row.level,
row.firstChild,
row.nextSibling);
rows[index] = clone(row, value);
}
}

return { ...state, rows }
}

function clone(row: AASTableRow, selected: boolean): AASTableRow {
return new AASTableRow(
row.document,
selected,
row.expanded,
row.isLeaf,
row.level,
row.firstChild,
row.nextSibling)
}
13 changes: 10 additions & 3 deletions projects/aas-lib/src/lib/aas-table/aas-table.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,21 @@ export const selectSelectedDocuments = createSelector(
return rows.filter(row => row.selected).map(row => row.document);
});

export const selectSomeSelections = createSelector(
export const selectSomeSelected = createSelector(
getRows,
(rows: AASTableRow[]): boolean => {
return rows.some(row => row.selected);
return rows.length > 0 && rows.some(row => row.selected) && !rows.every(row => row.selected);
});


export const selectEverySelected = createSelector(
getRows,
(rows: AASTableRow[]): boolean => {
return rows.length > 0 && rows.every(row => row.selected);
});

export const selectRows = createSelector(getState, state => {
return state.rows;
return state.rows;
});

export const selectIsFirstPage = createSelector(
Expand Down
5 changes: 2 additions & 3 deletions projects/aas-lib/src/lib/aas-tree/aas-tree.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,10 @@ export const collapse = createAction(

export const toggleSelected = createAction(
AASTreeActionType.TOGGLE_SELECTED,
props<{ row: AASTreeRow }>());
props<{ row: AASTreeRow, altKey: boolean, shiftKey: boolean }>());

export const toggleSelections = createAction(
AASTreeActionType.TOGGLE_SELECTIONS,
props<{ document: AASDocument | null }>());
AASTreeActionType.TOGGLE_SELECTIONS);

export const setSearchText = createAction(
AASTreeActionType.SET_SEARCH_TEXT,
Expand Down
7 changes: 4 additions & 3 deletions projects/aas-lib/src/lib/aas-tree/aas-tree.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
<tr>
<th class="aas-tree-th-checkbox">
<input type="checkbox" class="form-check-input" (change)="toggleSelections()"
[disabled]="state === 'online'" [checked]="someSelected | async">
[disabled]="state === 'online'" [indeterminate]="someSelected | async"
[checked]="everySelected | async">
</th>
<th>
<a class="link-secondary" href="javascript:void(0);" (click)="collapse()">
Expand All @@ -24,8 +25,8 @@
<tbody>
<tr *ngFor="let node of nodes | async" [ngClass]="visualState(node)" [id]="node.id">
<td>
<input type="checkbox" class="form-check-input" (change)="toggleSelection(node)" [checked]="node.selected"
[disabled]="state === 'online'" />
<input type="checkbox" class="form-check-input" (change)="toggleSelection(node)"
[checked]="node.selected" [disabled]="state === 'online'" />
</td>
<td [colSpan]="node.isLeaf ? 1 : 2">
<div class="d-flex" style="overflow-x: hidden">
Expand Down
26 changes: 23 additions & 3 deletions projects/aas-lib/src/lib/aas-tree/aas-tree.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {
private readonly liveNodes: LiveNode[] = [];
private readonly map = new Map<string, PropertyValue>();
private readonly subscription = new Subscription();
private shiftKey = false;
private altKey = false;

private webSocketSubject?: WebSocketSubject<WebSocketData>;

Expand All @@ -79,14 +81,18 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {
private readonly translate: TranslateService,
private readonly notify: NotifyService,
private readonly webSocketFactory: WebSocketFactoryService,
private readonly clipboard: ClipboardService
private readonly clipboard: ClipboardService,
) {
this.store = store as Store<AASTreeFeatureState>;
this.nodes = this.store.select(AASTreeSelectors.selectNodes);
this.someSelected = this.store.select(AASTreeSelectors.selectSomeSelected);
this.everySelected = this.store.select(AASTreeSelectors.selectEverySelected);

this.subscription.add(this.store.select(AASTreeSelectors.selectSelectedElements).pipe()
.subscribe(elements => this.selectedChange.emit({ elements })));

this.window.addEventListener('keyup', this.keyup);
this.window.addEventListener('keydown', this.keydown);
}

@Input()
Expand Down Expand Up @@ -115,6 +121,8 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {

public someSelected: Observable<boolean>;

public everySelected: Observable<boolean>;

public nodes: Observable<AASTreeRow[]>;

public ngOnInit(): void {
Expand Down Expand Up @@ -175,6 +183,8 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {
this.subscription.unsubscribe();
this.webSocketSubject?.unsubscribe();
this.searching?.destroy();
this.window.removeEventListener('keyup', this.keyup);
this.window.removeEventListener('keydown', this.keydown);
}

public visualState(node: AASTreeRow): string {
Expand Down Expand Up @@ -225,11 +235,11 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {
}

public toggleSelections(): void {
this.store.dispatch(AASTreeActions.toggleSelections({ document: this.document }));
this.store.dispatch(AASTreeActions.toggleSelections());
}

public toggleSelection(node: AASTreeRow): void {
this.store.dispatch(AASTreeActions.toggleSelected({ row: node }));
this.store.dispatch(AASTreeActions.toggleSelected({ row: node, altKey: this.altKey, shiftKey: this.shiftKey }));
}

public open(node: AASTreeRow): void {
Expand Down Expand Up @@ -523,6 +533,16 @@ export class AASTreeComponent implements OnInit, OnChanges, OnDestroy {
this.notify.log(LogType.Error, error);
}

private keyup = () => {
this.shiftKey = false;
this.altKey = false;
};

private keydown = (event: KeyboardEvent) => {
this.shiftKey = event.shiftKey;
this.altKey = event.altKey;
};

private resolveFile(file: aas.File): { url?: string, name?: string } {
const value: { url?: string, name?: string } = {};
if (this.document?.content && file.value) {
Expand Down
Loading

0 comments on commit caf721f

Please sign in to comment.