@c8y/ngx-components 1016.0.379 → 1016.0.383
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICES +1 -1
- package/core/range-display/range-display.component.d.ts +19 -1
- package/core/realtime/realtime-subject.service.d.ts +4 -0
- package/core/realtime/realtime.service.d.ts +10 -0
- package/device-protocols/device-protocols.factory.d.ts +14 -0
- package/device-protocols/device-protocols.guard.d.ts +12 -0
- package/device-protocols/device-protocols.module.d.ts +8 -0
- package/device-protocols/device-type-detail-edited.service.d.ts +8 -0
- package/device-protocols/device-type-detail.component.d.ts +12 -0
- package/device-protocols/device-type-detail.directive.d.ts +9 -0
- package/device-protocols/index.d.ts +6 -0
- package/esm2020/core/range-display/range-display.component.mjs +87 -4
- package/esm2020/core/realtime/realtime-subject.service.mjs +47 -4
- package/esm2020/core/realtime/realtime.service.mjs +15 -1
- package/esm2020/device-protocols/c8y-ngx-components-device-protocols.mjs +5 -0
- package/esm2020/device-protocols/device-protocols.factory.mjs +31 -0
- package/esm2020/device-protocols/device-protocols.guard.mjs +40 -0
- package/esm2020/device-protocols/device-protocols.module.mjs +38 -0
- package/esm2020/device-protocols/device-type-detail-edited.service.mjs +19 -0
- package/esm2020/device-protocols/device-type-detail.component.mjs +45 -0
- package/esm2020/device-protocols/device-type-detail.directive.mjs +19 -0
- package/esm2020/device-protocols/index.mjs +7 -0
- package/esm2020/ecosystem/application-properties/subscription-modal/subscription-modal.component.mjs +4 -1
- package/esm2020/upgrade/ng1/downgraded.services.mjs +6 -4
- package/esm2020/upgrade/ng1/index.mjs +6 -5
- package/esm2020/upgrade/upgrade.module.mjs +10 -10
- package/fesm2015/c8y-ngx-components-device-protocols.mjs +180 -0
- package/fesm2015/c8y-ngx-components-device-protocols.mjs.map +1 -0
- package/fesm2015/c8y-ngx-components-ecosystem.mjs +3 -0
- package/fesm2015/c8y-ngx-components-ecosystem.mjs.map +1 -1
- package/fesm2015/c8y-ngx-components-upgrade.mjs +91 -88
- package/fesm2015/c8y-ngx-components-upgrade.mjs.map +1 -1
- package/fesm2015/c8y-ngx-components.mjs +144 -4
- package/fesm2015/c8y-ngx-components.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components-device-protocols.mjs +177 -0
- package/fesm2020/c8y-ngx-components-device-protocols.mjs.map +1 -0
- package/fesm2020/c8y-ngx-components-ecosystem.mjs +3 -0
- package/fesm2020/c8y-ngx-components-ecosystem.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components-upgrade.mjs +90 -87
- package/fesm2020/c8y-ngx-components-upgrade.mjs.map +1 -1
- package/fesm2020/c8y-ngx-components.mjs +142 -4
- package/fesm2020/c8y-ngx-components.mjs.map +1 -1
- package/locales/locales.pot +1 -1
- package/package.json +10 -2
- package/upgrade/ng1/downgraded.services.d.ts +1 -0
|
@@ -3897,6 +3897,20 @@ class RealtimeService {
|
|
|
3897
3897
|
get active() {
|
|
3898
3898
|
return this.isActive.value;
|
|
3899
3899
|
}
|
|
3900
|
+
/**
|
|
3901
|
+
* An observable emitting a value in case the realtime connection has been interrupted.
|
|
3902
|
+
* Can be used to reload data of e.g. a datapoint graph that wasn't received while realtime was interrupted.
|
|
3903
|
+
*/
|
|
3904
|
+
get reconnect$() {
|
|
3905
|
+
return this.realtimeSubject.reconnect$;
|
|
3906
|
+
}
|
|
3907
|
+
/**
|
|
3908
|
+
* An observable emitting either `connected` or `disconnected` depending on the state of the realtime connection.
|
|
3909
|
+
* Can be used to e.g. inform the user about the interrupted realtime connection.
|
|
3910
|
+
*/
|
|
3911
|
+
get connectionStatus$() {
|
|
3912
|
+
return this.realtimeSubject.connectionStatus$;
|
|
3913
|
+
}
|
|
3900
3914
|
/**
|
|
3901
3915
|
* Get an Observable of all realtime notifications.
|
|
3902
3916
|
*
|
|
@@ -24227,6 +24241,13 @@ class RangeDisplayComponent {
|
|
|
24227
24241
|
this.sanitizer = sanitizer;
|
|
24228
24242
|
this.config = {};
|
|
24229
24243
|
this.display = 'full';
|
|
24244
|
+
this.currentRangeWidthChanged = new Subject();
|
|
24245
|
+
// width of current range is changing within 150ms, see style declaration for .range-display__range__current
|
|
24246
|
+
this.CURRENT_RANGE_WIDTH_TRANSITION_TIME = 150;
|
|
24247
|
+
this.DEFAULT_TOOLTIP_SHIFT = '50%';
|
|
24248
|
+
this.MIN_TOOLTIP_SHIFT = 10;
|
|
24249
|
+
this.tooltipShift = this.DEFAULT_TOOLTIP_SHIFT;
|
|
24250
|
+
this.destroyed$ = new Subject();
|
|
24230
24251
|
}
|
|
24231
24252
|
get inlineStyle() {
|
|
24232
24253
|
this.config = this.config || {};
|
|
@@ -24242,6 +24263,8 @@ class RangeDisplayComponent {
|
|
|
24242
24263
|
return this.sanitizer.bypassSecurityTrustStyle(`
|
|
24243
24264
|
--range-min: ${this.config.min};
|
|
24244
24265
|
--range-max: ${this.config.max};
|
|
24266
|
+
--range-display-tooltip-translate: translate(${this.tooltipShift}, -56px);
|
|
24267
|
+
--range-display-tooltip-bg: ${this.getTooltipBackground()};
|
|
24245
24268
|
--full-range: ${this.config.max - this.config.min};
|
|
24246
24269
|
--measurement-target: ${((this.config.target - this.config.min) * 100) / (this.config.max - this.config.min)}%;
|
|
24247
24270
|
--measurement-current: ${((this.config.current - this.config.min) * 100) / (this.config.max - this.config.min)}%;
|
|
@@ -24255,6 +24278,20 @@ class RangeDisplayComponent {
|
|
|
24255
24278
|
100}%;
|
|
24256
24279
|
`);
|
|
24257
24280
|
}
|
|
24281
|
+
ngOnChanges() {
|
|
24282
|
+
// It's necessary to handle tooltip shifting both in OnChanges and AfterViewInit. In case of Linear gauge widget, view is
|
|
24283
|
+
// rendered first (so as elements needed for calculating shifting) and config orientation is set later on.
|
|
24284
|
+
// In other cases it's possible that orientation is defined on initialization of class and view elements are rendered later.
|
|
24285
|
+
this.setupTooltipShiftingIfPossible();
|
|
24286
|
+
}
|
|
24287
|
+
ngAfterViewInit() {
|
|
24288
|
+
this.setupTooltipShiftingIfPossible();
|
|
24289
|
+
}
|
|
24290
|
+
ngOnDestroy() {
|
|
24291
|
+
this.currentRangeWidthObserver?.disconnect();
|
|
24292
|
+
this.destroyed$.next();
|
|
24293
|
+
this.destroyed$.complete();
|
|
24294
|
+
}
|
|
24258
24295
|
checkTarget() {
|
|
24259
24296
|
return (this.config.target !== undefined &&
|
|
24260
24297
|
this.config.target !== null &&
|
|
@@ -24282,12 +24319,64 @@ class RangeDisplayComponent {
|
|
|
24282
24319
|
isRangeDisplayed(rangeMin, rangeMax) {
|
|
24283
24320
|
return rangeMin === 0 || rangeMax === 0 || (rangeMin && rangeMax);
|
|
24284
24321
|
}
|
|
24322
|
+
setupTooltipShifting() {
|
|
24323
|
+
this.currentRangeWidthObserver = new ResizeObserver(([val]) => {
|
|
24324
|
+
if (getComputedStyle(val.target, null).display === 'block') {
|
|
24325
|
+
this.currentRangeWidthChanged.next(val.target);
|
|
24326
|
+
}
|
|
24327
|
+
});
|
|
24328
|
+
this.currentRangeWidthObserver.observe(this.currentRangeElement.nativeElement);
|
|
24329
|
+
this.currentRangeWidthChanged
|
|
24330
|
+
.pipe(debounceTime(this.CURRENT_RANGE_WIDTH_TRANSITION_TIME), map((rangeElement) => parseInt(getComputedStyle(rangeElement, null).width)), distinctUntilChanged(), takeUntil(this.destroyed$))
|
|
24331
|
+
.subscribe(rangeElementWidth => {
|
|
24332
|
+
this.setTooltipShiftValue(rangeElementWidth);
|
|
24333
|
+
});
|
|
24334
|
+
}
|
|
24335
|
+
setTooltipShiftValue(rangeElementWidth) {
|
|
24336
|
+
const tooltipWidth = parseInt(getComputedStyle(this.currentRangeElement.nativeElement, ':after').width);
|
|
24337
|
+
const currentRangeWidth = rangeElementWidth;
|
|
24338
|
+
const rangeDisplayWidth = parseInt(getComputedStyle(this.rangeDisplay.nativeElement, null).getPropertyValue('width'));
|
|
24339
|
+
const rangeDisplayPaddingLeft = parseInt(getComputedStyle(this.rangeDisplay.nativeElement, null).getPropertyValue('padding-left'));
|
|
24340
|
+
const tooltipOverflowsLeftEdge = tooltipWidth / 2 > rangeDisplayPaddingLeft + currentRangeWidth;
|
|
24341
|
+
const tooltipOverflowsRightEdge = tooltipWidth / 2 > rangeDisplayWidth - rangeDisplayPaddingLeft - currentRangeWidth;
|
|
24342
|
+
if (tooltipOverflowsLeftEdge) {
|
|
24343
|
+
this.tooltipShift = `${tooltipWidth - this.MIN_TOOLTIP_SHIFT}px`;
|
|
24344
|
+
}
|
|
24345
|
+
else if (tooltipOverflowsRightEdge) {
|
|
24346
|
+
this.tooltipShift = `${this.MIN_TOOLTIP_SHIFT}px`;
|
|
24347
|
+
}
|
|
24348
|
+
else {
|
|
24349
|
+
this.tooltipShift = this.DEFAULT_TOOLTIP_SHIFT;
|
|
24350
|
+
}
|
|
24351
|
+
}
|
|
24352
|
+
setupTooltipShiftingIfPossible() {
|
|
24353
|
+
if (this.config?.orientation === 'horizontal' &&
|
|
24354
|
+
!this.currentRangeWidthObserver &&
|
|
24355
|
+
this.rangeDisplay &&
|
|
24356
|
+
this.currentRangeElement) {
|
|
24357
|
+
this.setupTooltipShifting();
|
|
24358
|
+
}
|
|
24359
|
+
}
|
|
24360
|
+
getTooltipBackground() {
|
|
24361
|
+
const current = this.config.current;
|
|
24362
|
+
switch (true) {
|
|
24363
|
+
case this.isValueInRange(current, this.config.redRangeMin, this.config.redRangeMax):
|
|
24364
|
+
return 'var(--input-validation-error, #E0000E)';
|
|
24365
|
+
case this.isValueInRange(current, this.config.yellowRangeMin, this.config.yellowRangeMax):
|
|
24366
|
+
return 'var(--input-validation-warning, #FF801F)';
|
|
24367
|
+
default:
|
|
24368
|
+
return 'var(--gray-3, #394852)';
|
|
24369
|
+
}
|
|
24370
|
+
}
|
|
24371
|
+
isValueInRange(value, min, max) {
|
|
24372
|
+
return min != null && max != null && value >= min && value <= max;
|
|
24373
|
+
}
|
|
24285
24374
|
}
|
|
24286
24375
|
RangeDisplayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RangeDisplayComponent, deps: [{ token: i2$5.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
|
|
24287
|
-
RangeDisplayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: RangeDisplayComponent, selector: "c8y-range-display", inputs: { config: "config", display: "display" }, host: { properties: { "attr.style": "this.inlineStyle" } }, ngImport: i0, template: "<div
|
|
24376
|
+
RangeDisplayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: RangeDisplayComponent, selector: "c8y-range-display", inputs: { config: "config", display: "display" }, host: { properties: { "attr.style": "this.inlineStyle" } }, viewQueries: [{ propertyName: "rangeDisplay", first: true, predicate: ["rangeDisplay"], descendants: true }, { propertyName: "currentRangeElement", first: true, predicate: ["currentRangeElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n [ngClass]=\"{\n 'range-display--vertical': config.orientation === 'vertical',\n 'range-display--compact': display === 'compact',\n 'range-display--inline': display === 'inline'\n }\"\n attr.data-label=\"{{ config.unit }}\"\n>\n <div\n class=\"range-display\"\n #rangeDisplay\n >\n <div class=\"range-display__range\">\n <div class=\"range-display__range__unit\">\n {{ config.unit }}\n </div>\n <div\n *ngIf=\"isYellowRangeDisplayed()\"\n class=\"range-display__range__min\"\n ></div>\n <div\n *ngIf=\"isRedRangeDisplayed()\"\n class=\"range-display__range__max\"\n ></div>\n <div\n *ngIf=\"checkTarget()\"\n class=\"range-display__range__target\"\n attr.data-label=\"{{ config.target }} {{ config.unit }}\"\n title=\"{{ 'Target' | translate }}: {{ config.target }} {{ config.unit }}\"\n ></div>\n <div\n [ngStyle]=\"{\n display:\n config.current != undefined &&\n config.current >= config.min &&\n config.current <= config.max\n ? 'block'\n : 'none'\n }\"\n #currentRangeElement\n class=\"range-display__range__current\"\n attr.data-label=\"{{ config.current }} {{ config.unit }} 
{{ config.time | c8yDate }}\"\n title=\"{{ 'Current' | translate }}: {{ config.current }} {{ config.unit }} | {{\n config.time | c8yDate\n }}\"\n ></div>\n </div>\n <div class=\"range-display__ruler\">\n <div\n *ngFor=\"let x of [].constructor(10); let index = index; trackBy: trackByIndex\"\n attr.data-label=\"{{ rulerCalc(index) }}\"\n class=\"range-display__tick\"\n ></div>\n <div\n attr.data-label=\"{{ config.max || 100 | number }}\"\n class=\"range-display__tick\"\n ></div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] });
|
|
24288
24377
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RangeDisplayComponent, decorators: [{
|
|
24289
24378
|
type: Component,
|
|
24290
|
-
args: [{ selector: 'c8y-range-display', template: "<div
|
|
24379
|
+
args: [{ selector: 'c8y-range-display', template: "<div\n [ngClass]=\"{\n 'range-display--vertical': config.orientation === 'vertical',\n 'range-display--compact': display === 'compact',\n 'range-display--inline': display === 'inline'\n }\"\n attr.data-label=\"{{ config.unit }}\"\n>\n <div\n class=\"range-display\"\n #rangeDisplay\n >\n <div class=\"range-display__range\">\n <div class=\"range-display__range__unit\">\n {{ config.unit }}\n </div>\n <div\n *ngIf=\"isYellowRangeDisplayed()\"\n class=\"range-display__range__min\"\n ></div>\n <div\n *ngIf=\"isRedRangeDisplayed()\"\n class=\"range-display__range__max\"\n ></div>\n <div\n *ngIf=\"checkTarget()\"\n class=\"range-display__range__target\"\n attr.data-label=\"{{ config.target }} {{ config.unit }}\"\n title=\"{{ 'Target' | translate }}: {{ config.target }} {{ config.unit }}\"\n ></div>\n <div\n [ngStyle]=\"{\n display:\n config.current != undefined &&\n config.current >= config.min &&\n config.current <= config.max\n ? 'block'\n : 'none'\n }\"\n #currentRangeElement\n class=\"range-display__range__current\"\n attr.data-label=\"{{ config.current }} {{ config.unit }} 
{{ config.time | c8yDate }}\"\n title=\"{{ 'Current' | translate }}: {{ config.current }} {{ config.unit }} | {{\n config.time | c8yDate\n }}\"\n ></div>\n </div>\n <div class=\"range-display__ruler\">\n <div\n *ngFor=\"let x of [].constructor(10); let index = index; trackBy: trackByIndex\"\n attr.data-label=\"{{ rulerCalc(index) }}\"\n class=\"range-display__tick\"\n ></div>\n <div\n attr.data-label=\"{{ config.max || 100 | number }}\"\n class=\"range-display__tick\"\n ></div>\n </div>\n </div>\n</div>\n" }]
|
|
24291
24380
|
}], ctorParameters: function () { return [{ type: i2$5.DomSanitizer }]; }, propDecorators: { config: [{
|
|
24292
24381
|
type: Input
|
|
24293
24382
|
}], display: [{
|
|
@@ -24295,6 +24384,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
24295
24384
|
}], inlineStyle: [{
|
|
24296
24385
|
type: HostBinding,
|
|
24297
24386
|
args: ['attr.style']
|
|
24387
|
+
}], rangeDisplay: [{
|
|
24388
|
+
type: ViewChild,
|
|
24389
|
+
args: ['rangeDisplay', { static: false }]
|
|
24390
|
+
}], currentRangeElement: [{
|
|
24391
|
+
type: ViewChild,
|
|
24392
|
+
args: ['currentRangeElement', { static: false }]
|
|
24298
24393
|
}] } });
|
|
24299
24394
|
|
|
24300
24395
|
/**
|
|
@@ -25555,6 +25650,8 @@ class RealtimeSubjectService {
|
|
|
25555
25650
|
constructor(realtime) {
|
|
25556
25651
|
this.realtime = realtime;
|
|
25557
25652
|
this.subjects$ = new Map();
|
|
25653
|
+
this.reconnect$ = this.createObservableForReconnect().pipe(share());
|
|
25654
|
+
this.connectionStatus$ = this.createObservableForConnectionStatus().pipe(distinctUntilChanged(), shareReplay({ refCount: true, bufferSize: 1 }));
|
|
25558
25655
|
}
|
|
25559
25656
|
getObservableForChannel(channel) {
|
|
25560
25657
|
if (this.subjects$.has(channel)) {
|
|
@@ -25567,7 +25664,7 @@ class RealtimeSubjectService {
|
|
|
25567
25664
|
}
|
|
25568
25665
|
createObservableForChannel(channel, realtime) {
|
|
25569
25666
|
return new Observable(observer => {
|
|
25570
|
-
|
|
25667
|
+
let realtimeSubscription = realtime.subscribe(channel, msg => {
|
|
25571
25668
|
const data = {
|
|
25572
25669
|
channel: msg.channel,
|
|
25573
25670
|
data: msg.data.data,
|
|
@@ -25576,13 +25673,54 @@ class RealtimeSubjectService {
|
|
|
25576
25673
|
};
|
|
25577
25674
|
observer.next(data);
|
|
25578
25675
|
});
|
|
25676
|
+
/**
|
|
25677
|
+
* In (rare) case of a re-handshake, resubscribe valid subscriptions.
|
|
25678
|
+
* @see https://docs.cometd.org/current/reference/#_javascript_subscribe_resubscribe
|
|
25679
|
+
*/
|
|
25680
|
+
const reconnectSubscription = this.reconnect$.subscribe(() => {
|
|
25681
|
+
try {
|
|
25682
|
+
realtimeSubscription = this.realtime.resubscribe(realtimeSubscription);
|
|
25683
|
+
}
|
|
25684
|
+
catch (e) {
|
|
25685
|
+
console.warn(`Failed to resubscribe to channel: "${channel}" after reconnect.`, e);
|
|
25686
|
+
observer.error(e);
|
|
25687
|
+
}
|
|
25688
|
+
});
|
|
25579
25689
|
return {
|
|
25580
|
-
unsubscribe() {
|
|
25690
|
+
unsubscribe: () => {
|
|
25691
|
+
reconnectSubscription.unsubscribe();
|
|
25581
25692
|
realtime.unsubscribe(realtimeSubscription);
|
|
25582
25693
|
}
|
|
25583
25694
|
};
|
|
25584
25695
|
});
|
|
25585
25696
|
}
|
|
25697
|
+
createObservableForReconnect() {
|
|
25698
|
+
return new Observable(observer => {
|
|
25699
|
+
const handle = this.realtime.addHandshakeListener(msg => {
|
|
25700
|
+
if (msg.successful && msg.reestablish) {
|
|
25701
|
+
observer.next();
|
|
25702
|
+
}
|
|
25703
|
+
});
|
|
25704
|
+
return {
|
|
25705
|
+
unsubscribe: () => {
|
|
25706
|
+
this.realtime.removeListener(handle);
|
|
25707
|
+
}
|
|
25708
|
+
};
|
|
25709
|
+
});
|
|
25710
|
+
}
|
|
25711
|
+
createObservableForConnectionStatus() {
|
|
25712
|
+
return new Observable(observer => {
|
|
25713
|
+
observer.next(!this.realtime.isDisconnected() ? 'connected' : 'disconnected');
|
|
25714
|
+
const handle = this.realtime.addConnectListener(msg => {
|
|
25715
|
+
observer.next(msg.successful ? 'connected' : 'disconnected');
|
|
25716
|
+
});
|
|
25717
|
+
return {
|
|
25718
|
+
unsubscribe: () => {
|
|
25719
|
+
this.realtime.removeListener(handle);
|
|
25720
|
+
}
|
|
25721
|
+
};
|
|
25722
|
+
});
|
|
25723
|
+
}
|
|
25586
25724
|
}
|
|
25587
25725
|
RealtimeSubjectService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RealtimeSubjectService, deps: [{ token: i1$2.Realtime }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
25588
25726
|
RealtimeSubjectService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: RealtimeSubjectService, providedIn: 'root' });
|