UI: Implement sections count parameter for battery level widget.
This commit is contained in:
parent
1bb2e8fc72
commit
c836c48366
@ -40,6 +40,12 @@
|
|||||||
{{ batteryLevelLayoutTranslationMap.get(layout) | translate }}
|
{{ batteryLevelLayoutTranslationMap.get(layout) | translate }}
|
||||||
</tb-image-cards-select-option>
|
</tb-image-cards-select-option>
|
||||||
</tb-image-cards-select>
|
</tb-image-cards-select>
|
||||||
|
<div *ngIf="sectionsCountEnabled" class="tb-form-row space-between">
|
||||||
|
<div>{{ 'widgets.battery-level.sections-count' | translate }}</div>
|
||||||
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
||||||
|
<input matInput type="number" min="2" max="20" formControlName="sectionsCount" placeholder="{{ 'widget-config.set' | translate }}">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
<div class="tb-form-row column-xs">
|
<div class="tb-form-row column-xs">
|
||||||
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showTitle">
|
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showTitle">
|
||||||
{{ 'widget-config.title' | translate }}
|
{{ 'widget-config.title' | translate }}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
@ -35,6 +35,7 @@ import { formatValue, isUndefined } from '@core/utils';
|
|||||||
import { cssSizeToStrSize, resolveCssSize } from '@shared/models/widget-settings.models';
|
import { cssSizeToStrSize, resolveCssSize } from '@shared/models/widget-settings.models';
|
||||||
import {
|
import {
|
||||||
batteryLevelDefaultSettings,
|
batteryLevelDefaultSettings,
|
||||||
|
BatteryLevelLayout,
|
||||||
batteryLevelLayoutImages,
|
batteryLevelLayoutImages,
|
||||||
batteryLevelLayouts,
|
batteryLevelLayouts,
|
||||||
batteryLevelLayoutTranslations,
|
batteryLevelLayoutTranslations,
|
||||||
@ -67,9 +68,13 @@ export class BatteryLevelBasicConfigComponent extends BasicWidgetConfigComponent
|
|||||||
|
|
||||||
valuePreviewFn = this._valuePreviewFn.bind(this);
|
valuePreviewFn = this._valuePreviewFn.bind(this);
|
||||||
|
|
||||||
|
get sectionsCountEnabled(): boolean {
|
||||||
|
const layout: BatteryLevelLayout = this.batteryLevelWidgetConfigForm.get('layout').value;
|
||||||
|
return [BatteryLevelLayout.vertical_divided, BatteryLevelLayout.horizontal_divided].includes(layout);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
protected widgetConfigComponent: WidgetConfigComponent,
|
protected widgetConfigComponent: WidgetConfigComponent,
|
||||||
private $injector: Injector,
|
|
||||||
private fb: UntypedFormBuilder) {
|
private fb: UntypedFormBuilder) {
|
||||||
super(store, widgetConfigComponent);
|
super(store, widgetConfigComponent);
|
||||||
}
|
}
|
||||||
@ -90,6 +95,7 @@ export class BatteryLevelBasicConfigComponent extends BasicWidgetConfigComponent
|
|||||||
datasources: [configData.config.datasources, []],
|
datasources: [configData.config.datasources, []],
|
||||||
|
|
||||||
layout: [settings.layout, []],
|
layout: [settings.layout, []],
|
||||||
|
sectionsCount: [settings.sectionsCount, [Validators.min(2), Validators.max(20)]],
|
||||||
|
|
||||||
showTitle: [configData.config.showTitle, []],
|
showTitle: [configData.config.showTitle, []],
|
||||||
title: [configData.config.title, []],
|
title: [configData.config.title, []],
|
||||||
@ -136,6 +142,7 @@ export class BatteryLevelBasicConfigComponent extends BasicWidgetConfigComponent
|
|||||||
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
|
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
|
||||||
|
|
||||||
this.widgetConfig.config.settings.layout = config.layout;
|
this.widgetConfig.config.settings.layout = config.layout;
|
||||||
|
this.widgetConfig.config.settings.sectionsCount = config.sectionsCount;
|
||||||
|
|
||||||
this.widgetConfig.config.settings.showValue = config.showValue;
|
this.widgetConfig.config.settings.showValue = config.showValue;
|
||||||
this.widgetConfig.config.settings.autoScaleValueSize = config.autoScaleValueSize === true;
|
this.widgetConfig.config.settings.autoScaleValueSize = config.autoScaleValueSize === true;
|
||||||
@ -155,13 +162,15 @@ export class BatteryLevelBasicConfigComponent extends BasicWidgetConfigComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected validatorTriggers(): string[] {
|
protected validatorTriggers(): string[] {
|
||||||
return ['showTitle', 'showIcon', 'showValue'];
|
return ['showTitle', 'showIcon', 'showValue', 'layout'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updateValidators(emitEvent: boolean, trigger?: string) {
|
protected updateValidators(emitEvent: boolean, trigger?: string) {
|
||||||
const showTitle: boolean = this.batteryLevelWidgetConfigForm.get('showTitle').value;
|
const showTitle: boolean = this.batteryLevelWidgetConfigForm.get('showTitle').value;
|
||||||
const showIcon: boolean = this.batteryLevelWidgetConfigForm.get('showIcon').value;
|
const showIcon: boolean = this.batteryLevelWidgetConfigForm.get('showIcon').value;
|
||||||
const showValue: boolean = this.batteryLevelWidgetConfigForm.get('showValue').value;
|
const showValue: boolean = this.batteryLevelWidgetConfigForm.get('showValue').value;
|
||||||
|
const layout: BatteryLevelLayout = this.batteryLevelWidgetConfigForm.get('layout').value;
|
||||||
|
const divided = [BatteryLevelLayout.vertical_divided, BatteryLevelLayout.horizontal_divided].includes(layout);
|
||||||
|
|
||||||
if (showTitle) {
|
if (showTitle) {
|
||||||
this.batteryLevelWidgetConfigForm.get('title').enable();
|
this.batteryLevelWidgetConfigForm.get('title').enable();
|
||||||
@ -199,6 +208,11 @@ export class BatteryLevelBasicConfigComponent extends BasicWidgetConfigComponent
|
|||||||
this.batteryLevelWidgetConfigForm.get('valueFont').disable();
|
this.batteryLevelWidgetConfigForm.get('valueFont').disable();
|
||||||
this.batteryLevelWidgetConfigForm.get('valueColor').disable();
|
this.batteryLevelWidgetConfigForm.get('valueColor').disable();
|
||||||
}
|
}
|
||||||
|
if (divided) {
|
||||||
|
this.batteryLevelWidgetConfigForm.get('sectionsCount').enable();
|
||||||
|
} else {
|
||||||
|
this.batteryLevelWidgetConfigForm.get('sectionsCount').disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCardButtons(config: WidgetConfig): string[] {
|
private getCardButtons(config: WidgetConfig): string[] {
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<div #batteryLevelBox class="tb-battery-level-box">
|
<div #batteryLevelBox class="tb-battery-level-box">
|
||||||
<div #batteryLevelRectangle class="tb-battery-level-rectangle" [class]="layoutClass" [class.solid]="solid" [class.divided]="!solid">
|
<div #batteryLevelRectangle class="tb-battery-level-rectangle" [class]="layoutClass" [class.solid]="solid" [class.divided]="!solid">
|
||||||
<div class="tb-battery-level-shape" [style.background]="batteryShapeColor.color"></div>
|
<div class="tb-battery-level-shape" [style.background]="batteryShapeColor.color"></div>
|
||||||
<div class="tb-battery-level-container">
|
<div class="tb-battery-level-container" [style.gap]="dividedGap">
|
||||||
<div *ngIf="solid; else dividedIndicator" class="tb-battery-level-indicator-box solid"
|
<div *ngIf="solid; else dividedIndicator" class="tb-battery-level-indicator-box solid"
|
||||||
[style.background-image]="'linear-gradient(0deg, ' + batteryLevelColor.color + ' 0% 100%)'"
|
[style.background-image]="'linear-gradient(0deg, ' + batteryLevelColor.color + ' 0% 100%)'"
|
||||||
[style.background-size]="vertical ? '100% ' + (value + 1) + '%' : (value + 1) + '% 100%'">
|
[style.background-size]="vertical ? '100% ' + (value + 1) + '%' : (value + 1) + '% 100%'">
|
||||||
@ -38,5 +38,6 @@
|
|||||||
<ng-template #dividedIndicator>
|
<ng-template #dividedIndicator>
|
||||||
<div *ngFor="let section of batterySections; trackBy: trackBySection" class="tb-battery-level-indicator-box divided"
|
<div *ngFor="let section of batterySections; trackBy: trackBySection" class="tb-battery-level-indicator-box divided"
|
||||||
[style.background]="batteryLevelColor.color"
|
[style.background]="batteryLevelColor.color"
|
||||||
|
[style.border-radius]="dividedBorderRadius"
|
||||||
[style.opacity]="section ? '1': '0'"></div>
|
[style.opacity]="section ? '1': '0'"></div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|||||||
@ -117,7 +117,9 @@ export class BatteryLevelWidgetComponent implements OnInit, OnDestroy, AfterView
|
|||||||
|
|
||||||
value: number;
|
value: number;
|
||||||
|
|
||||||
batterySections: boolean[] = [false, false, false, false];
|
batterySections: boolean[];
|
||||||
|
dividedBorderRadius: string;
|
||||||
|
dividedGap: string;
|
||||||
|
|
||||||
batteryLevelColor: ColorProcessor;
|
batteryLevelColor: ColorProcessor;
|
||||||
|
|
||||||
@ -158,6 +160,26 @@ export class BatteryLevelWidgetComponent implements OnInit, OnDestroy, AfterView
|
|||||||
this.vertical = [BatteryLevelLayout.vertical_solid, BatteryLevelLayout.vertical_divided].includes(this.layout);
|
this.vertical = [BatteryLevelLayout.vertical_solid, BatteryLevelLayout.vertical_divided].includes(this.layout);
|
||||||
this.layoutClass = this.vertical ? 'vertical' : 'horizontal';
|
this.layoutClass = this.vertical ? 'vertical' : 'horizontal';
|
||||||
this.solid = [BatteryLevelLayout.vertical_solid, BatteryLevelLayout.horizontal_solid].includes(this.layout);
|
this.solid = [BatteryLevelLayout.vertical_solid, BatteryLevelLayout.horizontal_solid].includes(this.layout);
|
||||||
|
if (!this.solid) {
|
||||||
|
let sectionsCount = this.settings.sectionsCount;
|
||||||
|
if (!sectionsCount) {
|
||||||
|
sectionsCount = 4;
|
||||||
|
}
|
||||||
|
sectionsCount = Math.min(Math.max(sectionsCount, 2), 20);
|
||||||
|
this.batterySections = Array.from(Array(sectionsCount), () => false);
|
||||||
|
const gap = 1 + (24 - sectionsCount) / 10;
|
||||||
|
this.dividedGap = `${gap}%`;
|
||||||
|
const containerAspect = 0.5567;
|
||||||
|
const sectionHeight = (100 - (gap * (sectionsCount - 1))) / sectionsCount;
|
||||||
|
const sectionAspect = 100 * containerAspect / sectionHeight;
|
||||||
|
const rad1 = 8.425 - sectionsCount * 0.32125;
|
||||||
|
const rad2 = rad1 * sectionAspect;
|
||||||
|
if (this.vertical) {
|
||||||
|
this.dividedBorderRadius = `${rad1}% / ${rad2}%`;
|
||||||
|
} else {
|
||||||
|
this.dividedBorderRadius = `${rad2}% / ${rad1}%`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.showValue = this.settings.showValue;
|
this.showValue = this.settings.showValue;
|
||||||
this.autoScaleValueSize = this.showValue && this.settings.autoScaleValueSize;
|
this.autoScaleValueSize = this.showValue && this.settings.autoScaleValueSize;
|
||||||
@ -243,6 +265,8 @@ export class BatteryLevelWidgetComponent implements OnInit, OnDestroy, AfterView
|
|||||||
const valueLineHeight = ratios.valueLineHeightRaio * boxSize;
|
const valueLineHeight = ratios.valueLineHeightRaio * boxSize;
|
||||||
this.setValueFontSize(valueFontSize, valueLineHeight, boxWidth);
|
this.setValueFontSize(valueFontSize, valueLineHeight, boxWidth);
|
||||||
}
|
}
|
||||||
|
const fontSize = parseInt(window.getComputedStyle(this.batteryLevelValue.nativeElement).fontSize, 10) || 10;
|
||||||
|
this.renderer.setStyle(this.batteryLevelValue.nativeElement, 'minWidth', `${Math.min(fontSize*4, boxWidth)}px`);
|
||||||
}
|
}
|
||||||
let height = this.batteryLevelContent.nativeElement.getBoundingClientRect().height;
|
let height = this.batteryLevelContent.nativeElement.getBoundingClientRect().height;
|
||||||
const width = height * verticalBatteryDimensions.shapeAspectRatio;
|
const width = height * verticalBatteryDimensions.shapeAspectRatio;
|
||||||
|
|||||||
@ -53,6 +53,7 @@ export const batteryLevelLayoutImages = new Map<BatteryLevelLayout, string>(
|
|||||||
|
|
||||||
export interface BatteryLevelWidgetSettings {
|
export interface BatteryLevelWidgetSettings {
|
||||||
layout: BatteryLevelLayout;
|
layout: BatteryLevelLayout;
|
||||||
|
sectionsCount: number;
|
||||||
showValue: boolean;
|
showValue: boolean;
|
||||||
autoScaleValueSize: boolean;
|
autoScaleValueSize: boolean;
|
||||||
valueFont: Font;
|
valueFont: Font;
|
||||||
@ -64,6 +65,7 @@ export interface BatteryLevelWidgetSettings {
|
|||||||
|
|
||||||
export const batteryLevelDefaultSettings: BatteryLevelWidgetSettings = {
|
export const batteryLevelDefaultSettings: BatteryLevelWidgetSettings = {
|
||||||
layout: BatteryLevelLayout.vertical_solid,
|
layout: BatteryLevelLayout.vertical_solid,
|
||||||
|
sectionsCount: 4,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
autoScaleValueSize: true,
|
autoScaleValueSize: true,
|
||||||
valueFont: {
|
valueFont: {
|
||||||
|
|||||||
@ -28,6 +28,12 @@
|
|||||||
{{ batteryLevelLayoutTranslationMap.get(layout) | translate }}
|
{{ batteryLevelLayoutTranslationMap.get(layout) | translate }}
|
||||||
</tb-image-cards-select-option>
|
</tb-image-cards-select-option>
|
||||||
</tb-image-cards-select>
|
</tb-image-cards-select>
|
||||||
|
<div *ngIf="sectionsCountEnabled" class="tb-form-row space-between">
|
||||||
|
<div>{{ 'widgets.battery-level.sections-count' | translate }}</div>
|
||||||
|
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
|
||||||
|
<input matInput type="number" min="2" max="20" formControlName="sectionsCount" placeholder="{{ 'widget-config.set' | translate }}">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
<div class="tb-form-row space-between column-xs">
|
<div class="tb-form-row space-between column-xs">
|
||||||
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showValue">
|
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showValue">
|
||||||
{{ 'widgets.battery-level.value' | translate }}
|
{{ 'widgets.battery-level.value' | translate }}
|
||||||
|
|||||||
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
import { Component, Injector } from '@angular/core';
|
import { Component, Injector } from '@angular/core';
|
||||||
import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
|
import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
import { AppState } from '@core/core.state';
|
||||||
import { formatValue } from '@core/utils';
|
import { formatValue } from '@core/utils';
|
||||||
import {
|
import {
|
||||||
batteryLevelDefaultSettings,
|
batteryLevelDefaultSettings, BatteryLevelLayout,
|
||||||
batteryLevelLayoutImages,
|
batteryLevelLayoutImages,
|
||||||
batteryLevelLayouts,
|
batteryLevelLayouts,
|
||||||
batteryLevelLayoutTranslations
|
batteryLevelLayoutTranslations
|
||||||
@ -43,6 +43,11 @@ export class BatteryLevelWidgetSettingsComponent extends WidgetSettingsComponent
|
|||||||
|
|
||||||
valuePreviewFn = this._valuePreviewFn.bind(this);
|
valuePreviewFn = this._valuePreviewFn.bind(this);
|
||||||
|
|
||||||
|
get sectionsCountEnabled(): boolean {
|
||||||
|
const layout: BatteryLevelLayout = this.batteryLevelWidgetSettingsForm.get('layout').value;
|
||||||
|
return [BatteryLevelLayout.vertical_divided, BatteryLevelLayout.horizontal_divided].includes(layout);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>,
|
constructor(protected store: Store<AppState>,
|
||||||
private $injector: Injector,
|
private $injector: Injector,
|
||||||
private fb: UntypedFormBuilder) {
|
private fb: UntypedFormBuilder) {
|
||||||
@ -60,6 +65,7 @@ export class BatteryLevelWidgetSettingsComponent extends WidgetSettingsComponent
|
|||||||
protected onSettingsSet(settings: WidgetSettings) {
|
protected onSettingsSet(settings: WidgetSettings) {
|
||||||
this.batteryLevelWidgetSettingsForm = this.fb.group({
|
this.batteryLevelWidgetSettingsForm = this.fb.group({
|
||||||
layout: [settings.layout, []],
|
layout: [settings.layout, []],
|
||||||
|
sectionsCount: [settings.sectionsCount, [Validators.min(2), Validators.max(20)]],
|
||||||
|
|
||||||
showValue: [settings.showValue, []],
|
showValue: [settings.showValue, []],
|
||||||
autoScaleValueSize: [settings.autoScaleValueSize, []],
|
autoScaleValueSize: [settings.autoScaleValueSize, []],
|
||||||
@ -74,11 +80,13 @@ export class BatteryLevelWidgetSettingsComponent extends WidgetSettingsComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected validatorTriggers(): string[] {
|
protected validatorTriggers(): string[] {
|
||||||
return ['showValue'];
|
return ['showValue', 'layout'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updateValidators(emitEvent: boolean) {
|
protected updateValidators(emitEvent: boolean) {
|
||||||
const showValue: boolean = this.batteryLevelWidgetSettingsForm.get('showValue').value;
|
const showValue: boolean = this.batteryLevelWidgetSettingsForm.get('showValue').value;
|
||||||
|
const layout: BatteryLevelLayout = this.batteryLevelWidgetSettingsForm.get('layout').value;
|
||||||
|
const divided = [BatteryLevelLayout.vertical_divided, BatteryLevelLayout.horizontal_divided].includes(layout);
|
||||||
|
|
||||||
if (showValue) {
|
if (showValue) {
|
||||||
this.batteryLevelWidgetSettingsForm.get('autoScaleValueSize').enable();
|
this.batteryLevelWidgetSettingsForm.get('autoScaleValueSize').enable();
|
||||||
@ -90,9 +98,16 @@ export class BatteryLevelWidgetSettingsComponent extends WidgetSettingsComponent
|
|||||||
this.batteryLevelWidgetSettingsForm.get('valueColor').disable();
|
this.batteryLevelWidgetSettingsForm.get('valueColor').disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (divided) {
|
||||||
|
this.batteryLevelWidgetSettingsForm.get('sectionsCount').enable();
|
||||||
|
} else {
|
||||||
|
this.batteryLevelWidgetSettingsForm.get('sectionsCount').disable();
|
||||||
|
}
|
||||||
|
|
||||||
this.batteryLevelWidgetSettingsForm.get('autoScaleValueSize').updateValueAndValidity({emitEvent});
|
this.batteryLevelWidgetSettingsForm.get('autoScaleValueSize').updateValueAndValidity({emitEvent});
|
||||||
this.batteryLevelWidgetSettingsForm.get('valueFont').updateValueAndValidity({emitEvent});
|
this.batteryLevelWidgetSettingsForm.get('valueFont').updateValueAndValidity({emitEvent});
|
||||||
this.batteryLevelWidgetSettingsForm.get('valueColor').updateValueAndValidity({emitEvent});
|
this.batteryLevelWidgetSettingsForm.get('valueColor').updateValueAndValidity({emitEvent});
|
||||||
|
this.batteryLevelWidgetSettingsForm.get('sectionsCount').updateValueAndValidity({emitEvent});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _valuePreviewFn(): string {
|
private _valuePreviewFn(): string {
|
||||||
|
|||||||
@ -5057,7 +5057,8 @@
|
|||||||
"auto-scale": "Auto scale",
|
"auto-scale": "Auto scale",
|
||||||
"battery-level-color": "Battery level color",
|
"battery-level-color": "Battery level color",
|
||||||
"battery-shape-color": "Battery shape color",
|
"battery-shape-color": "Battery shape color",
|
||||||
"battery-level-card-style": "Battery level card style"
|
"battery-level-card-style": "Battery level card style",
|
||||||
|
"sections-count": "Sections count"
|
||||||
},
|
},
|
||||||
"chart": {
|
"chart": {
|
||||||
"common-settings": "Common settings",
|
"common-settings": "Common settings",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user