Browse Source

UI: Audit logs.

pull/1954/head
Igor Kulikov 7 years ago
parent
commit
9d4b79c91c
  1. 2
      ui-ngx/package.json
  2. 9
      ui-ngx/src/app/core/auth/auth.service.ts
  3. 59
      ui-ngx/src/app/core/http/audit-log.service.ts
  4. 45
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.html
  5. 25
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.scss
  6. 124
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.ts
  7. 138
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts
  8. 18
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.html
  9. 22
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.scss
  10. 133
      ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.ts
  11. 4
      ui-ngx/src/app/modules/home/components/entity/entities-table.component.html
  12. 14
      ui-ngx/src/app/modules/home/components/entity/entity-tabs.component.ts
  13. 10
      ui-ngx/src/app/modules/home/components/home-components.module.ts
  14. 21
      ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html
  15. 38
      ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.ts
  16. 3
      ui-ngx/src/app/modules/home/pages/asset/asset.module.ts
  17. 2
      ui-ngx/src/app/modules/home/pages/asset/assets-table-config.resolver.ts
  18. 41
      ui-ngx/src/app/modules/home/pages/audit-log/audit-log-routing.module.ts
  19. 31
      ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts
  20. 21
      ui-ngx/src/app/modules/home/pages/customer/customer-tabs.component.html
  21. 38
      ui-ngx/src/app/modules/home/pages/customer/customer-tabs.component.ts
  22. 7
      ui-ngx/src/app/modules/home/pages/customer/customer.module.ts
  23. 2
      ui-ngx/src/app/modules/home/pages/customer/customers-table-config.resolver.ts
  24. 21
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-tabs.component.html
  25. 38
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard-tabs.component.ts
  26. 3
      ui-ngx/src/app/modules/home/pages/dashboard/dashboard.module.ts
  27. 2
      ui-ngx/src/app/modules/home/pages/dashboard/dashboards-table-config.resolver.ts
  28. 14
      ui-ngx/src/app/modules/home/pages/device/device-tabs.component.html
  29. 2
      ui-ngx/src/app/modules/home/pages/device/device-tabs.component.ts
  30. 21
      ui-ngx/src/app/modules/home/pages/entity-view/entity-view-tabs.component.html
  31. 38
      ui-ngx/src/app/modules/home/pages/entity-view/entity-view-tabs.component.ts
  32. 3
      ui-ngx/src/app/modules/home/pages/entity-view/entity-view.module.ts
  33. 2
      ui-ngx/src/app/modules/home/pages/entity-view/entity-views-table-config.resolver.ts
  34. 4
      ui-ngx/src/app/modules/home/pages/home-pages.module.ts
  35. 21
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain-tabs.component.html
  36. 39
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain-tabs.component.ts
  37. 7
      ui-ngx/src/app/modules/home/pages/rulechain/rulechain.module.ts
  38. 2
      ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts
  39. 4
      ui-ngx/src/app/shared/components/user-menu.component.ts
  40. 102
      ui-ngx/src/app/shared/models/audit-log.models.ts
  41. 24
      ui-ngx/src/app/shared/models/id/audit-log-id.ts
  42. 6
      ui-ngx/src/app/shared/shared.module.ts

2
ui-ngx/package.json

@ -3,7 +3,7 @@
"version": "3.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --host 0.0.0.0 --open",
"start": "ng serve --open",
"build": "ng build",
"build:prod": "ng build --prod --vendor-chunk",
"test": "ng test",

9
ui-ngx/src/app/core/auth/auth.service.ts

@ -165,7 +165,14 @@ export class AuthService {
if (captureLastUrl) {
this.redirectUrl = this.router.url;
}
this.clearJwtToken();
this.http.post('/api/auth/logout', null, defaultHttpOptions(true, true))
.subscribe(() => {
this.clearJwtToken();
},
() => {
this.clearJwtToken();
}
);
}
private notifyUserLoaded(isUserLoaded: boolean) {

59
ui-ngx/src/app/core/http/audit-log.service.ts

@ -0,0 +1,59 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Injectable } from '@angular/core';
import { defaultHttpOptions } from './http-utils';
import { Observable } from 'rxjs/index';
import { HttpClient } from '@angular/common/http';
import { PageLink, TimePageLink } from '@shared/models/page/page-link';
import { PageData } from '@shared/models/page/page-data';
import { AuditLog } from '@shared/models/audit-log.models';
import { EntityId } from '@shared/models/id/entity-id';
@Injectable({
providedIn: 'root'
})
export class AuditLogService {
constructor(
private http: HttpClient
) { }
public getAuditLogs(pageLink: TimePageLink,
ignoreErrors: boolean = false, ignoreLoading: boolean = false): Observable<PageData<AuditLog>> {
return this.http.get<PageData<AuditLog>>(`/api/audit/logs${pageLink.toQuery()}`,
defaultHttpOptions(ignoreLoading, ignoreErrors));
}
public getAuditLogsByCustomerId(customerId: string, pageLink: TimePageLink,
ignoreErrors: boolean = false, ignoreLoading: boolean = false): Observable<PageData<AuditLog>> {
return this.http.get<PageData<AuditLog>>(`/api/audit/logs/customer/${customerId}${pageLink.toQuery()}`,
defaultHttpOptions(ignoreLoading, ignoreErrors));
}
public getAuditLogsByUserId(userId: string, pageLink: TimePageLink,
ignoreErrors: boolean = false, ignoreLoading: boolean = false): Observable<PageData<AuditLog>> {
return this.http.get<PageData<AuditLog>>(`/api/audit/logs/user/${userId}${pageLink.toQuery()}`,
defaultHttpOptions(ignoreLoading, ignoreErrors));
}
public getAuditLogsByEntityId(entityId: EntityId, pageLink: TimePageLink,
ignoreErrors: boolean = false, ignoreLoading: boolean = false): Observable<PageData<AuditLog>> {
return this.http.get<PageData<AuditLog>>(`/api/audit/logs/entity/${entityId.entityType}/${entityId.id}${pageLink.toQuery()}`,
defaultHttpOptions(ignoreLoading, ignoreErrors));
}
}

