mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 22:07:20 +00:00
Add Ignore Action + dialog updates (#13254)
This commit is contained in:
parent
63ea8e6568
commit
b9ae0e72b1
@ -27,14 +27,16 @@ export const fetchRepairsIssues = async (hass: HomeAssistant) =>
|
|||||||
type: "repairs/list_issues",
|
type: "repairs/list_issues",
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dismissRepairsIssue = async (
|
export const ignoreRepairsIssue = async (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
issue: RepairsIssue
|
issue: RepairsIssue,
|
||||||
|
ignore: boolean
|
||||||
) =>
|
) =>
|
||||||
hass.callWS<string>({
|
hass.callWS<string>({
|
||||||
type: "repairs/dismiss_issue",
|
type: "repairs/ignore_issue",
|
||||||
issue_id: issue.issue_id,
|
issue_id: issue.issue_id,
|
||||||
domain: issue.domain,
|
domain: issue.domain,
|
||||||
|
ignore,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createRepairsFlow = (
|
export const createRepairsFlow = (
|
||||||
|
@ -4,7 +4,7 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { createCloseHeading } from "../../../components/ha-dialog";
|
import { createCloseHeading } from "../../../components/ha-dialog";
|
||||||
import "../../../components/ha-markdown";
|
import "../../../components/ha-markdown";
|
||||||
import type { RepairsIssue } from "../../../data/repairs";
|
import { ignoreRepairsIssue, RepairsIssue } from "../../../data/repairs";
|
||||||
import { haStyleDialog } from "../../../resources/styles";
|
import { haStyleDialog } from "../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import type { RepairsIssueDialogParams } from "./show-repair-issue-dialog";
|
import type { RepairsIssueDialogParams } from "./show-repair-issue-dialog";
|
||||||
@ -23,6 +23,10 @@ class DialogRepairsIssue extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public closeDialog() {
|
public closeDialog() {
|
||||||
|
if (this._params?.dialogClosedCallback) {
|
||||||
|
this._params.dialogClosedCallback();
|
||||||
|
}
|
||||||
|
|
||||||
this._params = undefined;
|
this._params = undefined;
|
||||||
this._issue = undefined;
|
this._issue = undefined;
|
||||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
@ -50,6 +54,24 @@ class DialogRepairsIssue extends LitElement {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
<ha-alert
|
||||||
|
.alertType=${this._issue.severity === "error" ||
|
||||||
|
this._issue.severity === "critical"
|
||||||
|
? "error"
|
||||||
|
: "warning"}
|
||||||
|
.title=${this.hass.localize(
|
||||||
|
`ui.panel.config.repairs.${this._issue.severity}`
|
||||||
|
)}
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.repairs.dialog.alert_not_fixable"
|
||||||
|
)}
|
||||||
|
${this._issue.breaks_in_ha_version
|
||||||
|
? this.hass.localize(
|
||||||
|
"ui.panel.config.repairs.dialog.breaks_in_version",
|
||||||
|
{ version: this._issue.breaks_in_ha_version }
|
||||||
|
)
|
||||||
|
: ""}
|
||||||
|
</ha-alert>
|
||||||
<ha-markdown
|
<ha-markdown
|
||||||
allowsvg
|
allowsvg
|
||||||
breaks
|
breaks
|
||||||
@ -60,19 +82,14 @@ class DialogRepairsIssue extends LitElement {
|
|||||||
this._issue.translation_placeholders
|
this._issue.translation_placeholders
|
||||||
)}
|
)}
|
||||||
></ha-markdown>
|
></ha-markdown>
|
||||||
|
|
||||||
${this._issue.breaks_in_ha_version
|
|
||||||
? html`
|
|
||||||
<br />This will no longer work as of the
|
|
||||||
${this._issue.breaks_in_ha_version} release of Home Assistant.
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
<br />The issue is ${this._issue.severity} severity.<br />We can not
|
|
||||||
automatically repair this issue for you.
|
|
||||||
${this._issue.dismissed_version
|
${this._issue.dismissed_version
|
||||||
? html`
|
? html`
|
||||||
<br />This issue has been dismissed in version
|
<br /><span class="dismissed">
|
||||||
${this._issue.dismissed_version}.
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.repairs.dialog.dismissed_in_version",
|
||||||
|
{ version: this._issue.dismissed_version }
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
@ -84,20 +101,43 @@ class DialogRepairsIssue extends LitElement {
|
|||||||
slot="primaryAction"
|
slot="primaryAction"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<mwc-button .label=${"Learn More"}></mwc-button>
|
<mwc-button
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.repairs.dialog.learn"
|
||||||
|
)}
|
||||||
|
></mwc-button>
|
||||||
</a>
|
</a>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
|
<mwc-button
|
||||||
|
slot="secondaryAction"
|
||||||
|
.label=${this._issue!.ignored
|
||||||
|
? this.hass!.localize("ui.panel.config.repairs.dialog.unignore")
|
||||||
|
: this.hass!.localize("ui.panel.config.repairs.dialog.ignore")}
|
||||||
|
@click=${this._ignoreIssue}
|
||||||
|
></mwc-button>
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _ignoreIssue() {
|
||||||
|
ignoreRepairsIssue(this.hass, this._issue!, !this._issue!.ignored);
|
||||||
|
this.closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
static styles: CSSResultGroup = [
|
static styles: CSSResultGroup = [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
css`
|
css`
|
||||||
|
ha-alert {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.dismissed {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
|
import type { ActionDetail } from "@material/mwc-list";
|
||||||
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import type { RepairsIssue } from "../../../data/repairs";
|
import {
|
||||||
import { fetchRepairsIssues } from "../../../data/repairs";
|
fetchRepairsIssues,
|
||||||
|
RepairsIssue,
|
||||||
|
severitySort,
|
||||||
|
} from "../../../data/repairs";
|
||||||
import "../../../layouts/hass-subpage";
|
import "../../../layouts/hass-subpage";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import "./ha-config-repairs";
|
import "./ha-config-repairs";
|
||||||
@ -15,12 +21,25 @@ class HaConfigRepairsDashboard extends LitElement {
|
|||||||
|
|
||||||
@state() private _repairsIssues: RepairsIssue[] = [];
|
@state() private _repairsIssues: RepairsIssue[] = [];
|
||||||
|
|
||||||
|
@state() private _showIgnored = false;
|
||||||
|
|
||||||
|
private _getFilteredIssues = memoizeOne(
|
||||||
|
(showIgnored: boolean, repairsIssues: RepairsIssue[]) =>
|
||||||
|
showIgnored
|
||||||
|
? repairsIssues
|
||||||
|
: repairsIssues.filter((issue) => !issue.ignored)
|
||||||
|
);
|
||||||
|
|
||||||
protected firstUpdated(changedProps: PropertyValues): void {
|
protected firstUpdated(changedProps: PropertyValues): void {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._fetchIssues();
|
this._fetchIssues();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
const issues = this._getFilteredIssues(
|
||||||
|
this._showIgnored,
|
||||||
|
this._repairsIssues
|
||||||
|
);
|
||||||
return html`
|
return html`
|
||||||
<hass-subpage
|
<hass-subpage
|
||||||
back-path="/config/system"
|
back-path="/config/system"
|
||||||
@ -28,6 +47,20 @@ class HaConfigRepairsDashboard extends LitElement {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.header=${this.hass.localize("ui.panel.config.repairs.caption")}
|
.header=${this.hass.localize("ui.panel.config.repairs.caption")}
|
||||||
>
|
>
|
||||||
|
<div slot="toolbar-icon">
|
||||||
|
<ha-button-menu corner="BOTTOM_START" @action=${this._handleAction}>
|
||||||
|
<ha-icon-button
|
||||||
|
slot="trigger"
|
||||||
|
.label=${this.hass.localize("ui.common.menu")}
|
||||||
|
.path=${mdiDotsVertical}
|
||||||
|
></ha-icon-button>
|
||||||
|
<mwc-list-item id="skipped">
|
||||||
|
${this._showIgnored
|
||||||
|
? this.hass.localize("ui.panel.config.repairs.hide_ignored")
|
||||||
|
: this.hass.localize("ui.panel.config.repairs.show_ignored")}
|
||||||
|
</mwc-list-item>
|
||||||
|
</ha-button-menu>
|
||||||
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<ha-card outlined>
|
<ha-card outlined>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
@ -36,7 +69,7 @@ class HaConfigRepairsDashboard extends LitElement {
|
|||||||
<ha-config-repairs
|
<ha-config-repairs
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.repairsIssues=${this._repairsIssues}
|
.repairsIssues=${issues}
|
||||||
@update-issues=${this._fetchIssues}
|
@update-issues=${this._fetchIssues}
|
||||||
></ha-config-repairs>
|
></ha-config-repairs>
|
||||||
`
|
`
|
||||||
@ -55,7 +88,9 @@ class HaConfigRepairsDashboard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _fetchIssues(): Promise<void> {
|
private async _fetchIssues(): Promise<void> {
|
||||||
this._repairsIssues = (await fetchRepairsIssues(this.hass)).issues;
|
this._repairsIssues = (await fetchRepairsIssues(this.hass)).issues.sort(
|
||||||
|
(a, b) => severitySort[a.severity] - severitySort[b.severity]
|
||||||
|
);
|
||||||
const integrations: Set<string> = new Set();
|
const integrations: Set<string> = new Set();
|
||||||
for (const issue of this._repairsIssues) {
|
for (const issue of this._repairsIssues) {
|
||||||
integrations.add(issue.domain);
|
integrations.add(issue.domain);
|
||||||
@ -63,6 +98,14 @@ class HaConfigRepairsDashboard extends LitElement {
|
|||||||
this.hass.loadBackendTranslation("issues", [...integrations]);
|
this.hass.loadBackendTranslation("issues", [...integrations]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
||||||
|
switch (ev.detail.index) {
|
||||||
|
case 0:
|
||||||
|
this._showIgnored = !this._showIgnored;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
.content {
|
.content {
|
||||||
padding: 28px 20px 0;
|
padding: 28px 20px 0;
|
||||||
|
@ -41,43 +41,41 @@ class HaConfigRepairs extends LitElement {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<mwc-list>
|
<mwc-list>
|
||||||
${issues.map((issue) =>
|
${issues.map(
|
||||||
issue.ignored
|
(issue) => html`
|
||||||
? ""
|
<ha-list-item
|
||||||
: html`
|
twoline
|
||||||
<ha-list-item
|
graphic="avatar"
|
||||||
twoline
|
.hasMeta=${!this.narrow}
|
||||||
graphic="avatar"
|
.issue=${issue}
|
||||||
.hasMeta=${!this.narrow}
|
@click=${this._openShowMoreDialog}
|
||||||
.issue=${issue}
|
>
|
||||||
@click=${this._openShowMoreDialog}
|
<img
|
||||||
>
|
loading="lazy"
|
||||||
<img
|
src=${brandsUrl({
|
||||||
loading="lazy"
|
domain: issue.domain,
|
||||||
src=${brandsUrl({
|
type: "icon",
|
||||||
domain: issue.domain,
|
useFallback: true,
|
||||||
type: "icon",
|
darkOptimized: this.hass.themes?.darkMode,
|
||||||
useFallback: true,
|
})}
|
||||||
darkOptimized: this.hass.themes?.darkMode,
|
.title=${domainToName(this.hass.localize, issue.domain)}
|
||||||
})}
|
referrerpolicy="no-referrer"
|
||||||
.title=${domainToName(this.hass.localize, issue.domain)}
|
slot="graphic"
|
||||||
referrerpolicy="no-referrer"
|
/>
|
||||||
slot="graphic"
|
<span
|
||||||
/>
|
>${this.hass.localize(
|
||||||
<span
|
`component.${issue.domain}.issues.${
|
||||||
>${this.hass.localize(
|
issue.translation_key || issue.issue_id
|
||||||
`component.${issue.domain}.issues.${
|
}.title`
|
||||||
issue.translation_key || issue.issue_id
|
)}</span
|
||||||
}.title`
|
>
|
||||||
)}</span
|
<span slot="secondary" class="secondary">
|
||||||
>
|
${issue.created
|
||||||
<span slot="secondary" class="secondary">
|
? relativeTime(new Date(issue.created), this.hass.locale)
|
||||||
${issue.created
|
: ""}
|
||||||
? relativeTime(new Date(issue.created), this.hass.locale)
|
</span>
|
||||||
: ""}
|
</ha-list-item>
|
||||||
</span>
|
`
|
||||||
</ha-list-item>
|
|
||||||
`
|
|
||||||
)}
|
)}
|
||||||
</mwc-list>
|
</mwc-list>
|
||||||
`;
|
`;
|
||||||
@ -91,7 +89,13 @@ class HaConfigRepairs extends LitElement {
|
|||||||
fireEvent(this, "update-issues");
|
fireEvent(this, "update-issues");
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
showRepairsIssueDialog(this, { issue: (ev.currentTarget as any).issue });
|
showRepairsIssueDialog(this, {
|
||||||
|
issue,
|
||||||
|
dialogClosedCallback: () => {
|
||||||
|
// @ts-ignore
|
||||||
|
fireEvent(this, "update-issues");
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import type { RepairsIssue } from "../../../data/repairs";
|
|||||||
|
|
||||||
export interface RepairsIssueDialogParams {
|
export interface RepairsIssueDialogParams {
|
||||||
issue: RepairsIssue;
|
issue: RepairsIssue;
|
||||||
|
dialogClosedCallback: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadRepairsIssueDialog = () => import("./dialog-repairs-issue");
|
export const loadRepairsIssueDialog = () => import("./dialog-repairs-issue");
|
||||||
|
@ -1232,10 +1232,20 @@
|
|||||||
"title": "{count} {count, plural,\n one {repair}\n other {repairs}\n}",
|
"title": "{count} {count, plural,\n one {repair}\n other {repairs}\n}",
|
||||||
"no_repairs": "There are currently no repairs available",
|
"no_repairs": "There are currently no repairs available",
|
||||||
"more_repairs": "+{count} repairs",
|
"more_repairs": "+{count} repairs",
|
||||||
|
"show_ignored": "Show ignored",
|
||||||
|
"hide_ignored": "Hide ignored",
|
||||||
|
"critical": "Critical",
|
||||||
|
"error": "Error",
|
||||||
|
"warning": "Warning",
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"title": "Repair",
|
"title": "Repair",
|
||||||
"fix": "Repair",
|
"fix": "Repair",
|
||||||
"learn": "Learn more"
|
"learn": "Learn more",
|
||||||
|
"ignore": "Ignore",
|
||||||
|
"unignore": "Unignore",
|
||||||
|
"alert_not_fixable": "We can not repair this issue for you.",
|
||||||
|
"breaks_in_version": "This will break in version {version}. Please fix this issue before upgrading.",
|
||||||
|
"dismissed_in_version": "This issue was dismissed in version {version}."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"areas": {
|
"areas": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user