Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved column selector to own component + implemented column selection… #150

Merged
merged 10 commits into from
Dec 5, 2023
Merged
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
<div class="select-container">
<mat-select
class="form-control table-select"
multiple="true"
[(value)]="optionalColumnsSelected"
(selectionChange)="handleColumnSelection($event)"
panelClass="tall"
>
<mat-option disabled>
<button
mat-raised-button
class="mat-primary fill text-sm"
(click)="selectAll()">
{{'QUESTION.DATATARGET.SELECTALLDEVICES' | translate}}
</button>
<button
mat-raised-button
class="mat-primary fill text-sm"
(click)="deSelectAll()">
{{'QUESTION.DATATARGET.DESELECTALLDEVICES' | translate}}
</button>
</mat-option>
<mat-option *ngFor="let option of optionalColumnOptions" [value]="option.id">
{{option.display | translate}}
</mat-option>
</mat-select>
</div>
<app-column-selector
[(displayedColumns)]="displayedColumns"
[columnDefinitions]="columnDefinitions"
[localStorageKey]="applicationSavedColumns"
></app-column-selector>

<div class="mat-elevation-z8">
<div class="loading-shade" *ngIf="isLoadingResults">
Expand Down Expand Up @@ -69,15 +47,15 @@

<!-- Devices Column -->
<ng-container matColumnDef="devices">
<th mat-header-cell *matHeaderCellDef class="col-2">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="col-2">
{{ 'APPLICATION-TABLE.IOT-DEVICES' | translate }}</th>
<td mat-cell *matCellDef="let element">
{{element?.iotDevices?.length ?? 0}}
</td>
</ng-container>

<ng-container matColumnDef="dataTargets">
<th mat-header-cell *matHeaderCellDef class="col-1">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="col-1">
{{ 'APPLICATION-TABLE.DATA-TARGETS' | translate}}
</th>
<td mat-cell *matCellDef="let application">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
.table-select {
width: 180px;
margin: 5px;

}

.select-container {
display: flex;
flex-direction: row;
justify-content: flex-end;
}