45
ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.html

@ -0,0 +1,45 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-toolbar fxLayout="row" color="primary">
<h2 translate>audit-log.audit-log-details</h2>
<span fxFlex></span>
<button mat-button mat-icon-button
[mat-dialog-close]="false"
type="button">
<mat-icon class="material-icons">close</mat-icon>
</button>
</mat-toolbar>
<div mat-dialog-content fxLayout="column">
<label translate class="tb-title no-padding">audit-log.action-data</label>
<div #actionDataEditor class="tb-audit-log-action-data">
</div>
<span style="min-height: 30px;"></span>
<label [fxShow]="displayFailureDetails" translate class="tb-title no-padding">audit-log.failure-details</label>
<div #failureDetailsEditor [fxShow]="displayFailureDetails" class="tb-audit-log-failure-details">
</div>
</div>
<div mat-dialog-actions fxLayout="row">
<span fxFlex></span>
<button mat-button color="primary"
style="margin-right: 20px;"
type="button"
[disabled]="(isLoading$ | async)"
[mat-dialog-close]="false" cdkFocusInitial>
{{ 'action.close' | translate }}
</button>
</div>

25
ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.scss

@ -0,0 +1,25 @@
/**
* Copyright © 2016-2019 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
:host {
.tb-audit-log-action-data,
.tb-audit-log-failure-details {
width: 100%;
min-width: 400px;
height: 100%;
min-height: 50px;
border: 1px solid #c0c0c0;
}
}

124
ui-ngx/src/app/modules/home/components/audit-log/audit-log-details-dialog.component.ts

@ -0,0 +1,124 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import {
Component,
ElementRef,
Inject,
OnInit,
Renderer2,
ViewChild
} from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { TbAnchorComponent } from '@shared/components/tb-anchor.component';
import { ActionStatus, AuditLog } from '@shared/models/audit-log.models';
import * as ace from 'ace-builds';
export interface AuditLogDetailsDialogData {
auditLog: AuditLog;
}
@Component({
selector: 'tb-audit-log-details-dialog',
templateUrl: './audit-log-details-dialog.component.html',
styleUrls: ['./audit-log-details-dialog.component.scss']
})
export class AuditLogDetailsDialogComponent extends PageComponent implements OnInit {
@ViewChild('actionDataEditor', {static: true})
actionDataEditorElmRef: ElementRef;
private actionDataEditor: ace.Ace.Editor;
@ViewChild('failureDetailsEditor', {static: true})
failureDetailsEditorElmRef: ElementRef;
private failureDetailsEditor: ace.Ace.Editor;
auditLog: AuditLog;
displayFailureDetails: boolean;
actionData: string;
actionFailureDetails: string;
@ViewChild('entityDetailsForm', {static: true}) entityDetailsFormAnchor: TbAnchorComponent;
constructor(protected store: Store<AppState>,
@Inject(MAT_DIALOG_DATA) public data: AuditLogDetailsDialogData,
public dialogRef: MatDialogRef<AuditLogDetailsDialogComponent>,
private renderer: Renderer2) {
super(store);
}
ngOnInit(): void {
this.auditLog = this.data.auditLog;
this.displayFailureDetails = this.auditLog.actionStatus === ActionStatus.FAILURE;
this.actionData = this.auditLog.actionData ? JSON.stringify(this.auditLog.actionData, null, 2) : '';
this.actionFailureDetails = this.auditLog.actionFailureDetails;
this.actionDataEditor = this.createEditor(this.actionDataEditorElmRef, this.actionData);
if (this.displayFailureDetails) {
this.failureDetailsEditor = this.createEditor(this.failureDetailsEditorElmRef, this.actionFailureDetails);
}
}
createEditor(editorElementRef: ElementRef, content: string): ace.Ace.Editor {
const editorElement = editorElementRef.nativeElement;
let editorOptions: Partial<ace.Ace.EditorOptions> = {
mode: 'ace/mode/java',
theme: 'ace/theme/github',
showGutter: false,
showPrintMargin: false,
readOnly: true
};
const advancedOptions = {
enableSnippets: false,
enableBasicAutocompletion: false,
enableLiveAutocompletion: false
};
editorOptions = {...editorOptions, ...advancedOptions};
const editor = ace.edit(editorElement, editorOptions);
editor.session.setUseWrapMode(false);
editor.setValue(content, -1);
this.updateEditorSize(editorElement, content, editor);
return editor;
}
updateEditorSize(editorElement: any, content: string, editor: ace.Ace.Editor) {
let newHeight = 200;
let newWidth = 600;
if (content && content.length > 0) {
const lines = content.split('\n');
newHeight = 16 * lines.length + 16;
let maxLineLength = 0;
lines.forEach((row) => {
const line = row.replace(/\t/g, ' ').replace(/\n/g, '');
const lineLength = line.length;
maxLineLength = Math.max(maxLineLength, lineLength);
});
newWidth = 8 * maxLineLength + 16;
}
newHeight = Math.min(400, newHeight);
this.renderer.setStyle(editorElement, 'minHeight', newHeight.toString() + 'px');
this.renderer.setStyle(editorElement, 'height', newHeight.toString() + 'px');
this.renderer.setStyle(editorElement, 'width', newWidth.toString() + 'px');
editor.resize();
}
}

138
ui-ngx/src/app/modules/home/components/audit-log/audit-log-table-config.ts

@ -0,0 +1,138 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import {
DateEntityTableColumn,
EntityTableColumn,
EntityTableConfig
} from '@home/models/entity/entities-table-config.models';
import {
actionStatusTranslations,
actionTypeTranslations,
AuditLog,
AuditLogMode
} from '@shared/models/audit-log.models';
import {
EntityTypeResource,
EntityTypeTranslation,
entityTypeTranslations
} from '@shared/models/entity-type.models';
import { AuditLogService } from '@core/http/audit-log.service';
import { TranslateService } from '@ngx-translate/core';
import { DatePipe } from '@angular/common';
import { Direction } from '@shared/models/page/sort-order';
import { MatDialog } from '@angular/material';
import { PageLink, TimePageLink } from '@shared/models/page/page-link';
import { Observable } from 'rxjs';
import { PageData } from '@shared/models/page/page-data';
import { EntityId } from '@shared/models/id/entity-id';
import { UserId } from '@shared/models/id/user-id';
import { CustomerId } from '@shared/models/id/customer-id';
import {
AuditLogDetailsDialogComponent,
AuditLogDetailsDialogData
} from '@home/components/audit-log/audit-log-details-dialog.component';
export class AuditLogTableConfig extends EntityTableConfig<AuditLog, TimePageLink> {
constructor(private auditLogService: AuditLogService,
private translate: TranslateService,
private datePipe: DatePipe,
private dialog: MatDialog,
private auditLogMode: AuditLogMode = AuditLogMode.TENANT,
public entityId: EntityId = null,
public userId: UserId = null,
public customerId: CustomerId = null,
updateOnInit = true) {
super();
this.loadDataOnInit = updateOnInit;
this.tableTitle = '';
this.useTimePageLink = true;
this.detailsPanelEnabled = false;
this.selectionEnabled = false;
this.searchEnabled = true;
this.addEnabled = false;
this.entitiesDeleteEnabled = false;
this.actionsColumnTitle = 'audit-log.details';
this.entityTranslations = {
noEntities: 'audit-log.no-audit-logs-prompt',
search: 'audit-log.search'
};
this.entityResources = {
} as EntityTypeResource;
this.entitiesFetchFunction = pageLink => this.fetchAuditLogs(pageLink);
this.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
this.columns.push(
new DateEntityTableColumn<AuditLog>('createdTime', 'audit-log.timestamp', this.datePipe, '150px'));
if (this.auditLogMode !== AuditLogMode.ENTITY) {
this.columns.push(
new EntityTableColumn<AuditLog>('entityType', 'audit-log.entity-type', '100%',
(entity) => translate.instant(entityTypeTranslations.get(entity.entityId.entityType).type)),
new EntityTableColumn<AuditLog>('entityName', 'audit-log.entity-name'),
);
}
if (this.auditLogMode !== AuditLogMode.USER) {
this.columns.push(
new EntityTableColumn<AuditLog>('userName', 'audit-log.user')
);
}
this.columns.push(
new EntityTableColumn<AuditLog>('actionType', 'audit-log.type', '100%',
(entity) => translate.instant(actionTypeTranslations.get(entity.actionType))),
new EntityTableColumn<AuditLog>('actionStatus', 'audit-log.status', '100%',
(entity) => translate.instant(actionStatusTranslations.get(entity.actionStatus)))
);
this.cellActionDescriptors.push(
{
name: this.translate.instant('audit-log.details'),
icon: 'more_horiz',
isEnabled: () => true,
onAction: ($event, entity) => this.showAuditLogDetails(entity)
}
);
}
fetchAuditLogs(pageLink: TimePageLink): Observable<PageData<AuditLog>> {
switch (this.auditLogMode) {
case AuditLogMode.TENANT:
return this.auditLogService.getAuditLogs(pageLink);
case AuditLogMode.ENTITY:
return this.auditLogService.getAuditLogsByEntityId(this.entityId, pageLink);
case AuditLogMode.USER:
return this.auditLogService.getAuditLogsByUserId(this.userId.id, pageLink);
case AuditLogMode.CUSTOMER:
return this.auditLogService.getAuditLogsByCustomerId(this.customerId.id, pageLink);
}
}
showAuditLogDetails(entity: AuditLog) {
this.dialog.open<AuditLogDetailsDialogComponent, AuditLogDetailsDialogData>(AuditLogDetailsDialogComponent, {
disableClose: true,
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
data: {
auditLog: entity
}
});
}
}

18
ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.html

@ -0,0 +1,18 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<tb-entities-table [entitiesTableConfig]="auditLogTableConfig" [ngClass]="{'tb-details-mode': detailsMode}"></tb-entities-table>

22
ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.scss

@ -0,0 +1,22 @@
/**
* Copyright © 2016-2019 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
:host ::ng-deep {
tb-entities-table.tb-details-mode {
.mat-drawer-container {
background-color: white;
}
}
}

133
ui-ngx/src/app/modules/home/components/audit-log/audit-log-table.component.ts

@ -0,0 +1,133 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { AuditLogService } from '@core/http/audit-log.service';
import { TranslateService } from '@ngx-translate/core';
import { DatePipe } from '@angular/common';
import { MatDialog } from '@angular/material';
import { AuditLogMode } from '@shared/models/audit-log.models';
import { EntityId } from '@shared/models/id/entity-id';
import { UserId } from '@shared/models/id/user-id';
import { CustomerId } from '@shared/models/id/customer-id';
import { AuditLogTableConfig } from '@home/components/audit-log/audit-log-table-config';
import { EntitiesTableComponent } from '@home/components/entity/entities-table.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { Authority } from '@shared/models/authority.enum';
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
@Component({
selector: 'tb-audit-log-table',
templateUrl: './audit-log-table.component.html',
styleUrls: ['./audit-log-table.component.scss']
})
export class AuditLogTableComponent implements OnInit {
@Input()
auditLogMode: AuditLogMode;
@Input()
detailsMode: boolean;
activeValue = false;
dirtyValue = false;
entityIdValue: EntityId;
userIdValue: UserId;
customerIdValue: CustomerId;
@Input()
set active(active: boolean) {
if (this.activeValue !== active) {
this.activeValue = active;
if (this.activeValue && this.dirtyValue) {
this.dirtyValue = false;
this.entitiesTable.updateData();
}
}
}
@Input()
set entityId(entityId: EntityId) {
this.entityIdValue = entityId;
if (this.auditLogTableConfig && this.auditLogTableConfig.entityId !== entityId) {
this.auditLogTableConfig.entityId = entityId;
this.entitiesTable.resetSortAndFilter(this.activeValue);
if (!this.activeValue) {
this.dirtyValue = true;
}
}
}
@Input()
set userId(userId: UserId) {
this.userIdValue = userId;
if (this.auditLogTableConfig && this.auditLogTableConfig.userId !== userId) {
this.auditLogTableConfig.userId = userId;
this.entitiesTable.resetSortAndFilter(this.activeValue);
if (!this.activeValue) {
this.dirtyValue = true;
}
}
}
@Input()
set customerId(customerId: CustomerId) {
this.customerIdValue = customerId;
if (this.auditLogTableConfig && this.auditLogTableConfig.customerId !== customerId) {
this.auditLogTableConfig.customerId = customerId;
this.entitiesTable.resetSortAndFilter(this.activeValue);
if (!this.activeValue) {
this.dirtyValue = true;
}
}
}
@ViewChild(EntitiesTableComponent, {static: true}) entitiesTable: EntitiesTableComponent;
auditLogTableConfig: AuditLogTableConfig;
constructor(private auditLogService: AuditLogService,
private translate: TranslateService,
private datePipe: DatePipe,
private dialog: MatDialog,
private store: Store<AppState>) {
}
ngOnInit() {
let updateOnInit = this.activeValue;
this.dirtyValue = !this.activeValue;
if (!this.auditLogMode) {
const authUser = getCurrentAuthUser(this.store);
if (authUser.authority === Authority.TENANT_ADMIN) {
this.auditLogMode = AuditLogMode.TENANT;
}
updateOnInit = true;
}
this.auditLogTableConfig = new AuditLogTableConfig(
this.auditLogService,
this.translate,
this.datePipe,
this.dialog,
this.auditLogMode,
this.entityIdValue,
this.userIdValue,
this.customerIdValue,
updateOnInit
);
}
}

4
ui-ngx/src/app/modules/home/components/entity/entities-table.component.html

@ -158,10 +158,10 @@
[ngStyle]="cellStyle(entity, column, row, col)"></mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (cellActionDescriptors.length * 40) + 'px' }">
<mat-header-cell *matHeaderCellDef [ngStyle.gt-md]="{ minWidth: (cellActionDescriptors.length * 40) + 'px', maxWidth: (cellActionDescriptors.length * 40) + 'px' }">
{{ entitiesTableConfig.actionsColumnTitle ? (entitiesTableConfig.actionsColumnTitle | translate) : '' }}
</mat-header-cell>
<mat-cell *matCellDef="let entity" [ngStyle.gt-md]="{ minWidth: (cellActionDescriptors.length * 40) + 'px' }">
<mat-cell *matCellDef="let entity" [ngStyle.gt-md]="{ minWidth: (cellActionDescriptors.length * 40) + 'px', maxWidth: (cellActionDescriptors.length * 40) + 'px' }">
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<button mat-button mat-icon-button [disabled]="isLoading$ | async"
[fxShow]="actionDescriptor.isEnabled(entity)" *ngFor="let actionDescriptor of cellActionDescriptors"

14
ui-ngx/src/app/modules/home/components/entity/entity-tabs.component.ts

@ -32,9 +32,22 @@ import { EntityTableConfig } from '@home/models/entity/entities-table-config.mod
import { MatTab } from '@angular/material';
import { EntityAction } from '@home/models/entity/entity-component.models';
import { BehaviorSubject } from 'rxjs';
import { Authority } from '@app/shared/models/authority.enum';
import { selectAuthUser, getCurrentAuthUser } from '@core/auth/auth.selectors';
import { AuthUser } from '@shared/models/user.model';
import { EntityType } from '@shared/models/entity-type.models';
import { AuditLogMode } from '@shared/models/audit-log.models';
export abstract class EntityTabsComponent<T extends BaseData<HasId>> extends PageComponent implements OnInit, AfterViewInit {
authorities = Authority;
entityTypes = EntityType;
auditLogModes = AuditLogMode;
authUser: AuthUser;
entityValue: T;
@ViewChildren(MatTab) entityTabs: QueryList<MatTab>;
@ -68,6 +81,7 @@ export abstract class EntityTabsComponent<T extends BaseData<HasId>> extends Pag
protected constructor(protected store: Store<AppState>) {
super(store);
this.authUser = getCurrentAuthUser(store);
}
ngOnInit() {

10
ui-ngx/src/app/modules/home/components/home-components.module.ts

@ -22,10 +22,13 @@ import {EntitiesTableComponent} from './entity/entities-table.component';
import {DetailsPanelComponent} from './details-panel.component';
import {EntityDetailsPanelComponent} from './entity/entity-details-panel.component';
import {ContactComponent} from './contact.component';
import { AuditLogDetailsDialogComponent } from './audit-log/audit-log-details-dialog.component';
import { AuditLogTableComponent } from './audit-log/audit-log-table.component';
@NgModule({
entryComponents: [
AddEntityDialogComponent
AddEntityDialogComponent,
AuditLogDetailsDialogComponent
],
declarations:
[
@ -34,6 +37,8 @@ import {ContactComponent} from './contact.component';
DetailsPanelComponent,
EntityDetailsPanelComponent,
ContactComponent,
AuditLogTableComponent,
AuditLogDetailsDialogComponent
],
imports: [
CommonModule,
@ -44,7 +49,8 @@ import {ContactComponent} from './contact.component';
AddEntityDialogComponent,
DetailsPanelComponent,
EntityDetailsPanelComponent,
ContactComponent
ContactComponent,
AuditLogTableComponent
]
})
export class HomeComponentsModule { }

21
ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html

@ -0,0 +1,21 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

38
ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.ts

@ -0,0 +1,38 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { AssetInfo } from '@app/shared/models/asset.models';
@Component({
selector: 'tb-asset-tabs',
templateUrl: './asset-tabs.component.html',
styleUrls: []
})
export class AssetTabsComponent extends EntityTabsComponent<AssetInfo> {
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit() {
super.ngOnInit();
}
}

3
ui-ngx/src/app/modules/home/pages/asset/asset.module.ts

@ -22,14 +22,17 @@ import {AssetComponent} from './asset.component';
import {AssetTableHeaderComponent} from './asset-table-header.component';
import {AssetRoutingModule} from './asset-routing.module';
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
import { AssetTabsComponent } from '@home/pages/asset/asset-tabs.component';
@NgModule({
entryComponents: [
AssetComponent,
AssetTabsComponent,
AssetTableHeaderComponent
],
declarations: [
AssetComponent,
AssetTabsComponent,
AssetTableHeaderComponent
],
imports: [

2
ui-ngx/src/app/modules/home/pages/asset/assets-table-config.resolver.ts

@ -55,6 +55,7 @@ import {AssetService} from '@app/core/http/asset.service';
import {AssetComponent} from '@modules/home/pages/asset/asset.component';
import {AssetTableHeaderComponent} from '@modules/home/pages/asset/asset-table-header.component';
import {AssetId} from '@app/shared/models/id/asset-id';
import { AssetTabsComponent } from '@home/pages/asset/asset-tabs.component';
@Injectable()
export class AssetsTableConfigResolver implements Resolve<EntityTableConfig<AssetInfo>> {
@ -75,6 +76,7 @@ export class AssetsTableConfigResolver implements Resolve<EntityTableConfig<Asse
this.config.entityType = EntityType.ASSET;
this.config.entityComponent = AssetComponent;
this.config.entityTabsComponent = AssetTabsComponent;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.ASSET);
this.config.entityResources = entityTypeResources.get(EntityType.ASSET);

41
ui-ngx/src/app/modules/home/pages/audit-log/audit-log-routing.module.ts

@ -0,0 +1,41 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { Authority } from '@shared/models/authority.enum';
import { AuditLogTableComponent } from '@home/components/audit-log/audit-log-table.component';
const routes: Routes = [
{
path: 'auditLogs',
component: AuditLogTableComponent,
data: {
auth: [Authority.TENANT_ADMIN],
title: 'audit-log.audit-logs',
breadcrumb: {
label: 'audit-log.audit-logs',
icon: 'track_changes'
}
}
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AuditLogRoutingModule { }

31
ui-ngx/src/app/modules/home/pages/audit-log/audit-log.module.ts

@ -0,0 +1,31 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';
import { AuditLogRoutingModule } from '@modules/home/pages/audit-log/audit-log-routing.module';
@NgModule({
declarations: [
],
imports: [
CommonModule,
SharedModule,
AuditLogRoutingModule
]
})
export class AuditLogModule { }

21
ui-ngx/src/app/modules/home/pages/customer/customer-tabs.component.html

@ -0,0 +1,21 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.CUSTOMER" [customerId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

38
ui-ngx/src/app/modules/home/pages/customer/customer-tabs.component.ts

@ -0,0 +1,38 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { Customer } from '@shared/models/customer.model';
@Component({
selector: 'tb-customer-tabs',
templateUrl: './customer-tabs.component.html',
styleUrls: []
})
export class CustomerTabsComponent extends EntityTabsComponent<Customer> {
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit() {
super.ngOnInit();
}
}

7
ui-ngx/src/app/modules/home/pages/customer/customer.module.ts

@ -20,13 +20,16 @@ import { SharedModule } from '@shared/shared.module';
import {CustomerComponent} from '@modules/home/pages/customer/customer.component';
import {CustomerRoutingModule} from './customer-routing.module';
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
import { CustomerTabsComponent } from '@home/pages/customer/customer-tabs.component';
@NgModule({
entryComponents: [
CustomerComponent
CustomerComponent,
CustomerTabsComponent
],
declarations: [
CustomerComponent
CustomerComponent,
CustomerTabsComponent
],
imports: [
CommonModule,

2
ui-ngx/src/app/modules/home/pages/customer/customers-table-config.resolver.ts

@ -35,6 +35,7 @@ import { EntityAction } from '@home/models/entity/entity-component.models';
import {Customer} from '@app/shared/models/customer.model';
import {CustomerService} from '@app/core/http/customer.service';
import {CustomerComponent} from '@modules/home/pages/customer/customer.component';
import { CustomerTabsComponent } from '@home/pages/customer/customer-tabs.component';
@Injectable()
export class CustomersTableConfigResolver implements Resolve<EntityTableConfig<Customer>> {
@ -48,6 +49,7 @@ export class CustomersTableConfigResolver implements Resolve<EntityTableConfig<C
this.config.entityType = EntityType.CUSTOMER;
this.config.entityComponent = CustomerComponent;
this.config.entityTabsComponent = CustomerTabsComponent;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.CUSTOMER);
this.config.entityResources = entityTypeResources.get(EntityType.CUSTOMER);

21
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-tabs.component.html

@ -0,0 +1,21 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

38
ui-ngx/src/app/modules/home/pages/dashboard/dashboard-tabs.component.ts

@ -0,0 +1,38 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { Dashboard } from '@shared/models/dashboard.models';
@Component({
selector: 'tb-dashboard-tabs',
templateUrl: './dashboard-tabs.component.html',
styleUrls: []
})
export class DashboardTabsComponent extends EntityTabsComponent<Dashboard> {
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit() {
super.ngOnInit();
}
}

3
ui-ngx/src/app/modules/home/pages/dashboard/dashboard.module.ts

@ -23,15 +23,18 @@ import {ManageDashboardCustomersDialogComponent} from '@modules/home/pages/dashb
import {DashboardRoutingModule} from './dashboard-routing.module';
import {MakeDashboardPublicDialogComponent} from '@modules/home/pages/dashboard/make-dashboard-public-dialog.component';
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
import { DashboardTabsComponent } from '@home/pages/dashboard/dashboard-tabs.component';
@NgModule({
entryComponents: [
DashboardFormComponent,
DashboardTabsComponent,
ManageDashboardCustomersDialogComponent,
MakeDashboardPublicDialogComponent
],
declarations: [
DashboardFormComponent,
DashboardTabsComponent,
ManageDashboardCustomersDialogComponent,
MakeDashboardPublicDialogComponent
],

2
ui-ngx/src/app/modules/home/pages/dashboard/dashboards-table-config.resolver.ts

@ -62,6 +62,7 @@ import {
MakeDashboardPublicDialogComponent,
MakeDashboardPublicDialogData
} from '@modules/home/pages/dashboard/make-dashboard-public-dialog.component';
import { DashboardTabsComponent } from '@home/pages/dashboard/dashboard-tabs.component';
@Injectable()
export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig<DashboardInfo | Dashboard>> {
@ -79,6 +80,7 @@ export class DashboardsTableConfigResolver implements Resolve<EntityTableConfig<
this.config.entityType = EntityType.DASHBOARD;
this.config.entityComponent = DashboardFormComponent;
this.config.entityTabsComponent = DashboardTabsComponent;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.DASHBOARD);
this.config.entityResources = entityTypeResources.get(EntityType.DASHBOARD);

14
ui-ngx/src/app/modules/home/pages/device/device-tabs.component.html

@ -15,15 +15,7 @@
limitations under the License.
-->
<mat-tab label="{{entity?.name}}">
Hobotok<br/>
{{ entity | json }}
</mat-tab>
<mat-tab *ngIf="entity?.additionalInfo?.gateway" label="Gateway">
Hobotok 2<br/>
{{ entity | json }}
</mat-tab>
<mat-tab label="{{ 'extension.extensions' | translate }}">
Hobotok 2<br/>
{{ entity | json }}
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

2
ui-ngx/src/app/modules/home/pages/device/device-tabs.component.ts

@ -28,8 +28,6 @@ import { EntityTabsComponent } from '../../components/entity/entity-tabs.compone
})
export class DeviceTabsComponent extends EntityTabsComponent<DeviceInfo> {
entityType = EntityType;
constructor(protected store: Store<AppState>) {
super(store);
}

21
ui-ngx/src/app/modules/home/pages/entity-view/entity-view-tabs.component.html

@ -0,0 +1,21 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

38
ui-ngx/src/app/modules/home/pages/entity-view/entity-view-tabs.component.ts

@ -0,0 +1,38 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { EntityViewInfo } from '@app/shared/models/entity-view.models';
@Component({
selector: 'tb-entity-view-tabs',
templateUrl: './entity-view-tabs.component.html',
styleUrls: []
})
export class EntityViewTabsComponent extends EntityTabsComponent<EntityViewInfo> {
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit() {
super.ngOnInit();
}
}

3
ui-ngx/src/app/modules/home/pages/entity-view/entity-view.module.ts

@ -22,14 +22,17 @@ import {EntityViewComponent} from '@modules/home/pages/entity-view/entity-view.c
import {EntityViewTableHeaderComponent} from './entity-view-table-header.component';
import {EntityViewRoutingModule} from './entity-view-routing.module';
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
import { EntityViewTabsComponent } from '@home/pages/entity-view/entity-view-tabs.component';
@NgModule({
entryComponents: [
EntityViewComponent,
EntityViewTabsComponent,
EntityViewTableHeaderComponent
],
declarations: [
EntityViewComponent,
EntityViewTabsComponent,
EntityViewTableHeaderComponent
],
imports: [

2
ui-ngx/src/app/modules/home/pages/entity-view/entity-views-table-config.resolver.ts

@ -55,6 +55,7 @@ import {EntityViewService} from '@core/http/entity-view.service';
import {EntityViewComponent} from '@modules/home/pages/entity-view/entity-view.component';
import {EntityViewTableHeaderComponent} from '@modules/home/pages/entity-view/entity-view-table-header.component';
import {EntityViewId} from '@shared/models/id/entity-view-id';
import { EntityViewTabsComponent } from '@home/pages/entity-view/entity-view-tabs.component';
@Injectable()
export class EntityViewsTableConfigResolver implements Resolve<EntityTableConfig<EntityViewInfo>> {
@ -75,6 +76,7 @@ export class EntityViewsTableConfigResolver implements Resolve<EntityTableConfig
this.config.entityType = EntityType.ENTITY_VIEW;
this.config.entityComponent = EntityViewComponent;
this.config.entityTabsComponent = EntityViewTabsComponent;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.ENTITY_VIEW);
this.config.entityResources = entityTypeResources.get(EntityType.ENTITY_VIEW);

4
ui-ngx/src/app/modules/home/pages/home-pages.module.ts

@ -21,7 +21,7 @@ import { HomeLinksModule } from './home-links/home-links.module';
import { ProfileModule } from './profile/profile.module';
import { TenantModule } from '@modules/home/pages/tenant/tenant.module';
import { CustomerModule } from '@modules/home/pages/customer/customer.module';
// import { AuditLogModule } from '@modules/home/pages/audit-log/audit-log.module';
import { AuditLogModule } from '@modules/home/pages/audit-log/audit-log.module';
import { UserModule } from '@modules/home/pages/user/user.module';
import {DeviceModule} from '@modules/home/pages/device/device.module';
import {AssetModule} from '@modules/home/pages/asset/asset.module';
@ -43,7 +43,7 @@ import {DashboardModule} from '@modules/home/pages/dashboard/dashboard.module';
RuleChainModule,
WidgetLibraryModule,
DashboardModule,
// AuditLogModule,
AuditLogModule,
UserModule
]
})

21
ui-ngx/src/app/modules/home/pages/rulechain/rulechain-tabs.component.html

@ -0,0 +1,21 @@
<!--
Copyright © 2016-2019 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<mat-tab *ngIf="entity && authUser.authority === authorities.TENANT_ADMIN"
label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab">
<tb-audit-log-table [active]="auditLogsTab.isActive" [auditLogMode]="auditLogModes.ENTITY" [entityId]="entity.id" detailsMode="true"></tb-audit-log-table>
</mat-tab>

39
ui-ngx/src/app/modules/home/pages/rulechain/rulechain-tabs.component.ts

@ -0,0 +1,39 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { EntityTabsComponent } from '../../components/entity/entity-tabs.component';
import { AssetInfo } from '@app/shared/models/asset.models';
import { RuleChain } from '@shared/models/rule-chain.models';
@Component({
selector: 'tb-rulechain-tabs',
templateUrl: './rulechain-tabs.component.html',
styleUrls: []
})
export class RuleChainTabsComponent extends EntityTabsComponent<RuleChain> {
constructor(protected store: Store<AppState>) {
super(store);
}
ngOnInit() {
super.ngOnInit();
}
}

7
ui-ngx/src/app/modules/home/pages/rulechain/rulechain.module.ts

@ -20,13 +20,16 @@ import {SharedModule} from '@shared/shared.module';
import {RuleChainComponent} from '@modules/home/pages/rulechain/rulechain.component';
import {RuleChainRoutingModule} from '@modules/home/pages/rulechain/rulechain-routing.module';
import {HomeComponentsModule} from '@modules/home/components/home-components.module';
import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component';
@NgModule({
entryComponents: [
RuleChainComponent
RuleChainComponent,
RuleChainTabsComponent
],
declarations: [
RuleChainComponent
RuleChainComponent,
RuleChainTabsComponent
],
imports: [
CommonModule,

2
ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts

@ -31,6 +31,7 @@ import {RuleChain} from '@shared/models/rule-chain.models';
import {RuleChainService} from '@core/http/rule-chain.service';
import {RuleChainComponent} from '@modules/home/pages/rulechain/rulechain.component';
import {DialogService} from '@core/services/dialog.service';
import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component';
@Injectable()
export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<RuleChain>> {
@ -45,6 +46,7 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
this.config.entityType = EntityType.RULE_CHAIN;
this.config.entityComponent = RuleChainComponent;
this.config.entityTabsComponent = RuleChainTabsComponent;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.RULE_CHAIN);
this.config.entityResources = entityTypeResources.get(EntityType.RULE_CHAIN);

4
ui-ngx/src/app/shared/components/user-menu.component.ts

@ -105,10 +105,6 @@ export class UserMenuComponent implements OnInit, OnDestroy {
this.router.navigate(['profile']);
}
openCustomerProfile(): void {
this.router.navigate(['customerProfile']);
}
logout(): void {
this.authService.logout();
}

102
ui-ngx/src/app/shared/models/audit-log.models.ts

@ -0,0 +1,102 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { BaseData } from './base-data';
import { AuditLogId } from './id/audit-log-id';
import { CustomerId } from './id/customer-id';
import { EntityId } from './id/entity-id';
import { UserId } from './id/user-id';
import { TenantId } from './id/tenant-id';
export enum AuditLogMode {
TENANT,
ENTITY,
USER,
CUSTOMER
}
export enum ActionType {
ADDED = 'ADDED',
DELETED = 'DELETED',
UPDATED = 'UPDATED',
ATTRIBUTES_UPDATED = 'ATTRIBUTES_UPDATED',
ATTRIBUTES_DELETED = 'ATTRIBUTES_DELETED',
RPC_CALL = 'RPC_CALL',
CREDENTIALS_UPDATED = 'CREDENTIALS_UPDATED',
ASSIGNED_TO_CUSTOMER = 'ASSIGNED_TO_CUSTOMER',
UNASSIGNED_FROM_CUSTOMER = 'UNASSIGNED_FROM_CUSTOMER',
ACTIVATED = 'ACTIVATED',
SUSPENDED = 'SUSPENDED',
CREDENTIALS_READ = 'CREDENTIALS_READ',
ATTRIBUTES_READ = 'ATTRIBUTES_READ',
RELATION_ADD_OR_UPDATE = 'RELATION_ADD_OR_UPDATE',
RELATION_DELETED = 'RELATION_DELETED',
RELATIONS_DELETED = 'RELATIONS_DELETED',
ALARM_ACK = 'ALARM_ACK',
ALARM_CLEAR = 'ALARM_CLEAR',
LOGIN = 'LOGIN',
LOGOUT = 'LOGOUT'
}
export enum ActionStatus {
SUCCESS = 'SUCCESS',
FAILURE = 'FAILURE'
}
export const actionTypeTranslations = new Map<ActionType, string>(
[
[ActionType.ADDED, 'audit-log.type-added'],
[ActionType.DELETED, 'audit-log.type-deleted'],
[ActionType.UPDATED, 'audit-log.type-updated'],
[ActionType.ATTRIBUTES_UPDATED, 'audit-log.type-attributes-updated'],
[ActionType.ATTRIBUTES_DELETED, 'audit-log.type-attributes-deleted'],
[ActionType.RPC_CALL, 'audit-log.type-rpc-call'],
[ActionType.CREDENTIALS_UPDATED, 'audit-log.type-credentials-updated'],
[ActionType.ASSIGNED_TO_CUSTOMER, 'audit-log.type-assigned-to-customer'],
[ActionType.UNASSIGNED_FROM_CUSTOMER, 'audit-log.type-unassigned-from-customer'],
[ActionType.ACTIVATED, 'audit-log.type-activated'],
[ActionType.SUSPENDED, 'audit-log.type-suspended'],
[ActionType.CREDENTIALS_READ, 'audit-log.type-credentials-read'],
[ActionType.ATTRIBUTES_READ, 'audit-log.type-attributes-read'],
[ActionType.RELATION_ADD_OR_UPDATE, 'audit-log.type-relation-add-or-update'],
[ActionType.RELATION_DELETED, 'audit-log.type-relation-delete'],
[ActionType.RELATIONS_DELETED, 'audit-log.type-relations-delete'],
[ActionType.ALARM_ACK, 'audit-log.type-alarm-ack'],
[ActionType.ALARM_CLEAR, 'audit-log.type-alarm-clear'],
[ActionType.LOGIN, 'audit-log.type-login'],
[ActionType.LOGOUT, 'audit-log.type-logout']
]
);
export const actionStatusTranslations = new Map<ActionStatus, string>(
[
[ActionStatus.SUCCESS, 'audit-log.status-success'],
[ActionStatus.FAILURE, 'audit-log.status-failure'],
]
);
export interface AuditLog extends BaseData<AuditLogId> {
tenantId: TenantId;
customerId: CustomerId;
entityId: EntityId;
entityName: string;
userId: UserId;
userName: string;
actionType: ActionType;
actionData: any;
actionStatus: ActionStatus;
actionFailureDetails: string;
}

24
ui-ngx/src/app/shared/models/id/audit-log-id.ts

@ -0,0 +1,24 @@
///
/// Copyright © 2016-2019 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { HasUUID } from '@shared/models/id/has-uuid';
export class AuditLogId implements HasUUID {
id: string;
constructor(id: string) {
this.id = id;
}
}

6
ui-ngx/src/app/shared/shared.module.ts

@ -62,8 +62,6 @@ import {TranslateModule} from '@ngx-translate/core';
import {TbCheckboxComponent} from '@shared/components/tb-checkbox.component';
import {HelpComponent} from '@shared/components/help.component';
import {TbAnchorComponent} from '@shared/components/tb-anchor.component';
// import { AuditLogDetailsDialogComponent } from '@shared/components/audit-log/audit-log-details-dialog.component';
// import { AuditLogTableComponent } from '@shared/components/audit-log/audit-log-table.component';
import {MillisecondsToTimeStringPipe} from '@shared/pipe/milliseconds-to-time-string.pipe';
import {TimewindowComponent} from '@shared/components/time/timewindow.component';
import {OverlayModule} from '@angular/cdk/overlay';
@ -97,7 +95,6 @@ import {SocialSharePanelComponent} from './components/socialshare-panel.componen
entryComponents: [
TbSnackBarComponent,
TbAnchorComponent,
// AuditLogDetailsDialogComponent,
TimewindowPanelComponent,
],
declarations: [
@ -111,8 +108,6 @@ import {SocialSharePanelComponent} from './components/socialshare-panel.componen
TbSnackBarComponent,
BreadcrumbComponent,
UserMenuComponent,
// AuditLogTableComponent,
// AuditLogDetailsDialogComponent,
TimewindowComponent,
TimewindowPanelComponent,
TimeintervalComponent,
@ -184,7 +179,6 @@ import {SocialSharePanelComponent} from './components/socialshare-panel.componen
TbCheckboxComponent,
BreadcrumbComponent,
UserMenuComponent,
// AuditLogTableComponent,
TimewindowComponent,
TimewindowPanelComponent,
TimeintervalComponent,

Loading…
Cancel
Save