15 changed files with 607 additions and 49 deletions
@ -0,0 +1,66 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 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. |
||||
|
|
||||
|
--> |
||||
|
<div class="tb-card-content" fxLayout="column" fxLayoutGap="8px"> |
||||
|
<div class="tb-title">Configured features |
||||
|
<mat-icon |
||||
|
matTooltip="Status of features that require configuration" |
||||
|
matTooltipPosition="above" |
||||
|
class="tb-info-icon">info</mat-icon> |
||||
|
</div> |
||||
|
<div fxLayout="column" fxFlex fxLayoutGap="12px"> |
||||
|
<div fxLayout="row" fxFlex fxLayoutGap="12px"> |
||||
|
<a class="tb-feature-button" fxFlex |
||||
|
[matTooltip]="featureTooltip(featuresInfo?.emailEnabled)" |
||||
|
matTooltipPosition="above" |
||||
|
[ngClass]="{'configured': featuresInfo?.emailEnabled}" |
||||
|
routerLink="/settings/outgoing-mail"> |
||||
|
<div class="tb-feature-text">Email</div> |
||||
|
</a> |
||||
|
<a class="tb-feature-button" fxFlex |
||||
|
[matTooltip]="featureTooltip(featuresInfo?.smsEnabled)" |
||||
|
matTooltipPosition="above" |
||||
|
[ngClass]="{'configured': featuresInfo?.smsEnabled}" |
||||
|
routerLink="/settings/notifications"> |
||||
|
<div class="tb-feature-text">SMS</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div fxLayout="row" fxFlex fxLayoutGap="12px"> |
||||
|
<a class="tb-feature-button" fxFlex |
||||
|
[matTooltip]="featureTooltip(featuresInfo?.notificationEnabled)" |
||||
|
matTooltipPosition="above" |
||||
|
[ngClass]="{'configured': featuresInfo?.notificationEnabled}" |
||||
|
routerLink="/settings/notifications"> |
||||
|
<div class="tb-feature-text">Slack</div> |
||||
|
</a> |
||||
|
<a class="tb-feature-button" fxFlex |
||||
|
[matTooltip]="featureTooltip(featuresInfo?.oauthEnabled)" |
||||
|
matTooltipPosition="above" |
||||
|
[ngClass]="{'configured': featuresInfo?.oauthEnabled}" |
||||
|
routerLink="/security-settings/oauth2"> |
||||
|
<div class="tb-feature-text">OAuth 2</div> |
||||
|
</a> |
||||
|
<a class="tb-feature-button" fxFlex |
||||
|
[matTooltip]="featureTooltip(featuresInfo?.twoFaEnabled)" |
||||
|
matTooltipPosition="above" |
||||
|
[ngClass]="{'configured': featuresInfo?.twoFaEnabled}" |
||||
|
routerLink="/security-settings/2fa"> |
||||
|
<div class="tb-feature-text">2FA</div> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,85 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 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-card-content { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.tb-title { |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.25px; |
||||
|
color: rgba(0, 0, 0, 0.54); |
||||
|
} |
||||
|
|
||||
|
.tb-info-icon { |
||||
|
color: rgba(0, 0, 0, 0.12); |
||||
|
font-size: 16px; |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
line-height: 15px; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.tb-feature-button { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
padding: 12px; |
||||
|
background: #FFFFFF; |
||||
|
border: 1px solid rgba(0, 0, 0, 0.05); |
||||
|
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.04); |
||||
|
border-radius: 10px; |
||||
|
&:hover { |
||||
|
border: 1px solid rgba(0, 0, 0, 0.12); |
||||
|
box-shadow: 0 4px 10px rgba(23, 33, 90, 0.08); |
||||
|
} |
||||
|
.tb-feature-text { |
||||
|
font-weight: 400; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
&:before { |
||||
|
content: "close"; |
||||
|
font-family: 'Material Icons Round'; |
||||
|
font-size: 20px; |
||||
|
line-height: 1; |
||||
|
color: rgba(0, 0, 0, 0.12); |
||||
|
font-weight: 600; |
||||
|
position: relative; |
||||
|
background: #F4F4F4; |
||||
|
border-radius: 4px; |
||||
|
width: 24px; |
||||
|
height: 24px; |
||||
|
margin-right: 8px; |
||||
|
vertical-align: bottom; |
||||
|
} |
||||
|
} |
||||
|
&.configured { |
||||
|
.tb-feature-text { |
||||
|
&:before { |
||||
|
content: "check"; |
||||
|
color: #198038; |
||||
|
background: #F3F6FA; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 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 { ChangeDetectorRef, Component, OnInit } from '@angular/core'; |
||||
|
import { PageComponent } from '@shared/components/page.component'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
import { AdminService } from '@core/http/admin.service'; |
||||
|
import { FeaturesInfo } from '@shared/models/settings.models'; |
||||
|
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; |
||||
|
import { Authority } from '@shared/models/authority.enum'; |
||||
|
import { of } from 'rxjs'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-configured-features', |
||||
|
templateUrl: './configured-features.component.html', |
||||
|
styleUrls: ['./configured-features.component.scss'] |
||||
|
}) |
||||
|
export class ConfiguredFeaturesComponent extends PageComponent implements OnInit { |
||||
|
|
||||
|
authUser = getCurrentAuthUser(this.store); |
||||
|
featuresInfo: FeaturesInfo; |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
private cd: ChangeDetectorRef, |
||||
|
private adminService: AdminService) { |
||||
|
super(store); |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
(this.authUser.authority === Authority.SYS_ADMIN ? |
||||
|
this.adminService.getFeaturesInfo() : of(null)).subscribe( |
||||
|
(featuresInfo) => { |
||||
|
this.featuresInfo = featuresInfo; |
||||
|
this.cd.markForCheck(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
featureTooltip(configured: boolean): string { |
||||
|
if (configured) { |
||||
|
return 'Feature is configured.\nClick to setup'; |
||||
|
} else { |
||||
|
return 'Feature is not configured.\nClick to setup'; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 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. |
||||
|
|
||||
|
--> |
||||
|
<div class="tb-card-content" fxLayout="column" fxLayoutGap="8px"> |
||||
|
<div class="tb-card-header"> |
||||
|
<div class="tb-title">Version</div> |
||||
|
<a mat-button color="primary" href="https://thingsboard.io/docs/contact-us/" target="_blank">Contact us</a> |
||||
|
</div> |
||||
|
<div fxLayout="column" fxFlex fxLayoutGap="12px"> |
||||
|
<div class="tb-version-info-container" fxFlex> |
||||
|
<div class="tb-card-header"> |
||||
|
<a class="tb-version-link" [href]="updateMessage?.currentVersionReleaseNotesUrl" target="_blank">Current version</a> |
||||
|
</div> |
||||
|
<div class="tb-version">{{ updateMessage?.currentVersion }}</div> |
||||
|
</div> |
||||
|
<div class="tb-version-info-container" fxFlex *ngIf="updateMessage?.updateAvailable; else versionUpToDate"> |
||||
|
<div class="tb-card-header"> |
||||
|
<a class="tb-version-link" [href]="updateMessage?.latestVersionReleaseNotesUrl" target="_blank">Available version</a> |
||||
|
<a mat-flat-button color="primary" [href]="updateMessage?.upgradeInstructionsUrl" target="_blank">Upgrade</a> |
||||
|
</div> |
||||
|
<div class="tb-version">{{ updateMessage?.latestVersion }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<ng-template #versionUpToDate> |
||||
|
<div class="tb-version-info-container up-to-date" fxFlex> |
||||
|
<div class="material-icons-round check-icon">check</div> |
||||
|
<div class="up-to-date-text">Version is up to date</div> |
||||
|
</div> |
||||
|
</ng-template> |
||||
@ -0,0 +1,102 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 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-card-content { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.tb-card-header { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.tb-title { |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.25px; |
||||
|
color: rgba(0, 0, 0, 0.54); |
||||
|
} |
||||
|
|
||||
|
.tb-version-info-container { |
||||
|
border: 1px solid rgba(0, 0, 0, 0.05); |
||||
|
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.04); |
||||
|
border-radius: 10px; |
||||
|
padding: 16px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: space-evenly; |
||||
|
&.up-to-date { |
||||
|
box-shadow: none; |
||||
|
border: none; |
||||
|
align-items: center; |
||||
|
background: #F3F6FA; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-version-link { |
||||
|
font-weight: 400; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.2px; |
||||
|
color: rgba(0, 0, 0, 0.76); |
||||
|
position: relative; |
||||
|
border-bottom: none; |
||||
|
&:hover, &:focus { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
&::after { |
||||
|
content: 'arrow_forward'; |
||||
|
display: inline-block; |
||||
|
position: absolute; |
||||
|
top: -2px; |
||||
|
right: -28px; |
||||
|
transform: rotate(315deg); |
||||
|
font-family: 'Material Icons'; |
||||
|
font-weight: normal; |
||||
|
font-style: normal; |
||||
|
font-size: 18px; |
||||
|
color: rgba(0, 0, 0, 0.12); |
||||
|
} |
||||
|
&:hover::after { |
||||
|
color: inherit; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.tb-version { |
||||
|
font-weight: 500; |
||||
|
font-size: 18px; |
||||
|
line-height: 24px; |
||||
|
letter-spacing: 0.15px; |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
} |
||||
|
|
||||
|
.check-icon { |
||||
|
color: #198038; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.up-to-date-text { |
||||
|
font-weight: 400; |
||||
|
font-size: 14px; |
||||
|
line-height: 20px; |
||||
|
letter-spacing: 0.2px; |
||||
|
color: rgba(0, 0, 0, 0.76); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 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 { ChangeDetectorRef, Component, OnInit } from '@angular/core'; |
||||
|
import { PageComponent } from '@shared/components/page.component'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
import { AdminService } from '@core/http/admin.service'; |
||||
|
import { UpdateMessage } from '@shared/models/settings.models'; |
||||
|
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; |
||||
|
import { Authority } from '@shared/models/authority.enum'; |
||||
|
import { of } from 'rxjs'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-version-info', |
||||
|
templateUrl: './version-info.component.html', |
||||
|
styleUrls: ['./version-info.component.scss'] |
||||
|
}) |
||||
|
export class VersionInfoComponent extends PageComponent implements OnInit { |
||||
|
|
||||
|
authUser = getCurrentAuthUser(this.store); |
||||
|
updateMessage: UpdateMessage; |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
private cd: ChangeDetectorRef, |
||||
|
private adminService: AdminService) { |
||||
|
super(store); |
||||
|
} |
||||
|
|
||||
|
ngOnInit() { |
||||
|
(this.authUser.authority === Authority.SYS_ADMIN ? |
||||
|
this.adminService.checkUpdates() : of(null)).subscribe( |
||||
|
(updateMessage) => { |
||||
|
this.updateMessage = updateMessage; |
||||
|
this.cd.markForCheck(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
featureTooltip(configured: boolean): string { |
||||
|
if (configured) { |
||||
|
return 'Feature is configured.\nClick to setup'; |
||||
|
} else { |
||||
|
return 'Feature is not configured.\nClick to setup'; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue