Skip to content

Commit 9e83ca5

Browse files
43938: Applications overview update
Feature/43938 update applications list
2 parents 07a8048 + e283674 commit 9e83ca5

File tree

99 files changed

+2637
-847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2637
-847
lines changed

src/app/app-routing.module.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { NgModule } from "@angular/core";
2-
import { Routes, RouterModule, PreloadAllModules } from "@angular/router";
3-
import { AuthComponent } from "./auth/auth.component";
4-
import { ErrorPageComponent } from "./error-page/error-page.component";
5-
import { SearchComponent } from "./search/search.component";
6-
import { AuthGuardService as AuthGuard } from "./auth/auth-guard.service";
2+
import { PreloadAllModules, RouterModule, Routes } from "@angular/router";
73
import { NewUserComponent } from "./admin/users/new-kombit-user-page/new-user.component";
84
import { UserPageComponent } from "./admin/users/user-page/user-page.component";
5+
import { AuthGuardService as AuthGuard } from "./auth/auth-guard.service";
6+
import { AuthComponent } from "./auth/auth.component";
7+
import { ErrorPageComponent } from "./error-page/error-page.component";
98

109
const routes: Routes = [
1110
{
@@ -44,7 +43,6 @@ const routes: Routes = [
4443
loadChildren: () => import("./device-model/device-model.module").then(m => m.DeviceModelModule),
4544
canActivate: [AuthGuard],
4645
},
47-
{ path: "search", component: SearchComponent, canActivate: [AuthGuard] },
4846
{ path: "not-found", component: ErrorPageComponent, data: { message: "not-found", code: 404 } },
4947
{ path: "not-authorized", component: ErrorPageComponent },
5048
{ path: "new-user", component: NewUserComponent, canActivate: [AuthGuard] },

src/app/app.module.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,37 @@
1-
import { BrowserModule, Title } from "@angular/platform-browser";
1+
import { NgIf } from "@angular/common";
2+
import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from "@angular/common/http";
23
import { NgModule } from "@angular/core";
3-
import { TranslateModule, TranslateLoader } from "@ngx-translate/core";
4-
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
5-
import { HttpClient, HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
6-
import { AppRoutingModule } from "./app-routing.module";
7-
import { AppComponent } from "./app.component";
8-
import { NavbarModule } from "./navbar/navbar.module";
9-
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
104
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
11-
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
12-
import { ProfilesModule } from "./profiles/profiles.module";
13-
import { AuthJwtInterceptor } from "@shared/helpers/auth-jwt.interceptor";
14-
import { AuthModule } from "./auth/auth.module";
15-
import { GatewayModule } from "./gateway/gateway.module";
16-
import { SharedVariableModule } from "@shared/shared-variable/shared-variable.module";
17-
import { SAVER, getSaver } from "@shared/providers/saver.provider";
18-
import { ErrorPageComponent } from "./error-page/error-page.component";
19-
import { SearchModule } from "./search/search.module";
20-
import { JwtModule } from "@auth0/angular-jwt";
21-
import { MonacoEditorModule } from "ngx-monaco-editor-v2";
225
import { MatInputModule } from "@angular/material/input";
236
import { MatPaginatorIntl } from "@angular/material/paginator";
24-
import { MatPaginatorIntlDa } from "@shared/helpers/mat-paginator-intl-da";
257
import { MatTooltipModule } from "@angular/material/tooltip";
26-
import { NewUserComponent } from "./admin/users/new-kombit-user-page/new-user.component";
8+
import { BrowserModule, Title } from "@angular/platform-browser";
9+
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
10+
import { JwtModule } from "@auth0/angular-jwt";
11+
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
12+
import { TranslateLoader, TranslateModule } from "@ngx-translate/core";
13+
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
14+
import { MatSelectSearchModule } from "@shared/components/mat-select-search/mat-select-search.module";
2715
import { WelcomeDialogModule } from "@shared/components/welcome-dialog/welcome-dialog.module";
16+
import { AuthJwtInterceptor } from "@shared/helpers/auth-jwt.interceptor";
17+
import { MatPaginatorIntlDa } from "@shared/helpers/mat-paginator-intl-da";
2818
import { NGMaterialModule } from "@shared/Modules/materiale.module";
29-
import { MatSelectSearchModule } from "@shared/components/mat-select-search/mat-select-search.module";
30-
import { UserPageComponent } from "./admin/users/user-page/user-page.component";
31-
import { SharedModule } from "@shared/shared.module";
3219
import { PipesModule } from "@shared/pipes/pipes.module";
20+
import { SAVER, getSaver } from "@shared/providers/saver.provider";
21+
import { SharedVariableModule } from "@shared/shared-variable/shared-variable.module";
22+
import { SharedModule } from "@shared/shared.module";
3323
import { CookieService } from "ngx-cookie-service";
24+
import { MonacoEditorModule } from "ngx-monaco-editor-v2";
25+
import { NewUserComponent } from "./admin/users/new-kombit-user-page/new-user.component";
26+
import { UserPageComponent } from "./admin/users/user-page/user-page.component";
27+
import { AppRoutingModule } from "./app-routing.module";
28+
import { AppComponent } from "./app.component";
29+
import { AuthModule } from "./auth/auth.module";
30+
import { ErrorPageComponent } from "./error-page/error-page.component";
31+
import { GatewayModule } from "./gateway/gateway.module";
32+
import { NavbarModule } from "./navbar/navbar.module";
33+
import { ProfilesModule } from "./profiles/profiles.module";
34+
import { SearchModule } from "./search/search.module";
3435

3536
export function HttpLoaderFactory(http: HttpClient) {
3637
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
@@ -60,6 +61,7 @@ export function tokenGetter() {
6061
},
6162
}),
6263
NgbModule,
64+
NgIf,
6365
FormsModule,
6466
ReactiveFormsModule,
6567
BrowserAnimationsModule,

src/app/applications/application-detail/application-detail.component.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
import { AfterViewInit, Component, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core";
1+
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, OnDestroy, OnInit, Output } from "@angular/core";
2+
import { MatDialog } from "@angular/material/dialog";
23
import { Title } from "@angular/platform-browser";
34
import { ActivatedRoute, Router } from "@angular/router";
5+
import { Gateway, GatewayResponseMany } from "@app/gateway/gateway.model";
46
import { Application } from "@applications/application.model";
57
import { ApplicationService } from "@applications/application.service";
8+
import { IotDevicesApplicationMapResponse } from "@applications/iot-devices/iot-device.model";
69
import { TranslateService } from "@ngx-translate/core";
710
import { DeleteDialogService } from "@shared/components/delete-dialog/delete-dialog.service";
11+
import { OrganizationAccessScope } from "@shared/enums/access-scopes";
812
import { BackButton } from "@shared/models/back-button.model";
13+
import { ApplicationDialogModel } from "@shared/models/dialog.model";
914
import { DropdownButton } from "@shared/models/dropdown-button.model";
15+
import { ChirpstackGatewayService } from "@shared/services/chirpstack-gateway.service";
1016
import { MeService } from "@shared/services/me.service";
11-
import { Subscription } from "rxjs";
12-
import { OrganizationAccessScope } from "@shared/enums/access-scopes";
13-
import { IotDevicesApplicationMapResponse } from "@applications/iot-devices/iot-device.model";
1417
import { RestService } from "@shared/services/rest.service";
15-
import { Observable } from "rxjs";
16-
import { map } from "rxjs/operators";
1718
import { SharedVariableService } from "@shared/shared-variable/shared-variable.service";
18-
import { ChirpstackGatewayService } from "@shared/services/chirpstack-gateway.service";
19-
import { Gateway, GatewayResponseMany } from "@app/gateway/gateway.model";
20-
import { MatDialog } from "@angular/material/dialog";
19+
import { Observable, Subscription } from "rxjs";
20+
import { map } from "rxjs/operators";
2121
import { ApplicationChangeOrganizationDialogComponent } from "../application-change-organization-dialog/application-change-organization-dialog.component";
22-
import { ApplicationDialogModel } from "@shared/models/dialog.model";
2322

2423
@Component({
2524
selector: "app-application",
@@ -72,11 +71,13 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
7271
private restService: RestService,
7372
private sharedVariableService: SharedVariableService,
7473
private chirpstackGatewayService: ChirpstackGatewayService,
75-
private changeOrganizationDialog: MatDialog
74+
private changeOrganizationDialog: MatDialog,
75+
private cdr: ChangeDetectorRef
7676
) {}
7777

7878
ngOnInit(): void {
7979
this.id = +this.route.snapshot.paramMap.get("id");
80+
8081
if (this.id) {
8182
this.bindApplication(this.id);
8283
this.dropdownButton = {
@@ -147,7 +148,7 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
147148
useGeolocation: false,
148149
markerInfo: {
149150
name: dev.name,
150-
active: false,
151+
active: dev.type,
151152
id: dev.id,
152153
isDevice: true,
153154
internalOrganizationId: this.sharedVariableService.getSelectedOrganisationId(),
@@ -214,6 +215,7 @@ export class ApplicationDetailComponent implements OnInit, OnDestroy, AfterViewI
214215
bindApplication(id: number): void {
215216
this.applicationsSubscription = this.applicationService.getApplication(id).subscribe(application => {
216217
this.application = application;
218+
this.cdr.detectChanges();
217219
});
218220
}
219221

src/app/applications/application.model.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import { PermissionResponse } from "@app/admin/permission/permission.model";
12
import { ControlledPropertyTypes } from "@app/device-model/Enums/controlled-propperty.enum";
3+
import { Datatarget } from "@applications/datatarget/datatarget.model";
24
import { ApplicationDeviceTypeUnion } from "@shared/enums/device-type";
35
import { ControlledProperty } from "@shared/models/controlled-property.model";
46
import { Organisation } from "../admin/organisation/organisation.model";
57
import { ApplicationStatus } from "./enums/status.enum";
68
import { IotDevice } from "./iot-devices/iot-device.model";
79
import { ApplicationDeviceType } from "./models/application-device-type.model";
8-
import { PermissionResponse } from "@app/admin/permission/permission.model";
9-
import { Datatarget } from "@applications/datatarget/datatarget.model";
10+
11+
export type ApplicationWithStatus = Application & { statusCheck: "stable" | "alert" };
1012

1113
export class Application {
1214
public id: number;

src/app/applications/application.service.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { Injectable } from "@angular/core";
2+
import { UserMinimalService } from "@app/admin/users/user-minimal.service";
23
import { Application, ApplicationData, UpdateApplicationOrganization } from "@applications/application.model";
3-
import { RestService } from "../shared/services/rest.service";
44
import { Observable } from "rxjs";
55
import { map } from "rxjs/operators";
6-
import { UserMinimalService } from "@app/admin/users/user-minimal.service";
6+
import { RestService } from "../shared/services/rest.service";
7+
import { ApplicationsFilterService } from "./applications-list/application-filter/applications-filter.service";
8+
import { ApplicationStatus, ApplicationStatusCheck } from "./enums/status.enum";
9+
import { IotDevice } from "./iot-devices/iot-device.model";
710

811
interface GetApplicationParameters {
912
limit: number;
@@ -12,6 +15,15 @@ interface GetApplicationParameters {
1215
orderOn: string;
1316
organizationId?: number;
1417
permissionId?: number;
18+
status?: ApplicationStatus;
19+
statusCheck?: ApplicationStatusCheck;
20+
owner?: string;
21+
}
22+
23+
interface GetDevicesParameters {
24+
status?: ApplicationStatus;
25+
statusCheck?: ApplicationStatusCheck;
26+
owner?: string;
1527
}
1628

1729
@Injectable({
@@ -20,7 +32,11 @@ interface GetApplicationParameters {
2032
export class ApplicationService {
2133
public id: number;
2234
public canEdit = false;
23-
constructor(private restService: RestService, private userMinimalService: UserMinimalService) {}
35+
constructor(
36+
private restService: RestService,
37+
private userMinimalService: UserMinimalService,
38+
private filterService: ApplicationsFilterService
39+
) {}
2440

2541
createApplication(body: any): Observable<ApplicationData> {
2642
return this.restService.post("application", body, { observe: "response" });
@@ -41,6 +57,17 @@ export class ApplicationService {
4157
})
4258
);
4359
}
60+
getApplicationFilterOptions(id: number): Observable<string[]> {
61+
return this.restService.get(`application/${id}/filter-information`);
62+
}
63+
64+
getApplicationsWithError(id: number): Observable<{
65+
total: number;
66+
withError: number;
67+
totalDevices: number;
68+
}> {
69+
return this.restService.get(`application/${id}/application-dashboard-data`);
70+
}
4471

4572
getApplications(
4673
limit: number,
@@ -55,6 +82,9 @@ export class ApplicationService {
5582
offset,
5683
sort,
5784
orderOn,
85+
statusCheck: this.filterService.statusCheck === "All" ? null : this.filterService.statusCheck,
86+
status: this.filterService.status === "All" ? null : this.filterService.status,
87+
owner: this.filterService.owner === "All" ? null : this.filterService.owner,
5888
};
5989
if (permissionId) {
6090
body.permissionId = permissionId;
@@ -66,6 +96,16 @@ export class ApplicationService {
6696
return this.restService.get("application", body);
6797
}
6898

99+
getApplicationDevices(organizationId?: number): Observable<IotDevice[]> {
100+
const body: GetDevicesParameters = {
101+
statusCheck: this.filterService.statusCheck === "All" ? null : this.filterService.statusCheck,
102+
status: this.filterService.status === "All" ? null : this.filterService.status,
103+
owner: this.filterService.owner === "All" ? null : this.filterService.owner,
104+
};
105+
106+
return this.restService.get(`application/${organizationId}/iot-devices-org`, body);
107+
}
108+
69109
getApplicationsByOrganizationId(organizationId: number): Observable<ApplicationData> {
70110
const body = {
71111
organizationId,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<div class="filter-container">
2+
<div class="filter-selector-container">
3+
<div class="filter-title">{{ "APPLICATION-FILTER.STATUS" | translate }}</div>
4+
<mat-form-field appearance="outline">
5+
<mat-select class="withoutArrow" [(value)]="state" placeholder="test" (selectionChange)="onStatusCheck($event)">
6+
<mat-option *ngFor="let option of statusOptions" [value]="option.value">
7+
{{ option.label | translate }}
8+
</mat-option>
9+
</mat-select>
10+
</mat-form-field>
11+
</div>
12+
13+
<div class="filter-selector-container">
14+
<div class="filter-title">{{ "APPLICATION-FILTER.STATE" | translate }}</div>
15+
<mat-form-field appearance="outline">
16+
<mat-select class="withoutArrow" [(value)]="status" (selectionChange)="onStatus($event)">
17+
<mat-option *ngFor="let option of stateOptions" [value]="option.value">
18+
{{ option.label | translate }}
19+
</mat-option>
20+
</mat-select>
21+
</mat-form-field>
22+
</div>
23+
24+
<div class="filter-selector-container">
25+
<div class="filter-title">{{ "APPLICATION-FILTER.OWNER" | translate }}</div>
26+
<mat-form-field appearance="outline">
27+
<mat-select class="withoutArrow" [(value)]="owner" (selectionChange)="onOwner($event)">
28+
<mat-option [value]="owner">
29+
{{ "APPLICATION-FILTER.ALL" | translate }}
30+
</mat-option>
31+
<mat-option *ngFor="let option of ownerOptions" [value]="option.value">
32+
{{ option.label }}
33+
</mat-option>
34+
</mat-select>
35+
</mat-form-field>
36+
</div>
37+
38+
<div class="spacer"></div>
39+
<button class="filter-button" mat-flat-button (click)="onButtonClick()">
40+
<div class="filter-icon-container">
41+
<img ngSrc="../../../../assets/images/sliders.svg" width="18" height="16" priority />
42+
<div class="filter-label">
43+
{{ "APPLICATION-FILTER.RESET-FILTER" | translate }}
44+
</div>
45+
</div>
46+
</button>
47+
</div>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
@import "../../../../assets/scss/setup/variables";
2+
3+
.filter-container {
4+
display: flex;
5+
flex-direction: row;
6+
flex: 1;
7+
min-height: 65px;
8+
margin-bottom: 25px;
9+
flex-wrap: wrap;
10+
}
11+
12+
@media (max-width: 768px) {
13+
.filter-container {
14+
flex-direction: column;
15+
}
16+
}
17+
18+
.filter-selector-container {
19+
width: 200px;
20+
margin-right: 30px;
21+
display: flex;
22+
flex-direction: column;
23+
margin-bottom: 30px;
24+
}
25+
26+
.filter-title {
27+
font-size: 14px;
28+
}
29+
30+
.spacer {
31+
display: flex;
32+
flex: 1;
33+
}
34+
35+
.filter-button {
36+
margin-top: 26px;
37+
height: 40px !important;
38+
width: 170px !important;
39+
min-width: 170px !important;
40+
justify-content: center;
41+
display: flex !important;
42+
align-items: center;
43+
border: 1px solid $color-link !important;
44+
}
45+
46+
.filter-icon-container {
47+
display: flex !important;
48+
align-items: center;
49+
justify-content: center;
50+
gap: 10px;
51+
width: 150px;
52+
}
53+
54+
.filter-label {
55+
font-size: 16px;
56+
font-weight: 500;
57+
}
58+
59+
:host .mat-mdc-select {
60+
height: 24px;
61+
display: flex;
62+
align-items: center;
63+
font-size: 16px !important;
64+
color: $selector-font-color !important;
65+
}
66+
67+
:host .mat-mdc-form-field {
68+
height: 20px !important;
69+
display: flex;
70+
align-items: center;
71+
}
72+
73+
:host .mat-mdc-text-field-wrapper {
74+
background-color: $white !important;
75+
height: 40px !important;
76+
display: flex !important;
77+
align-items: center !important;
78+
font-size: 16px !important;
79+
}
80+
81+
:host .mat-mdc-select-arrow {
82+
display: none;
83+
}

0 commit comments

Comments
 (0)