Browse Source

Merge remote-tracking branch 'upstream/lts-4.3' into rc

pull/15294/head
Vladyslav Prykhodko 4 months ago
parent
commit
2469d97e0d
  1. 4
      ui-ngx/src/app/core/interceptors/global-http-interceptor.ts
  2. 18
      ui-ngx/src/app/core/utils.ts
  3. 24
      ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts
  4. 3
      ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts
  5. 9
      ui-ngx/src/app/shared/components/string-items-list.component.html
  6. 45
      ui-ngx/src/app/shared/components/string-items-list.component.ts
  7. 6
      ui-ngx/src/app/shared/models/constants.ts
  8. 6
      ui-ngx/yarn.lock

4
ui-ngx/src/app/core/interceptors/global-http-interceptor.ts

@ -129,10 +129,6 @@ export class GlobalHttpInterceptor implements HttpInterceptor {
this.showError(req.method + ': ' + req.url + '<br/>' +
errorResponse.status + ': ' + errorResponse.statusText);
}
} else if (errorResponse.status === 504) {
if (!ignoreErrors) {
this.showError('Request timeout');
}
} else {
unhandled = true;
}

18
ui-ngx/src/app/core/utils.ts

@ -23,7 +23,7 @@ import { NULL_UUID } from '@shared/models/id/has-uuid';
import { baseDetailsPageByEntityType, EntityType } from '@shared/models/entity-type.models';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import { serverErrorCodesTranslations } from '@shared/models/constants';
import { httpStatusMessageMap, serverErrorCodesTranslations } from '@shared/models/constants';
import { SubscriptionEntityInfo } from '@core/api/widget-api.models';
import {
CompiledTbFunction,
@ -910,11 +910,13 @@ export function parseHttpErrorMessage(errorResponse: HttpErrorResponse,
} else {
error = errorResponse.error;
}
if (error && !error.message) {
errorMessage = prepareMessageFromData(error);
} else if (error && error.message) {
if (error && error.message) {
errorMessage = error.message;
timeout = error.timeout ? error.timeout : 0;
} else if (isProxyError(errorResponse)) {
errorMessage = httpStatusMessageMap.get(errorResponse.status);
} else if (error) {
errorMessage = prepareMessageFromData(error);
} else {
errorMessage = `Unhandled error code ${error ? error.status : '\'Unknown\''}`;
}
@ -951,6 +953,14 @@ function prepareMessageFromData(data): string {
}
}
function isProxyError(errorResponse: HttpErrorResponse): boolean {
if (!httpStatusMessageMap.has(errorResponse.status)) {
return false;
}
const error = errorResponse.error;
return !error || typeof error === 'string' || (typeof error === 'object' && !error.message);
}
export const genNextLabel = (name: string, datasources: Datasource[]): string => {
let label = name;
let i = 1;

24
ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts

@ -433,7 +433,7 @@ export function noDataMessage(noDataDisplayMessage: string, defaultMessage: stri
return translate.instant(defaultMessage);
}
export function constructTableCssString(widgetConfig: WidgetConfig): string {
export function constructTableCssString(widgetConfig: WidgetConfig, isTabsEnabled = false): string {
const origColor = widgetConfig.color || 'rgba(0, 0, 0, 0.87)';
const origBackgroundColor = widgetConfig.backgroundColor || 'rgb(255, 255, 255)';
const currentEntityColor = 'rgba(221, 221, 221, 0.65)';
@ -451,13 +451,9 @@ export function constructTableCssString(widgetConfig: WidgetConfig): string {
const mdDarkDisabled = defaultColor.setAlpha(0.26).toRgbString();
const mdDarkDisabled2 = defaultColor.setAlpha(0.38).toRgbString();
const mdDarkDivider = defaultColor.setAlpha(0.12).toRgbString();
const cssString = ` {
let cssString = ` {
--mat-toolbar-container-text-color: ${mdDark};
--mat-tab-active-label-text-color: ${mdDark};
--mat-tab-inactive-label-text-color: ${mdDark};
--mat-tab-pagination-icon-color: ${mdDark};
--mat-tab-pagination-disabled-icon-color: ${mdDarkDisabled2};
--mat-table-header-headline-color: ${mdDarkSecondary};
--mat-table-row-item-label-text-color: ${mdDark};
--mat-icon-color: ${mdDarkSecondary};
@ -481,7 +477,19 @@ export function constructTableCssString(widgetConfig: WidgetConfig): string {
--tb-selected-sticky-color: ${selectedStickyColor};
}
`;
return cssString;
if (isTabsEnabled) {
cssString += `
.mat-mdc-tab-group {
--mat-tab-inactive-label-text-color: ${mdDarkSecondary};
--mat-tab-pagination-icon-color: ${mdDark};
--mat-tab-pagination-disabled-icon-color: ${mdDarkDisabled2};
--mat-tab-inactive-ripple-color: ${mdDarkSecondary};
--mat-tab-inactive-focus-label-text-color: ${mdDarkSecondary};
--mat-tab-inactive-hover-label-text-color: ${mdDarkSecondary};
}
`
}
return cssString ;
}
export function getHeaderTitle(dataKey: DataKey, keySettings: TableWidgetDataKeySettings | undefined, utils: UtilsService) {

3
ui-ngx/src/app/modules/home/components/widget/lib/timeseries-table-widget.component.ts

@ -379,8 +379,7 @@ export class TimeseriesTableWidgetComponent extends PageComponent implements OnI
this.noDataDisplayMessageText =
noDataMessage(this.widgetConfig.noDataDisplayMessage, 'widget.no-data-found', this.utils, this.translate);
let cssString = constructTableCssString(this.widgetConfig);
let cssString = constructTableCssString(this.widgetConfig, true);
const origBackgroundColor = this.widgetConfig.backgroundColor || 'rgb(255, 255, 255)';
cssString += '.tb-table-widget mat-toolbar.mat-mdc-table-toolbar:not([color=primary]) {\n' +

9
ui-ngx/src/app/shared/components/string-items-list.component.html

@ -31,7 +31,6 @@
<mat-icon matChipRemove *ngIf="!disabled">close</mat-icon>
</mat-chip-row>
<input matInput type="text"
(blur)="addOnBlur($event)"
placeholder="{{ placeholder }}"
style="max-width: 300px;min-width: 250px"
#stringItemInput
@ -40,20 +39,22 @@
#origin="matAutocompleteOrigin"
[matChipInputFor]="itemsChipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="true"
matAutocompleteOrigin
(matChipInputTokenEnd)="addOnEnd($event)"
[matAutocompleteConnectedTo]="origin"
[matAutocomplete]="stringItemAutocomplete"
[matAutocompleteDisabled]="!predefinedValues?.length">
[matAutocompleteDisabled]="!predefinedValues?.length && !fetchOptionsFn">
</mat-chip-grid>
<mat-autocomplete #stringItemAutocomplete="matAutocomplete"
[displayWith]="displayValueFn"
(optionSelected)="onOptionSelected($event)"
class="tb-autocomplete">
@for (value of filteredValues | async; track value.value) {
<mat-option [value]="value"><span [innerHTML]="value.name | highlight:searchText"></span></mat-option>
<mat-option [value]="value" (mousedown)="$event.preventDefault()"><span [innerHTML]="value.name | highlight:searchText:true"></span></mat-option>
} @empty {
@if (!allowUserValue) {
<mat-option [value]="null">{{ 'common.not-found' | translate }}</mat-option>
<mat-option [value]="null" (mousedown)="$event.preventDefault()">{{ 'common.not-found' | translate }}</mat-option>
}
}
</mat-autocomplete>

45
ui-ngx/src/app/shared/components/string-items-list.component.ts

@ -29,7 +29,7 @@ import { FloatLabelType, MatFormFieldAppearance, SubscriptSizing } from '@angula
import { coerceArray, coerceBoolean } from '@shared/decorators/coercion';
import { Observable, of } from 'rxjs';
import { filter, mergeMap, share, tap } from 'rxjs/operators';
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { isDefined, isUndefined } from '@core/utils';
export interface StringItemsOption {
@ -37,18 +37,18 @@ export interface StringItemsOption {
value: any;
}
@Component({
selector: 'tb-string-items-list',
templateUrl: './string-items-list.component.html',
styleUrls: [],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StringItemsListComponent),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
standalone: false
selector: 'tb-string-items-list',
templateUrl: './string-items-list.component.html',
styleUrls: [],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => StringItemsListComponent),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
standalone: false
})
export class StringItemsListComponent implements ControlValueAccessor, OnInit {
@ -149,9 +149,7 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit {
this.filteredValues = this.itemControl.valueChanges
.pipe(
tap((value) => {
if (value && typeof value !== 'string') {
this.add(value);
} else if (value === null) {
if (value === null) {
this.clear();
}
}),
@ -209,16 +207,17 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit {
this.dirty = true;
}
addOnBlur(event: FocusEvent) {
const target: HTMLElement = event.relatedTarget as HTMLElement;
if ((target && target.tagName !== 'MAT-OPTION') || this.allowUserValue) {
this.addItem(this.stringItemInput.nativeElement.value ?? '');
onOptionSelected(event: MatAutocompleteSelectedEvent): void {
if (event.option.value != null) {
this.add(event.option.value);
} else {
this.clear();
}
this.onTouched();
}
addOnEnd(event: MatChipInputEvent): void {
this.addItem(event.value ?? '')
this.addItem(event.value ?? '');
this.onTouched();
}
removeItems(item: StringItemsOption) {
@ -295,6 +294,8 @@ export class StringItemsListComponent implements ControlValueAccessor, OnInit {
this.stringItemInput.nativeElement.value = value;
this.itemControl.patchValue(value, {emitEvent: true});
setTimeout(() => {
this.stringItemInput.nativeElement.value = value;
this.itemControl.patchValue(null, {emitEvent: false});
this.stringItemInput.nativeElement.blur();
this.stringItemInput.nativeElement.focus();
}, 0);

6
ui-ngx/src/app/shared/models/constants.ts

@ -56,6 +56,12 @@ export const serverErrorCodesTranslations = new Map<number, string>([
[Constants.serverErrorCode.entitiesLimitExceeded, 'server-error.entities-limit-exceeded'],
]);
export const httpStatusMessageMap = new Map<number, string>([
[502, 'Server is temporarily unavailable (Bad Gateway)'],
[503, 'Server is temporarily unavailable'],
[504, 'Server did not respond in time (Gateway Timeout)'],
]);
export const MediaBreakpoints = {
xs: 'screen and (max-width: 599px)',
sm: 'screen and (min-width: 600px) and (max-width: 959px)',

6
ui-ngx/yarn.lock

@ -6033,9 +6033,9 @@ flat@^5.0.2:
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
flatted@^3.2.9:
version "3.4.1"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.1.tgz#84ccd9579e76e9cc0d246c11d8be0beb019143e6"
integrity sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==
version "3.4.2"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726"
integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==
"flot.curvedlines@https://github.com/MichaelZinsmaier/CurvedLines.git#master":
version "1.1.1"

Loading…
Cancel
Save