Add ZWave JS heal network UI (#9449)

* Add Z-Wave JS heal network dialog

* progress bar tweak

* tweak package.json

* typing tweak

* Update yarn.lock

* Align versions

* address review comments

* Use indeterminate linear-progress instead of circular-progress

* cleanup circular-progress

* prettier

* additional review cleanup

* subscribe to status update if heal already running

* more cleanup

* more cleanup

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Charles Garwood 2021-06-29 11:14:50 -04:00 committed by GitHub
parent a3d1a3566d
commit 0a50fc66e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 447 additions and 29 deletions

View File

@ -44,20 +44,21 @@
"@fullcalendar/list": "5.1.0",
"@lit-labs/virtualizer": "^0.6.0",
"@material/chips": "=12.0.0-canary.1a8d06483.0",
"@material/mwc-button": "canary",
"@material/mwc-checkbox": "canary",
"@material/mwc-circular-progress": "canary",
"@material/mwc-dialog": "canary",
"@material/mwc-fab": "canary",
"@material/mwc-formfield": "canary",
"@material/mwc-icon-button": "canary",
"@material/mwc-list": "canary",
"@material/mwc-menu": "canary",
"@material/mwc-radio": "canary",
"@material/mwc-ripple": "canary",
"@material/mwc-switch": "canary",
"@material/mwc-tab": "canary",
"@material/mwc-tab-bar": "canary",
"@material/mwc-button": "0.22.0-canary.cc04657a.0",
"@material/mwc-checkbox": "0.22.0-canary.cc04657a.0",
"@material/mwc-circular-progress": "0.22.0-canary.cc04657a.0",
"@material/mwc-dialog": "0.22.0-canary.cc04657a.0",
"@material/mwc-fab": "0.22.0-canary.cc04657a.0",
"@material/mwc-formfield": "0.22.0-canary.cc04657a.0",
"@material/mwc-icon-button": "0.22.0-canary.cc04657a.0",
"@material/mwc-linear-progress": "0.22.0-canary.cc04657a.0",
"@material/mwc-list": "0.22.0-canary.cc04657a.0",
"@material/mwc-menu": "0.22.0-canary.cc04657a.0",
"@material/mwc-radio": "0.22.0-canary.cc04657a.0",
"@material/mwc-ripple": "0.22.0-canary.cc04657a.0",
"@material/mwc-switch": "0.22.0-canary.cc04657a.0",
"@material/mwc-tab": "0.22.0-canary.cc04657a.0",
"@material/mwc-tab-bar": "0.22.0-canary.cc04657a.0",
"@material/top-app-bar": "=12.0.0-canary.1a8d06483.0",
"@mdi/js": "5.9.55",
"@mdi/svg": "5.9.55",

View File

@ -21,6 +21,7 @@ export interface ZWaveJSClient {
export interface ZWaveJSController {
home_id: string;
nodes: number[];
is_heal_network_active: boolean;
}
export interface ZWaveJSNode {
@ -77,6 +78,11 @@ export interface ZWaveJSRefreshNodeStatusMessage {
stage?: string;
}
export interface ZWaveJSHealNetworkStatusMessage {
event: string;
heal_node_status: { [key: number]: string };
}
export enum NodeStatus {
Unknown,
Asleep,
@ -172,6 +178,37 @@ export const reinterviewNode = (
}
);
export const healNetwork = (
hass: HomeAssistant,
entry_id: string
): Promise<UnsubscribeFunc> =>
hass.callWS({
type: "zwave_js/begin_healing_network",
entry_id: entry_id,
});
export const stopHealNetwork = (
hass: HomeAssistant,
entry_id: string
): Promise<UnsubscribeFunc> =>
hass.callWS({
type: "zwave_js/stop_healing_network",
entry_id: entry_id,
});
export const subscribeHealNetworkProgress = (
hass: HomeAssistant,
entry_id: string,
callbackFunction: (message: ZWaveJSHealNetworkStatusMessage) => void
): Promise<UnsubscribeFunc> =>
hass.connection.subscribeMessage(
(message: any) => callbackFunction(message),
{
type: "zwave_js/subscribe_heal_network_progress",
entry_id: entry_id,
}
);
export const getIdentifiersFromDevice = (
device: DeviceRegistryEntry
): ZWaveJSNodeIdentifiers | undefined => {

View File

@ -0,0 +1,312 @@
import "@material/mwc-button/mwc-button";
import "@material/mwc-linear-progress/mwc-linear-progress";
import { mdiStethoscope, mdiCheckCircle, mdiCloseCircle } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import {
fetchNetworkStatus,
healNetwork,
stopHealNetwork,
subscribeHealNetworkProgress,
ZWaveJSHealNetworkStatusMessage,
ZWaveJSNetwork,
} from "../../../../../data/zwave_js";
import { haStyleDialog } from "../../../../../resources/styles";
import { HomeAssistant } from "../../../../../types";
import { ZWaveJSHealNetworkDialogParams } from "./show-dialog-zwave_js-heal-network";
@customElement("dialog-zwave_js-heal-network")
class DialogZWaveJSHealNetwork extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@state() private entry_id?: string;
@state() private _status?: string;
@state() private _progress_total = 0;
@state() private _progress_finished = 0;
@state() private _progress_in_progress = 0;
private _subscribed?: Promise<UnsubscribeFunc>;
public showDialog(params: ZWaveJSHealNetworkDialogParams): void {
this._progress_total = 0;
this.entry_id = params.entry_id;
this._fetchData();
}
public closeDialog(): void {
this.entry_id = undefined;
this._status = undefined;
this._progress_total = 0;
this._unsubscribe();
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
protected render(): TemplateResult {
if (!this.entry_id) {
return html``;
}
return html`
<ha-dialog
open
@closed=${this.closeDialog}
.heading=${createCloseHeading(
this.hass,
this.hass.localize("ui.panel.config.zwave_js.heal_network.title")
)}
>
${!this._status
? html`
<div class="flex-container">
<ha-svg-icon
.path=${mdiStethoscope}
class="introduction"
></ha-svg-icon>
<div class="status">
<p>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.introduction"
)}
</p>
</div>
</div>
<p>
<em>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.traffic_warning"
)}
</em>
</p>
<mwc-button slot="primaryAction" @click=${this._startHeal}>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.start_heal"
)}
</mwc-button>
`
: ``}
${this._status === "started"
? html`
<div class="status">
<p>
<b>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.in_progress"
)}
</b>
</p>
<p>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.run_in_background"
)}
</p>
</div>
${!this._progress_total
? html`
<mwc-linear-progress indeterminate> </mwc-linear-progress>
`
: ""}
<mwc-button slot="secondaryAction" @click=${this._stopHeal}>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.stop_heal"
)}
</mwc-button>
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
</mwc-button>
`
: ``}
${this._status === "failed"
? html`
<div class="flex-container">
<ha-svg-icon
.path=${mdiCloseCircle}
class="failed"
></ha-svg-icon>
<div class="status">
<p>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.healing_failed"
)}
</p>
</div>
</div>
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
</mwc-button>
`
: ``}
${this._status === "finished"
? html`
<div class="flex-container">
<ha-svg-icon
.path=${mdiCheckCircle}
class="success"
></ha-svg-icon>
<div class="status">
<p>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.healing_complete"
)}
</p>
</div>
</div>
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
</mwc-button>
`
: ``}
${this._status === "cancelled"
? html`
<div class="flex-container">
<ha-svg-icon
.path=${mdiCloseCircle}
class="failed"
></ha-svg-icon>
<div class="status">
<p>
${this.hass.localize(
"ui.panel.config.zwave_js.heal_network.healing_cancelled"
)}
</p>
</div>
</div>
<mwc-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.panel.config.zwave_js.common.close")}
</mwc-button>
`
: ``}
${this._progress_total && this._status !== "finished"
? html`
<mwc-linear-progress
determinate
.progress=${this._progress_finished}
.buffer=${this._progress_in_progress}
>
</mwc-linear-progress>
`
: ""}
</ha-dialog>
`;
}
private async _fetchData(): Promise<void> {
if (!this.hass) {
return;
}
const network: ZWaveJSNetwork = await fetchNetworkStatus(
this.hass!,
this.entry_id!
);
if (network.controller.is_heal_network_active) {
this._status = "started";
this._subscribed = subscribeHealNetworkProgress(
this.hass,
this.entry_id!,
this._handleMessage.bind(this)
);
}
}
private _startHeal(): void {
if (!this.hass) {
return;
}
healNetwork(this.hass, this.entry_id!);
this._status = "started";
this._subscribed = subscribeHealNetworkProgress(
this.hass,
this.entry_id!,
this._handleMessage.bind(this)
);
}
private _stopHeal(): void {
if (!this.hass) {
return;
}
stopHealNetwork(this.hass, this.entry_id!);
this._unsubscribe();
this._status = "cancelled";
}
private _handleMessage(message: ZWaveJSHealNetworkStatusMessage): void {
if (message.event === "heal network progress") {
let finished = 0;
let in_progress = 0;
for (const status of Object.values(message.heal_node_status)) {
if (status === "pending") {
in_progress++;
}
if (["skipped", "failed", "done"].includes(status)) {
finished++;
}
}
this._progress_total = Object.keys(message.heal_node_status).length;
this._progress_finished = finished / this._progress_total;
this._progress_in_progress = in_progress / this._progress_total;
}
if (message.event === "heal network done") {
this._unsubscribe();
this._status = "finished";
}
}
private _unsubscribe(): void {
if (this._subscribed) {
this._subscribed.then((unsub) => unsub());
this._subscribed = undefined;
}
}
static get styles(): CSSResultGroup {
return [
haStyleDialog,
css`
.success {
color: var(--success-color);
}
.failed {
color: var(--warning-color);
}
.flex-container {
display: flex;
align-items: center;
}
ha-svg-icon {
width: 68px;
height: 48px;
}
ha-svg-icon.introduction {
color: var(--primary-color);
}
.flex-container ha-svg-icon {
margin-right: 20px;
}
mwc-linear-progress {
margin-top: 8px;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"dialog-zwave_js-heal-network": DialogZWaveJSHealNetwork;
}
}

View File

@ -0,0 +1,19 @@
import { fireEvent } from "../../../../../common/dom/fire_event";
export interface ZWaveJSHealNetworkDialogParams {
entry_id: string;
}
export const loadHealNetworkDialog = () =>
import("./dialog-zwave_js-heal-network");
export const showZWaveJSHealNetworkDialog = (
element: HTMLElement,
healNetworkDialogParams: ZWaveJSHealNetworkDialogParams
): void => {
fireEvent(element, "show-dialog", {
dialogTag: "dialog-zwave_js-heal-network",
dialogImport: loadHealNetworkDialog,
dialogParams: healNetworkDialogParams,
});
};

View File

@ -27,6 +27,7 @@ import type { HomeAssistant, Route } from "../../../../../types";
import { fileDownload } from "../../../../../util/file_download";
import "../../../ha-config-section";
import { showZWaveJSAddNodeDialog } from "./show-dialog-zwave_js-add-node";
import { showZWaveJSHealNetworkDialog } from "./show-dialog-zwave_js-heal-network";
import { showZWaveJSRemoveNodeDialog } from "./show-dialog-zwave_js-remove-node";
import { configTabs } from "./zwave_js-config-router";
import { getConfigEntries } from "../../../../../data/config_entries";
@ -164,6 +165,11 @@ class ZWaveJSConfigDashboard extends LitElement {
"ui.panel.config.zwave_js.common.remove_node"
)}
</mwc-button>
<mwc-button @click=${this._healNetworkClicked}>
${this.hass.localize(
"ui.panel.config.zwave_js.common.heal_network"
)}
</mwc-button>
<mwc-button @click=${this._openOptionFlow}>
${this.hass.localize(
"ui.panel.config.zwave_js.common.reconfigure_server"
@ -261,6 +267,12 @@ class ZWaveJSConfigDashboard extends LitElement {
});
}
private async _healNetworkClicked() {
showZWaveJSHealNetworkDialog(this, {
entry_id: this.configEntryId!,
});
}
private _dataCollectionToggled(ev) {
setDataCollectionPreference(
this.hass!,

View File

@ -2588,7 +2588,8 @@
"close": "Close",
"add_node": "Add Node",
"remove_node": "Remove Node",
"reconfigure_server": "Re-configure Server"
"reconfigure_server": "Re-configure Server",
"heal_network": "Heal Network"
},
"dashboard": {
"header": "Manage your Z-Wave Network",
@ -2670,6 +2671,18 @@
"interview_failed": "The device interview failed. Additional information may be available in the logs.",
"interview_complete": "Device interview complete."
},
"heal_network": {
"title": "Heal your Z-Wave Network",
"introduction": "Start a network heal on your Z-Wave network. A network heal will cause all devices to re-calculate their routes back to the controller and is recommended if you have recently moved devices or your controller.",
"traffic_warning": "The healing process generates a large amount of traffic on the Z-Wave network. This may cause devices to respond slowly (or not at all) while the heal is in progress.",
"start_heal": "Start Healing",
"in_progress": "Network healing is in progress. This will take some time.",
"run_in_background": "You can close this dialog and the network healing will continue in the background.",
"stop_heal": "Stop Healing",
"healing_complete": "Network healing is complete.",
"healing_failed": "Healing failed. Additional information may be available in the logs.",
"healing_cancelled": "Network healing has been cancelled."
},
"logs": {
"title": "Z-Wave JS Logs",
"log_level": "Log Level",

View File

@ -1519,6 +1519,19 @@
"@material/theme" "12.0.0-canary.1a8d06483.0"
tslib "^2.1.0"
"@material/linear-progress@=12.0.0-canary.1a8d06483.0":
version "12.0.0-canary.1a8d06483.0"
resolved "https://registry.yarnpkg.com/@material/linear-progress/-/linear-progress-12.0.0-canary.1a8d06483.0.tgz#85b91ef010a98abff972aab40168a695c78d0e83"
integrity sha512-pviLL7V77ruNlMaZARzNjc39whRZLN+CZxoPIW2f5/Do0ub9sxw8SDiXjFjC9RMM5a2hPTmA8jyUphS0FlWKbw==
dependencies:
"@material/animation" "12.0.0-canary.1a8d06483.0"
"@material/base" "12.0.0-canary.1a8d06483.0"
"@material/feature-targeting" "12.0.0-canary.1a8d06483.0"
"@material/progress-indicator" "12.0.0-canary.1a8d06483.0"
"@material/rtl" "12.0.0-canary.1a8d06483.0"
"@material/theme" "12.0.0-canary.1a8d06483.0"
tslib "^2.1.0"
"@material/list@12.0.0-canary.1a8d06483.0", "@material/list@=12.0.0-canary.1a8d06483.0":
version "12.0.0-canary.1a8d06483.0"
resolved "https://registry.yarnpkg.com/@material/list/-/list-12.0.0-canary.1a8d06483.0.tgz#6ba66e3e0f23dd0b3146090e3ba58a69f835d917"
@ -1575,7 +1588,7 @@
lit-element "^2.5.0"
tslib "^2.0.1"
"@material/mwc-button@0.22.0-canary.cc04657a.0", "@material/mwc-button@canary":
"@material/mwc-button@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-button/-/mwc-button-0.22.0-canary.cc04657a.0.tgz#9640668b340197325ecc493ddc861bc215c117a3"
integrity sha512-xM6VorfSUgYDFFHYr5GfzHFbqcgz0j3TE6xR6dXkJQTqQPFameOYFBKn7TKu2j5674+OY4QHeyhw8/fYaWeP0A==
@ -1586,7 +1599,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-checkbox@0.22.0-canary.cc04657a.0", "@material/mwc-checkbox@canary":
"@material/mwc-checkbox@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-checkbox/-/mwc-checkbox-0.22.0-canary.cc04657a.0.tgz#ebfd10c06120de3fbdcf05751757ca621ce9035c"
integrity sha512-m/BSKMecOmZ8xG2g7P0bHZ5mlMBNkXxcmw68FOv3qZZufEkLMEic07zxbHNePcmDhjildwMWzTLfWHgCdTQ0hQ==
@ -1597,7 +1610,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-circular-progress@canary":
"@material/mwc-circular-progress@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-circular-progress/-/mwc-circular-progress-0.22.0-canary.cc04657a.0.tgz#d5873e347979b2279f66826cca167ed3ac147f96"
integrity sha512-hBD2EZhiolkD3m7xaSK7ml+qomX+FCg78RbV1BArrEnLk21ui46NsmtvBBJ1UiZUGs1FvRUcVNyMjSRTByxeDA==
@ -1609,7 +1622,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-dialog@canary":
"@material/mwc-dialog@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-dialog/-/mwc-dialog-0.22.0-canary.cc04657a.0.tgz#d817a733149893cb4c0d1d1ea563e7c65d360af1"
integrity sha512-qcMVcrJxEzgswiP34WPPtR484d2G7YfViVxVUrmAupsIlKqCLn7jYf6OlE/NmX0d65XIdo+WQEt1Qprui6wQiA==
@ -1624,7 +1637,7 @@
tslib "^2.0.1"
wicg-inert "^3.0.0"
"@material/mwc-fab@canary":
"@material/mwc-fab@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-fab/-/mwc-fab-0.22.0-canary.cc04657a.0.tgz#a3307c19a5c432c20da1029451a4dc97a219aa46"
integrity sha512-VR1xGp+VaIcysklG6jXP2rky3iTTbI06AvWa3KYevlpwm/sfnY5N4onUpeckAzIVvKUKM9JO/Yx+snJCUCAY5w==
@ -1634,7 +1647,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-formfield@canary":
"@material/mwc-formfield@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-formfield/-/mwc-formfield-0.22.0-canary.cc04657a.0.tgz#3e5803793e19c047ac0ec71061069c1f4b593dd0"
integrity sha512-eVajWwlwSC0ySDYU3btu41agtDQlotuaa6LYR0ZamNa1CMcu8QFq3ZyLaQqqS66/FsJJ4W+72+MpkUnAthj55A==
@ -1645,7 +1658,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-icon-button@canary":
"@material/mwc-icon-button@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-icon-button/-/mwc-icon-button-0.22.0-canary.cc04657a.0.tgz#79171babfbfde7fd98e2d9fbe66af40fdeeadf80"
integrity sha512-GzWXtjTterfWKAjs+qRyPP0RIWHt34FJkMoMjD0YuoVzbKeTFURwo9QBduVUU36ERe73sssnxtBk+5pQ7GWGjA==
@ -1662,7 +1675,18 @@
lit-element "^2.5.0"
tslib "^2.0.1"
"@material/mwc-list@0.22.0-canary.cc04657a.0", "@material/mwc-list@canary":
"@material/mwc-linear-progress@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-linear-progress/-/mwc-linear-progress-0.22.0-canary.cc04657a.0.tgz#fdbe49f81250c5d6d7536778b07b17e63637378e"
integrity sha512-QDuou14Q3xrRr3PDFsgZIngPKNjK5GeMRaorYKJgFK1XC7nrwd0rmVZn0CP1jm3+7eRmbnKaoVzj0AU7oFog8w==
dependencies:
"@material/linear-progress" "=12.0.0-canary.1a8d06483.0"
"@material/theme" "=12.0.0-canary.1a8d06483.0"
lit-element "^2.5.0"
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-list@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-list/-/mwc-list-0.22.0-canary.cc04657a.0.tgz#490ac8b1aebf57f937122bd9e55bc406c4ef793f"
integrity sha512-yA0b38mTEh75+W3LxeSJe97/Yu9bZAXX9783v8lhbwlAbp/IZPcLr0FkSfUt4BM4TIuEU9Sb6E8L8YpCqM6NSA==
@ -1678,7 +1702,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-menu@canary":
"@material/mwc-menu@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-menu/-/mwc-menu-0.22.0-canary.cc04657a.0.tgz#61aa5d70af6509958aff9b583c5d86a048d23af2"
integrity sha512-unXilkODM05Q4Dhmw54OItlRO1A+k8STuWnDSpM7nti1r5uh25BfJ64qs70OBMn4FM9fZGbOAvX1GfW5o/nYrA==
@ -1693,7 +1717,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-radio@0.22.0-canary.cc04657a.0", "@material/mwc-radio@canary":
"@material/mwc-radio@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-radio/-/mwc-radio-0.22.0-canary.cc04657a.0.tgz#3cf7ea09b4c6bfb8cb654c39c1fadd288235ca91"
integrity sha512-NDCBflXsqbL8vZKce1BPlDJgjcC/XD+ZlmtSY2liZgvZ6fPUGxtii/YGQRrrmZvIKDc+JJG0rhzZOty5XHQy+A==
@ -1704,7 +1728,7 @@
lit-element "^2.5.0"
tslib "^2.0.1"
"@material/mwc-ripple@0.22.0-canary.cc04657a.0", "@material/mwc-ripple@canary":
"@material/mwc-ripple@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-ripple/-/mwc-ripple-0.22.0-canary.cc04657a.0.tgz#bd22e2babe11aeffe7a611eadf7d354597c18eae"
integrity sha512-mjXSH7OA7iBe6e6ssenInTav9gTGx0lK0hrJfi92ku3YYoSgw8ULK8TiL/7YmGGH7UN67Emv4fdGPhwfiMfYbg==
@ -1716,7 +1740,7 @@
lit-html "^1.4.0"
tslib "^2.0.1"
"@material/mwc-switch@canary":
"@material/mwc-switch@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-switch/-/mwc-switch-0.22.0-canary.cc04657a.0.tgz#44ccbb37946ec2884692b6fff8ef3beab854d07a"
integrity sha512-dP4dqqIYULckm7UDynVS5E62nZt28Ae622AGneiHtRc1ob9IVtGRkpTVNoz5QyKvrLyF4XKAsKoOwAm6x66nkg==
@ -1727,7 +1751,7 @@
lit-element "^2.5.0"
tslib "^2.0.1"
"@material/mwc-tab-bar@canary":
"@material/mwc-tab-bar@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-tab-bar/-/mwc-tab-bar-0.22.0-canary.cc04657a.0.tgz#5590d3a3e820b4a7a4dc134d44790735cd375884"
integrity sha512-p0T+65FmD2EdMN4L0MStjd1jXSLjq5/w0wQ08WiO2Q7EWgh2iuABxwLLzhL4hMLWKzDXqmzy1rKI2QyiTRIW8A==
@ -1762,7 +1786,7 @@
lit-element "^2.5.0"
tslib "^2.0.1"
"@material/mwc-tab@0.22.0-canary.cc04657a.0", "@material/mwc-tab@canary":
"@material/mwc-tab@0.22.0-canary.cc04657a.0":
version "0.22.0-canary.cc04657a.0"
resolved "https://registry.yarnpkg.com/@material/mwc-tab/-/mwc-tab-0.22.0-canary.cc04657a.0.tgz#8d4491f55758f5ac4cbabc18c3f4f0de26fd687b"
integrity sha512-G3i5bCIqoz1yivFNdNcQMvbGX4B2X99Ayt+VbOpr0Mo3xGDqxZ1FXIEK6bLBcfLPO92kgaWlSyzMFkVS4Z/xxw==