UI: mobile app qr code improvements, cleanup
This commit is contained in:
parent
9d71bb77ea
commit
45ed484c2a
@ -17,7 +17,7 @@
|
|||||||
"cards.label_widget",
|
"cards.label_widget",
|
||||||
"cards.dashboard_state_widget",
|
"cards.dashboard_state_widget",
|
||||||
"cards.qr_code",
|
"cards.qr_code",
|
||||||
"cards.mobile_app_qr_code",
|
"mobile_app_qr_code",
|
||||||
"cards.attributes_card",
|
"cards.attributes_card",
|
||||||
"cards.html_card",
|
"cards.html_card",
|
||||||
"cards.html_value_card",
|
"cards.html_value_card",
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
"home_page_widgets.quick_links",
|
"home_page_widgets.quick_links",
|
||||||
"home_page_widgets.documentation_links",
|
"home_page_widgets.documentation_links",
|
||||||
"home_page_widgets.dashboards",
|
"home_page_widgets.dashboards",
|
||||||
"home_page_widgets.usage_info",
|
"home_page_widgets.usage_info"
|
||||||
"home_page_widgets.home_page_mobile_app_qr_code"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -83,7 +83,7 @@ export const selectMobileQrEnabled = createSelector(
|
|||||||
(state: AuthState) => state.mobileQrEnabled
|
(state: AuthState) => state.mobileQrEnabled
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectPersistDeviceStateToTelemetryAndMobileQrEnabled = createSelector(
|
export const selectHomeDashboardParams = createSelector(
|
||||||
selectPersistDeviceStateToTelemetry,
|
selectPersistDeviceStateToTelemetry,
|
||||||
selectMobileQrEnabled,
|
selectMobileQrEnabled,
|
||||||
(persistDeviceStateToTelemetry, mobileQrEnabled) => ({persistDeviceStateToTelemetry, mobileQrEnabled})
|
(persistDeviceStateToTelemetry, mobileQrEnabled) => ({persistDeviceStateToTelemetry, mobileQrEnabled})
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils';
|
import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-utils';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { MobileAppQRCodeSettings } from '@shared/models/mobile-app.models';
|
import { MobileAppSettings } from '@shared/models/mobile-app.models';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -30,12 +30,12 @@ export class MobileAppService {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMobileAppSettings(config?: RequestConfig): Observable<MobileAppQRCodeSettings> {
|
public getMobileAppSettings(config?: RequestConfig): Observable<MobileAppSettings> {
|
||||||
return this.http.get<MobileAppQRCodeSettings>(`/api/mobile/app/settings`, defaultHttpOptionsFromConfig(config));
|
return this.http.get<MobileAppSettings>(`/api/mobile/app/settings`, defaultHttpOptionsFromConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveMobileAppSettings(mobileAppSettings: MobileAppQRCodeSettings, config?: RequestConfig): Observable<MobileAppQRCodeSettings> {
|
public saveMobileAppSettings(mobileAppSettings: MobileAppSettings, config?: RequestConfig): Observable<MobileAppSettings> {
|
||||||
return this.http.post<MobileAppQRCodeSettings>(`/api/mobile/app/settings`, mobileAppSettings, defaultHttpOptionsFromConfig(config));
|
return this.http.post<MobileAppSettings>(`/api/mobile/app/settings`, mobileAppSettings, defaultHttpOptionsFromConfig(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
public getMobileAppDeepLink(config?: RequestConfig): Observable<string> {
|
public getMobileAppDeepLink(config?: RequestConfig): Observable<string> {
|
||||||
|
|||||||
@ -22,23 +22,20 @@ import {
|
|||||||
QRCodeConfig
|
QRCodeConfig
|
||||||
} from '@shared/models/mobile-app.models';
|
} from '@shared/models/mobile-app.models';
|
||||||
|
|
||||||
export type MobileAppQrCodeWidgetSettings = {
|
export interface MobileAppQrCodeWidgetSettings {
|
||||||
useDefaultApp: boolean;
|
useSystemSettings: boolean;
|
||||||
androidConfig: AndroidConfig;
|
androidConfig: Pick<AndroidConfig, 'enabled'>;
|
||||||
iosConfig: IosConfig;
|
iosConfig: Pick<IosConfig, 'enabled'>;
|
||||||
qrCodeConfig: Omit<QRCodeConfig, 'showOnHomePage'>;
|
qrCodeConfig: Omit<QRCodeConfig, 'showOnHomePage'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mobileAppQrCodeWidgetDefaultSettings: MobileAppQrCodeWidgetSettings = {
|
export const mobileAppQrCodeWidgetDefaultSettings: MobileAppQrCodeWidgetSettings = {
|
||||||
useDefaultApp: true,
|
useSystemSettings: true,
|
||||||
androidConfig: {
|
androidConfig: {
|
||||||
enabled: true,
|
enabled: true
|
||||||
appPackage: '',
|
|
||||||
sha256CertFingerprints: ''
|
|
||||||
},
|
},
|
||||||
iosConfig: {
|
iosConfig: {
|
||||||
enabled: true,
|
enabled: true
|
||||||
appId: ''
|
|
||||||
},
|
},
|
||||||
qrCodeConfig: {
|
qrCodeConfig: {
|
||||||
badgeEnabled: true,
|
badgeEnabled: true,
|
||||||
|
|||||||
@ -15,16 +15,12 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div *ngIf="!previewMode && !ctx" class="tb-title" translate>admin.mobile-app.connect-mobile-app</div>
|
|
||||||
<div class="tb-flex column center align-center">
|
<div class="tb-flex column center align-center">
|
||||||
<div class="tb-flex row align-center shrink"
|
<div class="tb-flex row align-center shrink"
|
||||||
[class.row]="mobileAppSettings?.qrCodeConfig.badgePosition === badgePosition.RIGHT"
|
[class.row]="mobileAppSettings?.qrCodeConfig.badgePosition === badgePosition.RIGHT"
|
||||||
[class.row-reverse]="mobileAppSettings?.qrCodeConfig.badgePosition === badgePosition.LEFT">
|
[class.row-reverse]="mobileAppSettings?.qrCodeConfig.badgePosition === badgePosition.LEFT">
|
||||||
<!-- <canvas #canvas class="tb-qrcode"></canvas>-->
|
|
||||||
<canvas #canvas class="tb-qrcode"></canvas>
|
<canvas #canvas class="tb-qrcode"></canvas>
|
||||||
<div *ngIf="mobileAppSettings?.qrCodeConfig.badgeEnabled"
|
<div class="tb-flex column" *ngIf="mobileAppSettings?.qrCodeConfig.badgeEnabled && showBadgeContainer">
|
||||||
class="tb-flex column tb-badge-container"
|
|
||||||
[class.tb-badge-container]="!previewMode && !ctx">
|
|
||||||
<ng-container *ngIf="mobileAppSettings.qrCodeConfig.badgeStyle === badgeStyle.ORIGINAL;else white">
|
<ng-container *ngIf="mobileAppSettings.qrCodeConfig.badgeStyle === badgeStyle.ORIGINAL;else white">
|
||||||
<img *ngIf="mobileAppSettings.iosConfig.enabled" [src]="badgeStyleURLMap.get(badgeStyle.ORIGINAL).iOS">
|
<img *ngIf="mobileAppSettings.iosConfig.enabled" [src]="badgeStyleURLMap.get(badgeStyle.ORIGINAL).iOS">
|
||||||
<img *ngIf="mobileAppSettings.androidConfig.enabled" [src]="badgeStyleURLMap.get(badgeStyle.ORIGINAL).android">
|
<img *ngIf="mobileAppSettings.androidConfig.enabled" [src]="badgeStyleURLMap.get(badgeStyle.ORIGINAL).android">
|
||||||
|
|||||||
@ -23,24 +23,6 @@
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tb-title {
|
|
||||||
padding-bottom: 12px;
|
|
||||||
align-self: start;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 20px;
|
|
||||||
line-height: 24px;
|
|
||||||
letter-spacing: 0.1px;
|
|
||||||
color: rgba(0, 0, 0, 0.76);
|
|
||||||
|
|
||||||
@media #{$mat-md-lg} {
|
|
||||||
padding-bottom: 0;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
letter-spacing: 0.25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tb-qrcode-label {
|
.tb-qrcode-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgba(0, 0, 0, 0.54);
|
color: rgba(0, 0, 0, 0.54);
|
||||||
@ -56,8 +38,3 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tb-badge-container {
|
|
||||||
@media #{$mat-md} {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -14,97 +14,108 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import { PageComponent } from '@shared/components/page.component';
|
import { PageComponent } from '@shared/components/page.component';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { BadgePosition, BadgeStyle, badgeStyleURLMap, MobileAppQRCodeSettings } from '@shared/models/mobile-app.models';
|
import { BadgePosition, BadgeStyle, badgeStyleURLMap, MobileAppSettings } from '@shared/models/mobile-app.models';
|
||||||
import { MobileAppService } from '@core/http/mobile-app.service';
|
import { MobileAppService } from '@core/http/mobile-app.service';
|
||||||
import { WidgetContext } from '@home/models/widget-component.models';
|
import { WidgetContext } from '@home/models/widget-component.models';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { interval, mergeMap, Observable, Subject, takeUntil } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { MINUTE } from '@shared/models/time/time.models';
|
import { MINUTE } from '@shared/models/time/time.models';
|
||||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
|
||||||
import { MobileAppQrCodeWidgetSettings } from '@home/components/widget/lib/cards/mobile-app-qr-code-widget.models';
|
import { MobileAppQrCodeWidgetSettings } from '@home/components/widget/lib/cards/mobile-app-qr-code-widget.models';
|
||||||
|
import { isDefinedAndNotNull } from '@core/utils';
|
||||||
|
import { ResizeObserver } from '@juggle/resize-observer';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-mobile-app-qrcode-widget',
|
selector: 'tb-mobile-app-qrcode-widget',
|
||||||
templateUrl: './mobile-app-qrcode-widget.component.html',
|
templateUrl: './mobile-app-qrcode-widget.component.html',
|
||||||
styleUrls: ['./mobile-app-qrcode-widget.component.scss']
|
styleUrls: ['./mobile-app-qrcode-widget.component.scss']
|
||||||
})
|
})
|
||||||
export class MobileAppQrcodeWidgetComponent extends PageComponent implements OnInit, AfterViewInit, OnDestroy {
|
export class MobileAppQrcodeWidgetComponent extends PageComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
ctx: WidgetContext;
|
ctx: WidgetContext;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@coerceBoolean()
|
set mobileAppSettings(settings: MobileAppSettings | MobileAppQrCodeWidgetSettings) {
|
||||||
previewMode: boolean;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
set mobileAppSettings(settings: MobileAppQRCodeSettings | MobileAppQrCodeWidgetSettings) {
|
|
||||||
if (settings) {
|
if (settings) {
|
||||||
this.mobileAppSettingsValue = settings;
|
this.mobileAppSettingsValue = settings;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
get mobileAppSettings() {
|
get mobileAppSettings(): MobileAppSettings | MobileAppQrCodeWidgetSettings {
|
||||||
return this.mobileAppSettingsValue;
|
return this.mobileAppSettingsValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewChild('canvas', {static: false}) canvasRef: ElementRef<HTMLCanvasElement>;
|
@ViewChild('canvas', {static: true}) canvasRef: ElementRef<HTMLCanvasElement>;
|
||||||
|
|
||||||
private readonly destroy$ = new Subject<void>();
|
private readonly destroy$ = new Subject<void>();
|
||||||
|
private widgetResize$: ResizeObserver;
|
||||||
|
|
||||||
badgeStyle = BadgeStyle;
|
badgeStyle = BadgeStyle;
|
||||||
badgePosition = BadgePosition;
|
badgePosition = BadgePosition;
|
||||||
badgeStyleURLMap = badgeStyleURLMap;
|
badgeStyleURLMap = badgeStyleURLMap;
|
||||||
|
showBadgeContainer = true;
|
||||||
|
|
||||||
private mobileAppSettingsValue: MobileAppQRCodeSettings | MobileAppQrCodeWidgetSettings;
|
private mobileAppSettingsValue: MobileAppSettings | MobileAppQrCodeWidgetSettings;
|
||||||
private deepLinkTTL: number;
|
private deepLinkTTL: number;
|
||||||
|
private deepLinkTTLTimeoutID: NodeJS.Timeout;
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
protected cd: ChangeDetectorRef,
|
protected cd: ChangeDetectorRef,
|
||||||
private mobileAppService: MobileAppService,
|
private mobileAppService: MobileAppService,
|
||||||
private utilsService: UtilsService) {
|
private utilsService: UtilsService,
|
||||||
|
private elementRef: ElementRef) {
|
||||||
super(store);
|
super(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (!this.previewMode) {
|
if (!this.mobileAppSettings) {
|
||||||
if (this.ctx) {
|
if (isDefinedAndNotNull(this.ctx.settings.useSystemSettings) && !this.ctx.settings.useSystemSettings) {
|
||||||
this.mobileAppSettings = this.ctx.settings;
|
this.mobileAppSettings = this.ctx.settings;
|
||||||
} else {
|
} else {
|
||||||
this.mobileAppService.getMobileAppSettings().subscribe((settings => {
|
this.mobileAppService.getMobileAppSettings().subscribe((settings => {
|
||||||
this.mobileAppSettings = settings;
|
this.mobileAppSettings = settings;
|
||||||
this.cd.detectChanges();
|
this.cd.markForCheck();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.initMobileAppQRCode();
|
||||||
|
this.widgetResize$ = new ResizeObserver(() => {
|
||||||
|
const showHideBadgeContainer = this.elementRef.nativeElement.offsetWidth > 250;
|
||||||
|
if (showHideBadgeContainer !== this.showBadgeContainer) {
|
||||||
|
this.showBadgeContainer = showHideBadgeContainer;
|
||||||
|
this.cd.markForCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
|
||||||
this.getMobileAppDeepLink().subscribe(link => {
|
|
||||||
this.deepLinkTTL = Number(this.utilsService.getQueryParam('ttl', link)) * MINUTE;
|
|
||||||
this.updateQRCode(link);
|
|
||||||
interval(this.deepLinkTTL).pipe(
|
|
||||||
takeUntil(this.destroy$),
|
|
||||||
mergeMap(() => this.getMobileAppDeepLink())
|
|
||||||
).subscribe(link => this.updateQRCode(link));
|
|
||||||
});
|
});
|
||||||
|
this.widgetResize$.observe(this.elementRef.nativeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
if (this.widgetResize$) {
|
||||||
|
this.widgetResize$.disconnect();
|
||||||
|
}
|
||||||
super.ngOnDestroy();
|
super.ngOnDestroy();
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
|
clearTimeout(this.deepLinkTTLTimeoutID);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMobileAppDeepLink(): Observable<string> {
|
private initMobileAppQRCode() {
|
||||||
return this.mobileAppService.getMobileAppDeepLink();
|
if (this.deepLinkTTLTimeoutID) {
|
||||||
|
clearTimeout(this.deepLinkTTLTimeoutID);
|
||||||
|
this.deepLinkTTLTimeoutID = null;
|
||||||
|
}
|
||||||
|
this.mobileAppService.getMobileAppDeepLink().subscribe(link => {
|
||||||
|
this.deepLinkTTL = Number(this.utilsService.getQueryParam('ttl', link)) * MINUTE;
|
||||||
|
this.updateQRCode(link);
|
||||||
|
this.deepLinkTTLTimeoutID = setTimeout(() => this.initMobileAppQRCode(), this.deepLinkTTL);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateQRCode(link: string) {
|
private updateQRCode(link: string) {
|
||||||
import('qrcode').then((QRCode) => {
|
import('qrcode').then((QRCode) => {
|
||||||
QRCode.toCanvas(this.canvasRef.nativeElement, link, { width: 100 });
|
QRCode.toCanvas(this.canvasRef.nativeElement, link, { width: 100 });
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,88 +15,36 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<section class="tb-widget-settings tb-form-panel no-border no-padding" [formGroup]="mobileAppQRCodeWidgetSettingsForm" fxLayout="column">
|
<section class="tb-widget-settings tb-form-panel no-border no-padding" [formGroup]="mobileAppQRCodeWidgetSettingsForm">
|
||||||
<div class="tb-form-panel">
|
<div class="tb-form-panel no-padding">
|
||||||
<div fxLayout="row" fxLayoutAlign="space-between center">
|
|
||||||
<div class="tb-form-panel-title" translate>admin.mobile-app.applications</div>
|
|
||||||
<tb-toggle-select formControlName="useDefaultApp">
|
|
||||||
<tb-toggle-option [value]="true">{{ 'admin.mobile-app.default' | translate }}</tb-toggle-option>
|
|
||||||
<tb-toggle-option [value]="false">{{ 'admin.mobile-app.custom' | translate }}</tb-toggle-option>
|
|
||||||
</tb-toggle-select>
|
|
||||||
</div>
|
|
||||||
<div class="tb-form-panel stroked no-padding no-gap" formGroupName="androidConfig">
|
|
||||||
<div class="tb-form-row no-border no-padding-bottom">
|
<div class="tb-form-row no-border no-padding-bottom">
|
||||||
<mat-slide-toggle class="mat-slide" formControlName="enabled" (click)="$event.stopPropagation()">
|
<mat-slide-toggle class="mat-slide" formControlName="useSystemSettings" (click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.android' | translate }}
|
{{ 'admin.mobile-app.use-system-settings' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel no-border no-padding-top"
|
|
||||||
*ngIf="!mobileAppQRCodeWidgetSettingsForm.get('useDefaultApp').value && mobileAppQRCodeWidgetSettingsForm.get('androidConfig.enabled').value">
|
|
||||||
<div class="tb-form-row column-xs">
|
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.app-package-name' | translate }}</div>
|
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
|
||||||
<input matInput formControlName="appPackage" placeholder="{{'admin.mobile-app.set' | translate}}">
|
|
||||||
<mat-icon matSuffix
|
|
||||||
matTooltipPosition="above"
|
|
||||||
matTooltipClass="tb-error-tooltip"
|
|
||||||
[matTooltip]="'admin.mobile-app.app-package-name-required' | translate"
|
|
||||||
*ngIf="mobileAppQRCodeWidgetSettingsForm.get('androidConfig.appPackage').hasError('required')
|
|
||||||
&& mobileAppQRCodeWidgetSettingsForm.get('androidConfig.appPackage').touched"
|
|
||||||
class="tb-error">
|
|
||||||
warning
|
|
||||||
</mat-icon>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tb-form-panel no-border no-padding-top"
|
|
||||||
*ngIf="!mobileAppQRCodeWidgetSettingsForm.get('useDefaultApp').value && mobileAppQRCodeWidgetSettingsForm.get('androidConfig.enabled').value">
|
|
||||||
<div class="tb-form-row column-xs">
|
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.sha256-certificate-fingerprints' | translate }}</div>
|
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
|
||||||
<input matInput formControlName="sha256CertFingerprints" placeholder="{{'admin.mobile-app.set' | translate}}">
|
|
||||||
<mat-icon matSuffix
|
|
||||||
matTooltipPosition="above"
|
|
||||||
matTooltipClass="tb-error-tooltip"
|
|
||||||
[matTooltip]="'admin.mobile-app.sha256-certificate-fingerprints-required' | translate"
|
|
||||||
*ngIf="mobileAppQRCodeWidgetSettingsForm.get('androidConfig.sha256CertFingerprints').hasError('required')
|
|
||||||
&& mobileAppQRCodeWidgetSettingsForm.get('androidConfig.sha256CertFingerprints').touched"
|
|
||||||
class="tb-error">
|
|
||||||
warning
|
|
||||||
</mat-icon>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tb-form-panel" *ngIf="!mobileAppQRCodeWidgetSettingsForm.get('useSystemSettings').value">
|
||||||
|
<div class="tb-form-panel-title" translate>admin.mobile-app.applications</div>
|
||||||
|
<div class="tb-form-panel stroked no-padding no-gap">
|
||||||
|
<div class="tb-form-row no-border no-padding-bottom">
|
||||||
|
<mat-slide-toggle class="mat-slide" [formControl]="mobileAppQRCodeWidgetSettingsForm.get('androidConfig.enabled')" (click)="$event.stopPropagation()">
|
||||||
|
{{ 'admin.mobile-app.android' | translate }}
|
||||||
|
</mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel stroked no-padding no-gap" formGroupName="iosConfig">
|
<div class="tb-form-panel stroked no-padding no-gap" formGroupName="iosConfig">
|
||||||
<div class="tb-form-row no-border no-padding-bottom">
|
<div class="tb-form-row no-border no-padding-bottom">
|
||||||
<mat-slide-toggle class="mat-slide" formControlName="enabled" (click)="$event.stopPropagation()">
|
<mat-slide-toggle class="mat-slide" [formControl]="mobileAppQRCodeWidgetSettingsForm.get('iosConfig.enabled')" (click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.ios' | translate }}
|
{{ 'admin.mobile-app.ios' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel no-border no-padding-top"
|
|
||||||
*ngIf="!mobileAppQRCodeWidgetSettingsForm.get('useDefaultApp').value && mobileAppQRCodeWidgetSettingsForm.get('iosConfig.enabled').value">
|
|
||||||
<div class="tb-form-row column-xs">
|
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.app-id' | translate }}</div>
|
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
|
||||||
<input matInput formControlName="appId" placeholder="{{'admin.mobile-app.set' | translate}}">
|
|
||||||
<mat-icon matSuffix
|
|
||||||
matTooltipPosition="above"
|
|
||||||
matTooltipClass="tb-error-tooltip"
|
|
||||||
[matTooltip]="'admin.mobile-app.app-id-required' | translate"
|
|
||||||
*ngIf="mobileAppQRCodeWidgetSettingsForm.get('iosConfig.appId').hasError('required')
|
|
||||||
&& mobileAppQRCodeWidgetSettingsForm.get('iosConfig.appId').touched"
|
|
||||||
class="tb-error">
|
|
||||||
warning
|
|
||||||
</mat-icon>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="tb-form-panel" formGroupName="qrCodeConfig" *ngIf="!mobileAppQRCodeWidgetSettingsForm.get('useSystemSettings').value">
|
||||||
</div>
|
<div class="tb-form-panel-title" translate>admin.mobile-app.appearance</div>
|
||||||
<div class="tb-form-panel" formGroupName="qrCodeConfig">
|
|
||||||
<div class="tb-form-panel stroked no-padding no-gap">
|
<div class="tb-form-panel stroked no-padding no-gap">
|
||||||
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
||||||
<mat-slide-toggle class="mat-slide tb-fixed-width" formControlName="badgeEnabled"
|
<mat-slide-toggle class="mat-slide fixed-title-width-230" formControlName="badgeEnabled"
|
||||||
(click)="$event.stopPropagation()">
|
(click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.badges' | translate }}
|
{{ 'admin.mobile-app.badges' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
@ -118,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel stroked no-padding no-gap">
|
<div class="tb-form-panel stroked no-padding no-gap">
|
||||||
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
||||||
<mat-slide-toggle class="mat-slide tb-fixed-width" formControlName="qrCodeLabelEnabled" (click)="$event.stopPropagation()">
|
<mat-slide-toggle class="mat-slide fixed-title-width-230" formControlName="qrCodeLabelEnabled" (click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.label' | translate }}
|
{{ 'admin.mobile-app.label' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright © 2016-2024 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-fixed-width {
|
|
||||||
min-width: 230px;
|
|
||||||
}
|
|
||||||
@ -25,7 +25,7 @@ import { mobileAppQrCodeWidgetDefaultSettings } from '@home/components/widget/li
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-mobile-app-qr-code-widget-settings',
|
selector: 'tb-mobile-app-qr-code-widget-settings',
|
||||||
templateUrl: './mobile-app-qr-code-widget-settings.component.html',
|
templateUrl: './mobile-app-qr-code-widget-settings.component.html',
|
||||||
styleUrls: ['/mobile-app-qr-code-widget-settings.component.scss', './../widget-settings.scss']
|
styleUrls: ['./../widget-settings.scss']
|
||||||
})
|
})
|
||||||
export class MobileAppQrCodeWidgetSettingsComponent extends WidgetSettingsComponent {
|
export class MobileAppQrCodeWidgetSettingsComponent extends WidgetSettingsComponent {
|
||||||
|
|
||||||
@ -49,15 +49,12 @@ export class MobileAppQrCodeWidgetSettingsComponent extends WidgetSettingsCompon
|
|||||||
|
|
||||||
protected onSettingsSet(settings: WidgetSettings) {
|
protected onSettingsSet(settings: WidgetSettings) {
|
||||||
this.mobileAppQRCodeWidgetSettingsForm = this.fb.group({
|
this.mobileAppQRCodeWidgetSettingsForm = this.fb.group({
|
||||||
useDefaultApp: [settings.useDefaultApp],
|
useSystemSettings: [settings.useSystemSettings],
|
||||||
androidConfig: this.fb.group({
|
androidConfig: this.fb.group({
|
||||||
enabled: [settings.androidConfig.enabled],
|
enabled: [settings.androidConfig.enabled],
|
||||||
appPackage: [settings.androidConfig.appPackage, [Validators.required]],
|
|
||||||
sha256CertFingerprints: [settings.androidConfig.sha256CertFingerprints, [Validators.required]]
|
|
||||||
}),
|
}),
|
||||||
iosConfig: this.fb.group({
|
iosConfig: this.fb.group({
|
||||||
enabled: [settings.iosConfig.enabled],
|
enabled: [settings.iosConfig.enabled],
|
||||||
appId: [settings.iosConfig.appId, [Validators.required]]
|
|
||||||
}),
|
}),
|
||||||
qrCodeConfig: this.fb.group({
|
qrCodeConfig: this.fb.group({
|
||||||
badgeEnabled: [settings.qrCodeConfig.badgeEnabled],
|
badgeEnabled: [settings.qrCodeConfig.badgeEnabled],
|
||||||
@ -70,35 +67,16 @@ export class MobileAppQrCodeWidgetSettingsComponent extends WidgetSettingsCompon
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected validatorTriggers(): string[] {
|
protected validatorTriggers(): string[] {
|
||||||
return ['useDefaultApp', 'androidConfig.enabled', 'iosConfig.enabled', 'qrCodeConfig.badgeEnabled', 'qrCodeConfig.qrCodeLabelEnabled'];
|
return ['useSystemSettings', 'androidConfig.enabled', 'iosConfig.enabled', 'qrCodeConfig.badgeEnabled', 'qrCodeConfig.qrCodeLabelEnabled'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updateValidators(emitEvent: boolean) {
|
protected updateValidators(emitEvent: boolean) {
|
||||||
const useDefaultApp = this.mobileAppQRCodeWidgetSettingsForm.get('useDefaultApp').value;
|
const useSystemSettings = this.mobileAppQRCodeWidgetSettingsForm.get('useSystemSettings').value;
|
||||||
const androidEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.enabled').value;
|
const androidEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.enabled').value;
|
||||||
const iosEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('iosConfig.enabled').value;
|
const iosEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('iosConfig.enabled').value;
|
||||||
const badgeEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeEnabled').value;
|
const badgeEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeEnabled').value;
|
||||||
const qrCodeLabelEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabelEnabled').value;
|
const qrCodeLabelEnabled = this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabelEnabled').value;
|
||||||
|
|
||||||
if (useDefaultApp) {
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.appPackage').disable({emitEvent: false});
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.sha256CertFingerprints').disable({emitEvent: false});
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('iosConfig.appId').disable({emitEvent: false});
|
|
||||||
} else {
|
|
||||||
if (androidEnabled) {
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.appPackage').enable({emitEvent: false});
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.sha256CertFingerprints').enable({emitEvent: false});
|
|
||||||
} else {
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.appPackage').disable({emitEvent: false});
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('androidConfig.sha256CertFingerprints').disable({emitEvent: false});
|
|
||||||
}
|
|
||||||
if (iosEnabled) {
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('iosConfig.appId').enable({emitEvent: false});
|
|
||||||
} else {
|
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('iosConfig.appId').disable({emitEvent: false});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!androidEnabled && !iosEnabled) {
|
if (!androidEnabled && !iosEnabled) {
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeEnabled').disable({emitEvent: false});
|
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeEnabled').disable({emitEvent: false});
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeStyle').disable({emitEvent: false});
|
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.badgeStyle').disable({emitEvent: false});
|
||||||
@ -116,7 +94,7 @@ export class MobileAppQrCodeWidgetSettingsComponent extends WidgetSettingsCompon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qrCodeLabelEnabled) {
|
if (qrCodeLabelEnabled && !useSystemSettings) {
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabel').enable({emitEvent: false});
|
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabel').enable({emitEvent: false});
|
||||||
} else {
|
} else {
|
||||||
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabel').disable({emitEvent: false});
|
this.mobileAppQRCodeWidgetSettingsForm.get('qrCodeConfig.qrCodeLabel').disable({emitEvent: false});
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
<div class="tb-form-panel no-border no-padding-top"
|
<div class="tb-form-panel no-border no-padding-top"
|
||||||
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('androidConfig.enabled').value">
|
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('androidConfig.enabled').value">
|
||||||
<div class="tb-form-row column-xs">
|
<div class="tb-form-row column-xs">
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.app-package-name' | translate }}</div>
|
<div class="fixed-title-width-230">{{ 'admin.mobile-app.app-package-name' | translate }}</div>
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
||||||
<input matInput formControlName="appPackage" placeholder="{{'admin.mobile-app.set' | translate}}">
|
<input matInput formControlName="appPackage" placeholder="{{'admin.mobile-app.set' | translate}}">
|
||||||
<mat-icon matSuffix
|
<mat-icon matSuffix
|
||||||
@ -61,7 +61,7 @@
|
|||||||
<div class="tb-form-panel no-border no-padding-top"
|
<div class="tb-form-panel no-border no-padding-top"
|
||||||
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('androidConfig.enabled').value">
|
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('androidConfig.enabled').value">
|
||||||
<div class="tb-form-row column-xs">
|
<div class="tb-form-row column-xs">
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.sha256-certificate-fingerprints' | translate }}</div>
|
<div class="fixed-title-width-230">{{ 'admin.mobile-app.sha256-certificate-fingerprints' | translate }}</div>
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
||||||
<input matInput formControlName="sha256CertFingerprints" placeholder="{{'admin.mobile-app.set' | translate}}">
|
<input matInput formControlName="sha256CertFingerprints" placeholder="{{'admin.mobile-app.set' | translate}}">
|
||||||
<mat-icon matSuffix
|
<mat-icon matSuffix
|
||||||
@ -86,7 +86,7 @@
|
|||||||
<div class="tb-form-panel no-border no-padding-top"
|
<div class="tb-form-panel no-border no-padding-top"
|
||||||
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('iosConfig.enabled').value">
|
*ngIf="!mobileAppSettingsForm.get('useDefaultApp').value && mobileAppSettingsForm.get('iosConfig.enabled').value">
|
||||||
<div class="tb-form-row column-xs">
|
<div class="tb-form-row column-xs">
|
||||||
<div class="tb-fixed-width">{{ 'admin.mobile-app.app-id' | translate }}</div>
|
<div class="fixed-title-width-230">{{ 'admin.mobile-app.app-id' | translate }}</div>
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
||||||
<input matInput formControlName="appId" placeholder="{{'admin.mobile-app.set' | translate}}">
|
<input matInput formControlName="appId" placeholder="{{'admin.mobile-app.set' | translate}}">
|
||||||
<mat-icon matSuffix
|
<mat-icon matSuffix
|
||||||
@ -113,7 +113,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel stroked no-padding no-gap" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
<div class="tb-form-panel stroked no-padding no-gap" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
||||||
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
||||||
<mat-slide-toggle class="mat-slide tb-fixed-width" formControlName="badgeEnabled"
|
<mat-slide-toggle class="mat-slide fixed-title-width-230" formControlName="badgeEnabled"
|
||||||
(click)="$event.stopPropagation()">
|
(click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.badges' | translate }}
|
{{ 'admin.mobile-app.badges' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
@ -135,7 +135,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel stroked no-padding no-gap" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
<div class="tb-form-panel stroked no-padding no-gap" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
||||||
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
<div class="tb-form-row space-between no-border no-padding-bottom column-xs">
|
||||||
<mat-slide-toggle class="mat-slide tb-fixed-width" formControlName="qrCodeLabelEnabled" (click)="$event.stopPropagation()">
|
<mat-slide-toggle class="mat-slide fixed-title-width-230" formControlName="qrCodeLabelEnabled" (click)="$event.stopPropagation()">
|
||||||
{{ 'admin.mobile-app.label' | translate }}
|
{{ 'admin.mobile-app.label' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
||||||
@ -154,7 +154,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tb-form-panel tb-qrcode-preview" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
<div class="tb-form-panel tb-qrcode-preview" *ngIf="mobileAppSettingsForm.get('qrCodeConfig.showOnHomePage').value">
|
||||||
<div class="tb-form-panel-title" translate>admin.mobile-app.preview</div>
|
<div class="tb-form-panel-title" translate>admin.mobile-app.preview</div>
|
||||||
<tb-mobile-app-qrcode-widget previewMode
|
<tb-mobile-app-qrcode-widget
|
||||||
[mobileAppSettings]="mobileAppSettingsForm.getRawValue()">
|
[mobileAppSettings]="mobileAppSettingsForm.getRawValue()">
|
||||||
</tb-mobile-app-qrcode-widget>
|
</tb-mobile-app-qrcode-widget>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -14,10 +14,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.tb-fixed-width {
|
|
||||||
min-width: 230px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tb-qrcode-preview {
|
.tb-qrcode-preview {
|
||||||
background-color: rgba(0, 0, 0, 0.04);
|
background-color: rgba(0, 0, 0, 0.04);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import {
|
|||||||
badgePositionTranslationsMap,
|
badgePositionTranslationsMap,
|
||||||
BadgeStyle,
|
BadgeStyle,
|
||||||
badgeStyleTranslationsMap,
|
badgeStyleTranslationsMap,
|
||||||
MobileAppQRCodeSettings
|
MobileAppSettings
|
||||||
} from '@shared/models/mobile-app.models';
|
} from '@shared/models/mobile-app.models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -39,7 +39,7 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
|
|||||||
|
|
||||||
mobileAppSettingsForm: FormGroup;
|
mobileAppSettingsForm: FormGroup;
|
||||||
|
|
||||||
mobileAppSettings: MobileAppQRCodeSettings;
|
mobileAppSettings: MobileAppSettings;
|
||||||
|
|
||||||
private readonly destroy$ = new Subject<void>();
|
private readonly destroy$ = new Subject<void>();
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ export class MobileAppSettingsComponent extends PageComponent implements HasConf
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private processMobileAppSettings(mobileAppSettings: MobileAppQRCodeSettings): void {
|
private processMobileAppSettings(mobileAppSettings: MobileAppSettings): void {
|
||||||
this.mobileAppSettings = {...mobileAppSettings};
|
this.mobileAppSettings = {...mobileAppSettings};
|
||||||
this.mobileAppSettingsForm.reset(this.mobileAppSettings);
|
this.mobileAppSettingsForm.reset(this.mobileAppSettings);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,8 +27,9 @@ import { AppState } from '@core/core.state';
|
|||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
getCurrentAuthUser,
|
getCurrentAuthUser,
|
||||||
|
selectHomeDashboardParams,
|
||||||
selectMobileQrEnabled,
|
selectMobileQrEnabled,
|
||||||
selectPersistDeviceStateToTelemetryAndMobileQrEnabled
|
selectPersistDeviceStateToTelemetry
|
||||||
} from '@core/auth/auth.selectors';
|
} from '@core/auth/auth.selectors';
|
||||||
import { EntityKeyType } from '@shared/models/query/query.models';
|
import { EntityKeyType } from '@shared/models/query/query.models';
|
||||||
import { ResourcesService } from '@core/services/resources.service';
|
import { ResourcesService } from '@core/services/resources.service';
|
||||||
@ -37,9 +38,42 @@ const sysAdminHomePageJson = '/assets/dashboard/sys_admin_home_page.json';
|
|||||||
const tenantAdminHomePageJson = '/assets/dashboard/tenant_admin_home_page.json';
|
const tenantAdminHomePageJson = '/assets/dashboard/tenant_admin_home_page.json';
|
||||||
const customerUserHomePageJson = '/assets/dashboard/customer_user_home_page.json';
|
const customerUserHomePageJson = '/assets/dashboard/customer_user_home_page.json';
|
||||||
|
|
||||||
const updateDeviceActivityKeyFilterIfNeeded = (store: Store<AppState>,
|
const getHomeDashboard = (store: Store<AppState>, resourcesService: ResourcesService) => {
|
||||||
dashboard$: Observable<HomeDashboard>): Observable<HomeDashboard> =>
|
const authority = getCurrentAuthUser(store).authority;
|
||||||
store.pipe(select(selectPersistDeviceStateToTelemetryAndMobileQrEnabled)).pipe(
|
switch (authority) {
|
||||||
|
case Authority.SYS_ADMIN:
|
||||||
|
return applySystemParametersToHomeDashboard(store, resourcesService.loadJsonResource(sysAdminHomePageJson), authority);
|
||||||
|
case Authority.TENANT_ADMIN:
|
||||||
|
return applySystemParametersToHomeDashboard(store, resourcesService.loadJsonResource(tenantAdminHomePageJson), authority);
|
||||||
|
case Authority.CUSTOMER_USER:
|
||||||
|
return applySystemParametersToHomeDashboard(store, resourcesService.loadJsonResource(customerUserHomePageJson), authority);
|
||||||
|
default:
|
||||||
|
return of(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const applySystemParametersToHomeDashboard = (store: Store<AppState>,
|
||||||
|
dashboard$: Observable<HomeDashboard>,
|
||||||
|
authority: Authority): Observable<HomeDashboard> => {
|
||||||
|
let selectParams$: Observable<{persistDeviceStateToTelemetry?: boolean, mobileQrEnabled?: boolean}>;
|
||||||
|
switch (authority) {
|
||||||
|
case Authority.SYS_ADMIN:
|
||||||
|
selectParams$ = store.pipe(
|
||||||
|
select(selectMobileQrEnabled),
|
||||||
|
map(mobileQrEnabled => ({mobileQrEnabled}))
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case Authority.TENANT_ADMIN:
|
||||||
|
selectParams$ = store.pipe(select(selectHomeDashboardParams));
|
||||||
|
break;
|
||||||
|
case Authority.CUSTOMER_USER:
|
||||||
|
selectParams$ = store.pipe(
|
||||||
|
select(selectPersistDeviceStateToTelemetry),
|
||||||
|
map(persistDeviceStateToTelemetry => ({persistDeviceStateToTelemetry}))
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return selectParams$.pipe(
|
||||||
mergeMap((params) => dashboard$.pipe(
|
mergeMap((params) => dashboard$.pipe(
|
||||||
map((dashboard) => {
|
map((dashboard) => {
|
||||||
if (params.persistDeviceStateToTelemetry) {
|
if (params.persistDeviceStateToTelemetry) {
|
||||||
@ -49,22 +83,7 @@ const updateDeviceActivityKeyFilterIfNeeded = (store: Store<AppState>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params.mobileQrEnabled ? toggleMobileQRCodeDisplay(dashboard) : dashboard;
|
if (params.mobileQrEnabled) {
|
||||||
})
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
const toggleMobileQRCodeDisplayIfNeeded = (store: Store<AppState>,
|
|
||||||
dashboard$: Observable<HomeDashboard>): Observable<HomeDashboard> =>
|
|
||||||
store.pipe(select(selectMobileQrEnabled)).pipe(
|
|
||||||
mergeMap((mobileQrEnabled) => dashboard$.pipe(
|
|
||||||
map((dashboard) => {
|
|
||||||
return mobileQrEnabled ? toggleMobileQRCodeDisplay(dashboard) : dashboard;
|
|
||||||
})
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
const toggleMobileQRCodeDisplay = (dashboard: HomeDashboard) => {
|
|
||||||
for (const widgetId of Object.keys(dashboard.configuration.widgets)) {
|
for (const widgetId of Object.keys(dashboard.configuration.widgets)) {
|
||||||
if (dashboard.configuration.widgets[widgetId].config.title === 'Select show mobile QR code') {
|
if (dashboard.configuration.widgets[widgetId].config.title === 'Select show mobile QR code') {
|
||||||
dashboard.configuration.widgets[widgetId].config.settings.markdownTextFunction =
|
dashboard.configuration.widgets[widgetId].config.settings.markdownTextFunction =
|
||||||
@ -72,8 +91,13 @@ const toggleMobileQRCodeDisplay = (dashboard: HomeDashboard) => {
|
|||||||
.replace('\'${mobileQrEnabled}\'', String(true));
|
.replace('\'${mobileQrEnabled}\'', String(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dashboard;
|
|
||||||
}
|
}
|
||||||
|
dashboard.hideDashboardToolbar = true;
|
||||||
|
return dashboard;
|
||||||
|
})
|
||||||
|
))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const homeDashboardResolver: ResolveFn<HomeDashboard> = (
|
export const homeDashboardResolver: ResolveFn<HomeDashboard> = (
|
||||||
route: ActivatedRouteSnapshot,
|
route: ActivatedRouteSnapshot,
|
||||||
@ -85,27 +109,7 @@ export const homeDashboardResolver: ResolveFn<HomeDashboard> = (
|
|||||||
dashboardService.getHomeDashboard().pipe(
|
dashboardService.getHomeDashboard().pipe(
|
||||||
mergeMap((dashboard) => {
|
mergeMap((dashboard) => {
|
||||||
if (!dashboard) {
|
if (!dashboard) {
|
||||||
let dashboard$: Observable<HomeDashboard>;
|
return getHomeDashboard(store, resourcesService);
|
||||||
const authority = getCurrentAuthUser(store).authority;
|
|
||||||
switch (authority) {
|
|
||||||
case Authority.SYS_ADMIN:
|
|
||||||
dashboard$ = toggleMobileQRCodeDisplayIfNeeded(store, resourcesService.loadJsonResource(sysAdminHomePageJson));
|
|
||||||
break;
|
|
||||||
case Authority.TENANT_ADMIN:
|
|
||||||
dashboard$ = updateDeviceActivityKeyFilterIfNeeded(store, resourcesService.loadJsonResource(tenantAdminHomePageJson));
|
|
||||||
break;
|
|
||||||
case Authority.CUSTOMER_USER:
|
|
||||||
dashboard$ = updateDeviceActivityKeyFilterIfNeeded(store, resourcesService.loadJsonResource(customerUserHomePageJson));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (dashboard$) {
|
|
||||||
return dashboard$.pipe(
|
|
||||||
map((homeDashboard) => {
|
|
||||||
homeDashboard.hideDashboardToolbar = true;
|
|
||||||
return homeDashboard;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return of(dashboard);
|
return of(dashboard);
|
||||||
})
|
})
|
||||||
|
|||||||
@ -14,10 +14,9 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { TenantId } from '@shared/models/id/tenant-id';
|
import { HasTenantId } from '@shared/models/entity.models';
|
||||||
|
|
||||||
export interface MobileAppQRCodeSettings {
|
export interface MobileAppSettings extends HasTenantId {
|
||||||
tenantId: TenantId;
|
|
||||||
useDefaultApp: boolean;
|
useDefaultApp: boolean;
|
||||||
androidConfig: AndroidConfig;
|
androidConfig: AndroidConfig;
|
||||||
iosConfig: IosConfig;
|
iosConfig: IosConfig;
|
||||||
|
|||||||
@ -2634,22 +2634,24 @@
|
|||||||
"typeFullFqn": "system.home_page_widgets.getting_started"
|
"typeFullFqn": "system.home_page_widgets.getting_started"
|
||||||
},
|
},
|
||||||
"53d5f2dd-d432-5362-745f-63bf4487dc96": {
|
"53d5f2dd-d432-5362-745f-63bf4487dc96": {
|
||||||
"typeFullFqn": "system.home_page_widgets.home_page_mobile_app_qr_code",
|
"typeFullFqn": "system.mobile_app_qr_code",
|
||||||
"type": "static",
|
"type": "static",
|
||||||
"sizeX": 6,
|
"sizeX": 6,
|
||||||
"sizeY": 3,
|
"sizeY": 3,
|
||||||
"config": {
|
"config": {
|
||||||
"showTitle": false,
|
"showTitle": true,
|
||||||
"backgroundColor": "rgb(255, 255, 255)",
|
"backgroundColor": "rgb(255, 255, 255)",
|
||||||
"color": "rgba(0, 0, 0, 0.87)",
|
"color": "rgba(0, 0, 0, 0.87)",
|
||||||
"padding": "8px",
|
"padding": "8px",
|
||||||
"settings": {},
|
"settings": {},
|
||||||
"title": "Mobile app QR code",
|
"title": "{i18n:admin.mobile-app.connect-mobile-app}",
|
||||||
"dropShadow": false,
|
"dropShadow": false,
|
||||||
"enableFullscreen": false,
|
"enableFullscreen": false,
|
||||||
"widgetStyle": {},
|
"widgetStyle": {},
|
||||||
"widgetCss": "",
|
"widgetCss": ".tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title {\n padding: 0;\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title > .title-row > .title {\n padding-bottom: 12px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n",
|
||||||
"noDataDisplayMessage": ""
|
"showTitleIcon": false,
|
||||||
|
"titleTooltip": "",
|
||||||
|
"titleStyle": null
|
||||||
},
|
},
|
||||||
"row": 0,
|
"row": 0,
|
||||||
"col": 0,
|
"col": 0,
|
||||||
|
|||||||
@ -1177,19 +1177,24 @@
|
|||||||
"typeFullFqn": "system.home_page_widgets.getting_started"
|
"typeFullFqn": "system.home_page_widgets.getting_started"
|
||||||
},
|
},
|
||||||
"8c5207d8-7103-4dc2-db48-d61c0c8c61fd": {
|
"8c5207d8-7103-4dc2-db48-d61c0c8c61fd": {
|
||||||
"typeFullFqn": "system.home_page_widgets.home_page_mobile_app_qr_code",
|
"typeFullFqn": "system.mobile_app_qr_code",
|
||||||
"type": "static",
|
"type": "static",
|
||||||
"sizeX": 6,
|
"sizeX": 6,
|
||||||
"sizeY": 3,
|
"sizeY": 3,
|
||||||
"config": {
|
"config": {
|
||||||
"showTitle": false,
|
"showTitle": true,
|
||||||
"backgroundColor": "rgb(255, 255, 255)",
|
"backgroundColor": "rgb(255, 255, 255)",
|
||||||
"color": "rgba(0, 0, 0, 0.87)",
|
"color": "rgba(0, 0, 0, 0.87)",
|
||||||
"padding": "8px",
|
"padding": "8px",
|
||||||
"settings": {},
|
"settings": {},
|
||||||
"title": "Mobile app QR code",
|
"title": "{i18n:admin.mobile-app.connect-mobile-app}",
|
||||||
"dropShadow": false,
|
"dropShadow": false,
|
||||||
"enableFullscreen": false
|
"enableFullscreen": false,
|
||||||
|
"widgetStyle": {},
|
||||||
|
"widgetCss": ".tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title {\n padding: 0;\n}\n\n.tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title > .title-row > .title {\n padding-bottom: 12px;\n font-weight: 600;\n font-size: 20px;\n line-height: 24px;\n letter-spacing: 0.1px;\n color: rgba(0, 0, 0, 0.76);\n}\n\n@media screen and (min-width: 960px) and (max-width: 1819px) {\n .tb-widget-container > .tb-widget > .tb-widget-header > .tb-widget-title > .title-row > .title {\n padding-bottom: 0;\n font-weight: 500;\n font-size: 14px;\n line-height: 20px;\n letter-spacing: 0.25px;\n }\n}\n",
|
||||||
|
"showTitleIcon": false,
|
||||||
|
"titleTooltip": "",
|
||||||
|
"titleStyle": null
|
||||||
},
|
},
|
||||||
"row": 0,
|
"row": 0,
|
||||||
"col": 0,
|
"col": 0,
|
||||||
|
|||||||
@ -433,6 +433,7 @@
|
|||||||
"ios": "iOS",
|
"ios": "iOS",
|
||||||
"app-id": "App ID",
|
"app-id": "App ID",
|
||||||
"app-id-required": "App ID is required",
|
"app-id-required": "App ID is required",
|
||||||
|
"appearance": "Appearance",
|
||||||
"appearance-on-home-page": "Appearance on Home page",
|
"appearance-on-home-page": "Appearance on Home page",
|
||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
"disabled": "Disabled",
|
"disabled": "Disabled",
|
||||||
@ -445,7 +446,8 @@
|
|||||||
"left": "Left",
|
"left": "Left",
|
||||||
"set": "Set",
|
"set": "Set",
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"connect-mobile-app": "Connect mobile app"
|
"connect-mobile-app": "Connect mobile app",
|
||||||
|
"use-system-settings": "Use system settings"
|
||||||
},
|
},
|
||||||
"2fa": {
|
"2fa": {
|
||||||
"2fa": "Two-factor authentication",
|
"2fa": "Two-factor authentication",
|
||||||
|
|||||||
@ -234,6 +234,12 @@
|
|||||||
}
|
}
|
||||||
.fixed-title-width {
|
.fixed-title-width {
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
|
|
||||||
|
&-230 {
|
||||||
|
min-width: 230px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[class^="fixed-title-width"] {
|
||||||
@media #{$mat-xs} {
|
@media #{$mat-xs} {
|
||||||
min-width: fit-content;
|
min-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user