diff --git a/.github/commitlint.config.mjs b/.github/commitlint.config.mjs
index 4be77761..5e19cbe4 100644
--- a/.github/commitlint.config.mjs
+++ b/.github/commitlint.config.mjs
@@ -24,5 +24,7 @@ export default {
"subject-case": [0],
// Allow long body lines for detailed commit descriptions
"body-max-line-length": [0],
+ // Allow long footer lines (e.g. issue refs, BREAKING CHANGE blocks, links)
+ "footer-max-line-length": [0],
},
};
diff --git a/custom_components/hass_datapoints/hass-datapoints-cards.js b/custom_components/hass_datapoints/hass-datapoints-cards.js
index da42cc6b..2509bead 100644
--- a/custom_components/hass_datapoints/hass-datapoints-cards.js
+++ b/custom_components/hass_datapoints/hass-datapoints-cards.js
@@ -1343,7 +1343,7 @@
* - A ha-selector (target schema) lets the user add extra items per recording.
* - On submit both are merged; the selector resets to empty afterwards.
*/
- var HassRecordsActionCard = class extends i$2 {
+ var HassDatapointsActionCard = class extends i$2 {
constructor() {
super();
_defineProperty(this, "_userTarget", {});
@@ -1605,7 +1605,7 @@
return this._config?.show_annotation !== false ? 10 : 7;
}
};
- _defineProperty(HassRecordsActionCard, "properties", {
+ _defineProperty(HassDatapointsActionCard, "properties", {
_config: { state: true },
_hass: { state: true },
_color: { state: true },
@@ -1613,7 +1613,7 @@
_feedbackText: { state: true },
_feedbackVisible: { state: true }
});
- _defineProperty(HassRecordsActionCard, "styles", styles$71);
+ _defineProperty(HassDatapointsActionCard, "styles", styles$71);
//#endregion
//#region node_modules/.pnpm/@lit+localize@0.12.2/node_modules/@lit/localize/internal/locale-status-event.js
/**
@@ -5634,7 +5634,7 @@
customElements.define("editor-icon-picker", EditorIconPicker);
//#endregion
//#region custom_components/hass_datapoints/src/cards/action/editor.ts
- var HassRecordsActionCardEditor = class extends EditorBase {
+ var HassDatapointsActionCardEditor = class extends EditorBase {
_configTarget() {
return normalizeTargetValue(this._config.target ?? { entity_id: Array.isArray(this._config.entities) && this._config.entities.length ? this._config.entities : this._config.entity }) ?? {};
}
@@ -5727,7 +5727,7 @@
`;
}
};
- _defineProperty(HassRecordsActionCardEditor, "styles", [EditorBase.styles, styles$65]);
+ _defineProperty(HassDatapointsActionCardEditor, "styles", [EditorBase.styles, styles$65]);
//#endregion
//#region node_modules/.pnpm/@kipk+load-ha-components@1.0.3/node_modules/@kipk/load-ha-components/dist/load-ha-components.js
/**
@@ -6026,7 +6026,7 @@
`;
//#endregion
//#region custom_components/hass_datapoints/src/cards/dev-tool/editor.ts
- var HassRecordsDevToolCardEditor = class extends EditorBase {
+ var HassDatapointsDevToolCardEditor = class extends EditorBase {
render() {
return b`
@@ -6037,7 +6037,7 @@
`;
}
};
- _defineProperty(HassRecordsDevToolCardEditor, "styles", [EditorBase.styles]);
+ _defineProperty(HassDatapointsDevToolCardEditor, "styles", [EditorBase.styles]);
//#endregion
//#region custom_components/hass_datapoints/src/cards/dev-tool/dev-tool-results/dev-tool-results.styles.ts
var styles$58 = i$5`
@@ -6666,7 +6666,7 @@
customElements.define("dev-tool-windows", CardDevToolWindows);
//#endregion
//#region custom_components/hass_datapoints/src/cards/dev-tool/dev-tool.ts
- var HassRecordsDevToolCard = class extends HTMLElement {
+ var HassDatapointsDevToolCard = class extends HTMLElement {
constructor() {
super();
_defineProperty(this, "_config", {});
@@ -11650,13 +11650,13 @@
const topSlot = this._el("chart-top-slot");
const legend = this._el("legend");
const scrollViewport = this._el("chart-scroll-viewport");
- const wrap = this;
const cardHeight = card?.clientHeight || 0;
const occupiedHeight = (header?.offsetHeight || 0) + (topSlot && !topSlot.hidden ? topSlot.offsetHeight || 0 : 0) + (legend?.offsetHeight || 0);
const cardDerivedHeight = cardHeight ? Math.max(0, cardHeight - occupiedHeight) : 0;
const viewportHeight = scrollViewport?.clientHeight || 0;
- const wrapHeight = wrap?.clientHeight || 0;
- return Math.max(minChartHeight, cardDerivedHeight || viewportHeight || wrapHeight || 0);
+ if (cardDerivedHeight) return Math.max(minChartHeight, cardDerivedHeight);
+ if (viewportHeight) return Math.max(minChartHeight, viewportHeight);
+ return minChartHeight;
}
_syncTopSlotOffset() {
const topSlot = this._el("chart-top-slot");
@@ -15710,7 +15710,7 @@
}
//#endregion
//#region custom_components/hass_datapoints/src/cards/history/history.ts
- var HassRecordsHistoryCard = class extends ChartCardBase {
+ var HassDatapointsHistoryCard = class extends ChartCardBase {
constructor() {
super();
_defineProperty(this, "_hiddenSeries", /* @__PURE__ */ new Set());
@@ -16596,8 +16596,8 @@
return document.createElement("hass-datapoints-history-card-editor");
}
};
- _defineProperty(HassRecordsHistoryCard, "styles", styles$56);
- customElements.define("hass-datapoints-history-card", HassRecordsHistoryCard);
+ _defineProperty(HassDatapointsHistoryCard, "styles", styles$56);
+ customElements.define("hass-datapoints-history-card", HassDatapointsHistoryCard);
//#endregion
//#region custom_components/hass_datapoints/src/cards/history/editor.styles.ts
var styles$52 = i$5``;
@@ -19131,7 +19131,7 @@
customElements.define("sidebar-chart-display-section", SidebarChartDisplaySection);
//#endregion
//#region custom_components/hass_datapoints/src/cards/history/editor.ts
- var HassRecordsHistoryCardEditor = class extends EditorBase {
+ var HassDatapointsHistoryCardEditor = class extends EditorBase {
constructor(..._args) {
super(..._args);
_defineProperty(this, "_onTargetChanged", (e) => {
@@ -19451,7 +19451,7 @@
`;
}
};
- _defineProperty(HassRecordsHistoryCardEditor, "styles", [EditorBase.styles, styles$52]);
+ _defineProperty(HassDatapointsHistoryCardEditor, "styles", [EditorBase.styles, styles$52]);
//#endregion
//#region custom_components/hass_datapoints/src/lib/data/preferences-api.ts
/** HA user-data key for the saved history page. Stored via frontend/set_user_data. */
@@ -30466,7 +30466,7 @@
/**
* hass-datapoints-history-panel – Sidebar panel for annotated history exploration.
*/
- var HassRecordsHistoryPanel = class extends HTMLElement {
+ var HassDatapointsHistoryPanel = class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
@@ -34126,8 +34126,8 @@
customElements.define("list-event-item", CardListEventItem);
//#endregion
//#region custom_components/hass_datapoints/src/cards/list/list.ts
- var _HassRecordsListCard;
- var HassRecordsListCard = (_HassRecordsListCard = class HassRecordsListCard extends i$2 {
+ var _HassDatapointsListCard;
+ var HassDatapointsListCard = (_HassDatapointsListCard = class HassDatapointsListCard extends i$2 {
constructor() {
super();
_defineProperty(this, "_pageSize", 15);
@@ -34452,7 +34452,7 @@
min_rows: rows
};
}
- }, _defineProperty(_HassRecordsListCard, "properties", {
+ }, _defineProperty(_HassDatapointsListCard, "properties", {
_config: { state: true },
_hass: { state: true },
_allEvents: { state: true },
@@ -34460,14 +34460,14 @@
_page: { state: true },
_editingId: { state: true },
_editColor: { state: true }
- }), _defineProperty(_HassRecordsListCard, "styles", styles$16), _HassRecordsListCard);
- HassRecordsListCard = __decorate([localized()], HassRecordsListCard);
+ }), _defineProperty(_HassDatapointsListCard, "styles", styles$16), _HassDatapointsListCard);
+ HassDatapointsListCard = __decorate([localized()], HassDatapointsListCard);
//#endregion
//#region custom_components/hass_datapoints/src/cards/list/editor.styles.ts
var styles$11 = i$5``;
//#endregion
//#region custom_components/hass_datapoints/src/cards/list/editor.ts
- var HassRecordsListCardEditor = class extends EditorBase {
+ var HassDatapointsListCardEditor = class extends EditorBase {
constructor(..._args) {
super(..._args);
_defineProperty(this, "_onTargetChanged", (e) => {
@@ -34563,7 +34563,7 @@
`;
}
};
- _defineProperty(HassRecordsListCardEditor, "styles", [EditorBase.styles, styles$11]);
+ _defineProperty(HassDatapointsListCardEditor, "styles", [EditorBase.styles, styles$11]);
//#endregion
//#region custom_components/hass_datapoints/src/cards/quick/quick.styles.ts
var styles$10 = i$5`
@@ -34717,7 +34717,7 @@
customElements.define("quick-annotation", CardQuickAnnotation);
//#endregion
//#region custom_components/hass_datapoints/src/cards/quick/quick.ts
- var HassRecordsQuickCard = class extends i$2 {
+ var HassDatapointsQuickCard = class extends i$2 {
constructor() {
super();
this._config = {};
@@ -34864,7 +34864,7 @@
return this._config?.title ? baseRows + 1 : baseRows;
}
};
- _defineProperty(HassRecordsQuickCard, "properties", {
+ _defineProperty(HassDatapointsQuickCard, "properties", {
_config: {
type: Object,
state: true
@@ -34890,7 +34890,7 @@
state: true
}
});
- _defineProperty(HassRecordsQuickCard, "styles", styles$10);
+ _defineProperty(HassDatapointsQuickCard, "styles", styles$10);
//#endregion
//#region custom_components/hass_datapoints/src/cards/quick/editor.styles.ts
var styles$8 = i$5`
@@ -34901,7 +34901,7 @@
`;
//#endregion
//#region custom_components/hass_datapoints/src/cards/quick/editor.ts
- var HassRecordsQuickCardEditor = class extends EditorBase {
+ var HassDatapointsQuickCardEditor = class extends EditorBase {
constructor(..._args) {
super(..._args);
_defineProperty(this, "_onTargetChanged", (e) => {
@@ -34983,7 +34983,7 @@
`;
}
};
- _defineProperty(HassRecordsQuickCardEditor, "styles", [EditorBase.styles, styles$8]);
+ _defineProperty(HassDatapointsQuickCardEditor, "styles", [EditorBase.styles, styles$8]);
//#endregion
//#region custom_components/hass_datapoints/src/cards/sensor/sensor.styles.ts
var styles$7 = i$5`
@@ -36171,7 +36171,7 @@
* hass-datapoints-sensor-card – Sensor card with inline annotation icons.
* Canvas rendering is delegated to sensor-chart; annotation list to sensor-records.
*/
- var HassRecordsSensorCard = class extends i$2 {
+ var HassDatapointsSensorCard = class extends i$2 {
constructor() {
super();
_defineProperty(this, "_initialized", false);
@@ -36422,14 +36422,14 @@
};
}
};
- _defineProperty(HassRecordsSensorCard, "properties", {
+ _defineProperty(HassDatapointsSensorCard, "properties", {
_config: { state: true },
_hass: { state: true },
_annEvents: { state: true },
_hiddenEventIds: { state: true },
_recordsFooterHeight: { state: true }
});
- _defineProperty(HassRecordsSensorCard, "styles", styles$7);
+ _defineProperty(HassDatapointsSensorCard, "styles", styles$7);
//#endregion
//#region custom_components/hass_datapoints/src/cards/sensor/editor.styles.ts
var styles$2 = i$5``;
@@ -36582,7 +36582,7 @@
customElements.define("editor-select", EditorSelect);
//#endregion
//#region custom_components/hass_datapoints/src/cards/sensor/editor.ts
- var HassRecordsSensorCardEditor = class extends EditorBase {
+ var HassDatapointsSensorCardEditor = class extends EditorBase {
render() {
const c = this._config;
const showRecords = !!c.show_records;
@@ -36659,61 +36659,212 @@
`;
}
};
- _defineProperty(HassRecordsSensorCardEditor, "styles", [EditorBase.styles, styles$2]);
+ _defineProperty(HassDatapointsSensorCardEditor, "styles", [EditorBase.styles, styles$2]);
//#endregion
//#region custom_components/hass_datapoints/src/register.ts
/**
* Register all custom elements and advertise them to the Lovelace card picker.
*/
- if (!customElements.get("hass-datapoints-action-card")) customElements.define("hass-datapoints-action-card", HassRecordsActionCard);
- if (!customElements.get("hass-datapoints-quick-card")) customElements.define("hass-datapoints-quick-card", HassRecordsQuickCard);
- if (!customElements.get("hass-datapoints-history-card")) customElements.define("hass-datapoints-history-card", HassRecordsHistoryCard);
- if (!customElements.get("hass-datapoints-sensor-card")) customElements.define("hass-datapoints-sensor-card", HassRecordsSensorCard);
- if (!customElements.get("hass-datapoints-list-card")) customElements.define("hass-datapoints-list-card", HassRecordsListCard);
- if (!customElements.get("hass-datapoints-history-panel")) customElements.define("hass-datapoints-history-panel", HassRecordsHistoryPanel);
- if (!customElements.get("hass-datapoints-dev-tool-card")) customElements.define("hass-datapoints-dev-tool-card", HassRecordsDevToolCard);
- if (!customElements.get("hass-datapoints-action-card-editor")) customElements.define("hass-datapoints-action-card-editor", HassRecordsActionCardEditor);
- if (!customElements.get("hass-datapoints-quick-card-editor")) customElements.define("hass-datapoints-quick-card-editor", HassRecordsQuickCardEditor);
- if (!customElements.get("hass-datapoints-history-card-editor")) customElements.define("hass-datapoints-history-card-editor", HassRecordsHistoryCardEditor);
- if (!customElements.get("hass-datapoints-sensor-card-editor")) customElements.define("hass-datapoints-sensor-card-editor", HassRecordsSensorCardEditor);
- if (!customElements.get("hass-datapoints-list-card-editor")) customElements.define("hass-datapoints-list-card-editor", HassRecordsListCardEditor);
- if (!customElements.get("hass-datapoints-dev-tool-card-editor")) customElements.define("hass-datapoints-dev-tool-card-editor", HassRecordsDevToolCardEditor);
+ var _warnOnceKey = "__HASS_DATAPOINTS_DEPRECATED_TAG_WARNED__";
+ function _warnDeprecatedTag(oldTag, newTag) {
+ const win = window;
+ if (!win[_warnOnceKey]) win[_warnOnceKey] = {};
+ const warned = win[_warnOnceKey];
+ if (warned[oldTag]) return;
+ warned[oldTag] = true;
+ console.warn(`[hass-datapoints] deprecated card tag "${oldTag}" in use; migrate to "${newTag}".`);
+ }
+ function _defineDeprecatedAlias({ oldTag, newTag, base }) {
+ if (customElements.get(oldTag)) return;
+ class DeprecatedAlias extends base {
+ constructor() {
+ super();
+ _warnDeprecatedTag(oldTag, newTag);
+ }
+ }
+ customElements.define(oldTag, DeprecatedAlias);
+ }
+ var HassDatapointsRemovedStatisticsCard = class extends HTMLElement {
+ constructor(..._args) {
+ super(..._args);
+ _defineProperty(this, "_config", {});
+ }
+ setConfig(config) {
+ this._config = config ?? {};
+ this._render();
+ }
+ set hass(_hass) {}
+ connectedCallback() {
+ this._render();
+ }
+ _render() {
+ this.innerHTML = `
+
+
+
+
+ Datapoints statistics card removed.
+ Use custom:hass-datapoints-history-card instead.
+
+
+ Deprecated types: custom:hass-datapoints-statistics-card,
+ custom:hass-records-statistics-card.
+
+
+
+ `;
+ }
+ };
+ var HassDatapointsRemovedStatisticsCardEditor = class extends HTMLElement {
+ setConfig(_config) {
+ this._render();
+ }
+ set hass(_hass) {}
+ connectedCallback() {
+ this._render();
+ }
+ _render() {
+ this.innerHTML = `
+
+
+
+ Datapoints statistics card removed.
+ Replace with custom:hass-datapoints-history-card.
+
+
+
+ `;
+ }
+ };
+ if (!customElements.get("hass-datapoints-action-card")) customElements.define("hass-datapoints-action-card", HassDatapointsActionCard);
+ if (!customElements.get("hass-datapoints-quick-card")) customElements.define("hass-datapoints-quick-card", HassDatapointsQuickCard);
+ if (!customElements.get("hass-datapoints-history-card")) customElements.define("hass-datapoints-history-card", HassDatapointsHistoryCard);
+ if (!customElements.get("hass-datapoints-sensor-card")) customElements.define("hass-datapoints-sensor-card", HassDatapointsSensorCard);
+ if (!customElements.get("hass-datapoints-list-card")) customElements.define("hass-datapoints-list-card", HassDatapointsListCard);
+ if (!customElements.get("hass-datapoints-history-panel")) customElements.define("hass-datapoints-history-panel", HassDatapointsHistoryPanel);
+ if (!customElements.get("hass-datapoints-dev-tool-card")) customElements.define("hass-datapoints-dev-tool-card", HassDatapointsDevToolCard);
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-action-card",
+ newTag: "hass-datapoints-action-card",
+ base: HassDatapointsActionCard
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-quick-card",
+ newTag: "hass-datapoints-quick-card",
+ base: HassDatapointsQuickCard
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-history-card",
+ newTag: "hass-datapoints-history-card",
+ base: HassDatapointsHistoryCard
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-sensor-card",
+ newTag: "hass-datapoints-sensor-card",
+ base: HassDatapointsSensorCard
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-list-card",
+ newTag: "hass-datapoints-list-card",
+ base: HassDatapointsListCard
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-dev-tool-card",
+ newTag: "hass-datapoints-dev-tool-card",
+ base: HassDatapointsDevToolCard
+ });
+ if (!customElements.get("hass-datapoints-statistics-card")) customElements.define("hass-datapoints-statistics-card", HassDatapointsRemovedStatisticsCard);
+ if (!customElements.get("hass-records-statistics-card")) {
+ class HassRecordsRemovedStatisticsCard extends HassDatapointsRemovedStatisticsCard {
+ constructor() {
+ super();
+ _warnDeprecatedTag("hass-records-statistics-card", "hass-datapoints-history-card");
+ }
+ }
+ customElements.define("hass-records-statistics-card", HassRecordsRemovedStatisticsCard);
+ }
+ if (!customElements.get("hass-datapoints-action-card-editor")) customElements.define("hass-datapoints-action-card-editor", HassDatapointsActionCardEditor);
+ if (!customElements.get("hass-datapoints-quick-card-editor")) customElements.define("hass-datapoints-quick-card-editor", HassDatapointsQuickCardEditor);
+ if (!customElements.get("hass-datapoints-history-card-editor")) customElements.define("hass-datapoints-history-card-editor", HassDatapointsHistoryCardEditor);
+ if (!customElements.get("hass-datapoints-sensor-card-editor")) customElements.define("hass-datapoints-sensor-card-editor", HassDatapointsSensorCardEditor);
+ if (!customElements.get("hass-datapoints-list-card-editor")) customElements.define("hass-datapoints-list-card-editor", HassDatapointsListCardEditor);
+ if (!customElements.get("hass-datapoints-dev-tool-card-editor")) customElements.define("hass-datapoints-dev-tool-card-editor", HassDatapointsDevToolCardEditor);
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-action-card-editor",
+ newTag: "hass-datapoints-action-card-editor",
+ base: HassDatapointsActionCardEditor
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-quick-card-editor",
+ newTag: "hass-datapoints-quick-card-editor",
+ base: HassDatapointsQuickCardEditor
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-history-card-editor",
+ newTag: "hass-datapoints-history-card-editor",
+ base: HassDatapointsHistoryCardEditor
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-sensor-card-editor",
+ newTag: "hass-datapoints-sensor-card-editor",
+ base: HassDatapointsSensorCardEditor
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-list-card-editor",
+ newTag: "hass-datapoints-list-card-editor",
+ base: HassDatapointsListCardEditor
+ });
+ _defineDeprecatedAlias({
+ oldTag: "hass-records-dev-tool-card-editor",
+ newTag: "hass-datapoints-dev-tool-card-editor",
+ base: HassDatapointsDevToolCardEditor
+ });
+ if (!customElements.get("hass-datapoints-statistics-card-editor")) customElements.define("hass-datapoints-statistics-card-editor", HassDatapointsRemovedStatisticsCardEditor);
+ if (!customElements.get("hass-records-statistics-card-editor")) {
+ class HassRecordsRemovedStatisticsCardEditor extends HassDatapointsRemovedStatisticsCardEditor {
+ constructor() {
+ super();
+ _warnDeprecatedTag("hass-records-statistics-card-editor", "hass-datapoints-history-card");
+ }
+ }
+ customElements.define("hass-records-statistics-card-editor", HassRecordsRemovedStatisticsCardEditor);
+ }
window.customCards = window.customCards || [];
var registeredTypes = new Set(window.customCards.map((card) => card.type));
[
{
type: "hass-datapoints-action-card",
- name: "Hass Records – Action Card",
+ name: "Datapoints – Action Card",
description: "Full form to record a custom event with message, annotation, icon, colour and entity association.",
preview: false
},
{
type: "hass-datapoints-quick-card",
- name: "Hass Records – Quick Card",
+ name: "Datapoints – Quick Card",
description: "Simple one-field card to quickly record a note with a bookmark icon.",
preview: false
},
{
type: "hass-datapoints-history-card",
- name: "Hass Records – History Card",
+ name: "Datapoints – History Card",
description: "History line chart with coloured annotation markers for recorded events.",
preview: false
},
{
type: "hass-datapoints-sensor-card",
- name: "Hass Records – Sensor Card",
+ name: "Datapoints – Sensor Card",
description: "Sensor card with line chart — annotations shown as icons on the data line.",
preview: false
},
{
type: "hass-datapoints-list-card",
- name: "Hass Records – List Card",
+ name: "Datapoints – List Card",
description: "Activity-style datagrid to browse, search, edit and delete all recorded events.",
preview: false
},
{
type: "hass-datapoints-dev-tool-card",
- name: "Hass Records – Dev Tool",
+ name: "Datapoints – Dev Tool",
description: "Generate demo datapoints from HA history and bulk-delete dev-flagged events.",
preview: false
}
diff --git a/custom_components/hass_datapoints/src/__tests__/register-compat.spec.ts b/custom_components/hass_datapoints/src/__tests__/register-compat.spec.ts
new file mode 100644
index 00000000..ff35dc31
--- /dev/null
+++ b/custom_components/hass_datapoints/src/__tests__/register-compat.spec.ts
@@ -0,0 +1,53 @@
+import { beforeAll, describe, expect, it, vi } from "vitest";
+
+describe("register", () => {
+ beforeAll(async () => {
+ document.body.innerHTML = "";
+ (window as unknown as { customCards?: unknown[] }).customCards = [];
+
+ vi.spyOn(console, "groupCollapsed").mockImplementation(() => {});
+ vi.spyOn(console, "log").mockImplementation(() => {});
+ vi.spyOn(console, "groupEnd").mockImplementation(() => {});
+
+ await import("../register");
+ }, 30_000);
+
+ describe("GIVEN register.ts is loaded", () => {
+ describe("WHEN Lovelace custom card metadata is registered", () => {
+ it("THEN names use Datapoints prefix (not Hass Records/Hass Datapoints)", async () => {
+ expect.assertions(3);
+
+ const cards = window.customCards || [];
+ const names = cards.map((c) => c.name).filter(Boolean) as string[];
+
+ expect(names.length).toBeGreaterThan(0);
+ expect(names.every((name) => name.startsWith("Datapoints – "))).toBe(
+ true
+ );
+ expect(
+ names.some(
+ (name) => name.includes("Hass Records") || name.includes("Hass ")
+ )
+ ).toBe(false);
+ });
+ });
+
+ describe("WHEN old hass-records tags are referenced", () => {
+ it("THEN deprecated aliases exist for old dashboards", async () => {
+ expect.assertions(8);
+
+ expect(customElements.get("hass-records-action-card")).toBeTruthy();
+ expect(customElements.get("hass-records-quick-card")).toBeTruthy();
+ expect(customElements.get("hass-records-history-card")).toBeTruthy();
+ expect(customElements.get("hass-records-sensor-card")).toBeTruthy();
+ expect(customElements.get("hass-records-list-card")).toBeTruthy();
+ expect(customElements.get("hass-records-dev-tool-card")).toBeTruthy();
+
+ expect(customElements.get("hass-records-statistics-card")).toBeTruthy();
+ expect(
+ customElements.get("hass-datapoints-statistics-card")
+ ).toBeTruthy();
+ });
+ });
+ });
+});
diff --git a/custom_components/hass_datapoints/src/cards/action/__tests__/action.spec.ts b/custom_components/hass_datapoints/src/cards/action/__tests__/action.spec.ts
index ca9fdda0..5bbbc179 100644
--- a/custom_components/hass_datapoints/src/cards/action/__tests__/action.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/action/__tests__/action.spec.ts
@@ -1,9 +1,12 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsActionCard } from "../action.ts";
+import { HassDatapointsActionCard } from "../action.ts";
if (!customElements.get("hass-datapoints-action-card")) {
- customElements.define("hass-datapoints-action-card", HassRecordsActionCard);
+ customElements.define(
+ "hass-datapoints-action-card",
+ HassDatapointsActionCard
+ );
}
function createCard(config: RecordWithUnknownValues = {}) {
@@ -227,7 +230,7 @@ describe("action", () => {
describe("GIVEN the static config methods", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns default config", () => {
- expect(HassRecordsActionCard.getStubConfig()).toEqual({
+ expect(HassDatapointsActionCard.getStubConfig()).toEqual({
title: "Record Event",
});
});
@@ -235,7 +238,7 @@ describe("action", () => {
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the editor element tag", () => {
- const editorEl = HassRecordsActionCard.getConfigElement();
+ const editorEl = HassDatapointsActionCard.getConfigElement();
expect(editorEl.tagName.toLowerCase()).toBe(
"hass-datapoints-action-card-editor"
);
diff --git a/custom_components/hass_datapoints/src/cards/action/action.ts b/custom_components/hass_datapoints/src/cards/action/action.ts
index 04dcfbef..5dc57061 100644
--- a/custom_components/hass_datapoints/src/cards/action/action.ts
+++ b/custom_components/hass_datapoints/src/cards/action/action.ts
@@ -21,7 +21,7 @@ import { logger } from "@/lib/logger";
* - A ha-selector (target schema) lets the user add extra items per recording.
* - On submit both are merged; the selector resets to empty afterwards.
*/
-export class HassRecordsActionCard extends LitElement {
+export class HassDatapointsActionCard extends LitElement {
static properties = {
_config: { state: true },
_hass: { state: true },
diff --git a/custom_components/hass_datapoints/src/cards/action/editor.ts b/custom_components/hass_datapoints/src/cards/action/editor.ts
index 7222424e..f0217d0f 100644
--- a/custom_components/hass_datapoints/src/cards/action/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/action/editor.ts
@@ -16,7 +16,7 @@ type TargetPickerElement = Element & {
value?: TargetPickerValue;
};
-export class HassRecordsActionCardEditor extends EditorBase {
+export class HassDatapointsActionCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles, styles];
private _configTarget(): TargetPickerValue {
diff --git a/custom_components/hass_datapoints/src/cards/action/stories/action.stories.ts b/custom_components/hass_datapoints/src/cards/action/stories/action.stories.ts
index 4c68b1ed..19b4e582 100644
--- a/custom_components/hass_datapoints/src/cards/action/stories/action.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/action/stories/action.stories.ts
@@ -2,10 +2,13 @@ import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { expect } from "@storybook/test";
import { html } from "lit";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsActionCard } from "../action";
+import { HassDatapointsActionCard } from "../action";
if (!customElements.get("hass-datapoints-action-card")) {
- customElements.define("hass-datapoints-action-card", HassRecordsActionCard);
+ customElements.define(
+ "hass-datapoints-action-card",
+ HassDatapointsActionCard
+ );
}
type Story = StoryObj;
@@ -17,10 +20,10 @@ const meta: Meta = {
export default meta;
-function getCard(canvasElement: HTMLElement): HassRecordsActionCard {
+function getCard(canvasElement: HTMLElement): HassDatapointsActionCard {
return canvasElement.querySelector(
"hass-datapoints-action-card"
- ) as HassRecordsActionCard;
+ ) as HassDatapointsActionCard;
}
const mockHass = createMockHass();
@@ -29,7 +32,7 @@ export const Default: Story = {
render: () =>
html`
`,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsActionCard & {
+ const card = getCard(canvasElement) as HassDatapointsActionCard & {
updateComplete: Promise
;
};
card.setConfig({ title: "Record Event" });
@@ -44,7 +47,7 @@ export const WithTargetsAndAnnotation: Story = {
render: () =>
html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsActionCard & {
+ const card = getCard(canvasElement) as HassDatapointsActionCard & {
updateComplete: Promise;
};
card.setConfig({
diff --git a/custom_components/hass_datapoints/src/cards/dev-tool/__tests__/dev-tool.spec.ts b/custom_components/hass_datapoints/src/cards/dev-tool/__tests__/dev-tool.spec.ts
index 5900fb7e..de9cceaa 100644
--- a/custom_components/hass_datapoints/src/cards/dev-tool/__tests__/dev-tool.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/dev-tool/__tests__/dev-tool.spec.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsDevToolCard } from "../dev-tool.ts";
+import { HassDatapointsDevToolCard } from "../dev-tool.ts";
vi.mock("@/helpers.js", async (importOriginal) => {
const mod = (await importOriginal()) as RecordWithUnknownValues;
@@ -14,7 +14,7 @@ vi.mock("@/helpers.js", async (importOriginal) => {
if (!customElements.get("hass-datapoints-dev-tool-card")) {
customElements.define(
"hass-datapoints-dev-tool-card",
- HassRecordsDevToolCard
+ HassDatapointsDevToolCard
);
}
@@ -186,14 +186,16 @@ describe("dev-tool", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns default config", () => {
expect.assertions(1);
- expect(HassRecordsDevToolCard.getStubConfig()).toHaveProperty("title");
+ expect(HassDatapointsDevToolCard.getStubConfig()).toHaveProperty(
+ "title"
+ );
});
});
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the dev-tool editor element tag", () => {
expect.assertions(1);
- const editorEl = HassRecordsDevToolCard.getConfigElement();
+ const editorEl = HassDatapointsDevToolCard.getConfigElement();
expect(editorEl.tagName.toLowerCase()).toBe(
"hass-datapoints-dev-tool-card-editor"
);
diff --git a/custom_components/hass_datapoints/src/cards/dev-tool/dev-tool.ts b/custom_components/hass_datapoints/src/cards/dev-tool/dev-tool.ts
index 74ed11e4..234acc69 100644
--- a/custom_components/hass_datapoints/src/cards/dev-tool/dev-tool.ts
+++ b/custom_components/hass_datapoints/src/cards/dev-tool/dev-tool.ts
@@ -9,12 +9,12 @@ import type {
WindowConfig,
WindowResult,
} from "@/cards/dev-tool/types";
-import { HassRecordsDevToolCardEditor } from "./editor";
+import { HassDatapointsDevToolCardEditor } from "./editor";
import "@/atoms/display/feedback-banner/feedback-banner";
import "@/cards/dev-tool/dev-tool-results/dev-tool-results";
import "@/cards/dev-tool/dev-tool-windows/dev-tool-windows";
-export class HassRecordsDevToolCard extends HTMLElement {
+export class HassDatapointsDevToolCard extends HTMLElement {
_config: RecordWithUnknownValues = {};
_hass: Nullable = null;
@@ -625,4 +625,4 @@ export class HassRecordsDevToolCard extends HTMLElement {
}
}
-export { HassRecordsDevToolCardEditor };
+export { HassDatapointsDevToolCardEditor };
diff --git a/custom_components/hass_datapoints/src/cards/dev-tool/editor.ts b/custom_components/hass_datapoints/src/cards/dev-tool/editor.ts
index e52bbaeb..1cdab67d 100644
--- a/custom_components/hass_datapoints/src/cards/dev-tool/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/dev-tool/editor.ts
@@ -2,7 +2,7 @@ import { CSSResultGroup, html } from "lit";
import { msg } from "@/lib/i18n/localize";
import { EditorBase } from "@/molecules/editor-base/editor-base";
-export class HassRecordsDevToolCardEditor extends EditorBase {
+export class HassDatapointsDevToolCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles];
render() {
diff --git a/custom_components/hass_datapoints/src/cards/dev-tool/stories/dev-tool.stories.ts b/custom_components/hass_datapoints/src/cards/dev-tool/stories/dev-tool.stories.ts
index ebf9d7b5..be27f197 100644
--- a/custom_components/hass_datapoints/src/cards/dev-tool/stories/dev-tool.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/dev-tool/stories/dev-tool.stories.ts
@@ -2,12 +2,12 @@ import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { expect } from "@storybook/test";
import { html } from "lit";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsDevToolCard } from "../dev-tool";
+import { HassDatapointsDevToolCard } from "../dev-tool";
if (!customElements.get("hass-datapoints-dev-tool-card")) {
customElements.define(
"hass-datapoints-dev-tool-card",
- HassRecordsDevToolCard
+ HassDatapointsDevToolCard
);
}
@@ -20,10 +20,10 @@ const meta: Meta = {
export default meta;
-function getCard(canvasElement: HTMLElement): HassRecordsDevToolCard {
+function getCard(canvasElement: HTMLElement): HassDatapointsDevToolCard {
return canvasElement.querySelector(
"hass-datapoints-dev-tool-card"
- ) as HassRecordsDevToolCard;
+ ) as HassDatapointsDevToolCard;
}
function makeMockHass() {
@@ -87,7 +87,7 @@ export const WithResults: Story = {
render: () =>
html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsDevToolCard & {
+ const card = getCard(canvasElement) as HassDatapointsDevToolCard & {
_entities: string[];
_analyzeHistory: () => Promise;
};
diff --git a/custom_components/hass_datapoints/src/cards/history/__tests__/editor.spec.ts b/custom_components/hass_datapoints/src/cards/history/__tests__/editor.spec.ts
index 406b219c..7dec4880 100644
--- a/custom_components/hass_datapoints/src/cards/history/__tests__/editor.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/history/__tests__/editor.spec.ts
@@ -1,18 +1,18 @@
import { afterEach, describe, expect, it } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsHistoryCardEditor } from "../editor";
+import { HassDatapointsHistoryCardEditor } from "../editor";
if (!customElements.get("hass-datapoints-history-card-editor")) {
customElements.define(
"hass-datapoints-history-card-editor",
- HassRecordsHistoryCardEditor
+ HassDatapointsHistoryCardEditor
);
}
function createEditor() {
const el = document.createElement(
"hass-datapoints-history-card-editor"
- ) as HassRecordsHistoryCardEditor;
+ ) as HassDatapointsHistoryCardEditor;
document.body.appendChild(el);
el.hass = createMockHass();
el.setConfig({
@@ -34,7 +34,7 @@ function createEditor() {
}
describe("history editor", () => {
- let el: Nullable = null;
+ let el: Nullable = null;
afterEach(() => {
el?.remove();
diff --git a/custom_components/hass_datapoints/src/cards/history/__tests__/history.spec.ts b/custom_components/hass_datapoints/src/cards/history/__tests__/history.spec.ts
index 4616d276..fd9d16cc 100644
--- a/custom_components/hass_datapoints/src/cards/history/__tests__/history.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/history/__tests__/history.spec.ts
@@ -1,5 +1,5 @@
/**
- * history.spec.ts — GIVEN/WHEN/THEN tests for HassRecordsHistoryCard.
+ * history.spec.ts — GIVEN/WHEN/THEN tests for HassDatapointsHistoryCard.
*
* We test the public API surface: setConfig validation/normalisation,
* _entityIds getter, static helpers, and basic rendering.
@@ -55,10 +55,10 @@ vi.mock("@/lib/ha/navigation", async (importOriginal) => {
});
// Import the card AFTER mocks are set up
-let HassRecordsHistoryCard: typeof import("../history.ts").HassRecordsHistoryCard;
+let HassDatapointsHistoryCard: typeof import("../history.ts").HassDatapointsHistoryCard;
beforeAll(async () => {
- ({ HassRecordsHistoryCard } = await import("../history.ts"));
+ ({ HassDatapointsHistoryCard } = await import("../history.ts"));
});
// ── Helpers ───────────────────────────────────────────────────────────────────
@@ -86,7 +86,7 @@ function createMockHass(overrides = {}) {
function createCard(
config: RecordWithUnknownValues = { entity: "sensor.example" }
) {
- const el = new HassRecordsHistoryCard();
+ const el = new HassDatapointsHistoryCard();
el.setConfig(config);
return el;
}
@@ -104,7 +104,7 @@ describe("history", () => {
describe("WHEN setConfig is called", () => {
it("THEN it throws an error", () => {
expect.assertions(1);
- const el = new HassRecordsHistoryCard();
+ const el = new HassDatapointsHistoryCard();
expect(() => el.setConfig({})).toThrow();
});
});
@@ -418,7 +418,7 @@ describe("history", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns an object with entity and hours_to_show", () => {
expect.assertions(2);
- const stub = HassRecordsHistoryCard.getStubConfig();
+ const stub = HassDatapointsHistoryCard.getStubConfig();
expect(stub).toHaveProperty("entity");
expect(stub).toHaveProperty("hours_to_show");
});
@@ -427,7 +427,7 @@ describe("history", () => {
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the editor element tag name", () => {
expect.assertions(1);
- const editor = HassRecordsHistoryCard.getConfigElement();
+ const editor = HassDatapointsHistoryCard.getConfigElement();
expect(editor.tagName.toLowerCase()).toBe(
"hass-datapoints-history-card-editor"
);
@@ -438,7 +438,7 @@ describe("history", () => {
// ── Rendering ────────────────────────────────────────────────────────────
describe("GIVEN a card connected to the DOM with hass", () => {
- let el: HassRecordsHistoryCard;
+ let el: HassDatapointsHistoryCard;
beforeEach(async () => {
el = createCard({ entity: "sensor.example", title: "Test Chart" });
diff --git a/custom_components/hass_datapoints/src/cards/history/editor.ts b/custom_components/hass_datapoints/src/cards/history/editor.ts
index f1c35246..21ab3c2e 100644
--- a/custom_components/hass_datapoints/src/cards/history/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/history/editor.ts
@@ -40,7 +40,7 @@ type AnalysisChangeDetail = {
value?: unknown;
};
-export class HassRecordsHistoryCardEditor extends EditorBase {
+export class HassDatapointsHistoryCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles, styles];
private _configTarget(): TargetPickerValue {
diff --git a/custom_components/hass_datapoints/src/cards/history/history-chart/__tests__/history-chart-height.spec.ts b/custom_components/hass_datapoints/src/cards/history/history-chart/__tests__/history-chart-height.spec.ts
new file mode 100644
index 00000000..f9d3c7af
--- /dev/null
+++ b/custom_components/hass_datapoints/src/cards/history/history-chart/__tests__/history-chart-height.spec.ts
@@ -0,0 +1,41 @@
+import { describe, expect, it } from "vitest";
+import { HistoryChart } from "../history-chart";
+
+describe("history-chart height", () => {
+ describe("GIVEN ha-card has no measurable height", () => {
+ describe("WHEN available height is computed repeatedly", () => {
+ it("THEN it does not grow via host height feedback loop", () => {
+ expect.assertions(3);
+
+ const card = document.createElement("ha-card") as HTMLElement;
+ const header = document.createElement("div");
+ header.className = "card-header";
+ card.appendChild(header);
+
+ document.body.appendChild(card);
+
+ const chart = new HistoryChart();
+ card.appendChild(chart);
+
+ // Simulate runaway host sizing from a previous render.
+ Object.defineProperty(chart, "clientHeight", {
+ configurable: true,
+ get() {
+ return 10_000;
+ },
+ });
+
+ const first = (
+ chart as unknown as { _getAvailableChartHeight: any }
+ )._getAvailableChartHeight(280) as number;
+ const second = (
+ chart as unknown as { _getAvailableChartHeight: any }
+ )._getAvailableChartHeight(280) as number;
+
+ expect(first).toBe(280);
+ expect(second).toBe(280);
+ expect(second).toBe(first);
+ });
+ });
+ });
+});
diff --git a/custom_components/hass_datapoints/src/cards/history/history-chart/history-chart.ts b/custom_components/hass_datapoints/src/cards/history/history-chart/history-chart.ts
index de542741..82a8a2c7 100644
--- a/custom_components/hass_datapoints/src/cards/history/history-chart/history-chart.ts
+++ b/custom_components/hass_datapoints/src/cards/history/history-chart/history-chart.ts
@@ -440,7 +440,6 @@ export class HistoryChart extends HTMLElement {
const scrollViewport = this._el(
"chart-scroll-viewport"
) as Nullable;
- const wrap = this as HTMLElement;
const cardHeight = card?.clientHeight || 0;
const occupiedHeight =
@@ -451,12 +450,17 @@ export class HistoryChart extends HTMLElement {
? Math.max(0, cardHeight - occupiedHeight)
: 0;
const viewportHeight = scrollViewport?.clientHeight || 0;
- const wrapHeight = wrap?.clientHeight || 0;
- return Math.max(
- minChartHeight,
- cardDerivedHeight || viewportHeight || wrapHeight || 0
- );
+ // Avoid using the host element height as a fallback. The host height can
+ // include previous chart sizing + padding, causing a feedback loop:
+ // ResizeObserver -> redraw -> measure host height -> grow -> resize -> …
+ if (cardDerivedHeight) {
+ return Math.max(minChartHeight, cardDerivedHeight);
+ }
+ if (viewportHeight) {
+ return Math.max(minChartHeight, viewportHeight);
+ }
+ return minChartHeight;
}
_syncTopSlotOffset(): void {
diff --git a/custom_components/hass_datapoints/src/cards/history/history.ts b/custom_components/hass_datapoints/src/cards/history/history.ts
index e840aa3a..f550d121 100644
--- a/custom_components/hass_datapoints/src/cards/history/history.ts
+++ b/custom_components/hass_datapoints/src/cards/history/history.ts
@@ -69,7 +69,7 @@ interface PartialLoadState {
// ── Card ──────────────────────────────────────────────────────────────────────
-export class HassRecordsHistoryCard extends ChartCardBase {
+export class HassDatapointsHistoryCard extends ChartCardBase {
static styles = styles;
// ── State ──────────────────────────────────────────────────────────────────
@@ -1641,4 +1641,7 @@ export class HassRecordsHistoryCard extends ChartCardBase {
}
}
-customElements.define("hass-datapoints-history-card", HassRecordsHistoryCard);
+customElements.define(
+ "hass-datapoints-history-card",
+ HassDatapointsHistoryCard
+);
diff --git a/custom_components/hass_datapoints/src/cards/history/stories/history.stories.ts b/custom_components/hass_datapoints/src/cards/history/stories/history.stories.ts
index 573d1e51..46ed1fa9 100644
--- a/custom_components/hass_datapoints/src/cards/history/stories/history.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/history/stories/history.stories.ts
@@ -8,11 +8,14 @@
*/
import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { html } from "lit";
-import { HassRecordsHistoryCard } from "../history";
+import { HassDatapointsHistoryCard } from "../history";
// Self-registers if not already defined (guards against HMR double-registration).
if (!customElements.get("hass-datapoints-history-card")) {
- customElements.define("hass-datapoints-history-card", HassRecordsHistoryCard);
+ customElements.define(
+ "hass-datapoints-history-card",
+ HassDatapointsHistoryCard
+ );
}
type Story = StoryObj;
diff --git a/custom_components/hass_datapoints/src/cards/list/__tests__/list.spec.ts b/custom_components/hass_datapoints/src/cards/list/__tests__/list.spec.ts
index c3d8426f..6ee8533a 100644
--- a/custom_components/hass_datapoints/src/cards/list/__tests__/list.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/list/__tests__/list.spec.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsListCard } from "../list.ts";
+import { HassDatapointsListCard } from "../list.ts";
import type { EventRecord } from "@/lib/types";
import { fetchEvents } from "@/lib/data/events-api";
@@ -25,7 +25,7 @@ vi.mock("@/lib/data/events-api", async (importOriginal) => {
});
if (!customElements.get("hass-datapoints-list-card")) {
- customElements.define("hass-datapoints-list-card", HassRecordsListCard);
+ customElements.define("hass-datapoints-list-card", HassDatapointsListCard);
}
const mockEvents: EventRecord[] = [
@@ -279,13 +279,13 @@ describe("list", () => {
describe("GIVEN the static config methods", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns empty config", () => {
- expect(HassRecordsListCard.getStubConfig()).toEqual({});
+ expect(HassDatapointsListCard.getStubConfig()).toEqual({});
});
});
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the editor element tag", () => {
- const editorEl = HassRecordsListCard.getConfigElement();
+ const editorEl = HassDatapointsListCard.getConfigElement();
expect(editorEl.tagName.toLowerCase()).toBe(
"hass-datapoints-list-card-editor"
);
diff --git a/custom_components/hass_datapoints/src/cards/list/editor.ts b/custom_components/hass_datapoints/src/cards/list/editor.ts
index d9069c9b..a9fab8f6 100644
--- a/custom_components/hass_datapoints/src/cards/list/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/list/editor.ts
@@ -14,7 +14,7 @@ type TargetPickerElement = Element & {
value?: TargetPickerValue;
};
-export class HassRecordsListCardEditor extends EditorBase {
+export class HassDatapointsListCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles, styles];
private _configTarget(): TargetPickerValue {
diff --git a/custom_components/hass_datapoints/src/cards/list/list.ts b/custom_components/hass_datapoints/src/cards/list/list.ts
index afa5cfd8..60f95cd9 100644
--- a/custom_components/hass_datapoints/src/cards/list/list.ts
+++ b/custom_components/hass_datapoints/src/cards/list/list.ts
@@ -22,7 +22,7 @@ import { logger } from "@/lib/logger";
* hass-datapoints-list-card – Activity-style datagrid with search, pagination, edit/delete.
*/
@localized()
-export class HassRecordsListCard extends LitElement {
+export class HassDatapointsListCard extends LitElement {
static properties = {
_config: { state: true },
_hass: { state: true },
diff --git a/custom_components/hass_datapoints/src/cards/list/stories/list.stories.ts b/custom_components/hass_datapoints/src/cards/list/stories/list.stories.ts
index 4592a75c..e31c8ae7 100644
--- a/custom_components/hass_datapoints/src/cards/list/stories/list.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/list/stories/list.stories.ts
@@ -2,10 +2,10 @@ import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { expect } from "@storybook/test";
import { html } from "lit";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsListCard } from "../list";
+import { HassDatapointsListCard } from "../list";
if (!customElements.get("hass-datapoints-list-card")) {
- customElements.define("hass-datapoints-list-card", HassRecordsListCard);
+ customElements.define("hass-datapoints-list-card", HassDatapointsListCard);
}
type Story = StoryObj;
@@ -17,10 +17,10 @@ const meta: Meta = {
export default meta;
-function getCard(canvasElement: HTMLElement): HassRecordsListCard {
+function getCard(canvasElement: HTMLElement): HassDatapointsListCard {
return canvasElement.querySelector(
"hass-datapoints-list-card"
- ) as HassRecordsListCard;
+ ) as HassDatapointsListCard;
}
function makeMockHass() {
@@ -80,7 +80,7 @@ function makeMockHass() {
export const Default: Story = {
render: () => html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsListCard & {
+ const card = getCard(canvasElement) as HassDatapointsListCard & {
updateComplete: Promise;
_load: () => Promise;
};
@@ -96,7 +96,7 @@ export const Default: Story = {
export const WithoutSearch: Story = {
render: () => html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsListCard & {
+ const card = getCard(canvasElement) as HassDatapointsListCard & {
updateComplete: Promise;
_load: () => Promise;
};
diff --git a/custom_components/hass_datapoints/src/cards/quick/__tests__/quick.spec.ts b/custom_components/hass_datapoints/src/cards/quick/__tests__/quick.spec.ts
index 3f4e5614..5a825459 100644
--- a/custom_components/hass_datapoints/src/cards/quick/__tests__/quick.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/quick/__tests__/quick.spec.ts
@@ -1,9 +1,9 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsQuickCard } from "../quick";
+import { HassDatapointsQuickCard } from "../quick";
if (!customElements.get("hass-datapoints-quick-card")) {
- customElements.define("hass-datapoints-quick-card", HassRecordsQuickCard);
+ customElements.define("hass-datapoints-quick-card", HassDatapointsQuickCard);
}
function createCard(config: RecordWithUnknownValues = {}) {
@@ -105,7 +105,7 @@ describe("quick", () => {
describe("GIVEN a quick card with static config methods", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns default config", () => {
- expect(HassRecordsQuickCard.getStubConfig()).toEqual({
+ expect(HassDatapointsQuickCard.getStubConfig()).toEqual({
title: "Quick Record",
});
});
@@ -113,7 +113,7 @@ describe("quick", () => {
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the editor element tag", () => {
- const editorEl = HassRecordsQuickCard.getConfigElement();
+ const editorEl = HassDatapointsQuickCard.getConfigElement();
expect(editorEl.tagName.toLowerCase()).toBe(
"hass-datapoints-quick-card-editor"
);
diff --git a/custom_components/hass_datapoints/src/cards/quick/editor.ts b/custom_components/hass_datapoints/src/cards/quick/editor.ts
index aae186df..cf460133 100644
--- a/custom_components/hass_datapoints/src/cards/quick/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/quick/editor.ts
@@ -17,7 +17,7 @@ type TargetPickerElement = Element & {
value?: TargetPickerValue;
};
-export class HassRecordsQuickCardEditor extends EditorBase {
+export class HassDatapointsQuickCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles, styles];
private _configTarget(): TargetPickerValue {
diff --git a/custom_components/hass_datapoints/src/cards/quick/quick.ts b/custom_components/hass_datapoints/src/cards/quick/quick.ts
index 9ec99d27..8a49162c 100644
--- a/custom_components/hass_datapoints/src/cards/quick/quick.ts
+++ b/custom_components/hass_datapoints/src/cards/quick/quick.ts
@@ -7,7 +7,7 @@ import type { HassLike } from "@/lib/types";
import "@/atoms/display/feedback-banner/feedback-banner";
import "@/cards/quick/quick-annotation/quick-annotation";
-export class HassRecordsQuickCard extends LitElement {
+export class HassDatapointsQuickCard extends LitElement {
static properties = {
_config: { type: Object, state: true },
_hass: { type: Object, state: true },
diff --git a/custom_components/hass_datapoints/src/cards/quick/stories/quick.stories.ts b/custom_components/hass_datapoints/src/cards/quick/stories/quick.stories.ts
index 1b1adbdd..4847f29b 100644
--- a/custom_components/hass_datapoints/src/cards/quick/stories/quick.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/quick/stories/quick.stories.ts
@@ -2,10 +2,10 @@ import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { expect } from "@storybook/test";
import { html } from "lit";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsQuickCard } from "../quick";
+import { HassDatapointsQuickCard } from "../quick";
if (!customElements.get("hass-datapoints-quick-card")) {
- customElements.define("hass-datapoints-quick-card", HassRecordsQuickCard);
+ customElements.define("hass-datapoints-quick-card", HassDatapointsQuickCard);
}
type Story = StoryObj;
@@ -17,10 +17,10 @@ const meta: Meta = {
export default meta;
-function getCard(canvasElement: HTMLElement): HassRecordsQuickCard {
+function getCard(canvasElement: HTMLElement): HassDatapointsQuickCard {
return canvasElement.querySelector(
"hass-datapoints-quick-card"
- ) as HassRecordsQuickCard;
+ ) as HassDatapointsQuickCard;
}
const mockHass = createMockHass();
@@ -28,7 +28,7 @@ const mockHass = createMockHass();
export const Default: Story = {
render: () => html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsQuickCard & {
+ const card = getCard(canvasElement) as HassDatapointsQuickCard & {
updateComplete: Promise;
};
card.setConfig({ title: "Quick Record" });
@@ -42,7 +42,7 @@ export const Default: Story = {
export const WithAnnotation: Story = {
render: () => html``,
play: async ({ canvasElement }) => {
- const card = getCard(canvasElement) as HassRecordsQuickCard & {
+ const card = getCard(canvasElement) as HassDatapointsQuickCard & {
updateComplete: Promise;
};
card.setConfig({ title: "Quick Record", show_annotation: true });
diff --git a/custom_components/hass_datapoints/src/cards/sensor/__tests__/sensor.spec.ts b/custom_components/hass_datapoints/src/cards/sensor/__tests__/sensor.spec.ts
index f892b6c4..c2924770 100644
--- a/custom_components/hass_datapoints/src/cards/sensor/__tests__/sensor.spec.ts
+++ b/custom_components/hass_datapoints/src/cards/sensor/__tests__/sensor.spec.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createMockHass } from "@/test-support/mock-hass";
-import { HassRecordsSensorCard } from "../sensor.ts";
+import { HassDatapointsSensorCard } from "../sensor.ts";
import type { EventRecord } from "@/lib/types";
import { fetchEvents } from "@/lib/data/events-api";
@@ -51,7 +51,10 @@ vi.mock("@/lib/data/events-api", async (importOriginal) => {
});
if (!customElements.get("hass-datapoints-sensor-card")) {
- customElements.define("hass-datapoints-sensor-card", HassRecordsSensorCard);
+ customElements.define(
+ "hass-datapoints-sensor-card",
+ HassDatapointsSensorCard
+ );
}
const mockEvents: EventRecord[] = [
@@ -277,14 +280,14 @@ describe("sensor", () => {
describe("GIVEN the static config methods", () => {
describe("WHEN getStubConfig is called", () => {
it("THEN it returns a config with an entity", () => {
- const cfg = HassRecordsSensorCard.getStubConfig();
+ const cfg = HassDatapointsSensorCard.getStubConfig();
expect(cfg).toHaveProperty("entity");
});
});
describe("WHEN getConfigElement is called", () => {
it("THEN it returns the editor element tag", () => {
- const editorEl = HassRecordsSensorCard.getConfigElement();
+ const editorEl = HassDatapointsSensorCard.getConfigElement();
expect(editorEl.tagName.toLowerCase()).toBe(
"hass-datapoints-sensor-card-editor"
);
diff --git a/custom_components/hass_datapoints/src/cards/sensor/editor.ts b/custom_components/hass_datapoints/src/cards/sensor/editor.ts
index 11891328..ebf7d5fa 100644
--- a/custom_components/hass_datapoints/src/cards/sensor/editor.ts
+++ b/custom_components/hass_datapoints/src/cards/sensor/editor.ts
@@ -10,7 +10,7 @@ import "@/atoms/form/editor-switch/editor-switch";
import "@/atoms/form/editor-entity-picker/editor-entity-picker";
import "@/atoms/form/editor-select/editor-select";
-export class HassRecordsSensorCardEditor extends EditorBase {
+export class HassDatapointsSensorCardEditor extends EditorBase {
static styles: CSSResultGroup = [EditorBase.styles, styles];
render() {
diff --git a/custom_components/hass_datapoints/src/cards/sensor/sensor.ts b/custom_components/hass_datapoints/src/cards/sensor/sensor.ts
index 56c7a7d4..757931b7 100644
--- a/custom_components/hass_datapoints/src/cards/sensor/sensor.ts
+++ b/custom_components/hass_datapoints/src/cards/sensor/sensor.ts
@@ -16,7 +16,7 @@ import "./sensor-records/sensor-records";
* hass-datapoints-sensor-card – Sensor card with inline annotation icons.
* Canvas rendering is delegated to sensor-chart; annotation list to sensor-records.
*/
-export class HassRecordsSensorCard extends LitElement {
+export class HassDatapointsSensorCard extends LitElement {
static properties = {
_config: { state: true },
_hass: { state: true },
diff --git a/custom_components/hass_datapoints/src/cards/sensor/stories/sensor.stories.ts b/custom_components/hass_datapoints/src/cards/sensor/stories/sensor.stories.ts
index c939cc4f..a32ba5f1 100644
--- a/custom_components/hass_datapoints/src/cards/sensor/stories/sensor.stories.ts
+++ b/custom_components/hass_datapoints/src/cards/sensor/stories/sensor.stories.ts
@@ -13,10 +13,13 @@
*/
import type { Meta, StoryObj } from "@storybook/web-components-vite";
import { html, type TemplateResult } from "lit";
-import { HassRecordsSensorCard } from "../sensor";
+import { HassDatapointsSensorCard } from "../sensor";
if (!customElements.get("hass-datapoints-sensor-card")) {
- customElements.define("hass-datapoints-sensor-card", HassRecordsSensorCard);
+ customElements.define(
+ "hass-datapoints-sensor-card",
+ HassDatapointsSensorCard
+ );
}
type Story = StoryObj;
@@ -199,7 +202,7 @@ async function setupCard(
) {
const card = canvasElement.querySelector(
"hass-datapoints-sensor-card"
- ) as HassRecordsSensorCard;
+ ) as HassDatapointsSensorCard;
card.setConfig(config);
if (hass) {
card.hass = hass as any;
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-anomaly-overlap-mode.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-anomaly-overlap-mode.spec.ts
index 9f5a18d6..ef9a07c9 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-anomaly-overlap-mode.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-anomaly-overlap-mode.spec.ts
@@ -1,8 +1,8 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
import { normalizeHistorySeriesAnalysis } from "@/lib/domain/history-series";
-describe("HassRecordsHistoryPanel anomaly overlap mode config", () => {
+describe("HassDatapointsHistoryPanel anomaly overlap mode config", () => {
afterEach(() => {
vi.restoreAllMocks();
});
@@ -76,7 +76,7 @@ describe("HassRecordsHistoryPanel anomaly overlap mode config", () => {
_hass: null,
};
- HassRecordsHistoryPanel.prototype._renderContent.call(panel);
+ HassDatapointsHistoryPanel.prototype._renderContent.call(panel);
expect(setConfig).toHaveBeenCalledTimes(1);
expect(setConfig.mock.calls[0][0].anomaly_overlap_mode).toBe("only");
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-bootstrap.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-bootstrap.spec.ts
index 78905e2c..10c55cec 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-bootstrap.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-bootstrap.spec.ts
@@ -1,8 +1,8 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
import { normalizeHistorySeriesAnalysis } from "@/lib/domain/history-series";
-describe("HassRecordsHistoryPanel bootstrap", () => {
+describe("HassDatapointsHistoryPanel bootstrap", () => {
afterEach(() => {
vi.restoreAllMocks();
});
@@ -28,7 +28,9 @@ describe("HassRecordsHistoryPanel bootstrap", () => {
_updateUrl: updateUrl,
};
- HassRecordsHistoryPanel.prototype._bootstrapAfterShellBuilt.call(panel);
+ HassDatapointsHistoryPanel.prototype._bootstrapAfterShellBuilt.call(
+ panel
+ );
expect(ensureHistoryBounds).toHaveBeenCalledTimes(1);
expect(ensureUserPreferences).toHaveBeenCalledTimes(1);
@@ -60,14 +62,15 @@ describe("HassRecordsHistoryPanel bootstrap", () => {
},
],
_applyPreferredSeriesColors:
- HassRecordsHistoryPanel.prototype._applyPreferredSeriesColors,
+ HassDatapointsHistoryPanel.prototype._applyPreferredSeriesColors,
_mergeSavedSeriesRows:
- HassRecordsHistoryPanel.prototype._mergeSavedSeriesRows,
- _syncSeriesState: HassRecordsHistoryPanel.prototype._syncSeriesState,
+ HassDatapointsHistoryPanel.prototype._mergeSavedSeriesRows,
+ _syncSeriesState:
+ HassDatapointsHistoryPanel.prototype._syncSeriesState,
_seriesColorQueryKey: () => "temperature",
};
- HassRecordsHistoryPanel.prototype._applyPreferencePageState.call(
+ HassDatapointsHistoryPanel.prototype._applyPreferencePageState.call(
panel,
{
series_rows: [
@@ -117,7 +120,7 @@ describe("HassRecordsHistoryPanel bootstrap", () => {
],
_seriesColorQueryKey: () => "temperature",
_applyPreferredSeriesColors:
- HassRecordsHistoryPanel.prototype._applyPreferredSeriesColors,
+ HassDatapointsHistoryPanel.prototype._applyPreferredSeriesColors,
_applyPreferencePageState: applyPreferencePageState,
_saveUserPreferences: saveUserPreferences,
_rendered: true,
@@ -149,7 +152,7 @@ describe("HassRecordsHistoryPanel bootstrap", () => {
},
};
- return HassRecordsHistoryPanel.prototype._ensureUserPreferences
+ return HassDatapointsHistoryPanel.prototype._ensureUserPreferences
.call(panel)
.then(() => {
expect(applyPreferencePageState).not.toHaveBeenCalled();
@@ -207,7 +210,7 @@ describe("HassRecordsHistoryPanel bootstrap", () => {
},
};
- HassRecordsHistoryPanel.prototype.disconnectedCallback.call(panel);
+ HassDatapointsHistoryPanel.prototype.disconnectedCallback.call(panel);
expect(tabletMq.removeEventListener).toHaveBeenCalledTimes(1);
expect(mobileMq.removeEventListener).toHaveBeenCalledTimes(1);
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-resize.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-resize.spec.ts
index 1cfeded1..6034ca03 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-resize.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-resize.spec.ts
@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
-describe("HassRecordsHistoryPanel", () => {
+describe("HassDatapointsHistoryPanel", () => {
beforeEach(() => {
vi.restoreAllMocks();
});
@@ -39,7 +39,9 @@ describe("HassRecordsHistoryPanel", () => {
},
};
- HassRecordsHistoryPanel.prototype._requestChartResizeRedraw.call(panel);
+ HassDatapointsHistoryPanel.prototype._requestChartResizeRedraw.call(
+ panel
+ );
expect(rafSpy).toHaveBeenCalledOnce();
expect(drawSpy).toHaveBeenCalledOnce();
@@ -65,7 +67,9 @@ describe("HassRecordsHistoryPanel", () => {
_chartEl: null,
};
- HassRecordsHistoryPanel.prototype._requestChartResizeRedraw.call(panel);
+ HassDatapointsHistoryPanel.prototype._requestChartResizeRedraw.call(
+ panel
+ );
expect(requestChartResizeRedraw).toHaveBeenCalledWith(null);
});
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-zoom-highlight.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-zoom-highlight.spec.ts
index d6084e40..864a2026 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-zoom-highlight.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-chart-zoom-highlight.spec.ts
@@ -1,7 +1,7 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
-describe("HassRecordsHistoryPanel chart zoom highlight", () => {
+describe("HassDatapointsHistoryPanel chart zoom highlight", () => {
afterEach(() => {
vi.restoreAllMocks();
});
@@ -82,7 +82,7 @@ describe("HassRecordsHistoryPanel chart zoom highlight", () => {
}
);
- HassRecordsHistoryPanel.prototype._renderContent.call(panel);
+ HassDatapointsHistoryPanel.prototype._renderContent.call(panel);
expect(panel._chartZoomCommittedRange).toEqual(zoomRange);
expect(updateChartZoomHighlight).toHaveBeenCalled();
@@ -117,7 +117,7 @@ describe("HassRecordsHistoryPanel chart zoom highlight", () => {
_renderComparisonTabs: renderComparisonTabs,
};
- HassRecordsHistoryPanel.prototype._handleChartZoom.call(panel, {
+ HassDatapointsHistoryPanel.prototype._handleChartZoom.call(panel, {
detail: {
startTime: 100,
endTime: 200,
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-collapsed-sidebar.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-collapsed-sidebar.spec.ts
index 917d94f3..e99db74b 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-collapsed-sidebar.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-collapsed-sidebar.spec.ts
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
-describe("HassRecordsHistoryPanel collapsed sidebar interactions", () => {
+describe("HassDatapointsHistoryPanel collapsed sidebar interactions", () => {
let panel: RecordWithUnknownValues;
beforeEach(() => {
@@ -21,7 +21,7 @@ describe("HassRecordsHistoryPanel collapsed sidebar interactions", () => {
describe("WHEN the collapsed rail background is clicked", () => {
it("THEN it does not toggle the sidebar", () => {
expect.assertions(1);
- HassRecordsHistoryPanel.prototype._handleCollapsedSidebarClick.call(
+ HassDatapointsHistoryPanel.prototype._handleCollapsedSidebarClick.call(
panel,
{
composedPath: () => [
@@ -41,7 +41,7 @@ describe("HassRecordsHistoryPanel collapsed sidebar interactions", () => {
describe("WHEN the collapsed add button is clicked", () => {
it("THEN it does not toggle the sidebar", () => {
expect.assertions(1);
- HassRecordsHistoryPanel.prototype._handleCollapsedSidebarClick.call(
+ HassDatapointsHistoryPanel.prototype._handleCollapsedSidebarClick.call(
panel,
{
composedPath: () => [
@@ -76,7 +76,10 @@ describe("HassRecordsHistoryPanel collapsed sidebar interactions", () => {
},
};
- HassRecordsHistoryPanel.prototype._openTargetPicker.call(panel, null);
+ HassDatapointsHistoryPanel.prototype._openTargetPicker.call(
+ panel,
+ null
+ );
expect(openTargetPicker).toHaveBeenCalledWith(
panel._targetControl,
@@ -104,7 +107,10 @@ describe("HassRecordsHistoryPanel collapsed sidebar interactions", () => {
},
};
- HassRecordsHistoryPanel.prototype._openTargetPicker.call(panel, null);
+ HassDatapointsHistoryPanel.prototype._openTargetPicker.call(
+ panel,
+ null
+ );
expect(openTargetPicker).toHaveBeenCalledWith(
panel._targetControl,
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-comparison-tabs.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-comparison-tabs.spec.ts
index e4cb2e92..9e2db744 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-comparison-tabs.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-comparison-tabs.spec.ts
@@ -1,8 +1,8 @@
import { describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
import { createHistoryPageOrchestrationContext } from "../context/orchestration-context";
-describe("HassRecordsHistoryPanel comparison tabs", () => {
+describe("HassDatapointsHistoryPanel comparison tabs", () => {
describe("GIVEN the history card wraps an inner namespaced chart element", () => {
describe("WHEN rendering comparison tabs", () => {
it("THEN it mounts the tab rail into the inner chart top slot", () => {
@@ -43,7 +43,7 @@ describe("HassRecordsHistoryPanel comparison tabs", () => {
_deleteDateWindow: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._renderComparisonTabs.call(panel);
+ HassDatapointsHistoryPanel.prototype._renderComparisonTabs.call(panel);
expect(panel._comparisonTabsHostEl).toBe(topSlot);
expect(topSlot.hidden).toBe(false);
@@ -89,7 +89,7 @@ describe("HassRecordsHistoryPanel comparison tabs", () => {
_deleteDateWindow: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._renderComparisonTabs.call(panel);
+ HassDatapointsHistoryPanel.prototype._renderComparisonTabs.call(panel);
expect(panel._comparisonTabsHostEl).toBe(topSlot);
expect(topSlot.hidden).toBe(false);
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-event-visibility.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-event-visibility.spec.ts
index 26aaf683..8ce7ee12 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-event-visibility.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-event-visibility.spec.ts
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
-describe("HassRecordsHistoryPanel", () => {
+describe("HassDatapointsHistoryPanel", () => {
describe("GIVEN a hidden event id list", () => {
describe("WHEN toggling an already-hidden event", () => {
it("THEN it removes the event id from the hidden list", () => {
@@ -11,7 +11,7 @@ describe("HassRecordsHistoryPanel", () => {
_renderContent: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._handleToggleEventVisibility.call(
+ HassDatapointsHistoryPanel.prototype._handleToggleEventVisibility.call(
panel,
{
detail: { eventId: "evt-1" },
@@ -33,7 +33,7 @@ describe("HassRecordsHistoryPanel", () => {
_renderContent: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._handleToggleEventVisibility.call(
+ HassDatapointsHistoryPanel.prototype._handleToggleEventVisibility.call(
panel,
{
detail: { eventId: "evt-2" },
@@ -55,9 +55,12 @@ describe("HassRecordsHistoryPanel", () => {
_renderContent: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._handleHoverEventRecord.call(panel, {
- detail: { eventId: "evt-3", hovered: true },
- });
+ HassDatapointsHistoryPanel.prototype._handleHoverEventRecord.call(
+ panel,
+ {
+ detail: { eventId: "evt-3", hovered: true },
+ }
+ );
expect(panel._hoveredEventIds).toEqual(["evt-3"]);
expect(panel._renderContent).toHaveBeenCalledOnce();
@@ -72,9 +75,12 @@ describe("HassRecordsHistoryPanel", () => {
_renderContent: vi.fn(),
};
- HassRecordsHistoryPanel.prototype._handleHoverEventRecord.call(panel, {
- detail: { eventId: "evt-3", hovered: false },
- });
+ HassDatapointsHistoryPanel.prototype._handleHoverEventRecord.call(
+ panel,
+ {
+ detail: { eventId: "evt-3", hovered: false },
+ }
+ );
expect(panel._hoveredEventIds).toEqual([]);
expect(panel._renderContent).toHaveBeenCalledOnce();
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-update-url.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-update-url.spec.ts
index 05f4325b..80e2369a 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-update-url.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-update-url.spec.ts
@@ -1,7 +1,7 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
-describe("HassRecordsHistoryPanel updateUrl", () => {
+describe("HassDatapointsHistoryPanel updateUrl", () => {
afterEach(() => {
vi.restoreAllMocks();
});
@@ -56,10 +56,10 @@ describe("HassRecordsHistoryPanel updateUrl", () => {
_hiddenEventIds: [],
_selectedComparisonWindowId: null,
_seriesColorQueryKey:
- HassRecordsHistoryPanel.prototype._seriesColorQueryKey,
+ HassDatapointsHistoryPanel.prototype._seriesColorQueryKey,
};
- HassRecordsHistoryPanel.prototype._updateUrl.call(panel, {
+ HassDatapointsHistoryPanel.prototype._updateUrl.call(panel, {
push: false,
});
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-url-sync.spec.ts b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-url-sync.spec.ts
index 97f211fe..327f314b 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-url-sync.spec.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/__tests__/datapoints-url-sync.spec.ts
@@ -1,8 +1,8 @@
import { afterEach, describe, expect, it, vi } from "vitest";
-import { HassRecordsHistoryPanel } from "../datapoints";
+import { HassDatapointsHistoryPanel } from "../datapoints";
import { normalizeHistorySeriesAnalysis } from "@/lib/domain/history-series";
-describe("HassRecordsHistoryPanel URL sync", () => {
+describe("HassDatapointsHistoryPanel URL sync", () => {
afterEach(() => {
vi.restoreAllMocks();
});
@@ -23,7 +23,7 @@ describe("HassRecordsHistoryPanel URL sync", () => {
_renderContent: renderContent,
};
- HassRecordsHistoryPanel.prototype._setChartDatapointDisplayOption.call(
+ HassDatapointsHistoryPanel.prototype._setChartDatapointDisplayOption.call(
panel,
"hover_guides",
true
@@ -61,7 +61,9 @@ describe("HassRecordsHistoryPanel URL sync", () => {
isConnected: true,
};
- HassRecordsHistoryPanel.prototype._toggleSidebarCollapsed.call(panel);
+ HassDatapointsHistoryPanel.prototype._toggleSidebarCollapsed.call(
+ panel
+ );
expect(panel._sidebarCollapsed).toBe(true);
expect(updateUrl).toHaveBeenCalledWith({ push: false });
@@ -95,7 +97,7 @@ describe("HassRecordsHistoryPanel URL sync", () => {
_renderContent: renderContent,
};
- HassRecordsHistoryPanel.prototype._setSeriesAnalysisOption.call(
+ HassDatapointsHistoryPanel.prototype._setSeriesAnalysisOption.call(
panel,
"sensor.temp",
"show_trend_lines",
diff --git a/custom_components/hass_datapoints/src/panels/datapoints/datapoints.ts b/custom_components/hass_datapoints/src/panels/datapoints/datapoints.ts
index 08b2e71d..5c5d4715 100644
--- a/custom_components/hass_datapoints/src/panels/datapoints/datapoints.ts
+++ b/custom_components/hass_datapoints/src/panels/datapoints/datapoints.ts
@@ -256,7 +256,7 @@ type ResizablePanesElement = HTMLElement & {
// Shared timeline, domain, and history-page helpers now live in dedicated subsystem files.
-export class HassRecordsHistoryPanel extends HTMLElement {
+export class HassDatapointsHistoryPanel extends HTMLElement {
[key: string]: unknown;
// Explicit declarations take precedence over the index signature so TypeScript
diff --git a/custom_components/hass_datapoints/src/register.ts b/custom_components/hass_datapoints/src/register.ts
index 933e247e..6b63b272 100644
--- a/custom_components/hass_datapoints/src/register.ts
+++ b/custom_components/hass_datapoints/src/register.ts
@@ -1,17 +1,18 @@
-/* eslint-disable no-console */
-import { HassRecordsActionCard } from "@/cards/action/action";
-import { HassRecordsActionCardEditor } from "@/cards/action/editor";
-import { HassRecordsDevToolCard } from "@/cards/dev-tool/dev-tool";
-import { HassRecordsDevToolCardEditor } from "@/cards/dev-tool/editor";
-import { HassRecordsHistoryCard } from "@/cards/history/history";
-import { HassRecordsHistoryCardEditor } from "@/cards/history/editor";
-import { HassRecordsHistoryPanel } from "@/panels/datapoints/datapoints";
-import { HassRecordsListCard } from "@/cards/list/list";
-import { HassRecordsListCardEditor } from "@/cards/list/editor";
-import { HassRecordsQuickCard } from "@/cards/quick/quick";
-import { HassRecordsQuickCardEditor } from "@/cards/quick/editor";
-import { HassRecordsSensorCard } from "@/cards/sensor/sensor";
-import { HassRecordsSensorCardEditor } from "@/cards/sensor/editor";
+/* eslint-disable no-console, max-classes-per-file */
+import { HassDatapointsActionCard } from "@/cards/action/action";
+import { HassDatapointsActionCardEditor } from "@/cards/action/editor";
+import { HassDatapointsDevToolCard } from "@/cards/dev-tool/dev-tool";
+import { HassDatapointsDevToolCardEditor } from "@/cards/dev-tool/editor";
+import { HassDatapointsHistoryCard } from "@/cards/history/history";
+import { HassDatapointsHistoryCardEditor } from "@/cards/history/editor";
+import { HassDatapointsHistoryPanel } from "@/panels/datapoints/datapoints";
+import { HassDatapointsListCard } from "@/cards/list/list";
+import { HassDatapointsListCardEditor } from "@/cards/list/editor";
+import { HassDatapointsQuickCard } from "@/cards/quick/quick";
+import { HassDatapointsQuickCardEditor } from "@/cards/quick/editor";
+import { HassDatapointsSensorCard } from "@/cards/sensor/sensor";
+import { HassDatapointsSensorCardEditor } from "@/cards/sensor/editor";
+import type { CardConfig } from "@/lib/types";
interface LovelaceCardRegistration {
type: string;
@@ -30,32 +31,204 @@ declare global {
* Register all custom elements and advertise them to the Lovelace card picker.
*/
+// ── Deprecated element aliases (backwards compat) ───────────────────────────
+
+const _warnOnceKey = "__HASS_DATAPOINTS_DEPRECATED_TAG_WARNED__";
+function _warnDeprecatedTag(oldTag: string, newTag: string): void {
+ const win = window as unknown as Record;
+ if (!win[_warnOnceKey]) {
+ win[_warnOnceKey] = {};
+ }
+ const warned = win[_warnOnceKey] as Record;
+ if (warned[oldTag]) {
+ return;
+ }
+ warned[oldTag] = true;
+
+ console.warn(
+ `[hass-datapoints] deprecated card tag "${oldTag}" in use; migrate to "${newTag}".`
+ );
+}
+
+function _defineDeprecatedAlias({
+ oldTag,
+ newTag,
+ base,
+}: {
+ oldTag: string;
+ newTag: string;
+ base: T;
+}): void {
+ if (customElements.get(oldTag)) {
+ return;
+ }
+
+ class DeprecatedAlias extends (base as unknown as CustomElementConstructor) {
+ constructor() {
+ super();
+ _warnDeprecatedTag(oldTag, newTag);
+ }
+ }
+ customElements.define(oldTag, DeprecatedAlias);
+}
+
+class HassDatapointsRemovedStatisticsCard extends HTMLElement {
+ private _config: CardConfig = {};
+
+ setConfig(config: CardConfig): void {
+ this._config = config ?? {};
+ this._render();
+ }
+
+ set hass(_hass: import("@/lib/types").HassLike) {
+ // noop; exists so HA doesn't error when assigning hass.
+ }
+
+ connectedCallback(): void {
+ this._render();
+ }
+
+ private _render(): void {
+ const title =
+ ((this._config as unknown as Record)?.title as
+ | string
+ | undefined) || "Statistics card";
+ this.innerHTML = `
+
+
+
+
+ Datapoints statistics card removed.
+ Use custom:hass-datapoints-history-card instead.
+
+
+ Deprecated types: custom:hass-datapoints-statistics-card,
+ custom:hass-records-statistics-card.
+
+
+
+ `;
+ }
+}
+
+class HassDatapointsRemovedStatisticsCardEditor extends HTMLElement {
+ setConfig(_config: CardConfig): void {
+ this._render();
+ }
+
+ set hass(_hass: import("@/lib/types").HassLike) {
+ // noop
+ }
+
+ connectedCallback(): void {
+ this._render();
+ }
+
+ private _render(): void {
+ this.innerHTML = `
+
+
+
+ Datapoints statistics card removed.
+ Replace with custom:hass-datapoints-history-card.
+
+
+
+ `;
+ }
+}
+
// ── Card elements ──────────────────────────────────────────────────────────
if (!customElements.get("hass-datapoints-action-card")) {
- customElements.define("hass-datapoints-action-card", HassRecordsActionCard);
+ customElements.define(
+ "hass-datapoints-action-card",
+ HassDatapointsActionCard
+ );
}
if (!customElements.get("hass-datapoints-quick-card")) {
- customElements.define("hass-datapoints-quick-card", HassRecordsQuickCard);
+ customElements.define("hass-datapoints-quick-card", HassDatapointsQuickCard);
}
if (!customElements.get("hass-datapoints-history-card")) {
- customElements.define("hass-datapoints-history-card", HassRecordsHistoryCard);
+ customElements.define(
+ "hass-datapoints-history-card",
+ HassDatapointsHistoryCard
+ );
}
if (!customElements.get("hass-datapoints-sensor-card")) {
- customElements.define("hass-datapoints-sensor-card", HassRecordsSensorCard);
+ customElements.define(
+ "hass-datapoints-sensor-card",
+ HassDatapointsSensorCard
+ );
}
if (!customElements.get("hass-datapoints-list-card")) {
- customElements.define("hass-datapoints-list-card", HassRecordsListCard);
+ customElements.define("hass-datapoints-list-card", HassDatapointsListCard);
}
if (!customElements.get("hass-datapoints-history-panel")) {
customElements.define(
"hass-datapoints-history-panel",
- HassRecordsHistoryPanel
+ HassDatapointsHistoryPanel
);
}
if (!customElements.get("hass-datapoints-dev-tool-card")) {
customElements.define(
"hass-datapoints-dev-tool-card",
- HassRecordsDevToolCard
+ HassDatapointsDevToolCard
+ );
+}
+
+// ── Backwards compat: hass-records-* tags ───────────────────────────────────
+// These were used by Hass Records versions; keep working for existing dashboards.
+_defineDeprecatedAlias({
+ oldTag: "hass-records-action-card",
+ newTag: "hass-datapoints-action-card",
+ base: HassDatapointsActionCard,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-quick-card",
+ newTag: "hass-datapoints-quick-card",
+ base: HassDatapointsQuickCard,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-history-card",
+ newTag: "hass-datapoints-history-card",
+ base: HassDatapointsHistoryCard,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-sensor-card",
+ newTag: "hass-datapoints-sensor-card",
+ base: HassDatapointsSensorCard,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-list-card",
+ newTag: "hass-datapoints-list-card",
+ base: HassDatapointsListCard,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-dev-tool-card",
+ newTag: "hass-datapoints-dev-tool-card",
+ base: HassDatapointsDevToolCard,
+});
+
+// ── Backwards compat: removed statistics card ───────────────────────────────
+if (!customElements.get("hass-datapoints-statistics-card")) {
+ customElements.define(
+ "hass-datapoints-statistics-card",
+ HassDatapointsRemovedStatisticsCard
+ );
+}
+if (!customElements.get("hass-records-statistics-card")) {
+ class HassRecordsRemovedStatisticsCard extends HassDatapointsRemovedStatisticsCard {
+ constructor() {
+ super();
+ _warnDeprecatedTag(
+ "hass-records-statistics-card",
+ "hass-datapoints-history-card"
+ );
+ }
+ }
+ customElements.define(
+ "hass-records-statistics-card",
+ HassRecordsRemovedStatisticsCard
);
}
@@ -63,37 +236,92 @@ if (!customElements.get("hass-datapoints-dev-tool-card")) {
if (!customElements.get("hass-datapoints-action-card-editor")) {
customElements.define(
"hass-datapoints-action-card-editor",
- HassRecordsActionCardEditor
+ HassDatapointsActionCardEditor
);
}
if (!customElements.get("hass-datapoints-quick-card-editor")) {
customElements.define(
"hass-datapoints-quick-card-editor",
- HassRecordsQuickCardEditor
+ HassDatapointsQuickCardEditor
);
}
if (!customElements.get("hass-datapoints-history-card-editor")) {
customElements.define(
"hass-datapoints-history-card-editor",
- HassRecordsHistoryCardEditor
+ HassDatapointsHistoryCardEditor
);
}
if (!customElements.get("hass-datapoints-sensor-card-editor")) {
customElements.define(
"hass-datapoints-sensor-card-editor",
- HassRecordsSensorCardEditor
+ HassDatapointsSensorCardEditor
);
}
if (!customElements.get("hass-datapoints-list-card-editor")) {
customElements.define(
"hass-datapoints-list-card-editor",
- HassRecordsListCardEditor
+ HassDatapointsListCardEditor
);
}
if (!customElements.get("hass-datapoints-dev-tool-card-editor")) {
customElements.define(
"hass-datapoints-dev-tool-card-editor",
- HassRecordsDevToolCardEditor
+ HassDatapointsDevToolCardEditor
+ );
+}
+
+// ── Backwards compat editors: hass-records-* ────────────────────────────────
+_defineDeprecatedAlias({
+ oldTag: "hass-records-action-card-editor",
+ newTag: "hass-datapoints-action-card-editor",
+ base: HassDatapointsActionCardEditor,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-quick-card-editor",
+ newTag: "hass-datapoints-quick-card-editor",
+ base: HassDatapointsQuickCardEditor,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-history-card-editor",
+ newTag: "hass-datapoints-history-card-editor",
+ base: HassDatapointsHistoryCardEditor,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-sensor-card-editor",
+ newTag: "hass-datapoints-sensor-card-editor",
+ base: HassDatapointsSensorCardEditor,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-list-card-editor",
+ newTag: "hass-datapoints-list-card-editor",
+ base: HassDatapointsListCardEditor,
+});
+_defineDeprecatedAlias({
+ oldTag: "hass-records-dev-tool-card-editor",
+ newTag: "hass-datapoints-dev-tool-card-editor",
+ base: HassDatapointsDevToolCardEditor,
+});
+
+// ── Backwards compat editor: removed statistics card ────────────────────────
+if (!customElements.get("hass-datapoints-statistics-card-editor")) {
+ customElements.define(
+ "hass-datapoints-statistics-card-editor",
+ HassDatapointsRemovedStatisticsCardEditor
+ );
+}
+if (!customElements.get("hass-records-statistics-card-editor")) {
+ class HassRecordsRemovedStatisticsCardEditor extends HassDatapointsRemovedStatisticsCardEditor {
+ constructor() {
+ super();
+ _warnDeprecatedTag(
+ "hass-records-statistics-card-editor",
+ "hass-datapoints-history-card"
+ );
+ }
+ }
+ customElements.define(
+ "hass-records-statistics-card-editor",
+ HassRecordsRemovedStatisticsCardEditor
);
}
@@ -103,42 +331,42 @@ const registeredTypes = new Set(window.customCards.map((card) => card.type));
const cardsToAdd: LovelaceCardRegistration[] = [
{
type: "hass-datapoints-action-card",
- name: "Hass Records – Action Card",
+ name: "Datapoints – Action Card",
description:
"Full form to record a custom event with message, annotation, icon, colour and entity association.",
preview: false,
},
{
type: "hass-datapoints-quick-card",
- name: "Hass Records – Quick Card",
+ name: "Datapoints – Quick Card",
description:
"Simple one-field card to quickly record a note with a bookmark icon.",
preview: false,
},
{
type: "hass-datapoints-history-card",
- name: "Hass Records – History Card",
+ name: "Datapoints – History Card",
description:
"History line chart with coloured annotation markers for recorded events.",
preview: false,
},
{
type: "hass-datapoints-sensor-card",
- name: "Hass Records – Sensor Card",
+ name: "Datapoints – Sensor Card",
description:
"Sensor card with line chart — annotations shown as icons on the data line.",
preview: false,
},
{
type: "hass-datapoints-list-card",
- name: "Hass Records – List Card",
+ name: "Datapoints – List Card",
description:
"Activity-style datagrid to browse, search, edit and delete all recorded events.",
preview: false,
},
{
type: "hass-datapoints-dev-tool-card",
- name: "Hass Records – Dev Tool",
+ name: "Datapoints – Dev Tool",
description:
"Generate demo datapoints from HA history and bulk-delete dev-flagged events.",
preview: false,
diff --git a/docs/cards.md b/docs/cards.md
index 42fe1bc1..981497a0 100644
--- a/docs/cards.md
+++ b/docs/cards.md
@@ -15,6 +15,22 @@ Data Points ships six Lovelace cards and a dedicated history panel. All cards in
| `hass-datapoints-history-card` | Multi-series analysis chart with target rows, anomaly overlays, date windows, zoom, timeline slider, and chart-created datapoints. |
| `hass-datapoints-sensor-card` | Sensor-focused chart with inline datapoint markers. |
+### Deprecated card types
+
+Older installations may still reference `hass-records-*` card types. These are supported as aliases and can be replaced directly in YAML:
+
+| Deprecated type | Replacement |
+| ------------------------------ | ------------------------------- |
+| `hass-records-action-card` | `hass-datapoints-action-card` |
+| `hass-records-quick-card` | `hass-datapoints-quick-card` |
+| `hass-records-history-card` | `hass-datapoints-history-card` |
+| `hass-records-sensor-card` | `hass-datapoints-sensor-card` |
+| `hass-records-list-card` | `hass-datapoints-list-card` |
+| `hass-records-dev-tool-card` | `hass-datapoints-dev-tool-card` |
+| `hass-records-statistics-card` | `hass-datapoints-history-card` |
+
+The old `hass-datapoints-statistics-card` is no longer shipped. If present in a dashboard, it renders a migration hint.
+
### Visual editors
All bundled cards include Lovelace visual editors. The dev-tool editor is intentionally minimal because the card itself does not expose configurable options.