Browse Source

UI: Liquid level widget improvements, string autocomplete improvements

pull/9456/head
Dmitriymush 3 years ago
parent
commit
c20098088d
  1. 4
      ui-ngx/src/app/core/services/resources.service.ts
  2. 4
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/liquid-level-card-basic-config.component.html
  3. 3
      ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.models.ts
  4. 31
      ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.ts
  5. 3
      ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/liquid-level-card-widget-settings.component.html
  6. 22
      ui-ngx/src/app/shared/components/string-autocomplete.component.html
  7. 33
      ui-ngx/src/app/shared/components/string-autocomplete.component.scss
  8. 58
      ui-ngx/src/app/shared/components/string-autocomplete.component.ts
  9. 3
      ui-ngx/src/app/shared/shared.module.ts

4
ui-ngx/src/app/core/services/resources.service.ts

@ -68,7 +68,9 @@ export class ResourcesService {
}
const subject = new ReplaySubject<any>();
this.loadedJsonResources[url] = subject;
this.http.get<T>(url).subscribe(
const req$ = (url.endsWith('.raw') || url.endsWith('.svg') ?
this.http.get(url, {responseType: 'text'}) : this.http.get<T>(url)) as Observable<T>;
req$.subscribe(
{
next: (o) => {
if (postProcess) {

4
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/liquid-level-card-basic-config.component.html

@ -93,6 +93,7 @@
<div class="fixed-title-width tb-required" translate>widgets.liquid-level-card.shape-attribute-name</div>
<tb-string-autocomplete [fetchOptionsFn]="fetchOptions.bind(this)"
[required]="isRequired('shapeAttributeName')"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
formControlName="shapeAttributeName">
@ -151,6 +152,7 @@
<tb-string-autocomplete [fxShow]="levelCardWidgetConfigForm.get('widgetUnitsSource')?.value === levelOptions.attribute"
[fetchOptionsFn]="fetchOptions.bind(this)"
[required]="isRequired('widgetUnitsAttributeName')"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
formControlName="widgetUnitsAttributeName">
@ -183,6 +185,7 @@
<tb-string-autocomplete style="max-width: 25%"
[fxShow]="levelCardWidgetConfigForm.get('volumeSource')?.value === levelOptions.attribute"
[fetchOptionsFn]="fetchOptions.bind(this)"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
[required]="isRequired('volumeAttributeName')"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
@ -315,7 +318,6 @@
<div class="tb-form-row space-between column-lt-md">
<div translate>widget-config.show-card-buttons</div>
<mat-chip-listbox multiple formControlName="cardButtons">
<mat-chip-option value="dataExport">{{ 'widget-config.data-export' | translate }}</mat-chip-option>
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>

3
ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.models.ts

@ -16,7 +16,8 @@
import {
ColorSettings,
constantColor, cssTextFromInlineStyle,
constantColor,
cssTextFromInlineStyle,
DateFormatSettings,
Font,
lastUpdateAgoDateFormat

31
ui-ngx/src/app/modules/home/components/widget/lib/indicator/liquid-level-widget.ts

@ -43,13 +43,11 @@ import {
import ITooltipsterInstance = JQueryTooltipster.ITooltipsterInstance;
import { ResourcesService } from '@core/services/resources.service';
import { NULL_UUID } from '@shared/models/id/has-uuid';
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'tb-liquid-level-widget',
template: '',
styleUrls: [],
encapsulation: ViewEncapsulation.None
template: ''
})
export class LiquidLevelWidgetComponent implements OnInit {
@ -98,17 +96,7 @@ export class LiquidLevelWidgetComponent implements OnInit {
ngOnInit(): void {
this.ctx.$scope.liquidLevelWidget = this;
this.settings = {...levelCardDefaultSettings(), ...this.ctx.widgetConfig, ...this.ctx.settings};
this.tankColor = ColorProcessor.fromSettings(this.settings.tankColor);
this.volumeColor = ColorProcessor.fromSettings(this.settings.volumeColor);
this.valueColor = ColorProcessor.fromSettings(this.settings.valueColor);
this.liquidColor = ColorProcessor.fromSettings(this.settings.liquidColor);
this.backgroundOverlayColor = ColorProcessor.fromSettings(this.settings.backgroundOverlayColor);
this.tooltipLevelColor = ColorProcessor.fromSettings(this.settings.tooltipLevelColor);
this.tooltipDateColor = ColorProcessor.fromSettings(this.settings.tooltipDateColor);
this.tooltipBackgroundColor = ColorProcessor.fromSettings(this.settings.tooltipBackgroundColor);
this.tooltipDateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.tooltipDateFormat);
this.declareStyles();
}
public onInit() {
@ -140,6 +128,19 @@ export class LiquidLevelWidgetComponent implements OnInit {
});
}
private declareStyles():void {
this.tankColor = ColorProcessor.fromSettings(this.settings.tankColor);
this.volumeColor = ColorProcessor.fromSettings(this.settings.volumeColor);
this.valueColor = ColorProcessor.fromSettings(this.settings.valueColor);
this.liquidColor = ColorProcessor.fromSettings(this.settings.liquidColor);
this.backgroundOverlayColor = ColorProcessor.fromSettings(this.settings.backgroundOverlayColor);
this.tooltipLevelColor = ColorProcessor.fromSettings(this.settings.tooltipLevelColor);
this.tooltipDateColor = ColorProcessor.fromSettings(this.settings.tooltipDateColor);
this.tooltipBackgroundColor = ColorProcessor.fromSettings(this.settings.tooltipBackgroundColor);
this.tooltipDateFormat = DateFormatProcessor.fromSettings(this.ctx.$injector, this.settings.tooltipDateFormat);
}
private getData(): Observable<{ svg: string; volume: number; units: string }> {
const entityId: EntityId = {
entityType: this.ctx.datasources[0].entityType,

3
ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/liquid-level-card-widget-settings.component.html

@ -48,6 +48,7 @@
<div class="fixed-title-width" translate>widgets.liquid-level-card.shape-attribute-name</div>
<tb-string-autocomplete [fetchOptionsFn]="fetchOptions.bind(this)"
[required]="isRequired('shapeAttributeName')"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
formControlName="shapeAttributeName">
@ -110,6 +111,7 @@
<tb-string-autocomplete [fxShow]="levelCardWidgetSettingsForm.get('widgetUnitsSource')?.value === volumeOptions.attribute"
[fetchOptionsFn]="fetchOptions.bind(this)"
[required]="isRequired('widgetUnitsAttributeName')"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
formControlName="widgetUnitsAttributeName">
@ -143,6 +145,7 @@
[fxShow]="levelCardWidgetSettingsForm.get('volumeSource')?.value === volumeOptions.attribute"
[fetchOptionsFn]="fetchOptions.bind(this)"
[required]="isRequired('volumeAttributeName')"
[errorText]="'widgets.liquid-level-card.attribute-name-required' | translate"
style="flex: 1; width: auto;"
asBoxInput colorClearButton class="flex"
formControlName="volumeAttributeName">

22
ui-ngx/src/app/shared/components/string-autocomplete.component.html

@ -15,30 +15,36 @@
limitations under the License.
-->
<mat-form-field fxFlex appearance="outline" class="tb-inline-field tb-suffix-show-on-hover" subscriptSizing="dynamic" style="width: 100%">
<mat-form-field [appearance]="appearance" [ngClass]="ngClass"
[subscriptSizing]="subscriptSizing" style="width: 100%">
<mat-label *ngIf="label">{{label}}</mat-label>
<input matInput #nameInput [formControl]="selectionFormControl"
placeholder="{{ 'widget-config.set' | translate }}"
[placeholder]="placeholderText"
(focusin)="onFocus()"
[matAutocomplete]="optionsAutocomplete">
<button *ngIf="selectionFormControl.value && !disabled && selectionFormControl.valid"
<button *ngIf="selectionFormControl.value && !disabled"
type="button"
class="tb-icon-24"
matSuffix mat-icon-button aria-label="Clear"
(click)="clear()">
<mat-icon class="material-icons">close</mat-icon>
</button>
<mat-icon matSuffix
<mat-icon *ngIf="selectionFormControl.hasError('required') && !showInlineError"
matIconSuffix
[matTooltip]="errorText"
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'widget-config.units-required' | translate"
*ngIf="selectionFormControl.hasError('required')" class="material-icons tb-suffix-show-always tb-error">
[matTooltipClass]="tooltipClass"
class="material-icons tb-suffix-show-always tb-error">
warning
</mat-icon>
<mat-error *ngIf="selectionFormControl.hasError('required') && showInlineError">
{{errorText}}
</mat-error>
<mat-autocomplete
#optionsAutocomplete="matAutocomplete"
class="tb-autocomplete tb-options-input-autocomplete"
panelWidth="fit-content">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
<mat-option *ngFor="let option of filteredOptions$ | async" [value]="option">
<span class="tb-option-name" fxFlex [innerHTML]="option | highlight:searchText:true:'ig'"></span>
</mat-option>
</mat-autocomplete>

33
ui-ngx/src/app/shared/components/string-autocomplete.component.scss

@ -13,19 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.tb-autocomplete.tb-option-input-autocomplete {
.mat-mdc-option {
border-bottom: none;
.mdc-list-item__primary-text {
flex: 1;
display: flex;
flex-direction: row;
gap: 8px;
.tb-option {
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0.2px;
:host {
display: flex;
flex: 1 1 0%;
max-width: 100%;
box-sizing: border-box;
.tb-autocomplete.tb-option-input-autocomplete {
.mat-mdc-option {
border-bottom: none;
.mdc-list-item__primary-text {
flex: 1;
display: flex;
flex-direction: row;
gap: 8px;
.tb-option {
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0.2px;
}
}
}
}

58
ui-ngx/src/app/shared/components/string-autocomplete.component.ts

@ -19,11 +19,8 @@ import {
Input,
forwardRef,
OnInit,
AfterViewInit,
HostBinding,
ViewChild,
ElementRef,
Injector
ElementRef
} from '@angular/core';
import {
ControlValueAccessor,
@ -33,7 +30,9 @@ import {
FormBuilder
} from '@angular/forms';
import { Observable, of } from 'rxjs';
import { tap, map, switchMap } from 'rxjs/operators';
import { tap, map, switchMap, take } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({
selector: 'tb-string-autocomplete',
@ -47,13 +46,12 @@ import { tap, map, switchMap } from 'rxjs/operators';
}
]
})
export class StringAutocompleteComponent implements ControlValueAccessor, OnInit, AfterViewInit {
@HostBinding('style.display') get hostDisplay() {return 'flex';};
export class StringAutocompleteComponent implements ControlValueAccessor, OnInit {
@Input()
disabled: boolean;
@coerceBoolean()
@Input()
required: boolean;
@ -61,11 +59,36 @@ export class StringAutocompleteComponent implements ControlValueAccessor, OnInit
@ViewChild('nameInput', {static: true}) nameInput: ElementRef;
@Input()
placeholderText: string = this.translate.instant('widget-config.set');
@Input()
subscriptSizing: string = 'dynamic';
@Input()
ngClass: string | string[] | Set<string> | { [klass: string]: any; } = 'tb-inline-field tb-suffix-show-on-hover';
@Input()
appearance: string = 'outline';
@Input()
label: string;
@Input()
tooltipClass: string = 'tb-error-tooltip';
@Input()
errorText: string;
@coerceBoolean()
@Input()
showInlineError: boolean = false;
selectionFormControl: FormControl;
modelValue: string | null;
filteredOptions: Observable<Array<string>>;
filteredOptions$: Observable<Array<string>>;
searchText = '';
@ -73,13 +96,13 @@ export class StringAutocompleteComponent implements ControlValueAccessor, OnInit
private propagateChange = (_val: any) => {};
constructor(private injector: Injector,
private fb: FormBuilder) {
constructor(private fb: FormBuilder,
private translate: TranslateService) {
}
ngOnInit() {
this.selectionFormControl = this.fb.control('', []);
this.filteredOptions = this.selectionFormControl.valueChanges
this.selectionFormControl = this.fb.control('', this.required ? [Validators.required] : []);
this.filteredOptions$ = this.selectionFormControl.valueChanges
.pipe(
tap(value => this.updateView(value)),
map(value => value ? value : ''),
@ -87,12 +110,6 @@ export class StringAutocompleteComponent implements ControlValueAccessor, OnInit
);
}
ngAfterViewInit() {
if (this.required) {
this.selectionFormControl.setValidators([Validators.required]);
}
}
writeValue(option?: string): void {
this.searchText = '';
this.modelValue = option ? option : null;
@ -107,7 +124,8 @@ export class StringAutocompleteComponent implements ControlValueAccessor, OnInit
}
return option;
})
}),
take(1)
)
.subscribe(result => {
this.selectionFormControl.patchValue(result, { emitEvent: false });

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

@ -200,7 +200,6 @@ import { ColorPickerPanelComponent } from '@shared/components/color-picker/color
import { TbIconComponent } from '@shared/components/icon.component';
import { HintTooltipIconComponent } from '@shared/components/hint-tooltip-icon.component';
import { StringAutocompleteComponent } from '@shared/components/string-autocomplete.component';
import { MatFormFieldModule } from '@angular/material/form-field';
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
return markedOptionsService;
@ -401,7 +400,6 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
MatGridListModule,
MatDialogModule,
MatSelectModule,
MatFormFieldModule,
MatTooltipModule,
MatTableModule,
MatPaginatorModule,
@ -517,7 +515,6 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
MatGridListModule,
MatDialogModule,
MatSelectModule,
MatFormFieldModule,
MatTooltipModule,
MatTableModule,
MatPaginatorModule,

Loading…
Cancel
Save