Showing
15 changed files
with
385 additions
and
17 deletions
... | ... | @@ -29,8 +29,10 @@ export class NotificationMessage { |
29 | 29 | type: NotificationType; |
30 | 30 | target?: string; |
31 | 31 | duration?: number; |
32 | + forceDismiss?: boolean; | |
32 | 33 | horizontalPosition?: NotificationHorizontalPosition; |
33 | 34 | verticalPosition?: NotificationVerticalPosition; |
35 | + panelClass?: string | string[]; | |
34 | 36 | } |
35 | 37 | |
36 | 38 | export class HideNotification { | ... | ... |
... | ... | @@ -20,7 +20,7 @@ |
20 | 20 | import { Inject, Injectable, NgZone } from '@angular/core'; |
21 | 21 | import { WINDOW } from '@core/services/window.service'; |
22 | 22 | import { ExceptionData } from '@app/shared/models/error.models'; |
23 | -import { deepClone, deleteNullProperties, guid, isDefined, isUndefined } from '@core/utils'; | |
23 | +import { deepClone, deleteNullProperties, guid, isDefined, isDefinedAndNotNull, isUndefined } from '@core/utils'; | |
24 | 24 | import { WindowMessage } from '@shared/models/window-message.model'; |
25 | 25 | import { TranslateService } from '@ngx-translate/core'; |
26 | 26 | import { customTranslationsPrefix } from '@app/shared/models/constants'; |
... | ... | @@ -441,4 +441,23 @@ export class UtilsService { |
441 | 441 | this.window.history.replaceState({}, '', baseUrl + params); |
442 | 442 | } |
443 | 443 | |
444 | + public deepClone<T>(target: T, ignoreFields?: string[]): T { | |
445 | + return deepClone(target, ignoreFields); | |
446 | + } | |
447 | + | |
448 | + public isUndefined(value: any): boolean { | |
449 | + return isUndefined(value); | |
450 | + } | |
451 | + | |
452 | + public isDefined(value: any): boolean { | |
453 | + return isDefined(value); | |
454 | + } | |
455 | + | |
456 | + public defaultValue(value: any, defaultValue: any): any { | |
457 | + if (isDefinedAndNotNull(value)) { | |
458 | + return value; | |
459 | + } else { | |
460 | + return defaultValue; | |
461 | + } | |
462 | + } | |
444 | 463 | } | ... | ... |
... | ... | @@ -15,14 +15,19 @@ |
15 | 15 | /// |
16 | 16 | |
17 | 17 | import { PageComponent } from '@shared/components/page.component'; |
18 | -import { Inject, Injector, Input, OnDestroy, OnInit } from '@angular/core'; | |
18 | +import { Inject, Injector, OnDestroy, OnInit } from '@angular/core'; | |
19 | 19 | import { Store } from '@ngrx/store'; |
20 | 20 | import { AppState } from '@core/core.state'; |
21 | -import { WidgetContext, IDynamicWidgetComponent } from '@home/models/widget-component.models'; | |
22 | -import { ExceptionData } from '@shared/models/error.models'; | |
21 | +import { IDynamicWidgetComponent, WidgetContext } from '@home/models/widget-component.models'; | |
23 | 22 | import { HttpErrorResponse } from '@angular/common/http'; |
24 | 23 | import { RafService } from '@core/services/raf.service'; |
25 | -import { DeviceService } from '@core/http/device.service'; | |
24 | +import { ActionNotificationShow } from '@core/notification/notification.actions'; | |
25 | +import { | |
26 | + NotificationHorizontalPosition, | |
27 | + NotificationType, | |
28 | + NotificationVerticalPosition | |
29 | +} from '@core/notification/notification.models'; | |
30 | +import { FormBuilder, Validators } from '@angular/forms'; | |
26 | 31 | |
27 | 32 | export class DynamicWidgetComponent extends PageComponent implements IDynamicWidgetComponent, OnInit, OnDestroy { |
28 | 33 | |
... | ... | @@ -33,8 +38,11 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid |
33 | 38 | |
34 | 39 | [key: string]: any; |
35 | 40 | |
41 | + validators = Validators; | |
42 | + | |
36 | 43 | constructor(@Inject(RafService) public raf: RafService, |
37 | 44 | @Inject(Store) protected store: Store<AppState>, |
45 | + @Inject(FormBuilder) public fb: FormBuilder, | |
38 | 46 | @Inject(Injector) private $injector: Injector, |
39 | 47 | @Inject('widgetContext') public readonly ctx: WidgetContext, |
40 | 48 | @Inject('errorMessages') public readonly errorMessages: string[]) { |
... | ... | @@ -63,4 +71,35 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid |
63 | 71 | } |
64 | 72 | } |
65 | 73 | |
74 | + showSuccessToast(message: string, duration: number = 1000, | |
75 | + verticalPosition: NotificationVerticalPosition = 'bottom', | |
76 | + horizontalPosition: NotificationHorizontalPosition = 'left', | |
77 | + target?: string) { | |
78 | + this.showToast('success', message, duration, verticalPosition, horizontalPosition, target); | |
79 | + } | |
80 | + | |
81 | + showErrorToast(message: string, | |
82 | + verticalPosition: NotificationVerticalPosition = 'bottom', | |
83 | + horizontalPosition: NotificationHorizontalPosition = 'left', | |
84 | + target?: string) { | |
85 | + this.showToast('error', message, undefined, verticalPosition, horizontalPosition, target); | |
86 | + } | |
87 | + | |
88 | + showToast(type: NotificationType, message: string, duration: number = 1000, | |
89 | + verticalPosition: NotificationVerticalPosition = 'bottom', | |
90 | + horizontalPosition: NotificationHorizontalPosition = 'left', | |
91 | + target?: string) { | |
92 | + this.store.dispatch(new ActionNotificationShow( | |
93 | + { | |
94 | + message, | |
95 | + type, | |
96 | + duration, | |
97 | + verticalPosition, | |
98 | + horizontalPosition, | |
99 | + target, | |
100 | + panelClass: this.ctx.widgetNamespace, | |
101 | + forceDismiss: true | |
102 | + })); | |
103 | + } | |
104 | + | |
66 | 105 | } | ... | ... |
... | ... | @@ -95,6 +95,8 @@ import { DialogService } from '@core/services/dialog.service'; |
95 | 95 | import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; |
96 | 96 | import { DatePipe } from '@angular/common'; |
97 | 97 | import { AttributeService } from '@core/http/attribute.service'; |
98 | +import { TranslateService } from '@ngx-translate/core'; | |
99 | +import { HttpClient } from '@angular/common/http'; | |
98 | 100 | |
99 | 101 | const ServicesMap = new Map<string, Type<any>>(); |
100 | 102 | ServicesMap.set('deviceService', DeviceService); |
... | ... | @@ -104,6 +106,8 @@ ServicesMap.set('dialogs', DialogService); |
104 | 106 | ServicesMap.set('customDialog', CustomDialogService); |
105 | 107 | ServicesMap.set('date', DatePipe); |
106 | 108 | ServicesMap.set('utils', UtilsService); |
109 | +ServicesMap.set('translate', TranslateService); | |
110 | +ServicesMap.set('http', HttpClient); | |
107 | 111 | |
108 | 112 | @Component({ |
109 | 113 | selector: 'tb-widget', |
... | ... | @@ -390,10 +394,10 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI |
390 | 394 | } |
391 | 395 | |
392 | 396 | private loadFromWidgetInfo() { |
393 | - const widgetNamespace = `widget-type-${(this.widget.isSystemType ? 'sys-' : '')}${this.widget.bundleAlias}-${this.widget.typeAlias}`; | |
397 | + this.widgetContext.widgetNamespace = `widget-type-${(this.widget.isSystemType ? 'sys-' : '')}${this.widget.bundleAlias}-${this.widget.typeAlias}`; | |
394 | 398 | const elem = this.elementRef.nativeElement; |
395 | 399 | elem.classList.add('tb-widget'); |
396 | - elem.classList.add(widgetNamespace); | |
400 | + elem.classList.add(this.widgetContext.widgetNamespace); | |
397 | 401 | this.widgetType = this.widgetInfo.widgetTypeFunction; |
398 | 402 | this.typeParameters = this.widgetInfo.typeParameters; |
399 | 403 | ... | ... |
... | ... | @@ -22,5 +22,5 @@ |
22 | 22 | 'info-toast': notification.type === 'info' |
23 | 23 | }"> |
24 | 24 | <div class="toast-text" [innerHTML]="notification.message"></div> |
25 | - <button mat-button (click)="action()">{{ 'action.close' | translate }}</button> | |
25 | + <button #actionButton mat-button (click)="action()">{{ 'action.close' | translate }}</button> | |
26 | 26 | </div> | ... | ... |
... | ... | @@ -15,12 +15,12 @@ |
15 | 15 | /// |
16 | 16 | |
17 | 17 | import { |
18 | - AfterViewInit, | |
18 | + AfterViewInit, ApplicationRef, ChangeDetectorRef, | |
19 | 19 | Component, |
20 | 20 | Directive, |
21 | 21 | ElementRef, |
22 | 22 | Inject, Input, NgZone, |
23 | - OnDestroy, | |
23 | + OnDestroy, ViewChild, | |
24 | 24 | ViewContainerRef |
25 | 25 | } from '@angular/core'; |
26 | 26 | import { |
... | ... | @@ -35,6 +35,8 @@ import { Subscription } from 'rxjs'; |
35 | 35 | import { NotificationService } from '@app/core/services/notification.service'; |
36 | 36 | import { BreakpointObserver } from '@angular/cdk/layout'; |
37 | 37 | import { MediaBreakpoints } from '@shared/models/constants'; |
38 | +import Timeout = NodeJS.Timeout; | |
39 | +import { MatButton } from '@angular/material/button'; | |
38 | 40 | |
39 | 41 | @Directive({ |
40 | 42 | selector: '[tb-toast]' |
... | ... | @@ -50,6 +52,8 @@ export class ToastDirective implements AfterViewInit, OnDestroy { |
50 | 52 | private snackBarRef: MatSnackBarRef<TbSnackBarComponent> = null; |
51 | 53 | private currentMessage: NotificationMessage = null; |
52 | 54 | |
55 | + private dismissTimeout: Timeout = null; | |
56 | + | |
53 | 57 | constructor(public elementRef: ElementRef, |
54 | 58 | public viewContainerRef: ViewContainerRef, |
55 | 59 | private notificationService: NotificationService, |
... | ... | @@ -73,6 +77,7 @@ export class ToastDirective implements AfterViewInit, OnDestroy { |
73 | 77 | verticalPosition: !isGtSm ? 'bottom' : (notificationMessage.verticalPosition || 'top'), |
74 | 78 | viewContainerRef: this.viewContainerRef, |
75 | 79 | duration: notificationMessage.duration, |
80 | + panelClass: notificationMessage.panelClass, | |
76 | 81 | data |
77 | 82 | }; |
78 | 83 | this.ngZone.run(() => { |
... | ... | @@ -80,7 +85,23 @@ export class ToastDirective implements AfterViewInit, OnDestroy { |
80 | 85 | this.snackBarRef.dismiss(); |
81 | 86 | } |
82 | 87 | this.snackBarRef = this.snackBar.openFromComponent(TbSnackBarComponent, config); |
88 | + if (notificationMessage.duration && notificationMessage.duration > 0 && notificationMessage.forceDismiss) { | |
89 | + if (this.dismissTimeout !== null) { | |
90 | + clearTimeout(this.dismissTimeout); | |
91 | + this.dismissTimeout = null; | |
92 | + } | |
93 | + this.dismissTimeout = setTimeout(() => { | |
94 | + if (this.snackBarRef) { | |
95 | + this.snackBarRef.instance.actionButton._elementRef.nativeElement.click(); | |
96 | + } | |
97 | + this.dismissTimeout = null; | |
98 | + }, notificationMessage.duration); | |
99 | + } | |
83 | 100 | this.snackBarRef.afterDismissed().subscribe(() => { |
101 | + if (this.dismissTimeout !== null) { | |
102 | + clearTimeout(this.dismissTimeout); | |
103 | + this.dismissTimeout = null; | |
104 | + } | |
84 | 105 | this.snackBarRef = null; |
85 | 106 | this.currentMessage = null; |
86 | 107 | }); |
... | ... | @@ -134,11 +155,15 @@ export class ToastDirective implements AfterViewInit, OnDestroy { |
134 | 155 | styleUrls: ['snack-bar-component.scss'] |
135 | 156 | }) |
136 | 157 | export class TbSnackBarComponent implements AfterViewInit, OnDestroy { |
158 | + | |
159 | + @ViewChild('actionButton', {static: true}) actionButton: MatButton; | |
160 | + | |
137 | 161 | private parentEl: HTMLElement; |
138 | - private snackBarContainerEl: HTMLElement; | |
162 | + public snackBarContainerEl: HTMLElement; | |
139 | 163 | private parentScrollSubscription: Subscription = null; |
140 | 164 | public notification: NotificationMessage; |
141 | 165 | constructor(@Inject(MAT_SNACK_BAR_DATA) public data: any, private elementRef: ElementRef, |
166 | + public cd: ChangeDetectorRef, | |
142 | 167 | public snackBarRef: MatSnackBarRef<TbSnackBarComponent>) { |
143 | 168 | this.notification = data.notification; |
144 | 169 | } | ... | ... |
... | ... | @@ -1607,6 +1607,31 @@ |
1607 | 1607 | "Step size": "Schrittlänge", |
1608 | 1608 | "Ok": "Ok" |
1609 | 1609 | } |
1610 | + }, | |
1611 | + "input-widgets": { | |
1612 | + "attribute-not-allowed": "Attributparameter können in diesem Widget nicht verwendet werden", | |
1613 | + "date": "Datum", | |
1614 | + "discard-changes": "Änderungen verwerfen", | |
1615 | + "entity-attribute-required": "Entitätsattribut ist erforderlich", | |
1616 | + "entity-timeseries-required": "Zeitreihen für Entitäten sind erforderlich", | |
1617 | + "not-allowed-entity": "Die ausgewählte Entität kann keine gemeinsamen Attribute haben", | |
1618 | + "no-attribute-selected": "Es ist kein Attribut ausgewählt", | |
1619 | + "no-datakey-selected": "Es ist kein Datenschlüssel ausgewählt", | |
1620 | + "no-entity-selected": "Keine Entität ausgewählt", | |
1621 | + "no-image": "Kein Bild", | |
1622 | + "no-support-web-camera": "Keine unterstützte Webcam", | |
1623 | + "no-timeseries-selected": "Keine Zeitreihen ausgewählt", | |
1624 | + "switch-attribute-value": "Entitätsattributwert wechseln", | |
1625 | + "switch-camera": "Kamera wechseln", | |
1626 | + "switch-timeseries-value": "Wert für Zeitreihen von Entitäten wechseln", | |
1627 | + "take-photo": "Foto machen", | |
1628 | + "time": "Zeit", | |
1629 | + "timeseries-not-allowed": "Der Timeseries-Parameter kann in diesem Widget nicht verwendet werden", | |
1630 | + "update-failed": "Aktualisierung fehlgeschlagen", | |
1631 | + "update-successful": "Aktualisierung erfolgreich", | |
1632 | + "update-attribute": "Attribut aktualisieren", | |
1633 | + "update-timeseries": "Zeitreihen aktualisieren", | |
1634 | + "value": "Wert" | |
1610 | 1635 | } |
1611 | 1636 | }, |
1612 | 1637 | "icon": { |
... | ... | @@ -1641,7 +1666,7 @@ |
1641 | 1666 | "tr_TR": "Türkisch", |
1642 | 1667 | "fa_IR": "Persisch", |
1643 | 1668 | "uk_UA": "Ukrainisch", |
1644 | - "cs_CZ": "Tschechisch" | |
1669 | + "cs_CZ": "Tschechisch" | |
1645 | 1670 | } |
1646 | 1671 | } |
1647 | 1672 | } | ... | ... |
... | ... | @@ -1728,6 +1728,46 @@ |
1728 | 1728 | "Step size": "Step size", |
1729 | 1729 | "Ok": "Ok" |
1730 | 1730 | } |
1731 | + }, | |
1732 | + "input-widgets": { | |
1733 | + "attribute-not-allowed": "Attribute parameter cannot be used in this widget", | |
1734 | + "blocked-location": "Geolocation is blocked in your browser", | |
1735 | + "claim-device": "Claim device", | |
1736 | + "claim-failed": "Failed to claim the device!", | |
1737 | + "claim-not-found": "Device not found!", | |
1738 | + "claim-successful": "Device was successfully claimed!", | |
1739 | + "date": "Date", | |
1740 | + "device-name": "Device name", | |
1741 | + "device-name-required": "Device name is required", | |
1742 | + "discard-changes": "Discard changes", | |
1743 | + "entity-attribute-required": "Entity attribute is required", | |
1744 | + "entity-coordinate-required": "Both fields, latitude and longitude, are required", | |
1745 | + "entity-timeseries-required": "Entity timeseries is required", | |
1746 | + "get-location": "Get current location", | |
1747 | + "latitude": "Latitude", | |
1748 | + "longitude": "Longitude", | |
1749 | + "not-allowed-entity": "Selected entity cannot have shared attributes", | |
1750 | + "no-attribute-selected": "No attribute is selected", | |
1751 | + "no-datakey-selected": "No datakey is selected", | |
1752 | + "no-coordinate-specified": "Datakey for latitude/longitude doesn't specified", | |
1753 | + "no-entity-selected": "No entity selected", | |
1754 | + "no-image": "No image", | |
1755 | + "no-support-geolocation": "Your browser doesn't support geolocation", | |
1756 | + "no-support-web-camera": "No supported web camera", | |
1757 | + "no-timeseries-selected": "No timeseries selected", | |
1758 | + "secret-key": "Secret key", | |
1759 | + "secret-key-required": "Secret key is required", | |
1760 | + "switch-attribute-value": "Switch entity attribute value", | |
1761 | + "switch-camera": "Switch camera", | |
1762 | + "switch-timeseries-value": "Switch entity timeseries value", | |
1763 | + "take-photo": "Take photo", | |
1764 | + "time": "Time", | |
1765 | + "timeseries-not-allowed": "Timeseries parameter cannot be used in this widget", | |
1766 | + "update-failed": "Update failed", | |
1767 | + "update-successful": "Update successful", | |
1768 | + "update-attribute": "Update attribute", | |
1769 | + "update-timeseries": "Update timeseries", | |
1770 | + "value": "Value" | |
1731 | 1771 | } |
1732 | 1772 | }, |
1733 | 1773 | "icon": { | ... | ... |
... | ... | @@ -1680,6 +1680,31 @@ |
1680 | 1680 | "Step size": "Numero de pie", |
1681 | 1681 | "Ok": "De acuerdo" |
1682 | 1682 | } |
1683 | + }, | |
1684 | + "input-widgets": { | |
1685 | + "attribute-not-allowed": "El parámetro de atributo no se puede usar en este widget", | |
1686 | + "date": "Fecha", | |
1687 | + "discard-changes": "Descartar los cambios", | |
1688 | + "entity-attribute-required": "Se requiere atributo de entidad", | |
1689 | + "entity-timeseries-required": "Se requiere la serie de tiempo de la entidad", | |
1690 | + "not-allowed-entity": "La entidad seleccionada no puede tener atributos compartidos", | |
1691 | + "no-attribute-selected": "No se seleccionó ningún atributo", | |
1692 | + "no-datakey-selected": "No se seleccionó ninguna clave de datos", | |
1693 | + "no-entity-selected": "Ninguna entidad seleccionada", | |
1694 | + "no-image": "Sin imágen", | |
1695 | + "no-support-web-camera": "No hay cámara web compatible", | |
1696 | + "no-timeseries-selected": "No hay series de tiempo seleccionadas", | |
1697 | + "switch-attribute-value": "Cambiar el valor del atributo de entidad", | |
1698 | + "switch-camera": "Cambiar de cámara", | |
1699 | + "switch-timeseries-value": "Cambiar el valor de la serie de tiempo de la entidad", | |
1700 | + "take-photo": "Tomar foto", | |
1701 | + "time": "Tiempo", | |
1702 | + "timeseries-not-allowed": "El parámetro Timeseries no se puede usar en este widget", | |
1703 | + "update-failed": "Actualización fallida", | |
1704 | + "update-successful": "Actualización exitosa", | |
1705 | + "update-attribute": "Actualizar atributo", | |
1706 | + "update-timeseries": "Actualizar series de tiempo", | |
1707 | + "value": "Valor" | |
1683 | 1708 | } |
1684 | 1709 | }, |
1685 | 1710 | "icon": { | ... | ... |
... | ... | @@ -1018,7 +1018,7 @@ |
1018 | 1018 | "tr_TR": "Turc", |
1019 | 1019 | "fa_IR": "Persane", |
1020 | 1020 | "uk_UA": "Ukrainien", |
1021 | - "cs_CZ": "Tchèque" | |
1021 | + "cs_CZ": "Tchèque" | |
1022 | 1022 | } |
1023 | 1023 | }, |
1024 | 1024 | "layout": { |
... | ... | @@ -1501,6 +1501,31 @@ |
1501 | 1501 | "Step size": "Taille de pas", |
1502 | 1502 | "Ok": "Ok" |
1503 | 1503 | } |
1504 | + }, | |
1505 | + "input-widgets": { | |
1506 | + "attribute-not-allowed": "Le paramètre d'attribut ne peut pas être utilisé dans ce widget", | |
1507 | + "date": "Date", | |
1508 | + "discard-changes": "Annuler les modifications", | |
1509 | + "entity-attribute-required": "L'attribut d'entité est requis", | |
1510 | + "entity-timeseries-required": "Entité timeseries est requis", | |
1511 | + "not-allowed-entity": "L'entité sélectionnée ne peut pas avoir d'attributs partagés", | |
1512 | + "no-attribute-selected": "Aucun attribut n'est sélectionné", | |
1513 | + "no-datakey-selected": "Aucune date n'est sélectionnée", | |
1514 | + "no-entity-selected": "Aucune entité sélectionnée", | |
1515 | + "no-image": "Pas d'image", | |
1516 | + "no-support-web-camera": "Pas de webcam supportée", | |
1517 | + "no-timeseries-selected": "Aucune série temporelle sélectionnée", | |
1518 | + "switch-attribute-value": "Changer la valeur de l'attribut d'entité", | |
1519 | + "switch-camera": "Changer de caméra", | |
1520 | + "switch-timeseries-value": "Changer la valeur de l'entité série temporelle", | |
1521 | + "take-photo": "Prendre une photo", | |
1522 | + "time": "Temps", | |
1523 | + "timeseries-not-allowed": "Le paramètre série temporelle ne peut pas être utilisé dans ce widget", | |
1524 | + "update-failed": "Mise à jour a échoué", | |
1525 | + "update-successful": "Mise à jour réussie", | |
1526 | + "update-attribute": "Attribut de mise à jour", | |
1527 | + "update-timeseries": "Mise à jour de la série temporelle", | |
1528 | + "value": "Valeur" | |
1504 | 1529 | } |
1505 | 1530 | }, |
1506 | 1531 | "widgets-bundle": { | ... | ... |
... | ... | @@ -1615,6 +1615,31 @@ |
1615 | 1615 | "Step size": "Dimensione del passo", |
1616 | 1616 | "Ok": "Ok" |
1617 | 1617 | } |
1618 | + }, | |
1619 | + "input-widgets": { | |
1620 | + "attribute-not-allowed": "Questo widget non può usare un parametro di tipo attributo", | |
1621 | + "date": "Data", | |
1622 | + "discard-changes": "Annulla modifiche", | |
1623 | + "entity-attribute-required": "E' richiesta un'entità di tipo attributo", | |
1624 | + "entity-timeseries-required": "E' richiesta un'entità di tipo serie temporale", | |
1625 | + "not-allowed-entity": "L'entità selezionata non può avere attributi condivisi", | |
1626 | + "no-attribute-selected": "Nessun attributo selezionato", | |
1627 | + "no-datakey-selected": "Nessuna datakey selezionata", | |
1628 | + "no-entity-selected": "Nessuna entità selezionata", | |
1629 | + "no-image": "Nessuna immagine", | |
1630 | + "no-support-web-camera": "Web camera non supportata", | |
1631 | + "no-timeseries-selected": "Nessuna serie temporale selezionata", | |
1632 | + "switch-attribute-value": "Cambia il valore dell'attributo", | |
1633 | + "switch-camera": "Cambia camera", | |
1634 | + "switch-timeseries-value": "Cambia il valore della serie temporale", | |
1635 | + "take-photo": "Fai una foto", | |
1636 | + "time": "Tempo", | |
1637 | + "timeseries-not-allowed": "Questo widget non può usare un parametro di tipo serie temporale", | |
1638 | + "update-failed": "Aggiornamento fallito", | |
1639 | + "update-successful": "Aggiornamento eseguito con successo", | |
1640 | + "update-attribute": "Aggiorna attributo", | |
1641 | + "update-timeseries": "Aggiorna serie temporale", | |
1642 | + "value": "Valore" | |
1618 | 1643 | } |
1619 | 1644 | }, |
1620 | 1645 | "icon": { |
... | ... | @@ -1649,7 +1674,7 @@ |
1649 | 1674 | "tr_TR": "Turco", |
1650 | 1675 | "fa_IR": "Persiana", |
1651 | 1676 | "uk_UA": "Ucraino", |
1652 | - "cs_CZ": "Ceco" | |
1677 | + "cs_CZ": "Ceco" | |
1653 | 1678 | } |
1654 | 1679 | } |
1655 | 1680 | } | ... | ... |
... | ... | @@ -1611,6 +1611,46 @@ |
1611 | 1611 | "Step size": "Размер шага", |
1612 | 1612 | "Ok": "Ok" |
1613 | 1613 | } |
1614 | + }, | |
1615 | + "input-widgets": { | |
1616 | + "attribute-not-allowed": "Атрибут не может быть выбран в этом виджете", | |
1617 | + "date": "Дата", | |
1618 | + "blocked-location": "Геолокация заблокирована в вашем браузере", | |
1619 | + "claim-device": "Подтвердить устройство", | |
1620 | + "claim-failed": "Не удалось подтвердить устройство!", | |
1621 | + "claim-not-found": "Устройство не найдено!", | |
1622 | + "claim-successful": "Устройство успешно подтверждено!", | |
1623 | + "discard-changes": "Отменить изменения", | |
1624 | + "device-name": "Название устройства", | |
1625 | + "device-name-required": "Необходимо указать название устройства", | |
1626 | + "entity-attribute-required": "Значение атрибута обязателено", | |
1627 | + "entity-coordinate-required": "Необходимо указать широту и долготу", | |
1628 | + "entity-timeseries-required": "Значение телеметрии обязательно", | |
1629 | + "get-location": "Получить текущее местоположение", | |
1630 | + "latitude": "Широта", | |
1631 | + "longitude": "Долгота", | |
1632 | + "not-allowed-entity": "Выбраный объект не имеет общих атрибутов", | |
1633 | + "no-attribute-selected": "Атрибут не выбран", | |
1634 | + "no-datakey-selected": "Ни один datakey не выбран", | |
1635 | + "no-entity-selected": "Объект не выбран", | |
1636 | + "no-coordinate-specified": "Ключ для широты/долготы не указан", | |
1637 | + "no-support-geolocation": "Ваш браузер не поддерживает геолокацию", | |
1638 | + "no-image": "Нет изображения", | |
1639 | + "no-support-web-camera": "Нет поддерживаемой веб-камеры", | |
1640 | + "no-timeseries-selected": "Параметр телеметрии не выбран", | |
1641 | + "secret-key": "Секретный ключ", | |
1642 | + "secret-key-required": "Необходимо указать секретный ключ", | |
1643 | + "switch-attribute-value": "Изменить значение атрибута", | |
1644 | + "switch-camera": "Изменить камеру", | |
1645 | + "switch-timeseries-value": "Изменить значение телеметрии", | |
1646 | + "take-photo": "Сделать фото", | |
1647 | + "time": "Время", | |
1648 | + "timeseries-not-allowed": "Телеметрия не может быть выбрана в этом виджете", | |
1649 | + "update-failed": "Не удалось обновить", | |
1650 | + "update-successful": "Успешно обновлено", | |
1651 | + "update-attribute": "Обновить атрибут", | |
1652 | + "update-timeseries": "Обновить телеметрию", | |
1653 | + "value": "Значение" | |
1614 | 1654 | } |
1615 | 1655 | }, |
1616 | 1656 | "icon": { | ... | ... |
1 | 1 | { |
2 | 2 | "access": { |
3 | 3 | "unauthorized": "Неавторизований", |
4 | - "unauthorized-access": "Неавторизований доступ", | |
4 | + "unauthorized-access": "Неавторизований доступ", | |
5 | 5 | "unauthorized-access-text": "Щоб отримати доступ до цього ресурсу, потрібно ввійти в систему!", |
6 | 6 | "access-forbidden": "Доступ заборонено", |
7 | 7 | "access-forbidden-text": "Недостатньо прав для доступу! <br/> Спробуйте увійти як інший користувач, якщо ви все ще хочете отримати доступ до цього ресурсу.", |
... | ... | @@ -246,7 +246,7 @@ |
246 | 246 | "assign-assets": "Надати активи", |
247 | 247 | "assign-assets-text": "Надати { count, plural, 1 {1 актив} other {# активи} } клієнту", |
248 | 248 | "delete-assets": "Видалити активи", |
249 | - "unassign-assets": "Позбавити активів", | |
249 | + "unassign-assets": "Позбавити активів", | |
250 | 250 | "unassign-assets-action-title": "Позбавити { count, plural, 1 {1 актив} other {# активи} } клієнта", |
251 | 251 | "assign-new-asset": "Надати новий актив", |
252 | 252 | "delete-asset-title": "Ви впевнені, що хочете видалити актив '{{assetName}}'?", |
... | ... | @@ -2123,6 +2123,105 @@ |
2123 | 2123 | "widget-type-file": "Файл типу віджета", |
2124 | 2124 | "invalid-widget-type-file-error": "Неможливо імпортувати тип віджету: неправильна структура даних типу віджета." |
2125 | 2125 | }, |
2126 | + "widgets": { | |
2127 | + "date-range-navigator": { | |
2128 | + "localizationMap": { | |
2129 | + "Sun": "Нд", | |
2130 | + "Mon": "Пн", | |
2131 | + "Tue": "Вт", | |
2132 | + "Wed": "Ср", | |
2133 | + "Thu": "Чт", | |
2134 | + "Fri": "Пт", | |
2135 | + "Sat": "Сб", | |
2136 | + "Jan": "Січ.", | |
2137 | + "Feb": "Лют.", | |
2138 | + "Mar": "Берез.", | |
2139 | + "Apr": "Квіт.", | |
2140 | + "May": "Трав.", | |
2141 | + "Jun": "Черв.", | |
2142 | + "Jul": "Лип.", | |
2143 | + "Aug": "Серп.", | |
2144 | + "Sep": "Верес.", | |
2145 | + "Oct": "Жовт.", | |
2146 | + "Nov": "Листоп.", | |
2147 | + "Dec": "Груд.", | |
2148 | + "January": "Січень", | |
2149 | + "February": "Лютий", | |
2150 | + "March": "Березень", | |
2151 | + "April": "Квітень", | |
2152 | + "June": "Червень", | |
2153 | + "July": "Липень", | |
2154 | + "August": "Серпень", | |
2155 | + "September": "Вересень", | |
2156 | + "October": "Жовтень", | |
2157 | + "November": "Листопад", | |
2158 | + "December": "Грудень", | |
2159 | + "Custom Date Range": "Користувацький діапазон дат", | |
2160 | + "Date Range Template": "Шаблон діапазону дат", | |
2161 | + "Today": "Сьогодні", | |
2162 | + "Yesterday": "Вчора", | |
2163 | + "This Week": "Цього тижня", | |
2164 | + "Last Week": "Минулий тиждень", | |
2165 | + "This Month": "Цей місяць", | |
2166 | + "Last Month": "Минулий місяць", | |
2167 | + "Year": "Рік", | |
2168 | + "This Year": "Цього року", | |
2169 | + "Last Year": "Минулий рік", | |
2170 | + "Date picker": "Вибір дати", | |
2171 | + "Hour": "Година", | |
2172 | + "Day": "День", | |
2173 | + "Week": "Тиждень", | |
2174 | + "2 weeks": "2 Тижні", | |
2175 | + "Month": "Місяць", | |
2176 | + "3 months": "3 Місяці", | |
2177 | + "6 months": "6 Місяців", | |
2178 | + "Custom interval": "Користувацький інтервал", | |
2179 | + "Interval": "Інтервал", | |
2180 | + "Step size": "Розмір кроку", | |
2181 | + "Ok": "Ok" | |
2182 | + } | |
2183 | + }, | |
2184 | + "input-widgets": { | |
2185 | + "attribute-not-allowed": "Атрибут не може бути вибраний в цьому віджеті", | |
2186 | + "date": "Дата", | |
2187 | + "blocked-location": "Геолокація заблокована у вашому браузері", | |
2188 | + "claim-device": "Підтвердити пристрій", | |
2189 | + "claim-failed": "Не вдалося підтвердити пристрій!", | |
2190 | + "claim-not-found": "Пристрій не знайдено!", | |
2191 | + "claim-successful": "Пристрій успішно підтверджено!", | |
2192 | + "discard-changes": "Скасувати зміни", | |
2193 | + "device-name": "Назва пристрою", | |
2194 | + "device-name-required": "Необхідно вказати назву пристрою", | |
2195 | + "entity-attribute-required": "Значення атрибута обов'язкове", | |
2196 | + "entity-coordinate-required": "Необхідно вказати широту та довготу", | |
2197 | + "entity-timeseries-required": "Значення телеметрії обов'язкове", | |
2198 | + "get-location": "Отримати поточне місцезнаходження", | |
2199 | + "latitude": "Широта", | |
2200 | + "longitude": "Довгота", | |
2201 | + "not-allowed-entity": "Обрана сутність не має спільних атрибутів", | |
2202 | + "no-attribute-selected": "Атрибут не вибрано", | |
2203 | + "no-datakey-selected": "Ні один datakey не обраний", | |
2204 | + "no-entity-selected": "Сутність не вибрано", | |
2205 | + "no-coordinate-specified": "Ключ для широти/довготи не вказаний", | |
2206 | + "no-support-geolocation": "Ваш браузер не підтримує геолокацію", | |
2207 | + "no-image": "Немає зображення", | |
2208 | + "no-support-web-camera": "Нет поддерживаемой веб-камеры", | |
2209 | + "no-timeseries-selected": "Параметр телеметрії не вибрано", | |
2210 | + "secret-key": "Секретний ключ", | |
2211 | + "secret-key-required": "Необхідно вказати секретний ключ", | |
2212 | + "switch-attribute-value": "Змінити значення атрибута", | |
2213 | + "switch-camera": "Змінити камеру", | |
2214 | + "switch-timeseries-value": "Змінити значення телеметрії", | |
2215 | + "take-photo": "Зробити фото", | |
2216 | + "time": "Час", | |
2217 | + "timeseries-not-allowed": "Телеметрія не може бути вибрана в цьому віджеті", | |
2218 | + "update-failed": "Не вдалося оновити", | |
2219 | + "update-successful": "Успішно оновлено", | |
2220 | + "update-attribute": "Оновити атрибут", | |
2221 | + "update-timeseries": "Оновити телеметрію", | |
2222 | + "value": "Значення" | |
2223 | + } | |
2224 | + }, | |
2126 | 2225 | "white-labeling": { |
2127 | 2226 | "white-labeling": "Білий маркування", |
2128 | 2227 | "login-white-labeling": "Login White Labeling", | ... | ... |