diff --git a/src/data/recorder.ts b/src/data/recorder.ts
index 1b89af2834..d6d2b215cf 100644
--- a/src/data/recorder.ts
+++ b/src/data/recorder.ts
@@ -332,3 +332,6 @@ export const getDisplayUnit = (
export const isExternalStatistic = (statisticsId: string): boolean =>
statisticsId.includes(":");
+
+export const updateStatisticsIssues = (hass: HomeAssistant) =>
+ hass.callWS({ type: "recorder/update_statistics_issues" });
diff --git a/src/panels/config/repairs/ha-config-repairs.ts b/src/panels/config/repairs/ha-config-repairs.ts
index 50c4b9f2f4..98366f89bb 100644
--- a/src/panels/config/repairs/ha-config-repairs.ts
+++ b/src/panels/config/repairs/ha-config-repairs.ts
@@ -18,6 +18,7 @@ import { showRepairsIssueDialog } from "./show-repair-issue-dialog";
import {
STATISTIC_TYPES,
StatisticsValidationResult,
+ updateStatisticsIssues,
} from "../../../data/recorder";
@customElement("ha-config-repairs")
@@ -144,25 +145,19 @@ class HaConfigRepairs extends LitElement {
issue.translation_key &&
STATISTIC_TYPES.includes(issue.translation_key as any)
) {
- const localize =
- await this.hass.loadFragmentTranslation("developer-tools");
+ this.hass.loadFragmentTranslation("developer-tools");
const data = await fetchRepairsIssueData(
this.hass.connection,
issue.domain,
issue.issue_id
);
if ("issue_type" in data.issue_data) {
- await fixStatisticsIssue(
- this,
- this.hass,
- localize || this.hass.localize,
- {
- type: data.issue_data
- .issue_type as StatisticsValidationResult["type"],
- data: data.issue_data as any,
- }
- );
- this.hass.callWS({ type: "recorder/update_statistics_issues" });
+ await fixStatisticsIssue(this, {
+ type: data.issue_data
+ .issue_type as StatisticsValidationResult["type"],
+ data: data.issue_data as any,
+ });
+ updateStatisticsIssues(this.hass);
}
} else {
showRepairsIssueDialog(this, {
diff --git a/src/panels/developer-tools/statistics/developer-tools-statistics.ts b/src/panels/developer-tools/statistics/developer-tools-statistics.ts
index 8baafaf909..3e4bb2526f 100644
--- a/src/panels/developer-tools/statistics/developer-tools-statistics.ts
+++ b/src/panels/developer-tools/statistics/developer-tools-statistics.ts
@@ -50,8 +50,6 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
private _disabledEntities = new Set();
- private _deletedStatistics = new Set();
-
protected firstUpdated() {
this._validateStatistics();
}
@@ -225,9 +223,7 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
this._data = statisticIds
.filter(
- (statistic) =>
- !this._disabledEntities.has(statistic.statistic_id) &&
- !this._deletedStatistics.has(statistic.statistic_id)
+ (statistic) => !this._disabledEntities.has(statistic.statistic_id)
)
.map((statistic) => {
statsIds.add(statistic.statistic_id);
@@ -241,8 +237,7 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
Object.keys(issues).forEach((statisticId) => {
if (
!statsIds.has(statisticId) &&
- !this._disabledEntities.has(statisticId) &&
- !this._deletedStatistics.has(statisticId)
+ !this._disabledEntities.has(statisticId)
) {
this._data.push({
statistic_id: statisticId,
@@ -265,20 +260,7 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
(FIX_ISSUES_ORDER[itemB.type] ?? 99)
);
const issue = issues[0];
- const result = await fixStatisticsIssue(
- this,
- this.hass,
- this.hass.localize,
- issue
- );
- if (
- result &&
- ["no_state", "entity_no_longer_recorded", "state_class_removed"].includes(
- issue.type
- )
- ) {
- this._deletedStatistics.add(issue.data.statistic_id);
- }
+ await fixStatisticsIssue(this, issue);
this._validateStatistics();
};
diff --git a/src/panels/developer-tools/statistics/dialog-statistics-fix.ts b/src/panels/developer-tools/statistics/dialog-statistics-fix.ts
new file mode 100644
index 0000000000..f87c4f3d2e
--- /dev/null
+++ b/src/panels/developer-tools/statistics/dialog-statistics-fix.ts
@@ -0,0 +1,201 @@
+import "@material/mwc-button/mwc-button";
+import { CSSResultGroup, html, LitElement, nothing } from "lit";
+import { customElement, property, state } from "lit/decorators";
+import "../../../components/ha-circular-progress";
+import { fireEvent } from "../../../common/dom/fire_event";
+import "../../../components/ha-dialog";
+import { clearStatistics, getStatisticLabel } from "../../../data/recorder";
+import { haStyle, haStyleDialog } from "../../../resources/styles";
+import { HomeAssistant } from "../../../types";
+import { documentationUrl } from "../../../util/documentation-url";
+import type { DialogStatisticsFixParams } from "./show-dialog-statistics-fix";
+import { showAlertDialog } from "../../lovelace/custom-card-helpers";
+
+@customElement("dialog-statistics-fix")
+export class DialogStatisticsFix extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @state() private _params?: DialogStatisticsFixParams;
+
+ @state() private _clearing = false;
+
+ public showDialog(params: DialogStatisticsFixParams): void {
+ this._params = params;
+ }
+
+ public closeDialog(): void {
+ this._cancel();
+ }
+
+ private _closeDialog(): void {
+ this._params = undefined;
+ this._clearing = false;
+ fireEvent(this, "dialog-closed", { dialog: this.localName });
+ }
+
+ protected render() {
+ if (!this._params) {
+ return nothing;
+ }
+
+ const issue = this._params.issue;
+
+ return html`
+
+
+ ${this.hass.localize(
+ `ui.panel.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_1`,
+ {
+ name: getStatisticLabel(
+ this.hass,
+ this._params.issue.data.statistic_id,
+ undefined
+ ),
+ statistic_id: this._params.issue.data.statistic_id,
+ }
+ )}
+ ${this.hass.localize(
+ `ui.panel.developer-tools.tabs.statistics.fix_issue.${issue.type}.info_text_2`,
+ { statistic_id: issue.data.statistic_id }
+ )}
+ ${issue.type === "entity_not_recorded"
+ ? html`
+
+ ${this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
+ )}`
+ : issue.type === "entity_no_longer_recorded"
+ ? html`
+ ${this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link"
+ )}
+ ${this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4"
+ )}`
+ : issue.type === "state_class_removed"
+ ? html`
+ ${this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_6",
+ { statistic_id: issue.data.statistic_id }
+ )}`
+ : nothing}
+
+
+ ${issue.type !== "entity_not_recorded"
+ ? html`
+ ${this._clearing
+ ? html``
+ : nothing}
+ ${this.hass.localize("ui.common.delete")}
+
+
+ ${this.hass.localize("ui.common.close")}
+ `
+ : html`
+ ${this.hass.localize("ui.common.ok")}
+ `}
+
+ `;
+ }
+
+ private _cancel(): void {
+ this._params?.cancelCallback!();
+ this._closeDialog();
+ }
+
+ private async _clearStatistics(): Promise {
+ this._clearing = true;
+ try {
+ await clearStatistics(this.hass, [this._params!.issue.data.statistic_id]);
+ } catch (err: any) {
+ await showAlertDialog(this, {
+ title:
+ err.code === "timeout"
+ ? this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.clearing_timeout_title"
+ )
+ : this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.clearing_failed"
+ ),
+ text:
+ err.code === "timeout"
+ ? this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.fix_issue.clearing_timeout_text"
+ )
+ : err.message,
+ });
+ } finally {
+ this._clearing = false;
+ this._params?.fixedCallback!();
+ this._closeDialog();
+ }
+ }
+
+ static get styles(): CSSResultGroup {
+ return [haStyle, haStyleDialog];
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "dialog-statistics-fix": DialogStatisticsFix;
+ }
+}
diff --git a/src/panels/developer-tools/statistics/fix-statistics.ts b/src/panels/developer-tools/statistics/fix-statistics.ts
index 0329cf77be..fdaf571e0b 100644
--- a/src/panels/developer-tools/statistics/fix-statistics.ts
+++ b/src/panels/developer-tools/statistics/fix-statistics.ts
@@ -1,171 +1,17 @@
-import { html } from "lit";
-import {
- clearStatistics,
- getStatisticLabel,
- StatisticsValidationResult,
-} from "../../../data/recorder";
-import { documentationUrl } from "../../../util/documentation-url";
-import {
- showConfirmationDialog,
- showAlertDialog,
-} from "../../lovelace/custom-card-helpers";
+import { StatisticsValidationResult } from "../../../data/recorder";
+import { showFixStatisticsDialog } from "./show-dialog-statistics-fix";
import { showFixStatisticsUnitsChangedDialog } from "./show-dialog-statistics-fix-units-changed";
-import { LocalizeFunc } from "../../../common/translations/localize";
-import { HomeAssistant } from "../../../types";
export const fixStatisticsIssue = async (
element: HTMLElement,
- hass: HomeAssistant,
- localize: LocalizeFunc,
issue: StatisticsValidationResult
) => {
- switch (issue.type) {
- case "no_state":
- return showConfirmationDialog(element, {
- title: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.no_state.title"
- ),
- text: html`${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.no_state.info_text_1",
- {
- name: getStatisticLabel(hass, issue.data.statistic_id, undefined),
- statistic_id: issue.data.statistic_id,
- }
- )}
${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.no_state.info_text_2",
- { statistic_id: issue.data.statistic_id }
- )}`,
- confirmText: localize("ui.common.delete"),
- destructive: true,
- confirm: async () => {
- await clearStatistics(hass, [issue.data.statistic_id]);
- },
- });
- case "entity_not_recorded":
- return showAlertDialog(element, {
- title: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.title"
- ),
- text: html`${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_1",
- {
- name: getStatisticLabel(hass, issue.data.statistic_id, undefined),
- }
- )}
${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_2"
- )}
-
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_not_recorded.info_text_3_link"
- )}`,
- });
- case "entity_no_longer_recorded":
- return showConfirmationDialog(element, {
- title: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.title"
- ),
- text: html`${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_1",
- {
- name: getStatisticLabel(hass, issue.data.statistic_id, undefined),
- statistic_id: issue.data.statistic_id,
- }
- )}
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_2"
- )}
-
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_3_link"
- )}
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.entity_no_longer_recorded.info_text_4"
- )}`,
- confirmText: localize("ui.common.delete"),
- destructive: true,
- confirm: async () => {
- await clearStatistics(hass, [issue.data.statistic_id]);
- },
- });
- case "state_class_removed":
- return showConfirmationDialog(element, {
- title: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.title"
- ),
- text: html`${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_1",
- {
- name: getStatisticLabel(hass, issue.data.statistic_id, undefined),
- statistic_id: issue.data.statistic_id,
- }
- )}
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_2"
- )}
-
- ${localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.state_class_removed.info_text_6",
- { statistic_id: issue.data.statistic_id }
- )}`,
- confirmText: localize("ui.common.delete"),
- destructive: true,
- confirm: async () => {
- await clearStatistics(hass, [issue.data.statistic_id]);
- },
- });
- case "units_changed":
- return showFixStatisticsUnitsChangedDialog(element, {
- issue,
- });
- default:
- return showAlertDialog(element, {
- title: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.no_support.title"
- ),
- text: localize(
- "ui.panel.developer-tools.tabs.statistics.fix_issue.no_support.info_text_1"
- ),
- });
+ if (issue.type === "units_changed") {
+ return showFixStatisticsUnitsChangedDialog(element, {
+ issue,
+ });
}
+ return showFixStatisticsDialog(element, {
+ issue,
+ });
};
diff --git a/src/panels/developer-tools/statistics/show-dialog-statistics-fix.ts b/src/panels/developer-tools/statistics/show-dialog-statistics-fix.ts
new file mode 100644
index 0000000000..70ffa4f0c3
--- /dev/null
+++ b/src/panels/developer-tools/statistics/show-dialog-statistics-fix.ts
@@ -0,0 +1,33 @@
+import { fireEvent } from "../../../common/dom/fire_event";
+import { StatisticsValidationResult } from "../../../data/recorder";
+
+export const loadFixDialog = () => import("./dialog-statistics-fix");
+
+export interface DialogStatisticsFixParams {
+ issue: StatisticsValidationResult;
+ fixedCallback?: () => void;
+ cancelCallback?: () => void;
+}
+
+export const showFixStatisticsDialog = (
+ element: HTMLElement,
+ detailParams: DialogStatisticsFixParams
+) =>
+ new Promise((resolve) => {
+ const origCallback = detailParams.fixedCallback;
+
+ fireEvent(element, "show-dialog", {
+ dialogTag: "dialog-statistics-fix",
+ dialogImport: loadFixDialog,
+ dialogParams: {
+ ...detailParams,
+ cancelCallback: () => {
+ resolve(false);
+ },
+ fixedCallback: () => {
+ resolve(true);
+ origCallback?.();
+ },
+ },
+ });
+ });
diff --git a/src/panels/lovelace/editor/section-editor/hui-dialog-edit-section.ts b/src/panels/lovelace/editor/section-editor/hui-dialog-edit-section.ts
index 7801e58a3d..e6973e606a 100644
--- a/src/panels/lovelace/editor/section-editor/hui-dialog-edit-section.ts
+++ b/src/panels/lovelace/editor/section-editor/hui-dialog-edit-section.ts
@@ -15,7 +15,6 @@ import { fireEvent } from "../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../common/dom/stop_propagation";
import "../../../../components/ha-button";
import "../../../../components/ha-button-menu";
-import "../../../../components/ha-circular-progress";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/ha-icon-button";
diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
index 2d4c3c6bd3..84c7eb5679 100644
--- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
+++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts
@@ -507,12 +507,6 @@ export class HuiDialogEditView extends LitElement {
margin-inline-end: auto;
margin-inline-start: initial;
}
- ha-circular-progress {
- display: none;
- }
- ha-circular-progress[indeterminate] {
- display: block;
- }
.selected_menu_item {
color: var(--primary-color);
}
diff --git a/src/translations/en.json b/src/translations/en.json
index fc4b61bc24..06c27f4a93 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -6968,6 +6968,9 @@
},
"fix_issue": {
"fix": "Fix issue",
+ "clearing_failed": "Clearing the statistics failed",
+ "clearing_timeout_title": "Clearing not done yet",
+ "clearing_timeout_text": "The clearing of the statistics took longer than expected, it might take longer for the issue to disappear.",
"no_support": {
"title": "Fix issue",
"info_text_1": "Fixing this issue is not supported yet."