.flag-icon {
color: red;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
AfterViewInit,
ChangeDetectorRef,
Component,
Input,
OnInit,
Expand All @@ -16,13 +17,12 @@ import { DeleteDialogService } from '@shared/components/delete-dialog/delete-dia
import { merge, Observable, of as observableOf } from 'rxjs';
import { catchError, map, startWith, switchMap } from 'rxjs/operators';
import { DefaultPageSizeOptions } from '@shared/constants/page.constants';
import { MatSelectChange } from '@angular/material/select';
import { ControlledProperty } from '@shared/models/controlled-property.model';
import { ApplicationDeviceTypeEntries } from '@shared/enums/device-type';
import { ApplicationDeviceType } from '@applications/models/application-device-type.model';
import { Datatarget } from '@applications/datatarget/datatarget.model';
import { faFlag } from '@fortawesome/free-solid-svg-icons';
import { FormControl, FormGroup } from '@angular/forms';
import { TableColumn } from '@shared/types/table.type';

const columnDefinitions: TableColumn[] = [
{
Expand Down Expand Up @@ -123,9 +123,6 @@ export class ApplicationsTableComponent implements AfterViewInit, OnInit {
faFlagIcon = faFlag;

displayedColumns: string[] = [];
optionalColumnsSelected: string[] = [];
optionalColumnOptions: TableColumn[] = [];
d;

data: Application[] = [];

Expand All @@ -144,27 +141,13 @@ export class ApplicationsTableComponent implements AfterViewInit, OnInit {
public translate: TranslateService,
private applicationService: ApplicationService,
private router: Router,
private deleteDialogService: DeleteDialogService
private deleteDialogService: DeleteDialogService,
private cdRef: ChangeDetectorRef
) {}

ngOnInit() {
this.optionalColumnOptions = columnDefinitions.filter((o) => o.toggleable);

const userDisplayedColumns = localStorage.getItem(
this.applicationSavedColumns
);
if (userDisplayedColumns) {
const chosenColumns = userDisplayedColumns.split(',');
this.displayedColumns = chosenColumns;
this.optionalColumnsSelected = chosenColumns;
} else {
this.optionalColumnsSelected = columnDefinitions
.filter((o) => o.toggleable && o.default)
.map((o) => o.id);
this.displayedColumns = columnDefinitions
.filter((o) => o.default)
.map((o) => o.id);
}
// Detect changes done by child column selector
this.cdRef.detectChanges();
}

ngAfterViewInit() {
Expand Down Expand Up @@ -235,20 +218,6 @@ export class ApplicationsTableComponent implements AfterViewInit, OnInit {
this.router.navigate(['applications', 'edit-application', applicationId]);
}

handleColumnSelection({
source: { value: selectedColumns },
}: MatSelectChange) {
const displayedColumns = columnDefinitions
.filter((o) => !o.toggleable || selectedColumns.includes(o.id))
.map((o) => o.id);

localStorage.setItem(
this.applicationSavedColumns,
displayedColumns.join(',')
);
this.displayedColumns = displayedColumns;
}

mapControlledProperties(value: ControlledProperty[]) {
if (!value.length) return '-';

Expand Down Expand Up @@ -282,23 +251,5 @@ export class ApplicationsTableComponent implements AfterViewInit, OnInit {
return !!result;
}

selectAll() {
const allOptional = this.optionalColumnOptions.map((o) => o.id);
this.handleColumnSelection({
source: { value: allOptional },
} as MatSelectChange);
this.optionalColumnsSelected = allOptional;
}

deSelectAll() {
this.handleColumnSelection({ source: { value: [] } } as MatSelectChange);
this.optionalColumnsSelected = [];
}
}

interface TableColumn {
id: string;
display: string;
default: boolean;
toggleable: boolean;
protected readonly columnDefinitions = columnDefinitions;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
<app-column-selector
[(displayedColumns)]="displayedColumns"
[columnDefinitions]="columnDefinitions"
[localStorageKey]="iotDeviceSavedColumns"
[placeholder]=""
></app-column-selector>

<div class="mat-elevation-z8">
<div class="loading-shade" *ngIf="isLoadingResults">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
Expand All @@ -15,60 +22,47 @@
<th mat-sort-header="name" *matHeaderCellDef mat-header-cell>
{{ 'APPLICATION-TABLE.NAME' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<a [routerLink]="['../iot-device', element.id]" routerLinkActive="active" class="device-link">{{element.name}}</a>
<td mat-cell *matCellDef="let iotDevice">
<a [routerLink]="['../iot-device', iotDevice.id]" routerLinkActive="active" class="device-link">{{iotDevice.name}}</a>
</td>
</ng-container>

<!-- Technology Column -->
<ng-container matColumnDef="technology">
<th mat-header-cell *matHeaderCellDef>{{ 'IOT-TABLE.NETWORK-TECHNOLOGY' | translate }}</th>
<td mat-cell *matCellDef="let element">{{"IOT-DEVICE-TYPES." + element.type | translate}}</td>
<ng-container matColumnDef="type">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'IOT-TABLE.NETWORK-TECHNOLOGY' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{"IOT-DEVICE-TYPES." + iotDevice.type | translate }}</td>
</ng-container>

<!-- Alarm Column -->
<ng-container matColumnDef="alarm">
<th mat-header-cell *matHeaderCellDef>{{ 'IOT-TABLE.ALARM' | translate }}</th>
<td mat-cell *matCellDef="let element">
N/A
</td>
<ng-container matColumnDef="deviceModel">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'IOTDEVICE.DEVICEMODEL' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{ iotDevice.deviceModel?.body?.name ?? '-' }}</td>
</ng-container>

<!-- Battery Column -->
<ng-container matColumnDef="battery">
<th *matHeaderCellDef mat-header-cell>
{{ 'IOT-TABLE.BATTERY' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<div *ngIf="element.type === 'LORAWAN'; else noBatteryStatus">
<app-batteri-status [color]="batteryStatusColor" [percentage]="getBatteryProcentage(element)">
</app-batteri-status>
</div>
<ng-template #noBatteryStatus>
<div>
{{ 'IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT' | translate }}
</div>
</ng-template>
</td>
<ng-container matColumnDef="deviceProfileName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'IOTDEVICE.LORA.DEVICEPROFILE' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{ iotDevice.deviceProfileName ?? '-'}}</td>
</ng-container>

<!-- Active Column -->
<ng-container matColumnDef="active">
<th mat-header-cell *matHeaderCellDef mat-sort-header="active">
{{ 'IOT-TABLE.ACTIVE' | translate }}
</th>
<td mat-cell *matCellDef="let element">{{lastActive(element)}}</td>
<ng-container matColumnDef="deviceEUI">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'IOT-TABLE.DEV-EUI' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{iotDevice.deviceEUI ?? '-'}}</td>
</ng-container>

<ng-container matColumnDef="OTAAapplicationKey">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'IOT-TABLE.APP-KEY' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{iotDevice.OTAAapplicationKey ?? '-'}}</td>
</ng-container>


<!-- RSSI column -->
<ng-container matColumnDef="rssi">
<th *matHeaderCellDef mat-header-cell mat-sort-header="rssi">
{{ 'IOT-TABLE.RSSI' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.type === 'LORAWAN' || element.type === 'SIGFOX'; else notSupported">
<div *ngIf="element.latestReceivedMessage?.rssi; else notAvailable">
{{element.latestReceivedMessage.rssi}}
<td mat-cell *matCellDef="let iotDevice">
<ng-container *ngIf="iotDevice.type === 'LORAWAN' || iotDevice.type === 'SIGFOX'; else notSupported">
<div *ngIf="iotDevice.latestReceivedMessage?.rssi; else notAvailable">
{{iotDevice.latestReceivedMessage.rssi}}
</div>
</ng-container>
</td>
Expand All @@ -79,30 +73,61 @@
<th *matHeaderCellDef mat-header-cell mat-sort-header="snr">
{{ 'IOT-TABLE.SNR' | translate }}
</th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="element.type === 'LORAWAN' || element.type === 'SIGFOX'; else notSupported">
<div *ngIf="element.latestReceivedMessage?.snr; else notAvailable">
{{element.latestReceivedMessage?.snr}}
<td mat-cell *matCellDef="let iotDevice">
<ng-container *ngIf="iotDevice.type === 'LORAWAN' || iotDevice.type === 'SIGFOX'; else notSupported">
<div *ngIf="iotDevice.latestReceivedMessage?.snr; else notAvailable">
{{iotDevice.latestReceivedMessage?.snr}}
</div>
</ng-container>
</td>
</ng-container>

<ng-container matColumnDef="dataTargets">
<th mat-header-cell *matHeaderCellDef mat-sort-header>{{ 'APPLICATION-TABLE.DATA-TARGETS' | translate }}</th>
<td mat-cell *matCellDef="let iotDevice">{{iotDevice.connections?.length ?? 0}}</td>
</ng-container>

<!-- Battery Column -->
<ng-container matColumnDef="battery">
<th *matHeaderCellDef mat-header-cell>
{{ 'IOT-TABLE.BATTERY' | translate }}
</th>
<td mat-cell *matCellDef="let iotDevice">
<div *ngIf="iotDevice.type === 'LORAWAN'; else noBatteryStatus">
<app-batteri-status [color]="batteryStatusColor" [percentage]="getBatteryProcentage(iotDevice)">
</app-batteri-status>
</div>
<ng-template #noBatteryStatus>
<div>
{{ 'IOTDEVICE-TABLE-ROW.NOT-SUPPORTED-SHORT' | translate }}
</div>
</ng-template>
</td>
</ng-container>

<!-- Active Column -->
<ng-container matColumnDef="active">
<th mat-header-cell *matHeaderCellDef mat-sort-header="active">
{{ 'IOT-TABLE.ACTIVE' | translate }}
</th>
<td mat-cell *matCellDef="let iotDevice">{{lastActive(iotDevice)}}</td>
</ng-container>

<ng-container matColumnDef="menu">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let element">
<td mat-cell *matCellDef="let iotDevice">
<div class="dropdown" *ngIf="canEdit">
<a href="#" role="button" id="tableRowDropdown-{{element.id}}" class="applicationRow__edit dropdown-toggle"
<a href="#" role="button" id="tableRowDropdown-{{iotDevice.id}}" class="applicationRow__edit dropdown-toggle"
data-toggle="dropdown" aria-expanded="false"
[attr.aria-label]="'APPLICATION-TABLE-ROW.SHOW-OPTIONS' | translate"></a>
<ul class="dropdown-menu dropdown-menu--table" attr.aria-labelledby="tableRowDropdown-{{element.id}}">
<ul class="dropdown-menu dropdown-menu--table" attr.aria-labelledby="tableRowDropdown-{{iotDevice.id}}">
<li class="dropdown-item">
<a [routerLink]="['../iot-device-edit', element.id]" routerLinkActive="active">{{ 'IOTDEVICE-TABLE-ROW.EDIT'
<a [routerLink]="['../iot-device-edit', iotDevice.id]" routerLinkActive="active">{{ 'IOTDEVICE-TABLE-ROW.EDIT'
| translate }}
</a>
</li>
<li class="dropdown-item">
<a (click)="clickDelete(element)" [routerLink]="[]">{{ 'IOTDEVICE-TABLE-ROW.DELETE' | translate }}</a>
<a (click)="clickDelete(iotDevice)" [routerLink]="[]">{{ 'IOTDEVICE-TABLE-ROW.DELETE' | translate }}</a>
</li>
</ul>
</div>
Expand Down
Loading
Loading