committed by
GitHub
55 changed files with 1582 additions and 307 deletions
@ -0,0 +1,99 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2026 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.thingsboard.server.common.data.query; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
|
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
import io.swagger.v3.oas.annotations.media.ArraySchema; |
||||
|
import io.swagger.v3.oas.annotations.media.Schema; |
||||
|
import org.jspecify.annotations.Nullable; |
||||
|
import org.thingsboard.server.common.data.AttributeScope; |
||||
|
import org.thingsboard.server.common.data.EntityType; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
|
||||
|
@Schema( |
||||
|
description = """ |
||||
|
Contains unique time series and attribute key names discovered from entities matching a query, |
||||
|
optionally including a sample value for each key.""" |
||||
|
) |
||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||
|
public record AvailableEntityKeysV2( |
||||
|
@Schema( |
||||
|
description = "Set of entity types found among the matched entities.", |
||||
|
example = "[\"DEVICE\", \"ASSET\"]", |
||||
|
requiredMode = Schema.RequiredMode.REQUIRED |
||||
|
) |
||||
|
Set<EntityType> entityTypes, |
||||
|
|
||||
|
@ArraySchema( |
||||
|
arraySchema = @Schema( |
||||
|
description = """ |
||||
|
List of unique time series keys available on the matched entities, sorted alphabetically. |
||||
|
Omitted when timeseries keys were not requested.""", |
||||
|
nullable = true |
||||
|
), |
||||
|
schema = @Schema(implementation = KeyInfo.class) |
||||
|
) |
||||
|
@Nullable List<KeyInfo> timeseries, |
||||
|
|
||||
|
@Schema( |
||||
|
description = """ |
||||
|
Map of attribute scope to the list of unique attribute keys available on the matched entities. |
||||
|
Only scopes supported by the matched entity types are included. |
||||
|
Omitted when attribute keys were not requested or when none of the requested scopes apply to the matched entity types.""", |
||||
|
nullable = true |
||||
|
) |
||||
|
@Nullable Map<AttributeScope, List<KeyInfo>> attributes |
||||
|
) { |
||||
|
|
||||
|
@Schema(description = "Key name with an optional sample value.") |
||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||
|
public record KeyInfo( |
||||
|
@Schema( |
||||
|
description = "Key name.", |
||||
|
example = "temperature", |
||||
|
requiredMode = Schema.RequiredMode.REQUIRED |
||||
|
) |
||||
|
String key, |
||||
|
|
||||
|
@Schema( |
||||
|
description = "Most recent sample value for this key across the matched entities. Omitted when samples were not requested.", |
||||
|
nullable = true |
||||
|
) |
||||
|
@Nullable KeySample sample |
||||
|
) {} |
||||
|
|
||||
|
@Schema(description = "Most recent value and its timestamp.") |
||||
|
public record KeySample( |
||||
|
@Schema( |
||||
|
description = "Timestamp in milliseconds since epoch.", example = "1707000000000", |
||||
|
requiredMode = Schema.RequiredMode.REQUIRED |
||||
|
) |
||||
|
long ts, |
||||
|
|
||||
|
@Schema( |
||||
|
description = "Sample value.", |
||||
|
example = "23.5", |
||||
|
requiredMode = Schema.RequiredMode.REQUIRED, |
||||
|
implementation = Object.class |
||||
|
) |
||||
|
JsonNode value |
||||
|
) {} |
||||
|
|
||||
|
} |
||||
@ -1,46 +1,13 @@ |
|||||
diff --git a/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs b/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
diff --git a/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs b/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
||||
index a372799..a3d709a 100644
|
index a372799..f64a6f8 100644
|
||||
--- a/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
--- a/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
||||
+++ b/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
+++ b/node_modules/@iplab/ngx-color-picker/fesm2022/iplab-ngx-color-picker.mjs
|
||||
@@ -1129,11 +1129,11 @@ class RgbaComponent {
|
@@ -516,7 +516,7 @@ class Color {
|
||||
this.color.set(newColor); |
const s = (color.saturation / 100) * (l <= 1 ? l : 2 - l); |
||||
|
const value = (l + s) / 2; |
||||
|
const saturation = (2 * s) / (l + s) || 0; |
||||
|
- return new Hsva(hue, saturation, value, color.alpha);
|
||||
|
+ return new Hsva(hue, saturation * 100, value * 100, color.alpha);
|
||||
} |
} |
||||
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: RgbaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } |
rgbaToHsva(color) { |
||||
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: RgbaComponent, isStandalone: true, selector: "rgba-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isAlphaVisible: { classPropertyName: "isAlphaVisible", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getRed().toString()\" (inputChange)=\"onInputChange($event, 'R')\" />\r\n @if (labelVisible()) {\r\n <span>R</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getGreen().toString()\" (inputChange)=\"onInputChange($event, 'G')\" />\r\n @if (labelVisible()) {\r\n <span>G</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getBlue().toString()\" (inputChange)=\"onInputChange($event, 'B')\" />\r\n @if (labelVisible()) {\r\n <span>B</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], dependencies: [{ kind: "directive", type: ColorPickerInputDirective, selector: "[inputChange]", inputs: ["min", "max"], outputs: ["inputChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
const red = color.red / 255; |
||||
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: RgbaComponent, isStandalone: true, selector: "rgba-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isAlphaVisible: { classPropertyName: "isAlphaVisible", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getRed().toString()\" (inputChange)=\"onInputChange($event, 'R')\" />\r\n @if (labelVisible()) {\r\n <span>R</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getGreen().toString()\" (inputChange)=\"onInputChange($event, 'G')\" />\r\n @if (labelVisible()) {\r\n <span>G</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getBlue().toString()\" (inputChange)=\"onInputChange($event, 'B')\" />\r\n @if (labelVisible()) {\r\n <span>B</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], dependencies: [{ kind: "directive", type: ColorPickerInputDirective, selector: "[inputChange]", inputs: ["min", "max"], outputs: ["inputChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
||||
} |
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: RgbaComponent, decorators: [{ |
|
||||
type: Component, |
|
||||
- args: [{ selector: `rgba-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ColorPickerInputDirective], template: "<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getRed().toString()\" (inputChange)=\"onInputChange($event, 'R')\" />\r\n @if (labelVisible()) {\r\n <span>R</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getGreen().toString()\" (inputChange)=\"onInputChange($event, 'G')\" />\r\n @if (labelVisible()) {\r\n <span>G</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getBlue().toString()\" (inputChange)=\"onInputChange($event, 'B')\" />\r\n @if (labelVisible()) {\r\n <span>B</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
+ args: [{ selector: `rgba-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ColorPickerInputDirective], template: "<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getRed().toString()\" (inputChange)=\"onInputChange($event, 'R')\" />\r\n @if (labelVisible()) {\r\n <span>R</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getGreen().toString()\" (inputChange)=\"onInputChange($event, 'G')\" />\r\n @if (labelVisible()) {\r\n <span>G</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"255\" [value]=\"value?.getBlue().toString()\" (inputChange)=\"onInputChange($event, 'B')\" />\r\n @if (labelVisible()) {\r\n <span>B</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
}] }); |
|
||||
|
|
||||
class HslaComponent { |
|
||||
@@ -1155,11 +1155,11 @@ class HslaComponent {
|
|
||||
this.color.set(newColor); |
|
||||
} |
|
||||
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HslaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } |
|
||||
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: HslaComponent, isStandalone: true, selector: "hsla-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isAlphaVisible: { classPropertyName: "isAlphaVisible", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"360\" [value]=\"value?.getHue().toString()\" (inputChange)=\"onInputChange($event, 'H')\" />\r\n @if (labelVisible()) {\r\n <span>H</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getSaturation() + '%'\" (inputChange)=\"onInputChange($event, 'S')\" />\r\n @if (labelVisible()) {\r\n <span>S</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getLightness() + '%'\" (inputChange)=\"onInputChange($event, 'L')\" />\r\n @if (labelVisible()) {\r\n <span>L</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], dependencies: [{ kind: "directive", type: ColorPickerInputDirective, selector: "[inputChange]", inputs: ["min", "max"], outputs: ["inputChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
||||
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: HslaComponent, isStandalone: true, selector: "hsla-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isAlphaVisible: { classPropertyName: "isAlphaVisible", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"360\" [value]=\"value?.getHue().toString()\" (inputChange)=\"onInputChange($event, 'H')\" />\r\n @if (labelVisible()) {\r\n <span>H</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getSaturation() + '%'\" (inputChange)=\"onInputChange($event, 'S')\" />\r\n @if (labelVisible()) {\r\n <span>S</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getLightness() + '%'\" (inputChange)=\"onInputChange($event, 'L')\" />\r\n @if (labelVisible()) {\r\n <span>L</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], dependencies: [{ kind: "directive", type: ColorPickerInputDirective, selector: "[inputChange]", inputs: ["min", "max"], outputs: ["inputChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
||||
} |
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HslaComponent, decorators: [{ |
|
||||
type: Component, |
|
||||
- args: [{ selector: `hsla-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ColorPickerInputDirective], template: "<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"360\" [value]=\"value?.getHue().toString()\" (inputChange)=\"onInputChange($event, 'H')\" />\r\n @if (labelVisible()) {\r\n <span>H</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getSaturation() + '%'\" (inputChange)=\"onInputChange($event, 'S')\" />\r\n @if (labelVisible()) {\r\n <span>S</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getLightness() + '%'\" (inputChange)=\"onInputChange($event, 'L')\" />\r\n @if (labelVisible()) {\r\n <span>L</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"text\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
+ args: [{ selector: `hsla-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [ColorPickerInputDirective], template: "<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"360\" [value]=\"value?.getHue().toString()\" (inputChange)=\"onInputChange($event, 'H')\" />\r\n @if (labelVisible()) {\r\n <span>H</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getSaturation() + '%'\" (inputChange)=\"onInputChange($event, 'S')\" />\r\n @if (labelVisible()) {\r\n <span>S</span>\r\n }\r\n</div>\r\n<div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]*\" min=\"0\" max=\"100\" [value]=\"value?.getLightness() + '%'\" (inputChange)=\"onInputChange($event, 'L')\" />\r\n @if (labelVisible()) {\r\n <span>L</span>\r\n }\r\n</div>\r\n@if (isAlphaVisible()) {\r\n <div class=\"column\">\r\n <input type=\"number\" pattern=\"[0-9]+([\\.,][0-9]{1,2})?\" min=\"0\" max=\"1\" [value]=\"value?.getAlpha(true).toString()\" (inputChange)=\"onInputChange($event, 'A')\" />\r\n @if (labelVisible()) {\r\n <span>A</span>\r\n }\r\n </div>\r\n}", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
}] }); |
|
||||
|
|
||||
class HexComponent { |
|
||||
@@ -1190,11 +1190,11 @@ class HexComponent {
|
|
||||
} |
|
||||
} |
|
||||
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HexComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } |
|
||||
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: HexComponent, isStandalone: true, selector: "hex-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, prefixValue: { classPropertyName: "prefixValue", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input #elRef type=\"text\" [value]=\"value\" (keyup)=\"onInputChange($event, elRef.value)\" />\r\n @if (labelVisible()) {\r\n <span>HEX</span>\r\n }\r\n</div>", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
||||
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: HexComponent, isStandalone: true, selector: "hex-input-component", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: true, transformFunction: null }, labelVisible: { classPropertyName: "labelVisible", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, prefixValue: { classPropertyName: "prefixValue", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { color: "colorChange" }, ngImport: i0, template: "<div class=\"column\">\r\n <input #elRef type=\"number\" [value]=\"value\" (keyup)=\"onInputChange($event, elRef.value)\" />\r\n @if (labelVisible()) {\r\n <span>HEX</span>\r\n }\r\n</div>", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n", ""], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
||||
} |
|
||||
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: HexComponent, decorators: [{ |
|
||||
type: Component, |
|
||||
- args: [{ selector: `hex-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"column\">\r\n <input #elRef type=\"text\" [value]=\"value\" (keyup)=\"onInputChange($event, elRef.value)\" />\r\n @if (labelVisible()) {\r\n <span>HEX</span>\r\n }\r\n</div>", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
+ args: [{ selector: `hex-input-component`, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"column\">\r\n <input #elRef type=\"number\" [value]=\"value\" (keyup)=\"onInputChange($event, elRef.value)\" />\r\n @if (labelVisible()) {\r\n <span>HEX</span>\r\n }\r\n</div>", styles: [":host,:host ::ng-deep *{padding:0;margin:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}\n", ":host{display:table;width:100%;text-align:center;color:#b4b4b4;font-size:11px}.column{display:table-cell;padding:0 2px}input{width:100%;border:1px solid rgb(218,218,218);color:#272727;text-align:center;font-size:12px;-webkit-appearance:none;border-radius:0;margin:0 0 6px;height:26px;outline:none}\n"] }]
|
|
||||
}] }); |
|
||||
|
|
||||
const OpacityAnimation = trigger('opacityAnimation', [ |
|
||||
|
|||||
@ -0,0 +1,28 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2026 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
:host { |
||||
|
.color-input-container { |
||||
|
display: flex; |
||||
|
gap: 4px; |
||||
|
align-items: center; |
||||
|
} |
||||
|
.color-input { |
||||
|
max-width: 72px; |
||||
|
margin-bottom: 4px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -0,0 +1,54 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2026 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<div class="color-input-container"> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" appearance="outline" subscriptSizing="dynamic"> |
||||
|
<input matInput type="number" [min]="0" [max]="360" [value]="value.getHue()" (inputChange)="onInputChange($event, 'H')"/> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>H</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" appearance="outline" subscriptSizing="dynamic"> |
||||
|
<input matInput type="number" [min]="0" [max]="100" [value]="value.getSaturation()" (inputChange)="onInputChange($event, 'S')" /> |
||||
|
<span matSuffix>{{suffixValue}}</span> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>S</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" appearance="outline" subscriptSizing="dynamic"> |
||||
|
<input matInput type="number" [min]="0" [max]="100" [value]="value.getLightness()" (inputChange)="onInputChange($event,'L')" /> |
||||
|
<span matSuffix>{{suffixValue}}</span> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>L</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" appearance="outline" subscriptSizing="dynamic"> |
||||
|
<input matInput type="number" [min]="0" [max]="100" [value]="alphaValue" (inputChange)="onAlphaInputChange($event)" /> |
||||
|
<span matSuffix>{{suffixValue}}</span> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>A</span> |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,72 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2026 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core'; |
||||
|
import { Color } from '@iplab/ngx-color-picker'; |
||||
|
import { coerceBoolean } from '@shared/decorators/coercion'; |
||||
|
|
||||
|
type Channel = 'H' | 'S' | 'L'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-hsla-input', |
||||
|
templateUrl: './hsla-input.component.html', |
||||
|
styleUrl: './color-input.base.scss', |
||||
|
standalone: false |
||||
|
}) |
||||
|
export class HslaInputComponent { |
||||
|
|
||||
|
@Input() |
||||
|
public color: Color; |
||||
|
|
||||
|
@Output() |
||||
|
public colorChange = new EventEmitter<Color>(false); |
||||
|
|
||||
|
@Input() |
||||
|
@coerceBoolean() |
||||
|
public labelVisible = false; |
||||
|
|
||||
|
@Input() |
||||
|
public suffixValue = '%'; |
||||
|
|
||||
|
public get value() { |
||||
|
return this.color.getHsla(); |
||||
|
} |
||||
|
|
||||
|
public get alphaValue(): number { |
||||
|
return this.color ? Math.round(this.color.getHsla().getAlpha() * 100) : 0; |
||||
|
} |
||||
|
|
||||
|
public onAlphaInputChange(inputValue: number): void { |
||||
|
if (!this.color) return; |
||||
|
const hsla = this.color.getHsla(); |
||||
|
const alpha = +inputValue / 100; |
||||
|
if (hsla.alpha !== alpha) { |
||||
|
const newColor = new Color().setHsla(hsla.getHue(), hsla.getSaturation(), hsla.getLightness(), alpha); |
||||
|
this.colorChange.emit(newColor); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public onInputChange(newValue: number, channel: Channel): void { |
||||
|
if (!this.color) return; |
||||
|
const hsla = this.value; |
||||
|
const hue = channel === 'H' ? +newValue : hsla.getHue(); |
||||
|
const saturation = channel === 'S' ? +newValue : hsla.getSaturation(); |
||||
|
const lightness = channel === 'L' ? +newValue : hsla.getLightness(); |
||||
|
if (hue === hsla.getHue() && saturation === hsla.getSaturation() && lightness === hsla.getLightness()) return; |
||||
|
const newColor = new Color().setHsla(hue, saturation, lightness, hsla.getAlpha()); |
||||
|
this.colorChange.emit(newColor); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2026 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Directive, EventEmitter, HostBinding, HostListener, Input, numberAttribute, Output } from '@angular/core'; |
||||
|
|
||||
|
@Directive({ |
||||
|
selector: '[inputChange]', |
||||
|
standalone: false |
||||
|
}) |
||||
|
export class InputChangeDirective { |
||||
|
|
||||
|
@Input({transform: numberAttribute}) |
||||
|
@HostBinding('attr.min') |
||||
|
min = 0; |
||||
|
|
||||
|
@Input({transform: numberAttribute}) |
||||
|
@HostBinding('attr.max') |
||||
|
max = 255; |
||||
|
|
||||
|
@Output() |
||||
|
public inputChange = new EventEmitter<number>(); |
||||
|
|
||||
|
@HostListener('input', ['$event']) |
||||
|
public inputChanges(event: any): void { |
||||
|
const element = event.target as HTMLInputElement || event.srcElement as HTMLInputElement; |
||||
|
const value = element.value; |
||||
|
|
||||
|
const numeric = parseFloat(value); |
||||
|
if (!isNaN(numeric) && numeric >= this.min && numeric <= this.max) { |
||||
|
this.inputChange.emit(numeric); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2026 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<div class="color-input-container"> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" subscriptSizing="dynamic" appearance="outline"> |
||||
|
<input matInput type="number" [min]="0" [max]="255" [value]="value?.getRed()" (inputChange)="onInputChange($event, 'R')" /> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>R</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" subscriptSizing="dynamic" appearance="outline"> |
||||
|
<input matInput type="number" [min]="0" [max]="255" [value]="value?.getGreen()" (inputChange)="onInputChange($event, 'G')" /> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>G</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" subscriptSizing="dynamic" appearance="outline"> |
||||
|
<input matInput type="number" [min]="0" [max]="255" [value]="value?.getBlue()" (inputChange)="onInputChange($event,'B')" /> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>B</span> |
||||
|
} |
||||
|
</div> |
||||
|
<div class="tb-form-row tb-flex no-gap no-border no-padding column align-center"> |
||||
|
<mat-form-field class="color-input number" subscriptSizing="dynamic" appearance="outline"> |
||||
|
<input matInput type="number" [min]="0" [max]="100" [value]="alphaValue" (inputChange)="onAlphaInputChange($event)" /> |
||||
|
<span matSuffix>{{suffixValue}}</span> |
||||
|
</mat-form-field> |
||||
|
@if (labelVisible) { |
||||
|
<span>A</span> |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,71 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2026 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core'; |
||||
|
import { Color } from '@iplab/ngx-color-picker'; |
||||
|
import { coerceBoolean } from '@shared/decorators/coercion'; |
||||
|
|
||||
|
type Channel = 'R' | 'G' | 'B'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-rgba-input', |
||||
|
templateUrl: './rgba-input.component.html', |
||||
|
styleUrl: './color-input.base.scss', |
||||
|
standalone: false |
||||
|
}) |
||||
|
export class RgbaInputComponent { |
||||
|
|
||||
|
@Input() |
||||
|
public color: Color; |
||||
|
|
||||
|
@Output() |
||||
|
public colorChange = new EventEmitter<Color>(false); |
||||
|
|
||||
|
@Input() |
||||
|
@coerceBoolean() |
||||
|
public labelVisible = false; |
||||
|
|
||||
|
@Input() |
||||
|
public suffixValue = '%'; |
||||
|
|
||||
|
public get value() { |
||||
|
return this.color.getRgba(); |
||||
|
} |
||||
|
|
||||
|
public get alphaValue(): string { |
||||
|
return this.color ? Math.round(this.color.getRgba().getAlpha() * 100).toString() : ''; |
||||
|
} |
||||
|
|
||||
|
public onAlphaInputChange(inputValue: number): void { |
||||
|
if (!this.color) return; |
||||
|
const color = this.color.getRgba(); |
||||
|
const alpha = +inputValue / 100; |
||||
|
if (color.getAlpha() !== alpha) { |
||||
|
const newColor = new Color().setRgba(color.getRed(), color.getGreen(), color.getBlue(), alpha).toRgbaString(); |
||||
|
this.colorChange.emit(new Color(newColor)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
onInputChange(newValue: number, channel: Channel) { |
||||
|
if (!this.color) return; |
||||
|
const rgba = this.value; |
||||
|
const red = channel === 'R' ? newValue : rgba.getRed(); |
||||
|
const green = channel === 'G' ? newValue : rgba.getGreen(); |
||||
|
const blue = channel === 'B' ? newValue : rgba.getBlue(); |
||||
|
if (red === rgba.getRed() && green === rgba.getGreen() && blue === rgba.getBlue()) return; |
||||
|
this.colorChange.emit(new Color().setRgba(red, green, blue, rgba.alpha)); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue