mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Merge pull request #9267 from home-assistant/dev
This commit is contained in:
commit
4a8a7c997e
@ -28,9 +28,7 @@
|
||||
"__BUILD__": false,
|
||||
"__VERSION__": false,
|
||||
"__STATIC_PATH__": false,
|
||||
"Polymer": true,
|
||||
"webkitSpeechRecognition": false,
|
||||
"ResizeObserver": false
|
||||
"Polymer": true
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
|
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@ -6,8 +6,8 @@ on:
|
||||
- published
|
||||
|
||||
env:
|
||||
WHEELS_TAG: 3.7-alpine3.11
|
||||
PYTHON_VERSION: 3.7
|
||||
WHEELS_TAG: 3.8-alpine3.12
|
||||
PYTHON_VERSION: 3.8
|
||||
NODE_VERSION: 12.1
|
||||
|
||||
jobs:
|
||||
|
4
.mocharc.cjs
Normal file
4
.mocharc.cjs
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
require: "test-mocha/testconf.js",
|
||||
timeout: 10000,
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path");
|
||||
const env = require("./env.js");
|
||||
const paths = require("./paths.js");
|
||||
@ -53,13 +54,13 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
||||
babelrc: false,
|
||||
presets: [
|
||||
!latestBuild && [
|
||||
require("@babel/preset-env").default,
|
||||
"@babel/preset-env",
|
||||
{
|
||||
useBuiltIns: "entry",
|
||||
corejs: "3.6",
|
||||
},
|
||||
],
|
||||
require("@babel/preset-typescript").default,
|
||||
"@babel/preset-typescript",
|
||||
].filter(Boolean),
|
||||
plugins: [
|
||||
// Part of ES2018. Converts {...a, b: 2} to Object.assign({}, a, {b: 2})
|
||||
@ -72,14 +73,9 @@ module.exports.babelOptions = ({ latestBuild }) => ({
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
[
|
||||
require("@babel/plugin-proposal-decorators").default,
|
||||
{ decoratorsBeforeExport: true },
|
||||
],
|
||||
[
|
||||
require("@babel/plugin-proposal-class-properties").default,
|
||||
{ loose: true },
|
||||
],
|
||||
["@babel/plugin-proposal-decorators", { decoratorsBeforeExport: true }],
|
||||
["@babel/plugin-proposal-private-methods", { loose: true }],
|
||||
["@babel/plugin-proposal-class-properties", { loose: true }],
|
||||
].filter(Boolean),
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const paths = require("./paths.js");
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path");
|
||||
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
@ -32,88 +33,78 @@ const createRollupConfig = ({
|
||||
publicPath,
|
||||
dontHash,
|
||||
isWDS,
|
||||
}) => {
|
||||
return {
|
||||
/**
|
||||
* @type { import("rollup").InputOptions }
|
||||
*/
|
||||
inputOptions: {
|
||||
input: entry,
|
||||
// Some entry points contain no JavaScript. This setting silences a warning about that.
|
||||
// https://rollupjs.org/guide/en/#preserveentrysignatures
|
||||
preserveEntrySignatures: false,
|
||||
plugins: [
|
||||
ignore({
|
||||
files: bundle.emptyPackages({ latestBuild }),
|
||||
}) => ({
|
||||
/**
|
||||
* @type { import("rollup").InputOptions }
|
||||
*/
|
||||
inputOptions: {
|
||||
input: entry,
|
||||
// Some entry points contain no JavaScript. This setting silences a warning about that.
|
||||
// https://rollupjs.org/guide/en/#preserveentrysignatures
|
||||
preserveEntrySignatures: false,
|
||||
plugins: [
|
||||
ignore({
|
||||
files: bundle.emptyPackages({ latestBuild }),
|
||||
}),
|
||||
resolve({
|
||||
extensions,
|
||||
preferBuiltins: false,
|
||||
browser: true,
|
||||
rootDir: paths.polymer_dir,
|
||||
}),
|
||||
commonjs(),
|
||||
json(),
|
||||
babel({
|
||||
...bundle.babelOptions({ latestBuild }),
|
||||
extensions,
|
||||
exclude: bundle.babelExclude(),
|
||||
babelHelpers: isWDS ? "inline" : "bundled",
|
||||
}),
|
||||
string({
|
||||
// Import certain extensions as strings
|
||||
include: [path.join(paths.polymer_dir, "node_modules/**/*.css")],
|
||||
}),
|
||||
replace(bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })),
|
||||
!isWDS &&
|
||||
manifest({
|
||||
publicPath,
|
||||
}),
|
||||
resolve({
|
||||
extensions,
|
||||
preferBuiltins: false,
|
||||
browser: true,
|
||||
rootDir: paths.polymer_dir,
|
||||
!isWDS && worker(),
|
||||
!isWDS && dontHashPlugin({ dontHash }),
|
||||
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
||||
!isWDS &&
|
||||
isStatsBuild &&
|
||||
visualizer({
|
||||
// https://github.com/btd/rollup-plugin-visualizer#options
|
||||
open: true,
|
||||
sourcemap: true,
|
||||
}),
|
||||
commonjs({
|
||||
namedExports: {
|
||||
"js-yaml": ["safeDump", "safeLoad"],
|
||||
},
|
||||
}),
|
||||
json(),
|
||||
babel({
|
||||
...bundle.babelOptions({ latestBuild }),
|
||||
extensions,
|
||||
exclude: bundle.babelExclude(),
|
||||
babelHelpers: isWDS ? "inline" : "bundled",
|
||||
}),
|
||||
string({
|
||||
// Import certain extensions as strings
|
||||
include: [path.join(paths.polymer_dir, "node_modules/**/*.css")],
|
||||
}),
|
||||
replace(
|
||||
bundle.definedVars({ isProdBuild, latestBuild, defineOverlay })
|
||||
),
|
||||
!isWDS &&
|
||||
manifest({
|
||||
publicPath,
|
||||
}),
|
||||
!isWDS && worker(),
|
||||
!isWDS && dontHashPlugin({ dontHash }),
|
||||
!isWDS && isProdBuild && terser(bundle.terserOptions(latestBuild)),
|
||||
!isWDS &&
|
||||
isStatsBuild &&
|
||||
visualizer({
|
||||
// https://github.com/btd/rollup-plugin-visualizer#options
|
||||
open: true,
|
||||
sourcemap: true,
|
||||
}),
|
||||
].filter(Boolean),
|
||||
},
|
||||
/**
|
||||
* @type { import("rollup").OutputOptions }
|
||||
*/
|
||||
outputOptions: {
|
||||
// https://rollupjs.org/guide/en/#outputdir
|
||||
dir: outputPath,
|
||||
// https://rollupjs.org/guide/en/#outputformat
|
||||
format: latestBuild ? "es" : "systemjs",
|
||||
// https://rollupjs.org/guide/en/#outputexternallivebindings
|
||||
externalLiveBindings: false,
|
||||
// https://rollupjs.org/guide/en/#outputentryfilenames
|
||||
// https://rollupjs.org/guide/en/#outputchunkfilenames
|
||||
// https://rollupjs.org/guide/en/#outputassetfilenames
|
||||
entryFileNames:
|
||||
isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js",
|
||||
chunkFileNames:
|
||||
isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js",
|
||||
assetFileNames:
|
||||
isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js",
|
||||
// https://rollupjs.org/guide/en/#outputsourcemap
|
||||
sourcemap: isProdBuild ? true : "inline",
|
||||
},
|
||||
};
|
||||
};
|
||||
].filter(Boolean),
|
||||
},
|
||||
/**
|
||||
* @type { import("rollup").OutputOptions }
|
||||
*/
|
||||
outputOptions: {
|
||||
// https://rollupjs.org/guide/en/#outputdir
|
||||
dir: outputPath,
|
||||
// https://rollupjs.org/guide/en/#outputformat
|
||||
format: latestBuild ? "es" : "systemjs",
|
||||
// https://rollupjs.org/guide/en/#outputexternallivebindings
|
||||
externalLiveBindings: false,
|
||||
// https://rollupjs.org/guide/en/#outputentryfilenames
|
||||
// https://rollupjs.org/guide/en/#outputchunkfilenames
|
||||
// https://rollupjs.org/guide/en/#outputassetfilenames
|
||||
entryFileNames:
|
||||
isProdBuild && !isStatsBuild ? "[name]-[hash].js" : "[name].js",
|
||||
chunkFileNames: isProdBuild && !isStatsBuild ? "c.[hash].js" : "[name].js",
|
||||
assetFileNames: isProdBuild && !isStatsBuild ? "a.[hash].js" : "[name].js",
|
||||
// https://rollupjs.org/guide/en/#outputsourcemap
|
||||
sourcemap: isProdBuild ? true : "inline",
|
||||
},
|
||||
});
|
||||
|
||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
|
||||
return createRollupConfig(
|
||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) =>
|
||||
createRollupConfig(
|
||||
bundle.config.app({
|
||||
isProdBuild,
|
||||
latestBuild,
|
||||
@ -121,31 +112,24 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild, isWDS }) => {
|
||||
isWDS,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||
return createRollupConfig(
|
||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||
createRollupConfig(
|
||||
bundle.config.demo({
|
||||
isProdBuild,
|
||||
latestBuild,
|
||||
isStatsBuild,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const createCastConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createRollupConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||
};
|
||||
const createCastConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createRollupConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||
|
||||
const createHassioConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createRollupConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
||||
};
|
||||
const createHassioConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createRollupConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
||||
|
||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createRollupConfig(
|
||||
bundle.config.gallery({ isProdBuild, latestBuild })
|
||||
);
|
||||
};
|
||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createRollupConfig(bundle.config.gallery({ isProdBuild, latestBuild }));
|
||||
|
||||
module.exports = {
|
||||
createAppConfig,
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const webpack = require("webpack");
|
||||
const path = require("path");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
|
||||
const paths = require("./paths.js");
|
||||
const bundle = require("./bundle");
|
||||
const bundle = require("./bundle.js");
|
||||
const log = require("fancy-log");
|
||||
|
||||
class LogStartCompilePlugin {
|
||||
@ -94,6 +95,7 @@ const createWebpackConfig = ({
|
||||
? path.resolve(context, resource)
|
||||
: require.resolve(resource);
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
"Error in Home Assistant ignore plugin",
|
||||
resource,
|
||||
@ -115,7 +117,7 @@ const createWebpackConfig = ({
|
||||
new webpack.NormalModuleReplacementPlugin(
|
||||
new RegExp(
|
||||
require.resolve(
|
||||
"lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js"
|
||||
"@lit-labs/virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js"
|
||||
)
|
||||
),
|
||||
path.resolve(paths.polymer_dir, "src/resources/EventTarget-ponyfill.js")
|
||||
@ -124,6 +126,11 @@ const createWebpackConfig = ({
|
||||
].filter(Boolean),
|
||||
resolve: {
|
||||
extensions: [".ts", ".js", ".json"],
|
||||
alias: {
|
||||
"lit/decorators$": "lit/decorators.js",
|
||||
"lit/directive$": "lit/directive.js",
|
||||
"lit/polyfill-support$": "lit/polyfill-support.js",
|
||||
},
|
||||
},
|
||||
output: {
|
||||
filename: ({ chunk }) => {
|
||||
@ -144,33 +151,24 @@ const createWebpackConfig = ({
|
||||
};
|
||||
};
|
||||
|
||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||
return createWebpackConfig(
|
||||
const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||
createWebpackConfig(
|
||||
bundle.config.app({ isProdBuild, latestBuild, isStatsBuild })
|
||||
);
|
||||
};
|
||||
|
||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => {
|
||||
return createWebpackConfig(
|
||||
const createDemoConfig = ({ isProdBuild, latestBuild, isStatsBuild }) =>
|
||||
createWebpackConfig(
|
||||
bundle.config.demo({ isProdBuild, latestBuild, isStatsBuild })
|
||||
);
|
||||
};
|
||||
|
||||
const createCastConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||
};
|
||||
const createCastConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createWebpackConfig(bundle.config.cast({ isProdBuild, latestBuild }));
|
||||
|
||||
const createHassioConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createWebpackConfig(
|
||||
bundle.config.hassio({ isProdBuild, latestBuild })
|
||||
);
|
||||
};
|
||||
const createHassioConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createWebpackConfig(bundle.config.hassio({ isProdBuild, latestBuild }));
|
||||
|
||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) => {
|
||||
return createWebpackConfig(
|
||||
bundle.config.gallery({ isProdBuild, latestBuild })
|
||||
);
|
||||
};
|
||||
const createGalleryConfig = ({ isProdBuild, latestBuild }) =>
|
||||
createWebpackConfig(bundle.config.gallery({ isProdBuild, latestBuild }));
|
||||
|
||||
module.exports = {
|
||||
createAppConfig,
|
||||
|
@ -1,16 +1,9 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import { Auth, Connection } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
internalProperty,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { CastManager } from "../../../../src/cast/cast_manager";
|
||||
import {
|
||||
castSendShowLovelaceView,
|
||||
@ -32,7 +25,6 @@ import {
|
||||
import "../../../../src/layouts/hass-loading-screen";
|
||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||
import "./hc-layout";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
|
||||
@customElement("hc-cast")
|
||||
class HcCast extends LitElement {
|
||||
@ -42,9 +34,9 @@ class HcCast extends LitElement {
|
||||
|
||||
@property() public castManager!: CastManager;
|
||||
|
||||
@internalProperty() private askWrite = false;
|
||||
@state() private askWrite = false;
|
||||
|
||||
@internalProperty() private lovelaceConfig?: LovelaceConfig | null;
|
||||
@state() private lovelaceConfig?: LovelaceConfig | null;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (this.lovelaceConfig === undefined) {
|
||||
@ -204,7 +196,7 @@ class HcCast extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
.center-item {
|
||||
display: flex;
|
||||
|
@ -11,15 +11,8 @@ import {
|
||||
getAuth,
|
||||
getAuthOptions,
|
||||
} from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
internalProperty,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { CastManager, getCastManager } from "../../../../src/cast/cast_manager";
|
||||
import { castSendShowDemo } from "../../../../src/cast/receiver_messages";
|
||||
import {
|
||||
@ -60,19 +53,19 @@ const INTRO = html`
|
||||
|
||||
@customElement("hc-connect")
|
||||
export class HcConnect extends LitElement {
|
||||
@internalProperty() private loading = false;
|
||||
@state() private loading = false;
|
||||
|
||||
// If we had stored credentials but we cannot connect,
|
||||
// show a screen asking retry or logout.
|
||||
@internalProperty() private cannotConnect = false;
|
||||
@state() private cannotConnect = false;
|
||||
|
||||
@internalProperty() private error?: string | TemplateResult;
|
||||
@state() private error?: string | TemplateResult;
|
||||
|
||||
@internalProperty() private auth?: Auth;
|
||||
@state() private auth?: Auth;
|
||||
|
||||
@internalProperty() private connection?: Connection;
|
||||
@state() private connection?: Connection;
|
||||
|
||||
@internalProperty() private castManager?: CastManager | null;
|
||||
@state() private castManager?: CastManager | null;
|
||||
|
||||
private openDemo = false;
|
||||
|
||||
@ -297,7 +290,7 @@ export class HcConnect extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
.card-content a {
|
||||
color: var(--primary-color);
|
||||
|
@ -4,15 +4,8 @@ import {
|
||||
getUser,
|
||||
HassUser,
|
||||
} from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-card";
|
||||
|
||||
@customElement("hc-layout")
|
||||
@ -69,7 +62,7 @@ class HcLayout extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
|
@ -1,10 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { mockHistory } from "../../../../demo/src/stubs/history";
|
||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||
import {
|
||||
@ -21,7 +16,7 @@ import "./hc-lovelace";
|
||||
class HcDemo extends HassElement {
|
||||
@property({ attribute: false }) public lovelacePath!: string;
|
||||
|
||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
||||
@state() private _lovelaceConfig?: LovelaceConfig;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._lovelaceConfig) {
|
||||
@ -38,10 +33,10 @@ class HcDemo extends HassElement {
|
||||
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._initialize();
|
||||
this._initializeHass();
|
||||
}
|
||||
|
||||
private async _initialize() {
|
||||
private async _initializeHass() {
|
||||
const initial: Partial<MockHomeAssistant> = {
|
||||
// Override updateHass so that the correct hass lifecycle methods are called
|
||||
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
|
||||
@customElement("hc-launch-screen")
|
||||
@ -29,7 +22,7 @@ class HcLaunchScreen extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { LovelaceConfig } from "../../../../src/data/lovelace";
|
||||
import { Lovelace } from "../../../../src/panels/lovelace/types";
|
||||
import "../../../../src/panels/lovelace/views/hui-view";
|
||||
@ -91,7 +84,7 @@ class HcLovelace extends LitElement {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
min-height: 100vh;
|
||||
|
@ -3,12 +3,8 @@ import {
|
||||
getAuth,
|
||||
UnsubscribeFunc,
|
||||
} from "home-assistant-js-websocket";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { CAST_NS } from "../../../../src/cast/const";
|
||||
import {
|
||||
ConnectMessage,
|
||||
@ -36,13 +32,13 @@ let resourcesLoaded = false;
|
||||
|
||||
@customElement("hc-main")
|
||||
export class HcMain extends HassElement {
|
||||
@internalProperty() private _showDemo = false;
|
||||
@state() private _showDemo = false;
|
||||
|
||||
@internalProperty() private _lovelaceConfig?: LovelaceConfig;
|
||||
@state() private _lovelaceConfig?: LovelaceConfig;
|
||||
|
||||
@internalProperty() private _lovelacePath: string | number | null = null;
|
||||
@state() private _lovelacePath: string | number | null = null;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
private _unsubLovelace?: UnsubscribeFunc;
|
||||
|
||||
|
@ -440,57 +440,43 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
type: "horizontal-stack",
|
||||
},
|
||||
{
|
||||
type: "grid",
|
||||
columns: 2,
|
||||
cards: [
|
||||
{
|
||||
cards: [
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_bedroom",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "S's room",
|
||||
entity: "sensor.temperature_stefan",
|
||||
},
|
||||
],
|
||||
type: "horizontal-stack",
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_bedroom",
|
||||
},
|
||||
{
|
||||
cards: [
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_passage",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "Bathroom",
|
||||
entity: "sensor.temperature_downstairs_bathroom",
|
||||
},
|
||||
],
|
||||
type: "horizontal-stack",
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "S's room",
|
||||
entity: "sensor.temperature_stefan",
|
||||
},
|
||||
{
|
||||
cards: [
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_storage",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "Refrigerator",
|
||||
entity: "sensor.refrigerator",
|
||||
},
|
||||
],
|
||||
type: "horizontal-stack",
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_passage",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "Bathroom",
|
||||
entity: "sensor.temperature_downstairs_bathroom",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
entity: "sensor.temperature_storage",
|
||||
},
|
||||
{
|
||||
graph: "line",
|
||||
type: "sensor",
|
||||
name: "Refrigerator",
|
||||
entity: "sensor.refrigerator",
|
||||
},
|
||||
],
|
||||
type: "vertical-stack",
|
||||
},
|
||||
{
|
||||
entities: [
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* eslint-disable */
|
||||
import { LitElement } from "lit-element";
|
||||
import { LitElement } from "lit";
|
||||
import "./card-tools";
|
||||
|
||||
class CardModder extends LitElement {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* eslint-disable */
|
||||
import { html, LitElement } from "lit-element";
|
||||
import { html, LitElement } from "lit";
|
||||
|
||||
if (!window.cardTools) {
|
||||
const version = 0.2;
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { CastManager } from "../../../src/cast/cast_manager";
|
||||
import { castSendShowDemo } from "../../../src/cast/receiver_messages";
|
||||
import "../../../src/components/ha-icon";
|
||||
@ -20,7 +13,7 @@ import { HomeAssistant } from "../../../src/types";
|
||||
class CastDemoRow extends LitElement implements LovelaceRow {
|
||||
public hass!: HomeAssistant;
|
||||
|
||||
@internalProperty() private _castManager?: CastManager | null;
|
||||
@state() private _castManager?: CastManager | null;
|
||||
|
||||
public setConfig(_config: CastConfig): void {
|
||||
// No config possible.
|
||||
@ -73,7 +66,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
|
||||
this.style.display = this._castManager ? "" : "none";
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
display: flex;
|
||||
|
@ -1,14 +1,7 @@
|
||||
import "@material/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import { until } from "lit/directives/until";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-circular-progress";
|
||||
import { LovelaceCardConfig } from "../../../src/data/lovelace";
|
||||
@ -26,7 +19,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
|
||||
@property({ attribute: false }) public hass!: MockHomeAssistant;
|
||||
|
||||
@internalProperty() private _switching?: boolean;
|
||||
@state() private _switching?: boolean;
|
||||
|
||||
private _hidden = localStorage.hide_demo_card;
|
||||
|
||||
@ -113,7 +106,7 @@ export class HADemoCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
css`
|
||||
a {
|
||||
|
@ -22,9 +22,9 @@ import { mockTemplate } from "./stubs/template";
|
||||
import { mockTranslations } from "./stubs/translations";
|
||||
|
||||
class HaDemo extends HomeAssistantAppEl {
|
||||
protected async _initialize() {
|
||||
protected async _initializeHass() {
|
||||
const initial: Partial<MockHomeAssistant> = {
|
||||
panelUrl: (this as any).panelUrl,
|
||||
panelUrl: (this as any)._panelUrl,
|
||||
// Override updateHass so that the correct hass lifecycle methods are called
|
||||
updateHass: (hassUpdate: Partial<HomeAssistant>) =>
|
||||
this._updateHass(hassUpdate),
|
||||
@ -70,7 +70,7 @@ class HaDemo extends HomeAssistantAppEl {
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
navigate(this, href);
|
||||
navigate(href);
|
||||
},
|
||||
{ capture: true }
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { safeLoad } from "js-yaml";
|
||||
import { load } from "js-yaml";
|
||||
import { createCardElement } from "../../../src/panels/lovelace/create-element/create-card-element";
|
||||
|
||||
class DemoCard extends PolymerElement {
|
||||
@ -80,7 +80,7 @@ class DemoCard extends PolymerElement {
|
||||
card.removeChild(card.lastChild);
|
||||
}
|
||||
|
||||
const el = this._createCardElement(safeLoad(config.config)[0]);
|
||||
const el = this._createCardElement(load(config.config)[0]);
|
||||
card.appendChild(el);
|
||||
this._getSize(el);
|
||||
}
|
||||
|
@ -1,12 +1,6 @@
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { dump } from "js-yaml";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import { describeAction } from "../../../src/data/script_i18n";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
@ -62,7 +56,7 @@ export class DemoAutomationDescribeAction extends LitElement {
|
||||
(conf) => html`
|
||||
<div class="action">
|
||||
<span>${describeAction(this.hass, conf as any)}</span>
|
||||
<pre>${safeDump(conf)}</pre>
|
||||
<pre>${dump(conf)}</pre>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
|
@ -1,11 +1,6 @@
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { dump } from "js-yaml";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import { describeCondition } from "../../../src/data/automation_i18n";
|
||||
|
||||
@ -31,7 +26,7 @@ export class DemoAutomationDescribeCondition extends LitElement {
|
||||
(conf) => html`
|
||||
<div class="condition">
|
||||
<span>${describeCondition(conf as any)}</span>
|
||||
<pre>${safeDump(conf)}</pre>
|
||||
<pre>${dump(conf)}</pre>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
|
@ -1,11 +1,6 @@
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { dump } from "js-yaml";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import { describeTrigger } from "../../../src/data/automation_i18n";
|
||||
|
||||
@ -34,7 +29,7 @@ export class DemoAutomationDescribeTrigger extends LitElement {
|
||||
(conf) => html`
|
||||
<div class="trigger">
|
||||
<span>${describeTrigger(conf as any)}</span>
|
||||
<pre>${safeDump(conf)}</pre>
|
||||
<pre>${dump(conf)}</pre>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/trace/hat-script-graph";
|
||||
import "../../../src/components/trace/hat-trace-timeline";
|
||||
|
@ -1,12 +1,4 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
internalProperty,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/trace/hat-script-graph";
|
||||
import "../../../src/components/trace/hat-trace-timeline";
|
||||
@ -15,6 +7,7 @@ import { HomeAssistant } from "../../../src/types";
|
||||
import { DemoTrace } from "../data/traces/types";
|
||||
import { basicTrace } from "../data/traces/basic_trace";
|
||||
import { motionLightTrace } from "../data/traces/motion-light-trace";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
|
||||
const traces: DemoTrace[] = [basicTrace, motionLightTrace];
|
||||
|
||||
@ -22,7 +15,7 @@ const traces: DemoTrace[] = [basicTrace, motionLightTrace];
|
||||
export class DemoAutomationTrace extends LitElement {
|
||||
@property({ attribute: false }) hass?: HomeAssistant;
|
||||
|
||||
@internalProperty() private _selected = {};
|
||||
@state() private _selected = {};
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass) {
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { mockHistory } from "../../../demo/src/stubs/history";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { customElement, html, LitElement, TemplateResult } from "lit-element";
|
||||
import { html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import "../components/demo-cards";
|
||||
|
||||
const CONFIGS = [
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { mockTemplate } from "../../../demo/src/stubs/template";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
import { createMediaPlayerEntities } from "../data/media_players";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
import { createMediaPlayerEntities } from "../data/media_players";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
import { createPlantEntities } from "../data/plants";
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
||||
|
@ -1,11 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { getEntity } from "../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../src/fake_data/provide_hass";
|
||||
import "../components/demo-cards";
|
||||
|
@ -1,12 +1,4 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { html, css, LitElement, TemplateResult } from "lit";
|
||||
import "../../../src/components/ha-formfield";
|
||||
import "../../../src/components/ha-switch";
|
||||
|
||||
@ -23,7 +15,8 @@ import type {
|
||||
} from "../../../src/panels/config/integrations/ha-config-integrations";
|
||||
import { DeviceRegistryEntry } from "../../../src/data/device_registry";
|
||||
import { EntityRegistryEntry } from "../../../src/data/entity_registry";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
|
||||
const createConfigEntry = (
|
||||
title: string,
|
||||
@ -220,9 +213,9 @@ const createDeviceRegistryEntries = (
|
||||
export class DemoIntegrationCard extends LitElement {
|
||||
@property({ attribute: false }) hass?: HomeAssistant;
|
||||
|
||||
@internalProperty() isCustomIntegration = false;
|
||||
@state() isCustomIntegration = false;
|
||||
|
||||
@internalProperty() isCloud = false;
|
||||
@state() isCloud = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass) {
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
|
||||
import { customElement, property, query } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import {
|
||||
LightColorModes,
|
||||
|
@ -1,5 +1,6 @@
|
||||
import "@material/mwc-button";
|
||||
import { customElement, html, LitElement, TemplateResult } from "lit-element";
|
||||
import { html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import "../../../src/components/ha-card";
|
||||
import { ActionHandlerEvent } from "../../../src/data/lovelace";
|
||||
import { actionHandler } from "../../../src/panels/lovelace/common/directives/action-handler-directive";
|
||||
|
@ -1,12 +1,6 @@
|
||||
import { mdiArrowUpBoldCircle, mdiPuzzle } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResultArray,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { navigate } from "../../../src/common/navigate";
|
||||
@ -126,10 +120,10 @@ class HassioAddonRepositoryEl extends LitElement {
|
||||
}
|
||||
|
||||
private _addonTapped(ev) {
|
||||
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`);
|
||||
navigate(`/hassio/addon/${ev.currentTarget.addon.slug}`);
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
hassioStyle,
|
||||
css`
|
||||
|
@ -4,13 +4,13 @@ import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
internalProperty,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { html, TemplateResult } from "lit-html";
|
||||
TemplateResult,
|
||||
} from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
@ -58,7 +58,7 @@ class HassioAddonStore extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@internalProperty() private _filter?: string;
|
||||
@state() private _filter?: string;
|
||||
|
||||
public async refreshData() {
|
||||
await reloadHassioAddons(this.hass);
|
||||
@ -138,7 +138,7 @@ class HassioAddonStore extends LitElement {
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
const repositoryUrl = extractSearchParam("repository_url");
|
||||
navigate(this, "/hassio/store", true);
|
||||
navigate("/hassio/store", { replace: true });
|
||||
if (repositoryUrl) {
|
||||
this._manageRepositories(repositoryUrl);
|
||||
}
|
||||
@ -218,7 +218,7 @@ class HassioAddonStore extends LitElement {
|
||||
this._filter = e.detail.value;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
hassio-addon-repository {
|
||||
margin-top: 24px;
|
||||
|
@ -4,15 +4,13 @@ import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "web-animations-js/web-animations-next-lite.min";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-card";
|
||||
@ -39,15 +37,15 @@ class HassioAddonAudio extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _inputDevices?: HassioHardwareAudioDevice[];
|
||||
@state() private _inputDevices?: HassioHardwareAudioDevice[];
|
||||
|
||||
@internalProperty() private _outputDevices?: HassioHardwareAudioDevice[];
|
||||
@state() private _outputDevices?: HassioHardwareAudioDevice[];
|
||||
|
||||
@internalProperty() private _selectedInput!: null | string;
|
||||
@state() private _selectedInput!: null | string;
|
||||
|
||||
@internalProperty() private _selectedOutput!: null | string;
|
||||
@state() private _selectedOutput!: null | string;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
@ -109,7 +107,7 @@ class HassioAddonAudio extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
@ -70,7 +63,7 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -5,16 +5,13 @@ import { mdiDotsVertical } from "@mdi/js";
|
||||
import "@polymer/iron-autogrow-textarea/iron-autogrow-textarea";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
} from "lit";
|
||||
import { customElement, property, state, query } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
@ -53,15 +50,15 @@ class HassioAddonConfig extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) private _valid = true;
|
||||
|
||||
@internalProperty() private _canShowSchema = false;
|
||||
@state() private _canShowSchema = false;
|
||||
|
||||
@internalProperty() private _showOptional = false;
|
||||
@state() private _showOptional = false;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _options?: Record<string, unknown>;
|
||||
@state() private _options?: Record<string, unknown>;
|
||||
|
||||
@internalProperty() private _yamlMode = false;
|
||||
@state() private _yamlMode = false;
|
||||
|
||||
@query("ha-yaml-editor") private _editor?: HaYamlEditor;
|
||||
|
||||
@ -262,6 +259,11 @@ class HassioAddonConfig extends LitElement {
|
||||
|
||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||
const button = ev.currentTarget as any;
|
||||
const eventdata = {
|
||||
success: true,
|
||||
response: undefined,
|
||||
path: "options",
|
||||
};
|
||||
button.progress = true;
|
||||
|
||||
this._error = undefined;
|
||||
@ -272,26 +274,22 @@ class HassioAddonConfig extends LitElement {
|
||||
});
|
||||
|
||||
this._configHasChanged = false;
|
||||
const eventdata = {
|
||||
success: true,
|
||||
response: undefined,
|
||||
path: "options",
|
||||
};
|
||||
fireEvent(this, "hass-api-called", eventdata);
|
||||
if (this.addon?.state === "started") {
|
||||
await suggestAddonRestart(this, this.hass, this.supervisor, this.addon);
|
||||
}
|
||||
} catch (err) {
|
||||
this._error = this.supervisor.localize(
|
||||
"addon.configuration.options.failed_to_save",
|
||||
"addon.failed_to_save",
|
||||
"error",
|
||||
extractApiErrorMessage(err)
|
||||
);
|
||||
eventdata.success = false;
|
||||
}
|
||||
button.progress = false;
|
||||
fireEvent(this, "hass-api-called", eventdata);
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,15 +1,13 @@
|
||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-card";
|
||||
@ -43,9 +41,9 @@ class HassioAddonNetwork extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _config?: NetworkItem[];
|
||||
@state() private _config?: NetworkItem[];
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
@ -216,7 +214,7 @@ class HassioAddonNetwork extends LitElement {
|
||||
button.progress = false;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,14 +1,5 @@
|
||||
import "../../../../src/components/ha-card";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "../../../../src/components/ha-markdown";
|
||||
import {
|
||||
@ -21,6 +12,7 @@ import { haStyle } from "../../../../src/resources/styles";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
import { hassioStyle } from "../../resources/hassio-style";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
|
||||
@customElement("hassio-addon-documentation-tab")
|
||||
class HassioAddonDocumentationDashboard extends LitElement {
|
||||
@ -30,9 +22,9 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _content?: string;
|
||||
@state() private _content?: string;
|
||||
|
||||
public async connectedCallback(): Promise<void> {
|
||||
super.connectedCallback();
|
||||
@ -57,7 +49,7 @@ class HassioAddonDocumentationDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -4,16 +4,8 @@ import {
|
||||
mdiInformationVariant,
|
||||
mdiMathLog,
|
||||
} from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import { navigate } from "../../../src/common/navigate";
|
||||
@ -52,7 +44,7 @@ class HassioAddonDashboard extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public narrow!: boolean;
|
||||
|
||||
@internalProperty() _error?: string;
|
||||
@state() _error?: string;
|
||||
|
||||
private _computeTail = memoizeOne((route: Route) => {
|
||||
const dividerPos = route.path.indexOf("/", 1);
|
||||
@ -133,7 +125,7 @@ class HassioAddonDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
@ -183,7 +175,7 @@ class HassioAddonDashboard extends LitElement {
|
||||
if (!validAddon) {
|
||||
this._error = this.supervisor.localize("my.error_addon_not_found");
|
||||
} else {
|
||||
navigate(this, `/hassio/addon/${requestedAddon}`, true);
|
||||
navigate(`/hassio/addon/${requestedAddon}`, { replace: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,6 +183,10 @@ class HassioAddonDashboard extends LitElement {
|
||||
}
|
||||
|
||||
private async _apiCalled(ev): Promise<void> {
|
||||
if (!ev.detail.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pathSplit: string[] = ev.detail.path?.split("/");
|
||||
|
||||
if (!pathSplit || pathSplit.length === 0) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { customElement, property } from "lit-element";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { HassioAddonDetails } from "../../../src/data/hassio/addon";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import {
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
@ -42,7 +35,7 @@ class HassioAddonInfoDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -14,17 +14,9 @@ import {
|
||||
mdiPound,
|
||||
mdiShield,
|
||||
} from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
@ -90,9 +82,9 @@ class HassioAddonInfo extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _metrics?: HassioStats;
|
||||
@state() private _metrics?: HassioStats;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
private _addonStoreInfo = memoizeOne(
|
||||
(slug: string, storeAddons: StoreAddon[]) =>
|
||||
@ -171,16 +163,16 @@ class HassioAddonInfo extends LitElement {
|
||||
: ""}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._updateClicked}>
|
||||
${this.supervisor.localize("common.update")}
|
||||
</mwc-button>
|
||||
${this.addon.changelog
|
||||
? html`
|
||||
<mwc-button @click=${this._openChangelog}>
|
||||
${this.supervisor.localize("addon.dashboard.changelog")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ""}
|
||||
: html`<span></span>`}
|
||||
<mwc-button @click=${this._updateClicked}>
|
||||
${this.supervisor.localize("common.update")}
|
||||
</mwc-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
@ -769,7 +761,7 @@ class HassioAddonInfo extends LitElement {
|
||||
}
|
||||
|
||||
private _openIngress(): void {
|
||||
navigate(this, `/hassio/ingress/${this.addon.slug}`);
|
||||
navigate(`/hassio/ingress/${this.addon.slug}`);
|
||||
}
|
||||
|
||||
private get _computeShowIngressUI(): boolean {
|
||||
@ -1059,7 +1051,7 @@ class HassioAddonInfo extends LitElement {
|
||||
}
|
||||
|
||||
private _openConfiguration(): void {
|
||||
navigate(this, `/hassio/addon/${this.addon.slug}/config`);
|
||||
navigate(`/hassio/addon/${this.addon.slug}/config`);
|
||||
}
|
||||
|
||||
private async _uninstallClicked(ev: CustomEvent): Promise<void> {
|
||||
@ -1098,7 +1090,7 @@ class HassioAddonInfo extends LitElement {
|
||||
button.progress = false;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
@ -38,7 +31,7 @@ class HassioAddonLogDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,14 +1,6 @@
|
||||
import "@material/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../../../../src/components/ha-card";
|
||||
import {
|
||||
fetchHassioAddonLogs,
|
||||
@ -29,9 +21,9 @@ class HassioAddonLogs extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _content?: string;
|
||||
@state() private _content?: string;
|
||||
|
||||
public async connectedCallback(): Promise<void> {
|
||||
super.connectedCallback();
|
||||
@ -59,7 +51,7 @@ class HassioAddonLogs extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
|
||||
interface State {
|
||||
bold: boolean;
|
||||
@ -25,7 +18,7 @@ class HassioAnsiToHtml extends LitElement {
|
||||
return html`${this._parseTextToColoredPre(this.content)}`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
pre {
|
||||
overflow-x: auto;
|
||||
|
@ -1,13 +1,6 @@
|
||||
import { mdiHelpCircle } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../src/components/ha-relative-time";
|
||||
import "../../../src/components/ha-svg-icon";
|
||||
import { HomeAssistant } from "../../../src/types";
|
||||
@ -77,7 +70,7 @@ class HassioCardContent extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
ha-svg-icon {
|
||||
margin-right: 24px;
|
||||
|
@ -2,13 +2,8 @@ import "@material/mwc-icon-button/mwc-icon-button";
|
||||
import { mdiFolderUpload } from "@mdi/js";
|
||||
import "@polymer/iron-input/iron-input";
|
||||
import "@polymer/paper-input/paper-input-container";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/ha-circular-progress";
|
||||
import "../../../src/components/ha-file-upload";
|
||||
@ -33,9 +28,9 @@ const MAX_FILE_SIZE = 1 * 1024 * 1024 * 1024; // 1GB
|
||||
export class HassioUploadSnapshot extends LitElement {
|
||||
public hass!: HomeAssistant;
|
||||
|
||||
@internalProperty() public value: string | null = null;
|
||||
@state() public value: string | null = null;
|
||||
|
||||
@internalProperty() private _uploading = false;
|
||||
@state() private _uploading = false;
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
|
55
hassio/src/components/supervisor-formfield-label.ts
Normal file
55
hassio/src/components/supervisor-formfield-label.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../src/components/ha-svg-icon";
|
||||
|
||||
@customElement("supervisor-formfield-label")
|
||||
class SupervisorFormfieldLabel extends LitElement {
|
||||
@property({ type: String }) public label!: string;
|
||||
|
||||
@property({ type: String }) public imageUrl?: string;
|
||||
|
||||
@property({ type: String }) public iconPath?: string;
|
||||
|
||||
@property({ type: String }) public version?: string;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
${this.imageUrl
|
||||
? html`<img loading="lazy" .src=${this.imageUrl} class="icon" />`
|
||||
: this.iconPath
|
||||
? html`<ha-svg-icon .path=${this.iconPath} class="icon"></ha-svg-icon>`
|
||||
: ""}
|
||||
<span class="label">${this.label}</span>
|
||||
${this.version
|
||||
? html`<span class="version">(${this.version})</span>`
|
||||
: ""}
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.label {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.version {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.icon {
|
||||
max-height: 22px;
|
||||
max-width: 22px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"supervisor-formfield-label": SupervisorFormfieldLabel;
|
||||
}
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import "../../../src/components/ha-bar";
|
||||
import "../../../src/components/ha-settings-row";
|
||||
import { roundWithOneDecimal } from "../../../src/util/calculate";
|
||||
@ -37,7 +30,7 @@ class SupervisorMetric extends LitElement {
|
||||
</ha-settings-row>`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
ha-settings-row {
|
||||
padding: 0;
|
||||
@ -71,6 +64,7 @@ class SupervisorMetric extends LitElement {
|
||||
.value {
|
||||
width: 48px;
|
||||
padding-right: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
418
hassio/src/components/supervisor-snapshot-content.ts
Normal file
418
hassio/src/components/supervisor-snapshot-content.ts
Normal file
@ -0,0 +1,418 @@
|
||||
import { mdiFolder, mdiHomeAssistant, mdiPuzzle } from "@mdi/js";
|
||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { formatDate } from "../../../src/common/datetime/format_date";
|
||||
import { formatDateTime } from "../../../src/common/datetime/format_date_time";
|
||||
import "../../../src/components/ha-checkbox";
|
||||
import "../../../src/components/ha-formfield";
|
||||
import "../../../src/components/ha-radio";
|
||||
import type { HaRadio } from "../../../src/components/ha-radio";
|
||||
import {
|
||||
HassioFullSnapshotCreateParams,
|
||||
HassioPartialSnapshotCreateParams,
|
||||
HassioSnapshotDetail,
|
||||
} from "../../../src/data/hassio/snapshot";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import { PolymerChangedEvent } from "../../../src/polymer-types";
|
||||
import { HomeAssistant } from "../../../src/types";
|
||||
import "./supervisor-formfield-label";
|
||||
|
||||
interface CheckboxItem {
|
||||
slug: string;
|
||||
checked: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface AddonCheckboxItem extends CheckboxItem {
|
||||
version: string;
|
||||
}
|
||||
|
||||
const _computeFolders = (folders): CheckboxItem[] => {
|
||||
const list: CheckboxItem[] = [];
|
||||
if (folders.includes("homeassistant")) {
|
||||
list.push({
|
||||
slug: "homeassistant",
|
||||
name: "Home Assistant configuration",
|
||||
checked: false,
|
||||
});
|
||||
}
|
||||
if (folders.includes("ssl")) {
|
||||
list.push({ slug: "ssl", name: "SSL", checked: false });
|
||||
}
|
||||
if (folders.includes("share")) {
|
||||
list.push({ slug: "share", name: "Share", checked: false });
|
||||
}
|
||||
if (folders.includes("addons/local")) {
|
||||
list.push({ slug: "addons/local", name: "Local add-ons", checked: false });
|
||||
}
|
||||
return list.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
};
|
||||
|
||||
const _computeAddons = (addons): AddonCheckboxItem[] =>
|
||||
addons
|
||||
.map((addon) => ({
|
||||
slug: addon.slug,
|
||||
name: addon.name,
|
||||
version: addon.version,
|
||||
checked: false,
|
||||
}))
|
||||
.sort((a, b) => (a.name > b.name ? 1 : -1));
|
||||
|
||||
@customElement("supervisor-snapshot-content")
|
||||
export class SupervisorSnapshotContent extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public supervisor?: Supervisor;
|
||||
|
||||
@property({ attribute: false }) public snapshot?: HassioSnapshotDetail;
|
||||
|
||||
@property() public snapshotType: HassioSnapshotDetail["type"] = "full";
|
||||
|
||||
@property({ attribute: false }) public folders?: CheckboxItem[];
|
||||
|
||||
@property({ attribute: false }) public addons?: AddonCheckboxItem[];
|
||||
|
||||
@property({ type: Boolean }) public homeAssistant = false;
|
||||
|
||||
@property({ type: Boolean }) public snapshotHasPassword = false;
|
||||
|
||||
@property() public snapshotName = "";
|
||||
|
||||
@property() public snapshotPassword = "";
|
||||
|
||||
public willUpdate(changedProps) {
|
||||
super.willUpdate(changedProps);
|
||||
if (!this.hasUpdated) {
|
||||
this.folders = _computeFolders(
|
||||
this.snapshot
|
||||
? this.snapshot.folders
|
||||
: ["homeassistant", "ssl", "share", "media", "addons/local"]
|
||||
);
|
||||
this.addons = _computeAddons(
|
||||
this.snapshot
|
||||
? this.snapshot.addons
|
||||
: this.supervisor?.supervisor.addons
|
||||
);
|
||||
this.snapshotType = this.snapshot?.type || "full";
|
||||
this.snapshotName = this.snapshot?.name || "";
|
||||
this.snapshotHasPassword = this.snapshot?.protected || false;
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.supervisor) {
|
||||
return html``;
|
||||
}
|
||||
const foldersSection =
|
||||
this.snapshotType === "partial" ? this._getSection("folders") : undefined;
|
||||
const addonsSection =
|
||||
this.snapshotType === "partial" ? this._getSection("addons") : undefined;
|
||||
|
||||
return html`
|
||||
${this.snapshot
|
||||
? html`<div class="details">
|
||||
${this.snapshot.type === "full"
|
||||
? this.supervisor.localize("snapshot.full_snapshot")
|
||||
: this.supervisor.localize("snapshot.partial_snapshot")}
|
||||
(${Math.ceil(this.snapshot.size * 10) / 10 + " MB"})<br />
|
||||
${formatDateTime(new Date(this.snapshot.date), this.hass.locale)}
|
||||
</div>`
|
||||
: html`<paper-input
|
||||
name="snapshotName"
|
||||
.label=${this.supervisor.localize("snapshot.name")}
|
||||
.value=${this.snapshotName}
|
||||
@value-changed=${this._handleTextValueChanged}
|
||||
>
|
||||
</paper-input>`}
|
||||
${!this.snapshot || this.snapshot.type === "full"
|
||||
? html`<div class="sub-header">
|
||||
${!this.snapshot
|
||||
? this.supervisor.localize("snapshot.type")
|
||||
: this.supervisor.localize("snapshot.select_type")}
|
||||
</div>
|
||||
<div class="snapshot-types">
|
||||
<ha-formfield
|
||||
.label=${this.supervisor.localize("snapshot.full_snapshot")}
|
||||
>
|
||||
<ha-radio
|
||||
@change=${this._handleRadioValueChanged}
|
||||
value="full"
|
||||
name="snapshotType"
|
||||
.checked=${this.snapshotType === "full"}
|
||||
>
|
||||
</ha-radio>
|
||||
</ha-formfield>
|
||||
<ha-formfield
|
||||
.label=${this.supervisor!.localize("snapshot.partial_snapshot")}
|
||||
>
|
||||
<ha-radio
|
||||
@change=${this._handleRadioValueChanged}
|
||||
value="partial"
|
||||
name="snapshotType"
|
||||
.checked=${this.snapshotType === "partial"}
|
||||
>
|
||||
</ha-radio>
|
||||
</ha-formfield>
|
||||
</div>`
|
||||
: ""}
|
||||
${this.snapshot && this.snapshotType === "partial"
|
||||
? html`
|
||||
${this.snapshot.homeassistant
|
||||
? html`
|
||||
<ha-formfield
|
||||
.label=${html`<supervisor-formfield-label
|
||||
label="Home Assistant"
|
||||
.iconPath=${mdiHomeAssistant}
|
||||
.version=${this.snapshot.homeassistant}
|
||||
>
|
||||
</supervisor-formfield-label>`}
|
||||
>
|
||||
<ha-checkbox
|
||||
.checked=${this.homeAssistant}
|
||||
@click=${() => {
|
||||
this.homeAssistant = !this.homeAssistant;
|
||||
}}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</ha-formfield>
|
||||
`
|
||||
: ""}
|
||||
`
|
||||
: ""}
|
||||
${this.snapshotType === "partial"
|
||||
? html`
|
||||
${foldersSection?.templates.length
|
||||
? html`
|
||||
<ha-formfield
|
||||
.label=${html`<supervisor-formfield-label
|
||||
.label=${this.supervisor.localize("snapshot.folders")}
|
||||
.iconPath=${mdiFolder}
|
||||
>
|
||||
</supervisor-formfield-label>`}
|
||||
>
|
||||
<ha-checkbox
|
||||
@change=${this._toggleSection}
|
||||
.checked=${foldersSection.checked}
|
||||
.indeterminate=${foldersSection.indeterminate}
|
||||
.section=${"folders"}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</ha-formfield>
|
||||
<div class="section-content">${foldersSection.templates}</div>
|
||||
`
|
||||
: ""}
|
||||
${addonsSection?.templates.length
|
||||
? html`
|
||||
<ha-formfield
|
||||
.label=${html`<supervisor-formfield-label
|
||||
.label=${this.supervisor.localize("snapshot.addons")}
|
||||
.iconPath=${mdiPuzzle}
|
||||
>
|
||||
</supervisor-formfield-label>`}
|
||||
>
|
||||
<ha-checkbox
|
||||
@change=${this._toggleSection}
|
||||
.checked=${addonsSection.checked}
|
||||
.indeterminate=${addonsSection.indeterminate}
|
||||
.section=${"addons"}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</ha-formfield>
|
||||
<div class="section-content">${addonsSection.templates}</div>
|
||||
`
|
||||
: ""}
|
||||
`
|
||||
: ""}
|
||||
${!this.snapshot
|
||||
? html`<ha-formfield
|
||||
.label=${this.supervisor.localize("snapshot.password_protection")}
|
||||
>
|
||||
<ha-checkbox
|
||||
.checked=${this.snapshotHasPassword}
|
||||
@change=${this._toggleHasPassword}
|
||||
>
|
||||
</ha-checkbox
|
||||
></ha-formfield>`
|
||||
: ""}
|
||||
${this.snapshotHasPassword
|
||||
? html`
|
||||
<paper-input
|
||||
.label=${this.supervisor.localize("snapshot.password")}
|
||||
type="password"
|
||||
name="snapshotPassword"
|
||||
.value=${this.snapshotPassword}
|
||||
@value-changed=${this._handleTextValueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
`
|
||||
: ""}
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
ha-checkbox {
|
||||
--mdc-checkbox-touch-target-size: 16px;
|
||||
display: block;
|
||||
margin: 4px 12px 8px 0;
|
||||
}
|
||||
ha-formfield {
|
||||
display: contents;
|
||||
}
|
||||
supervisor-formfield-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
paper-input[type="password"] {
|
||||
display: block;
|
||||
margin: 4px 0 4px 16px;
|
||||
}
|
||||
.details {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.section-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 16px;
|
||||
}
|
||||
.security {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.snapshot-types {
|
||||
display: flex;
|
||||
}
|
||||
.sub-header {
|
||||
margin-top: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
public snapshotDetails():
|
||||
| HassioPartialSnapshotCreateParams
|
||||
| HassioFullSnapshotCreateParams {
|
||||
const data: any = {};
|
||||
|
||||
if (!this.snapshot) {
|
||||
data.name = this.snapshotName || formatDate(new Date(), this.hass.locale);
|
||||
}
|
||||
|
||||
if (this.snapshotHasPassword) {
|
||||
data.password = this.snapshotPassword;
|
||||
}
|
||||
|
||||
if (this.snapshotType === "full") {
|
||||
return data;
|
||||
}
|
||||
|
||||
const addons = this.addons
|
||||
?.filter((addon) => addon.checked)
|
||||
.map((addon) => addon.slug);
|
||||
const folders = this.folders
|
||||
?.filter((folder) => folder.checked)
|
||||
.map((folder) => folder.slug);
|
||||
|
||||
if (addons?.length) {
|
||||
data.addons = addons;
|
||||
}
|
||||
if (folders?.length) {
|
||||
data.folders = folders;
|
||||
}
|
||||
if (this.homeAssistant) {
|
||||
data.homeassistant = this.homeAssistant;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private _getSection(section: string) {
|
||||
const templates: TemplateResult[] = [];
|
||||
const addons =
|
||||
section === "addons"
|
||||
? new Map(
|
||||
this.supervisor!.addon.addons.map((item) => [item.slug, item])
|
||||
)
|
||||
: undefined;
|
||||
let checkedItems = 0;
|
||||
this[section].forEach((item) => {
|
||||
templates.push(html`<ha-formfield
|
||||
.label=${html`<supervisor-formfield-label
|
||||
.label=${item.name}
|
||||
.iconPath=${section === "addons" ? mdiPuzzle : mdiFolder}
|
||||
.imageUrl=${section === "addons" &&
|
||||
atLeastVersion(this.hass.config.version, 0, 105) &&
|
||||
addons?.get(item.slug)?.icon
|
||||
? `/api/hassio/addons/${item.slug}/icon`
|
||||
: undefined}
|
||||
.version=${item.version}
|
||||
>
|
||||
</supervisor-formfield-label>`}
|
||||
>
|
||||
<ha-checkbox
|
||||
.item=${item}
|
||||
.checked=${item.checked}
|
||||
.section=${section}
|
||||
@change=${this._updateSectionEntry}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</ha-formfield>`);
|
||||
|
||||
if (item.checked) {
|
||||
checkedItems++;
|
||||
}
|
||||
});
|
||||
|
||||
const checked = checkedItems === this[section].length;
|
||||
|
||||
return {
|
||||
templates,
|
||||
checked,
|
||||
indeterminate: !checked && checkedItems !== 0,
|
||||
};
|
||||
}
|
||||
|
||||
private _handleRadioValueChanged(ev: CustomEvent) {
|
||||
const input = ev.currentTarget as HaRadio;
|
||||
this[input.name] = input.value;
|
||||
}
|
||||
|
||||
private _handleTextValueChanged(ev: PolymerChangedEvent<string>) {
|
||||
const input = ev.currentTarget as PaperInputElement;
|
||||
this[input.name!] = ev.detail.value;
|
||||
}
|
||||
|
||||
private _toggleHasPassword(): void {
|
||||
this.snapshotHasPassword = !this.snapshotHasPassword;
|
||||
}
|
||||
|
||||
private _toggleSection(ev): void {
|
||||
const section = ev.currentTarget.section;
|
||||
|
||||
this[section] = (section === "addons" ? this.addons : this.folders)!.map(
|
||||
(item) => ({
|
||||
...item,
|
||||
checked: ev.currentTarget.checked,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _updateSectionEntry(ev): void {
|
||||
const item = ev.currentTarget.item;
|
||||
const section = ev.currentTarget.section;
|
||||
this[section] = this[section].map((entry) =>
|
||||
entry.slug === item.slug
|
||||
? {
|
||||
...entry,
|
||||
checked: ev.currentTarget.checked,
|
||||
}
|
||||
: entry
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"supervisor-snapshot-content": SupervisorSnapshotContent;
|
||||
}
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
import { mdiArrowUpBoldCircle, mdiPuzzle } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { navigate } from "../../../src/common/navigate";
|
||||
import { compare } from "../../../src/common/string/compare";
|
||||
@ -90,7 +83,7 @@ class HassioAddons extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
@ -103,11 +96,11 @@ class HassioAddons extends LitElement {
|
||||
}
|
||||
|
||||
private _addonTapped(ev: any): void {
|
||||
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}/info`);
|
||||
navigate(`/hassio/addon/${ev.currentTarget.addon.slug}/info`);
|
||||
}
|
||||
|
||||
private _openStore(): void {
|
||||
navigate(this, "/hassio/store");
|
||||
navigate("/hassio/store");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import "../../../src/layouts/hass-tabs-subpage";
|
||||
import { haStyle } from "../../../src/resources/styles";
|
||||
@ -53,7 +46,7 @@ class HassioDashboard extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
|
@ -1,14 +1,7 @@
|
||||
import "@material/mwc-button";
|
||||
import { mdiHomeAssistant } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
@ -233,7 +226,7 @@ export class HassioUpdate extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,13 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-markdown";
|
||||
import { haStyleDialog } from "../../../../src/resources/styles";
|
||||
@ -23,7 +15,7 @@ class HassioMarkdownDialog extends LitElement {
|
||||
|
||||
@property() public content!: string;
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
public showDialog(params: HassioMarkdownDialogParams) {
|
||||
this.title = params.title;
|
||||
@ -50,7 +42,7 @@ class HassioMarkdownDialog extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
hassioStyle,
|
||||
|
@ -6,17 +6,9 @@ import "@material/mwc-tab";
|
||||
import "@material/mwc-tab-bar";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { cache } from "lit-html/directives/cache";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { cache } from "lit/directives/cache";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
@ -54,23 +46,23 @@ export class DialogHassioNetwork
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _accessPoints?: AccessPoints;
|
||||
@state() private _accessPoints?: AccessPoints;
|
||||
|
||||
@internalProperty() private _curTabIndex = 0;
|
||||
@state() private _curTabIndex = 0;
|
||||
|
||||
@internalProperty() private _dirty = false;
|
||||
@state() private _dirty = false;
|
||||
|
||||
@internalProperty() private _interface?: NetworkInterface;
|
||||
@state() private _interface?: NetworkInterface;
|
||||
|
||||
@internalProperty() private _interfaces!: NetworkInterface[];
|
||||
@state() private _interfaces!: NetworkInterface[];
|
||||
|
||||
@internalProperty() private _params?: HassioNetworkDialogParams;
|
||||
@state() private _params?: HassioNetworkDialogParams;
|
||||
|
||||
@internalProperty() private _processing = false;
|
||||
@state() private _processing = false;
|
||||
|
||||
@internalProperty() private _scanning = false;
|
||||
@state() private _scanning = false;
|
||||
|
||||
@internalProperty() private _wifiConfiguration?: WifiConfiguration;
|
||||
@state() private _wifiConfiguration?: WifiConfiguration;
|
||||
|
||||
public async showDialog(params: HassioNetworkDialogParams): Promise<void> {
|
||||
this._params = params;
|
||||
@ -543,7 +535,7 @@ export class DialogHassioNetwork
|
||||
this._wifiConfiguration![id] = value;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
|
@ -3,16 +3,8 @@ import "@material/mwc-icon-button/mwc-icon-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDelete } from "@mdi/js";
|
||||
import { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
@ -39,21 +31,21 @@ class HassioRegistriesDialog extends LitElement {
|
||||
username: string;
|
||||
}[];
|
||||
|
||||
@internalProperty() private _registry?: string;
|
||||
@state() private _registry?: string;
|
||||
|
||||
@internalProperty() private _username?: string;
|
||||
@state() private _username?: string;
|
||||
|
||||
@internalProperty() private _password?: string;
|
||||
@state() private _password?: string;
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
@internalProperty() private _addingRegistry = false;
|
||||
@state() private _addingRegistry = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-dialog
|
||||
.open=${this._opened}
|
||||
@closing=${this.closeDialog}
|
||||
@closed=${this.closeDialog}
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
.heading=${createCloseHeading(
|
||||
@ -220,7 +212,7 @@ class HassioRegistriesDialog extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
|
@ -5,17 +5,8 @@ import "@polymer/paper-input/paper-input";
|
||||
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
@ -37,15 +28,15 @@ class HassioRepositoriesDialog extends LitElement {
|
||||
|
||||
@query("#repository_input", true) private _optionInput?: PaperInputElement;
|
||||
|
||||
@internalProperty() private _repositories?: HassioAddonRepository[];
|
||||
@state() private _repositories?: HassioAddonRepository[];
|
||||
|
||||
@internalProperty() private _dialogParams?: HassioRepositoryDialogParams;
|
||||
@state() private _dialogParams?: HassioRepositoryDialogParams;
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
@internalProperty() private _processing = false;
|
||||
@state() private _processing = false;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
public async showDialog(
|
||||
dialogParams: HassioRepositoryDialogParams
|
||||
@ -76,7 +67,7 @@ class HassioRepositoriesDialog extends LitElement {
|
||||
return html`
|
||||
<ha-dialog
|
||||
.open=${this._opened}
|
||||
@closing=${this.closeDialog}
|
||||
@closed=${this.closeDialog}
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
.heading=${createCloseHeading(
|
||||
@ -137,7 +128,7 @@ class HassioRepositoriesDialog extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
|
142
hassio/src/dialogs/snapshot/dialog-hassio-create-snapshot.ts
Executable file
142
hassio/src/dialogs/snapshot/dialog-hassio-create-snapshot.ts
Executable file
@ -0,0 +1,142 @@
|
||||
import "@material/mwc-button";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||
import {
|
||||
createHassioFullSnapshot,
|
||||
createHassioPartialSnapshot,
|
||||
} from "../../../../src/data/hassio/snapshot";
|
||||
import { showAlertDialog } from "../../../../src/dialogs/generic/show-dialog-box";
|
||||
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/supervisor-snapshot-content";
|
||||
import type { SupervisorSnapshotContent } from "../../components/supervisor-snapshot-content";
|
||||
import { HassioCreateSnapshotDialogParams } from "./show-dialog-hassio-create-snapshot";
|
||||
|
||||
@customElement("dialog-hassio-create-snapshot")
|
||||
class HassioCreateSnapshotDialog extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _dialogParams?: HassioCreateSnapshotDialogParams;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
@state() private _creatingSnapshot = false;
|
||||
|
||||
@query("supervisor-snapshot-content")
|
||||
private _snapshotContent!: SupervisorSnapshotContent;
|
||||
|
||||
public showDialog(params: HassioCreateSnapshotDialogParams) {
|
||||
this._dialogParams = params;
|
||||
this._creatingSnapshot = false;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._dialogParams = undefined;
|
||||
this._creatingSnapshot = false;
|
||||
this._error = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._dialogParams) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this._dialogParams.supervisor.localize("snapshot.create_snapshot")
|
||||
)}
|
||||
>
|
||||
${this._creatingSnapshot
|
||||
? html` <ha-circular-progress active></ha-circular-progress>`
|
||||
: html`<supervisor-snapshot-content
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this._dialogParams.supervisor}
|
||||
>
|
||||
</supervisor-snapshot-content>`}
|
||||
${this._error ? html`<p class="error">Error: ${this._error}</p>` : ""}
|
||||
<mwc-button slot="secondaryAction" @click=${this.closeDialog}>
|
||||
${this._dialogParams.supervisor.localize("common.close")}
|
||||
</mwc-button>
|
||||
<mwc-button
|
||||
.disabled=${this._creatingSnapshot}
|
||||
slot="primaryAction"
|
||||
@click=${this._createSnapshot}
|
||||
>
|
||||
${this._dialogParams.supervisor.localize("snapshot.create")}
|
||||
</mwc-button>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _createSnapshot(): Promise<void> {
|
||||
if (this._dialogParams!.supervisor.info.state !== "running") {
|
||||
showAlertDialog(this, {
|
||||
title: this._dialogParams!.supervisor.localize(
|
||||
"snapshot.could_not_create"
|
||||
),
|
||||
text: this._dialogParams!.supervisor.localize(
|
||||
"snapshot.create_blocked_not_running",
|
||||
"state",
|
||||
this._dialogParams!.supervisor.info.state
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
const snapshotDetails = this._snapshotContent.snapshotDetails();
|
||||
this._creatingSnapshot = true;
|
||||
|
||||
this._error = "";
|
||||
if (
|
||||
this._snapshotContent.snapshotHasPassword &&
|
||||
!this._snapshotContent.snapshotPassword.length
|
||||
) {
|
||||
this._error = this._dialogParams!.supervisor.localize(
|
||||
"snapshot.enter_password"
|
||||
);
|
||||
this._creatingSnapshot = false;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this._snapshotContent.snapshotType === "full") {
|
||||
await createHassioFullSnapshot(this.hass, snapshotDetails);
|
||||
} else {
|
||||
await createHassioPartialSnapshot(this.hass, snapshotDetails);
|
||||
}
|
||||
|
||||
this._dialogParams!.onCreate();
|
||||
this.closeDialog();
|
||||
} catch (err) {
|
||||
this._error = extractApiErrorMessage(err);
|
||||
}
|
||||
this._creatingSnapshot = false;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-circular-progress {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-hassio-create-snapshot": HassioCreateSnapshotDialog;
|
||||
}
|
||||
}
|
@ -1,14 +1,6 @@
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-header-bar";
|
||||
import { HassDialog } from "../../../../src/dialogs/make-dialog-manager";
|
||||
@ -23,7 +15,7 @@ export class DialogHassioSnapshotUpload
|
||||
implements HassDialog<HassioSnapshotUploadDialogParams> {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@internalProperty() private _params?: HassioSnapshotUploadDialogParams;
|
||||
@state() private _params?: HassioSnapshotUploadDialogParams;
|
||||
|
||||
public async showDialog(
|
||||
params: HassioSnapshotUploadDialogParams
|
||||
@ -78,7 +70,7 @@ export class DialogHassioSnapshotUpload
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
|
@ -1,20 +1,12 @@
|
||||
import "@material/mwc-button";
|
||||
import { mdiClose, mdiDelete, mdiDownload, mdiHistory } from "@mdi/js";
|
||||
import "@polymer/paper-checkbox/paper-checkbox";
|
||||
import type { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { ActionDetail } from "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-header-bar";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-button-menu";
|
||||
import { createCloseHeading } from "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import { getSignedPath } from "../../../../src/data/auth";
|
||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||
@ -22,95 +14,46 @@ import {
|
||||
fetchHassioSnapshotInfo,
|
||||
HassioSnapshotDetail,
|
||||
} from "../../../../src/data/hassio/snapshot";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../../src/dialogs/generic/show-dialog-box";
|
||||
import { PolymerChangedEvent } from "../../../../src/polymer-types";
|
||||
import { HassDialog } from "../../../../src/dialogs/make-dialog-manager";
|
||||
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
|
||||
import { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/supervisor-snapshot-content";
|
||||
import type { SupervisorSnapshotContent } from "../../components/supervisor-snapshot-content";
|
||||
import { HassioSnapshotDialogParams } from "./show-dialog-hassio-snapshot";
|
||||
|
||||
const _computeFolders = (folders) => {
|
||||
const list: Array<{ slug: string; name: string; checked: boolean }> = [];
|
||||
if (folders.includes("homeassistant")) {
|
||||
list.push({
|
||||
slug: "homeassistant",
|
||||
name: "Home Assistant configuration",
|
||||
checked: true,
|
||||
});
|
||||
}
|
||||
if (folders.includes("ssl")) {
|
||||
list.push({ slug: "ssl", name: "SSL", checked: true });
|
||||
}
|
||||
if (folders.includes("share")) {
|
||||
list.push({ slug: "share", name: "Share", checked: true });
|
||||
}
|
||||
if (folders.includes("addons/local")) {
|
||||
list.push({ slug: "addons/local", name: "Local add-ons", checked: true });
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
const _computeAddons = (addons) =>
|
||||
addons.map((addon) => ({
|
||||
slug: addon.slug,
|
||||
name: addon.name,
|
||||
version: addon.version,
|
||||
checked: true,
|
||||
}));
|
||||
|
||||
interface AddonItem {
|
||||
slug: string;
|
||||
name: string;
|
||||
version: string;
|
||||
checked: boolean | null | undefined;
|
||||
}
|
||||
|
||||
interface FolderItem {
|
||||
slug: string;
|
||||
name: string;
|
||||
checked: boolean | null | undefined;
|
||||
}
|
||||
|
||||
@customElement("dialog-hassio-snapshot")
|
||||
class HassioSnapshotDialog extends LitElement {
|
||||
class HassioSnapshotDialog
|
||||
extends LitElement
|
||||
implements HassDialog<HassioSnapshotDialogParams> {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public supervisor?: Supervisor;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _snapshot?: HassioSnapshotDetail;
|
||||
|
||||
@internalProperty() private _onboarding = false;
|
||||
@state() private _dialogParams?: HassioSnapshotDialogParams;
|
||||
|
||||
@internalProperty() private _snapshot?: HassioSnapshotDetail;
|
||||
@state() private _restoringSnapshot = false;
|
||||
|
||||
@internalProperty() private _folders!: FolderItem[];
|
||||
|
||||
@internalProperty() private _addons!: AddonItem[];
|
||||
|
||||
@internalProperty() private _dialogParams?: HassioSnapshotDialogParams;
|
||||
|
||||
@internalProperty() private _snapshotPassword!: string;
|
||||
|
||||
@internalProperty() private _restoreHass = true;
|
||||
@query("supervisor-snapshot-content")
|
||||
private _snapshotContent!: SupervisorSnapshotContent;
|
||||
|
||||
public async showDialog(params: HassioSnapshotDialogParams) {
|
||||
this._snapshot = await fetchHassioSnapshotInfo(this.hass, params.slug);
|
||||
this._folders = _computeFolders(
|
||||
this._snapshot?.folders
|
||||
).sort((a: FolderItem, b: FolderItem) => (a.name > b.name ? 1 : -1));
|
||||
this._addons = _computeAddons(
|
||||
this._snapshot?.addons
|
||||
).sort((a: AddonItem, b: AddonItem) => (a.name > b.name ? 1 : -1));
|
||||
|
||||
this._dialogParams = params;
|
||||
this._onboarding = params.onboarding ?? false;
|
||||
this.supervisor = params.supervisor;
|
||||
if (!this._snapshot.homeassistant) {
|
||||
this._restoreHass = false;
|
||||
}
|
||||
this._restoringSnapshot = false;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._snapshot = undefined;
|
||||
this._dialogParams = undefined;
|
||||
this._restoringSnapshot = false;
|
||||
this._error = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
@ -118,202 +61,92 @@ class HassioSnapshotDialog extends LitElement {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<ha-dialog open @closing=${this._closeDialog} .heading=${true}>
|
||||
<div slot="heading">
|
||||
<ha-header-bar>
|
||||
<span slot="title"> ${this._computeName} </span>
|
||||
<mwc-icon-button slot="actionItems" dialogAction="cancel">
|
||||
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
</ha-header-bar>
|
||||
</div>
|
||||
<div class="details">
|
||||
${this._snapshot.type === "full"
|
||||
? "Full snapshot"
|
||||
: "Partial snapshot"}
|
||||
(${this._computeSize})<br />
|
||||
${this._formatDatetime(this._snapshot.date)}
|
||||
</div>
|
||||
${this._snapshot.homeassistant
|
||||
? html`<div>Home Assistant:</div>
|
||||
<paper-checkbox
|
||||
.checked=${this._restoreHass}
|
||||
@change="${(ev: Event) => {
|
||||
this._restoreHass = (ev.target as PaperCheckboxElement).checked!;
|
||||
}}"
|
||||
>
|
||||
Home Assistant ${this._snapshot.homeassistant}
|
||||
</paper-checkbox>`
|
||||
: ""}
|
||||
${this._folders.length
|
||||
? html`
|
||||
<div>Folders:</div>
|
||||
<paper-dialog-scrollable class="no-margin-top">
|
||||
${this._folders.map(
|
||||
(item) => html`
|
||||
<paper-checkbox
|
||||
.checked=${item.checked}
|
||||
@change="${(ev: Event) =>
|
||||
this._updateFolders(
|
||||
item,
|
||||
(ev.target as PaperCheckboxElement).checked
|
||||
)}"
|
||||
>
|
||||
${item.name}
|
||||
</paper-checkbox>
|
||||
`
|
||||
)}
|
||||
</paper-dialog-scrollable>
|
||||
`
|
||||
: ""}
|
||||
${this._addons.length
|
||||
? html`
|
||||
<div>Add-on:</div>
|
||||
<paper-dialog-scrollable class="no-margin-top">
|
||||
${this._addons.map(
|
||||
(item) => html`
|
||||
<paper-checkbox
|
||||
.checked=${item.checked}
|
||||
@change="${(ev: Event) =>
|
||||
this._updateAddons(
|
||||
item,
|
||||
(ev.target as PaperCheckboxElement).checked
|
||||
)}"
|
||||
>
|
||||
${item.name}
|
||||
</paper-checkbox>
|
||||
`
|
||||
)}
|
||||
</paper-dialog-scrollable>
|
||||
`
|
||||
: ""}
|
||||
${this._snapshot.protected
|
||||
? html`
|
||||
<paper-input
|
||||
autofocus=""
|
||||
label="Password"
|
||||
type="password"
|
||||
@value-changed=${this._passwordInput}
|
||||
.value=${this._snapshotPassword}
|
||||
></paper-input>
|
||||
`
|
||||
: ""}
|
||||
${this._error ? html` <p class="error">Error: ${this._error}</p> ` : ""}
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(this.hass, this._computeName)}
|
||||
>
|
||||
${this._restoringSnapshot
|
||||
? html` <ha-circular-progress active></ha-circular-progress>`
|
||||
: html`<supervisor-snapshot-content
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this._dialogParams.supervisor}
|
||||
.snapshot=${this._snapshot}
|
||||
>
|
||||
</supervisor-snapshot-content>`}
|
||||
${this._error ? html`<p class="error">Error: ${this._error}</p>` : ""}
|
||||
|
||||
<div class="button-row" slot="primaryAction">
|
||||
<mwc-button @click=${this._partialRestoreClicked}>
|
||||
<ha-svg-icon .path=${mdiHistory} class="icon"></ha-svg-icon>
|
||||
Restore Selected
|
||||
</mwc-button>
|
||||
${!this._onboarding
|
||||
? html`
|
||||
<mwc-button @click=${this._deleteClicked}>
|
||||
<ha-svg-icon .path=${mdiDelete} class="icon warning">
|
||||
</ha-svg-icon>
|
||||
<span class="warning">Delete Snapshot</span>
|
||||
</mwc-button>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
<div class="button-row" slot="secondaryAction">
|
||||
${this._snapshot.type === "full"
|
||||
? html`
|
||||
<mwc-button @click=${this._fullRestoreClicked}>
|
||||
<ha-svg-icon .path=${mdiHistory} class="icon"></ha-svg-icon>
|
||||
Restore Everything
|
||||
</mwc-button>
|
||||
`
|
||||
: ""}
|
||||
${!this._onboarding
|
||||
? html`<mwc-button @click=${this._downloadClicked}>
|
||||
<ha-svg-icon .path=${mdiDownload} class="icon"></ha-svg-icon>
|
||||
Download Snapshot
|
||||
</mwc-button>`
|
||||
: ""}
|
||||
</div>
|
||||
<mwc-button
|
||||
.disabled=${this._restoringSnapshot}
|
||||
slot="secondaryAction"
|
||||
@click=${this._restoreClicked}
|
||||
>
|
||||
Restore
|
||||
</mwc-button>
|
||||
|
||||
<ha-button-menu
|
||||
fixed
|
||||
slot="primaryAction"
|
||||
@action=${this._handleMenuAction}
|
||||
@closed=${(ev: Event) => ev.stopPropagation()}
|
||||
>
|
||||
<mwc-icon-button slot="trigger" alt="menu">
|
||||
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
<mwc-list-item>Download Snapshot</mwc-list-item>
|
||||
<mwc-list-item class="error">Delete Snapshot</mwc-list-item>
|
||||
</ha-button-menu>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
paper-checkbox {
|
||||
ha-svg-icon {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
ha-circular-progress {
|
||||
display: block;
|
||||
margin: 4px;
|
||||
}
|
||||
mwc-button ha-svg-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
.button-row {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.details {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.warning,
|
||||
.error {
|
||||
color: var(--error-color);
|
||||
}
|
||||
.buttons li {
|
||||
list-style-type: none;
|
||||
}
|
||||
.buttons .icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.no-margin-top {
|
||||
margin-top: 0;
|
||||
}
|
||||
ha-header-bar {
|
||||
--mdc-theme-on-primary: var(--primary-text-color);
|
||||
--mdc-theme-primary: var(--mdc-theme-surface);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* overrule the ha-style-dialog max-height on small screens */
|
||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||
ha-header-bar {
|
||||
--mdc-theme-primary: var(--app-header-background-color);
|
||||
--mdc-theme-on-primary: var(--app-header-text-color, white);
|
||||
}
|
||||
text-align: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
private _updateFolders(item: FolderItem, value: boolean | null | undefined) {
|
||||
this._folders = this._folders.map((folder) => {
|
||||
if (folder.slug === item.slug) {
|
||||
folder.checked = value;
|
||||
}
|
||||
return folder;
|
||||
});
|
||||
private _handleMenuAction(ev: CustomEvent<ActionDetail>) {
|
||||
switch (ev.detail.index) {
|
||||
case 0:
|
||||
this._downloadClicked();
|
||||
break;
|
||||
case 1:
|
||||
this._deleteClicked();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private _updateAddons(item: AddonItem, value: boolean | null | undefined) {
|
||||
this._addons = this._addons.map((addon) => {
|
||||
if (addon.slug === item.slug) {
|
||||
addon.checked = value;
|
||||
}
|
||||
return addon;
|
||||
});
|
||||
private async _restoreClicked() {
|
||||
const snapshotDetails = this._snapshotContent.snapshotDetails();
|
||||
this._restoringSnapshot = true;
|
||||
if (this._snapshotContent.snapshotType === "full") {
|
||||
await this._fullRestoreClicked(snapshotDetails);
|
||||
} else {
|
||||
await this._partialRestoreClicked(snapshotDetails);
|
||||
}
|
||||
this._restoringSnapshot = false;
|
||||
}
|
||||
|
||||
private _passwordInput(ev: PolymerChangedEvent<string>) {
|
||||
this._snapshotPassword = ev.detail.value;
|
||||
}
|
||||
|
||||
private async _partialRestoreClicked() {
|
||||
private async _partialRestoreClicked(snapshotDetails) {
|
||||
if (
|
||||
this.supervisor !== undefined &&
|
||||
this.supervisor.info.state !== "running"
|
||||
this._dialogParams?.supervisor !== undefined &&
|
||||
this._dialogParams?.supervisor.info.state !== "running"
|
||||
) {
|
||||
await showAlertDialog(this, {
|
||||
title: "Could not restore snapshot",
|
||||
text: `Restoring a snapshot is not possible right now because the system is in ${this.supervisor.info.state} state.`,
|
||||
text: `Restoring a snapshot is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -327,41 +160,17 @@ class HassioSnapshotDialog extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const addons = this._addons
|
||||
.filter((addon) => addon.checked)
|
||||
.map((addon) => addon.slug);
|
||||
|
||||
const folders = this._folders
|
||||
.filter((folder) => folder.checked)
|
||||
.map((folder) => folder.slug);
|
||||
|
||||
const data: {
|
||||
homeassistant: boolean;
|
||||
addons: any;
|
||||
folders: any;
|
||||
password?: string;
|
||||
} = {
|
||||
homeassistant: this._restoreHass,
|
||||
addons,
|
||||
folders,
|
||||
};
|
||||
|
||||
if (this._snapshot!.protected) {
|
||||
data.password = this._snapshotPassword;
|
||||
}
|
||||
|
||||
if (!this._onboarding) {
|
||||
if (!this._dialogParams?.onboarding) {
|
||||
this.hass
|
||||
.callApi(
|
||||
"POST",
|
||||
|
||||
`hassio/snapshots/${this._snapshot!.slug}/restore/partial`,
|
||||
data
|
||||
snapshotDetails
|
||||
)
|
||||
.then(
|
||||
() => {
|
||||
alert("Snapshot restored!");
|
||||
this._closeDialog();
|
||||
this.closeDialog();
|
||||
},
|
||||
(error) => {
|
||||
this._error = error.body.message;
|
||||
@ -371,20 +180,20 @@ class HassioSnapshotDialog extends LitElement {
|
||||
fireEvent(this, "restoring");
|
||||
fetch(`/api/hassio/snapshots/${this._snapshot!.slug}/restore/partial`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
body: JSON.stringify(snapshotDetails),
|
||||
});
|
||||
this._closeDialog();
|
||||
this.closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
private async _fullRestoreClicked() {
|
||||
private async _fullRestoreClicked(snapshotDetails) {
|
||||
if (
|
||||
this.supervisor !== undefined &&
|
||||
this.supervisor.info.state !== "running"
|
||||
this._dialogParams?.supervisor !== undefined &&
|
||||
this._dialogParams?.supervisor.info.state !== "running"
|
||||
) {
|
||||
await showAlertDialog(this, {
|
||||
title: "Could not restore snapshot",
|
||||
text: `Restoring a snapshot is not possible right now because the system is in ${this.supervisor.info.state} state.`,
|
||||
text: `Restoring a snapshot is not possible right now because the system is in ${this._dialogParams?.supervisor.info.state} state.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
@ -399,20 +208,16 @@ class HassioSnapshotDialog extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = this._snapshot!.protected
|
||||
? { password: this._snapshotPassword }
|
||||
: undefined;
|
||||
if (!this._onboarding) {
|
||||
if (!this._dialogParams?.onboarding) {
|
||||
this.hass
|
||||
.callApi(
|
||||
"POST",
|
||||
`hassio/snapshots/${this._snapshot!.slug}/restore/full`,
|
||||
data
|
||||
snapshotDetails
|
||||
)
|
||||
.then(
|
||||
() => {
|
||||
alert("Snapshot restored!");
|
||||
this._closeDialog();
|
||||
this.closeDialog();
|
||||
},
|
||||
(error) => {
|
||||
this._error = error.body.message;
|
||||
@ -422,9 +227,9 @@ class HassioSnapshotDialog extends LitElement {
|
||||
fireEvent(this, "restoring");
|
||||
fetch(`/api/hassio/snapshots/${this._snapshot!.slug}/restore/full`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
body: JSON.stringify(snapshotDetails),
|
||||
});
|
||||
this._closeDialog();
|
||||
this.closeDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +252,7 @@ class HassioSnapshotDialog extends LitElement {
|
||||
if (this._dialogParams!.onDelete) {
|
||||
this._dialogParams!.onDelete();
|
||||
}
|
||||
this._closeDialog();
|
||||
this.closeDialog();
|
||||
},
|
||||
(error) => {
|
||||
this._error = error.body.message;
|
||||
@ -463,7 +268,9 @@ class HassioSnapshotDialog extends LitElement {
|
||||
`/api/hassio/snapshots/${this._snapshot!.slug}/download`
|
||||
);
|
||||
} catch (err) {
|
||||
alert(`Error: ${extractApiErrorMessage(err)}`);
|
||||
await showAlertDialog(this, {
|
||||
text: extractApiErrorMessage(err),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -494,29 +301,6 @@ class HassioSnapshotDialog extends LitElement {
|
||||
? this._snapshot.name || this._snapshot.slug
|
||||
: "Unnamed snapshot";
|
||||
}
|
||||
|
||||
private get _computeSize() {
|
||||
return Math.ceil(this._snapshot!.size * 10) / 10 + " MB";
|
||||
}
|
||||
|
||||
private _formatDatetime(datetime) {
|
||||
return new Date(datetime).toLocaleDateString(navigator.language, {
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "2-digit",
|
||||
});
|
||||
}
|
||||
|
||||
private _closeDialog() {
|
||||
this._dialogParams = undefined;
|
||||
this._snapshot = undefined;
|
||||
this._snapshotPassword = "";
|
||||
this._folders = [];
|
||||
this._addons = [];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -0,0 +1,18 @@
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
|
||||
export interface HassioCreateSnapshotDialogParams {
|
||||
supervisor: Supervisor;
|
||||
onCreate: () => void;
|
||||
}
|
||||
|
||||
export const showHassioCreateSnapshotDialog = (
|
||||
element: HTMLElement,
|
||||
dialogParams: HassioCreateSnapshotDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-hassio-create-snapshot",
|
||||
dialogImport: () => import("./dialog-hassio-create-snapshot"),
|
||||
dialogParams,
|
||||
});
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
import type { LitElement } from "lit-element";
|
||||
import type { LitElement } from "lit";
|
||||
import {
|
||||
HassioAddonDetails,
|
||||
restartHassioAddon,
|
||||
|
@ -1,13 +1,6 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-circular-progress";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
@ -27,15 +20,15 @@ import { SupervisorDialogSupervisorUpdateParams } from "./show-dialog-update";
|
||||
class DialogSupervisorUpdate extends LitElement {
|
||||
public hass!: HomeAssistant;
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
@state() private _opened = false;
|
||||
|
||||
@internalProperty() private _createSnapshot = true;
|
||||
@state() private _createSnapshot = true;
|
||||
|
||||
@internalProperty() private _action: "snapshot" | "update" | null = null;
|
||||
@state() private _action: "snapshot" | "update" | null = null;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty()
|
||||
@state()
|
||||
private _dialogParams?: SupervisorDialogSupervisorUpdateParams;
|
||||
|
||||
public async showDialog(
|
||||
@ -173,7 +166,7 @@ class DialogSupervisorUpdate extends LitElement {
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
|
@ -15,5 +15,11 @@ body {
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #111111;
|
||||
color: #e1e1e1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleEl);
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { customElement, html, property, PropertyValues } from "lit-element";
|
||||
import { html, PropertyValues } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../src/common/config/version";
|
||||
import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../src/common/dom/fire_event";
|
||||
import { isNavigationClick } from "../../src/common/dom/is-navigation-click";
|
||||
import { mainWindow } from "../../src/common/dom/get_main_window";
|
||||
import { navigate } from "../../src/common/navigate";
|
||||
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
||||
import { Supervisor } from "../../src/data/supervisor/supervisor";
|
||||
import { makeDialogManager } from "../../src/dialogs/make-dialog-manager";
|
||||
@ -46,14 +50,23 @@ export class HassioMain extends SupervisorBaseElement {
|
||||
// listen on this element for navigation events, so we need to forward them.
|
||||
|
||||
// Joakim - April 26, 2021
|
||||
// Due to changes in behavior in Google Chrome, we changed navigate to fire on the top element
|
||||
top.addEventListener("location-changed", (ev) =>
|
||||
// Due to changes in behavior in Google Chrome, we changed navigate to listen on the top element
|
||||
mainWindow.addEventListener("location-changed", (ev) =>
|
||||
// @ts-ignore
|
||||
fireEvent(this, ev.type, ev.detail, {
|
||||
bubbles: false,
|
||||
})
|
||||
);
|
||||
|
||||
// Paulus - May 17, 2021
|
||||
// Convert the <a> tags to native nav in Home Assistant < 2021.6
|
||||
document.body.addEventListener("click", (ev) => {
|
||||
const href = isNavigationClick(ev);
|
||||
if (href) {
|
||||
navigate(href);
|
||||
}
|
||||
});
|
||||
|
||||
// Forward haptic events to parent window.
|
||||
window.addEventListener("haptic", (ev) => {
|
||||
// @ts-ignore
|
||||
@ -90,25 +103,27 @@ export class HassioMain extends SupervisorBaseElement {
|
||||
|
||||
private _applyTheme() {
|
||||
let themeName: string;
|
||||
let options: Partial<HomeAssistant["selectedTheme"]> | undefined;
|
||||
let themeSettings:
|
||||
| Partial<HomeAssistant["selectedThemeSettings"]>
|
||||
| undefined;
|
||||
|
||||
if (atLeastVersion(this.hass.config.version, 0, 114)) {
|
||||
themeName =
|
||||
this.hass.selectedTheme?.theme ||
|
||||
this.hass.selectedThemeSettings?.theme ||
|
||||
(this.hass.themes.darkMode && this.hass.themes.default_dark_theme
|
||||
? this.hass.themes.default_dark_theme!
|
||||
: this.hass.themes.default_theme);
|
||||
|
||||
options = this.hass.selectedTheme;
|
||||
if (themeName === "default" && options?.dark === undefined) {
|
||||
options = {
|
||||
...this.hass.selectedTheme,
|
||||
themeSettings = this.hass.selectedThemeSettings;
|
||||
if (themeSettings?.dark === undefined) {
|
||||
themeSettings = {
|
||||
...this.hass.selectedThemeSettings,
|
||||
dark: this.hass.themes.darkMode,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
themeName =
|
||||
((this.hass.selectedTheme as unknown) as string) ||
|
||||
((this.hass.selectedThemeSettings as unknown) as string) ||
|
||||
this.hass.themes.default_theme;
|
||||
}
|
||||
|
||||
@ -116,7 +131,7 @@ export class HassioMain extends SupervisorBaseElement {
|
||||
this.parentElement,
|
||||
this.hass.themes,
|
||||
themeName,
|
||||
options
|
||||
themeSettings
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,4 @@
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { html, LitElement, TemplateResult } from "lit";
|
||||
import { sanitizeUrl } from "@braintree/sanitize-url";
|
||||
import {
|
||||
createSearchParam,
|
||||
@ -20,6 +13,7 @@ import {
|
||||
import { navigate } from "../../src/common/navigate";
|
||||
import { HomeAssistant, Route } from "../../src/types";
|
||||
import { Supervisor } from "../../src/data/supervisor/supervisor";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
|
||||
const REDIRECTS: Redirects = {
|
||||
supervisor: {
|
||||
@ -43,6 +37,12 @@ const REDIRECTS: Redirects = {
|
||||
addon: "string",
|
||||
},
|
||||
},
|
||||
supervisor_ingress: {
|
||||
redirect: "/hassio/ingress",
|
||||
params: {
|
||||
addon: "string",
|
||||
},
|
||||
},
|
||||
supervisor_add_addon_repository: {
|
||||
redirect: "/hassio/store",
|
||||
params: {
|
||||
@ -59,7 +59,7 @@ class HassioMyRedirect extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@internalProperty() public _error?: TemplateResult | string;
|
||||
@state() public _error?: TemplateResult | string;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
@ -89,7 +89,7 @@ class HassioMyRedirect extends LitElement {
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(this, url, true);
|
||||
navigate(url, { replace: true });
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { customElement, property } from "lit-element";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { Supervisor } from "../../src/data/supervisor/supervisor";
|
||||
import {
|
||||
HassRouterPage,
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import {
|
||||
Supervisor,
|
||||
supervisorCollection,
|
||||
@ -46,7 +39,7 @@ class HassioPanel extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
:host {
|
||||
--app-header-background-color: var(--sidebar-background-color);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { customElement, property } from "lit-element";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { HassioPanelInfo } from "../../src/data/hassio/supervisor";
|
||||
import { Supervisor } from "../../src/data/supervisor/supervisor";
|
||||
import {
|
||||
@ -61,11 +61,10 @@ class HassioRouter extends HassRouterPage {
|
||||
el.hass = this.hass;
|
||||
el.narrow = this.narrow;
|
||||
el.route = route;
|
||||
el.supervisor = this.supervisor;
|
||||
|
||||
if (el.localName === "hassio-ingress-view") {
|
||||
el.ingressPanel = this.panel.config && this.panel.config.ingress;
|
||||
} else {
|
||||
el.supervisor = this.supervisor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,27 @@
|
||||
import { mdiMenu } from "@mdi/js";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import { navigate } from "../../../src/common/navigate";
|
||||
import { extractSearchParam } from "../../../src/common/url/search-params";
|
||||
import { nextRender } from "../../../src/common/util/render-status";
|
||||
import {
|
||||
fetchHassioAddonInfo,
|
||||
HassioAddonDetails,
|
||||
} from "../../../src/data/hassio/addon";
|
||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||
import {
|
||||
createHassioSession,
|
||||
validateHassioSession,
|
||||
} from "../../../src/data/hassio/ingress";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||
import "../../../src/layouts/hass-loading-screen";
|
||||
import "../../../src/layouts/hass-subpage";
|
||||
@ -29,11 +31,13 @@ import { HomeAssistant, Route } from "../../../src/types";
|
||||
class HassioIngressView extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@property() public route!: Route;
|
||||
|
||||
@property() public ingressPanel = false;
|
||||
|
||||
@internalProperty() private _addon?: HassioAddonDetails;
|
||||
@state() private _addon?: HassioAddonDetails;
|
||||
|
||||
@property({ type: Boolean })
|
||||
public narrow = false;
|
||||
@ -80,6 +84,36 @@ class HassioIngressView extends LitElement {
|
||||
: iframe}`;
|
||||
}
|
||||
|
||||
protected async firstUpdated(): Promise<void> {
|
||||
if (this.route.path === "") {
|
||||
const requestedAddon = extractSearchParam("addon");
|
||||
let addonInfo: HassioAddonDetails;
|
||||
if (requestedAddon) {
|
||||
try {
|
||||
addonInfo = await fetchHassioAddonInfo(this.hass, requestedAddon);
|
||||
} catch (err) {
|
||||
await showAlertDialog(this, {
|
||||
text: extractApiErrorMessage(err),
|
||||
title: requestedAddon,
|
||||
});
|
||||
await nextRender();
|
||||
history.back();
|
||||
return;
|
||||
}
|
||||
if (!addonInfo.ingress) {
|
||||
await showAlertDialog(this, {
|
||||
text: this.supervisor.localize("my.error_addon_no_ingress"),
|
||||
title: addonInfo.name,
|
||||
});
|
||||
await nextRender();
|
||||
history.back();
|
||||
} else {
|
||||
navigate(`/hassio/ingress/${addonInfo.slug}`, { replace: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
super.updated(changedProps);
|
||||
|
||||
@ -109,6 +143,7 @@ class HassioIngressView extends LitElement {
|
||||
text: "Unable to fetch add-on info to start Ingress",
|
||||
title: "Supervisor",
|
||||
});
|
||||
await nextRender();
|
||||
history.back();
|
||||
return;
|
||||
}
|
||||
@ -118,6 +153,7 @@ class HassioIngressView extends LitElement {
|
||||
text: "Add-on does not support Ingress",
|
||||
title: addon.name,
|
||||
});
|
||||
await nextRender();
|
||||
history.back();
|
||||
return;
|
||||
}
|
||||
@ -127,7 +163,8 @@ class HassioIngressView extends LitElement {
|
||||
text: "Add-on is not running. Please start it first",
|
||||
title: addon.name,
|
||||
});
|
||||
navigate(this, `/hassio/addon/${addon.slug}/info`, true);
|
||||
await nextRender();
|
||||
navigate(`/hassio/addon/${addon.slug}/info`, { replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -140,6 +177,7 @@ class HassioIngressView extends LitElement {
|
||||
text: "Unable to create an Ingress session",
|
||||
title: addon.name,
|
||||
});
|
||||
await nextRender();
|
||||
history.back();
|
||||
return;
|
||||
}
|
||||
@ -162,7 +200,7 @@ class HassioIngressView extends LitElement {
|
||||
fireEvent(this, "hass-toggle-menu");
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
iframe {
|
||||
display: block;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { css } from "lit-element";
|
||||
import { css } from "lit";
|
||||
|
||||
export const hassioStyle = css`
|
||||
.content {
|
||||
|
@ -1,118 +1,163 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-icon-button";
|
||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import { ActionDetail } from "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical, mdiPlus } from "@mdi/js";
|
||||
import {
|
||||
mdiDotsVertical,
|
||||
mdiPackageVariant,
|
||||
mdiPackageVariantClosed,
|
||||
} from "@mdi/js";
|
||||
import "@polymer/paper-checkbox/paper-checkbox";
|
||||
import type { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-radio-button/paper-radio-button";
|
||||
import "@polymer/paper-radio-group/paper-radio-group";
|
||||
import type { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group";
|
||||
import {
|
||||
css,
|
||||
CSSResultArray,
|
||||
customElement,
|
||||
CSSResultGroup,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
} from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-svg-icon";
|
||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||
import relativeTime from "../../../src/common/datetime/relative_time";
|
||||
import { HASSDomEvent } from "../../../src/common/dom/fire_event";
|
||||
import {
|
||||
DataTableColumnContainer,
|
||||
RowClickedEvent,
|
||||
} from "../../../src/components/data-table/ha-data-table";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-fab";
|
||||
import {
|
||||
createHassioFullSnapshot,
|
||||
createHassioPartialSnapshot,
|
||||
fetchHassioSnapshots,
|
||||
HassioFullSnapshotCreateParams,
|
||||
HassioPartialSnapshotCreateParams,
|
||||
friendlyFolderName,
|
||||
HassioSnapshot,
|
||||
reloadHassioSnapshots,
|
||||
} from "../../../src/data/hassio/snapshot";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box";
|
||||
import "../../../src/layouts/hass-tabs-subpage";
|
||||
import { PolymerChangedEvent } from "../../../src/polymer-types";
|
||||
import "../../../src/layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../src/resources/styles";
|
||||
import { HomeAssistant, Route } from "../../../src/types";
|
||||
import "../components/hassio-card-content";
|
||||
import "../components/hassio-upload-snapshot";
|
||||
import { showHassioCreateSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-create-snapshot";
|
||||
import { showHassioSnapshotDialog } from "../dialogs/snapshot/show-dialog-hassio-snapshot";
|
||||
import { showSnapshotUploadDialog } from "../dialogs/snapshot/show-dialog-snapshot-upload";
|
||||
import { supervisorTabs } from "../hassio-tabs";
|
||||
import { hassioStyle } from "../resources/hassio-style";
|
||||
|
||||
interface CheckboxItem {
|
||||
slug: string;
|
||||
checked: boolean;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
@customElement("hassio-snapshots")
|
||||
class HassioSnapshots extends LitElement {
|
||||
export class HassioSnapshots extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ type: Boolean }) public narrow!: boolean;
|
||||
|
||||
@property({ attribute: false }) public route!: Route;
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _snapshotName = "";
|
||||
@property({ type: Object }) public route!: Route;
|
||||
|
||||
@internalProperty() private _snapshotPassword = "";
|
||||
@property({ type: Boolean }) public narrow!: boolean;
|
||||
|
||||
@internalProperty() private _snapshotHasPassword = false;
|
||||
@property({ type: Boolean }) public isWide!: boolean;
|
||||
|
||||
@internalProperty() private _snapshotType: HassioSnapshot["type"] = "full";
|
||||
private _firstUpdatedCalled = false;
|
||||
|
||||
@internalProperty() private _snapshots?: HassioSnapshot[] = [];
|
||||
@state() private _snapshots?: HassioSnapshot[] = [];
|
||||
|
||||
@internalProperty() private _addonList: CheckboxItem[] = [];
|
||||
|
||||
@internalProperty() private _folderList: CheckboxItem[] = [
|
||||
{
|
||||
slug: "homeassistant",
|
||||
checked: true,
|
||||
},
|
||||
{ slug: "ssl", checked: true },
|
||||
{ slug: "share", checked: true },
|
||||
{ slug: "media", checked: true },
|
||||
{ slug: "addons/local", checked: true },
|
||||
];
|
||||
|
||||
@internalProperty() private _error = "";
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
if (this.hass && this._firstUpdatedCalled) {
|
||||
this.refreshData();
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshData() {
|
||||
await reloadHassioSnapshots(this.hass);
|
||||
await this._updateSnapshots();
|
||||
await this.fetchSnapshots();
|
||||
}
|
||||
|
||||
private _computeSnapshotContent = (snapshot: HassioSnapshot): string => {
|
||||
if (snapshot.type === "full") {
|
||||
return this.supervisor.localize("snapshot.full_snapshot");
|
||||
}
|
||||
const content: string[] = [];
|
||||
if (snapshot.content.homeassistant) {
|
||||
content.push("Home Assistant");
|
||||
}
|
||||
if (snapshot.content.folders.length !== 0) {
|
||||
for (const folder of snapshot.content.folders) {
|
||||
content.push(friendlyFolderName[folder] || folder);
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot.content.addons.length !== 0) {
|
||||
for (const addon of snapshot.content.addons) {
|
||||
content.push(
|
||||
this.supervisor.supervisor.addons.find(
|
||||
(entry) => entry.slug === addon
|
||||
)?.name || addon
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return content.join(", ");
|
||||
};
|
||||
|
||||
protected firstUpdated(changedProperties: PropertyValues): void {
|
||||
super.firstUpdated(changedProperties);
|
||||
if (this.hass && this.isConnected) {
|
||||
this.refreshData();
|
||||
}
|
||||
this._firstUpdatedCalled = true;
|
||||
}
|
||||
|
||||
private _columns = memoizeOne(
|
||||
(narrow: boolean): DataTableColumnContainer => ({
|
||||
name: {
|
||||
title: this.supervisor?.localize("snapshot.name") || "",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
grows: true,
|
||||
template: (entry: string, snapshot: any) =>
|
||||
html`${entry || snapshot.slug}
|
||||
<div class="secondary">${snapshot.secondary}</div>`,
|
||||
},
|
||||
date: {
|
||||
title: this.supervisor?.localize("snapshot.created") || "",
|
||||
width: "15%",
|
||||
direction: "desc",
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
sortable: true,
|
||||
template: (entry: string) =>
|
||||
relativeTime(new Date(entry), this.hass.localize),
|
||||
},
|
||||
secondary: {
|
||||
title: "",
|
||||
hidden: true,
|
||||
filterable: true,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
private _snapshotData = memoizeOne((snapshots: HassioSnapshot[]) =>
|
||||
snapshots.map((snapshot) => ({
|
||||
...snapshot,
|
||||
secondary: this._computeSnapshotContent(snapshot),
|
||||
}))
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.supervisor) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
<hass-tabs-subpage-data-table
|
||||
.tabs=${supervisorTabs}
|
||||
.hass=${this.hass}
|
||||
.localizeFunc=${this.supervisor.localize}
|
||||
.searchLabel=${this.supervisor.localize("search")}
|
||||
.noDataText=${this.supervisor.localize("snapshot.no_snapshots")}
|
||||
.narrow=${this.narrow}
|
||||
.route=${this.route}
|
||||
.tabs=${supervisorTabs}
|
||||
.columns=${this._columns(this.narrow)}
|
||||
.data=${this._snapshotData(this._snapshots || [])}
|
||||
id="slug"
|
||||
@row-click=${this._handleRowClicked}
|
||||
clickable
|
||||
hasFab
|
||||
main-page
|
||||
supervisor
|
||||
>
|
||||
<span slot="header">
|
||||
${this.supervisor.localize("panel.snapshots")}
|
||||
</span>
|
||||
<ha-button-menu
|
||||
corner="BOTTOM_START"
|
||||
slot="toolbar-icon"
|
||||
@ -122,172 +167,27 @@ class HassioSnapshots extends LitElement {
|
||||
<ha-svg-icon .path=${mdiDotsVertical}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
<mwc-list-item>
|
||||
${this.supervisor.localize("common.reload")}
|
||||
${this.supervisor?.localize("common.reload")}
|
||||
</mwc-list-item>
|
||||
${atLeastVersion(this.hass.config.version, 0, 116)
|
||||
? html`<mwc-list-item>
|
||||
${this.supervisor.localize("snapshot.upload_snapshot")}
|
||||
${this.supervisor?.localize("snapshot.upload_snapshot")}
|
||||
</mwc-list-item>`
|
||||
: ""}
|
||||
</ha-button-menu>
|
||||
|
||||
<div class="content">
|
||||
<h1>${this.supervisor.localize("snapshot.create_snapshot")}</h1>
|
||||
<p class="description">
|
||||
${this.supervisor.localize("snapshot.description")}
|
||||
</p>
|
||||
<div class="card-group">
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
autofocus
|
||||
.label=${this.supervisor.localize("snapshot.name")}
|
||||
name="snapshotName"
|
||||
.value=${this._snapshotName}
|
||||
@value-changed=${this._handleTextValueChanged}
|
||||
></paper-input>
|
||||
${this.supervisor.localize("snapshot.type")}:
|
||||
<paper-radio-group
|
||||
name="snapshotType"
|
||||
type="${this.supervisor.localize("snapshot.type")}"
|
||||
.selected=${this._snapshotType}
|
||||
@selected-changed=${this._handleRadioValueChanged}
|
||||
>
|
||||
<paper-radio-button name="full">
|
||||
${this.supervisor.localize("snapshot.full_snapshot")}
|
||||
</paper-radio-button>
|
||||
<paper-radio-button name="partial">
|
||||
${this.supervisor.localize("snapshot.partial_snapshot")}
|
||||
</paper-radio-button>
|
||||
</paper-radio-group>
|
||||
${this._snapshotType === "full"
|
||||
? undefined
|
||||
: html`
|
||||
${this.supervisor.localize("snapshot.folders")}:
|
||||
${this._folderList.map(
|
||||
(folder, idx) => html`
|
||||
<paper-checkbox
|
||||
.idx=${idx}
|
||||
.checked=${folder.checked}
|
||||
@checked-changed=${this._folderChecked}
|
||||
>
|
||||
${this.supervisor.localize(
|
||||
`snapshot.folder.${folder.slug}`
|
||||
)}
|
||||
</paper-checkbox>
|
||||
`
|
||||
)}
|
||||
${this.supervisor.localize("snapshot.addons")}:
|
||||
${this._addonList.map(
|
||||
(addon, idx) => html`
|
||||
<paper-checkbox
|
||||
.idx=${idx}
|
||||
.checked=${addon.checked}
|
||||
@checked-changed=${this._addonChecked}
|
||||
>
|
||||
${addon.name}
|
||||
</paper-checkbox>
|
||||
`
|
||||
)}
|
||||
`}
|
||||
${this.supervisor.localize("snapshot.security")}:
|
||||
<paper-checkbox
|
||||
name="snapshotHasPassword"
|
||||
.checked=${this._snapshotHasPassword}
|
||||
@checked-changed=${this._handleCheckboxValueChanged}
|
||||
>
|
||||
${this.supervisor.localize("snapshot.password_protection")}
|
||||
</paper-checkbox>
|
||||
${this._snapshotHasPassword
|
||||
? html`
|
||||
<paper-input
|
||||
.label=${this.supervisor.localize("snapshot.password")}
|
||||
type="password"
|
||||
name="snapshotPassword"
|
||||
.value=${this._snapshotPassword}
|
||||
@value-changed=${this._handleTextValueChanged}
|
||||
></paper-input>
|
||||
`
|
||||
: undefined}
|
||||
${this._error !== ""
|
||||
? html` <p class="error">${this._error}</p> `
|
||||
: undefined}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-progress-button
|
||||
@click=${this._createSnapshot}
|
||||
.title=${this.supervisor.info.state !== "running"
|
||||
? this.supervisor.localize(
|
||||
"snapshot.create_blocked_not_running",
|
||||
"state",
|
||||
this.supervisor.info.state
|
||||
)
|
||||
: ""}
|
||||
.disabled=${this.supervisor.info.state !== "running"}
|
||||
>
|
||||
${this.supervisor.localize("snapshot.create")}
|
||||
</ha-progress-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
</div>
|
||||
|
||||
<h1>${this.supervisor.localize("snapshot.available_snapshots")}</h1>
|
||||
<div class="card-group">
|
||||
${this._snapshots === undefined
|
||||
? undefined
|
||||
: this._snapshots.length === 0
|
||||
? html`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
${this.supervisor.localize("snapshot.no_snapshots")}
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: this._snapshots.map(
|
||||
(snapshot) => html`
|
||||
<ha-card
|
||||
class="pointer"
|
||||
.snapshot=${snapshot}
|
||||
@click=${this._snapshotClicked}
|
||||
>
|
||||
<div class="card-content">
|
||||
<hassio-card-content
|
||||
.hass=${this.hass}
|
||||
.title=${snapshot.name || snapshot.slug}
|
||||
.description=${this._computeDetails(snapshot)}
|
||||
.datetime=${snapshot.date}
|
||||
.icon=${snapshot.type === "full"
|
||||
? mdiPackageVariantClosed
|
||||
: mdiPackageVariant}
|
||||
icon-class="snapshot"
|
||||
></hassio-card-content>
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</hass-tabs-subpage>
|
||||
<ha-fab
|
||||
slot="fab"
|
||||
@click=${this._createSnapshot}
|
||||
.label=${this.supervisor.localize("snapshot.create_snapshot")}
|
||||
extended
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
|
||||
</ha-fab>
|
||||
</hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
if (changedProps.has("supervisor")) {
|
||||
this._addonList = this.supervisor.supervisor.addons
|
||||
.map((addon) => ({
|
||||
slug: addon.slug,
|
||||
name: addon.name,
|
||||
checked: true,
|
||||
}))
|
||||
.sort((a, b) => (a.name < b.name ? -1 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
private _handleAction(ev: CustomEvent<ActionDetail>) {
|
||||
switch (ev.detail.index) {
|
||||
case 0:
|
||||
@ -299,157 +199,52 @@ class HassioSnapshots extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleTextValueChanged(ev: PolymerChangedEvent<string>) {
|
||||
const input = ev.currentTarget as PaperInputElement;
|
||||
this[`_${input.name}`] = ev.detail.value;
|
||||
}
|
||||
|
||||
private _handleCheckboxValueChanged(ev) {
|
||||
const input = ev.currentTarget as PaperCheckboxElement;
|
||||
this[`_${input.name}`] = input.checked;
|
||||
}
|
||||
|
||||
private _handleRadioValueChanged(ev: PolymerChangedEvent<string>) {
|
||||
const input = ev.currentTarget as PaperRadioGroupElement;
|
||||
this[`_${input.getAttribute("name")}`] = ev.detail.value;
|
||||
}
|
||||
|
||||
private _folderChecked(ev) {
|
||||
const { idx, checked } = ev.currentTarget!;
|
||||
this._folderList = this._folderList.map((folder, curIdx) =>
|
||||
curIdx === idx ? { ...folder, checked } : folder
|
||||
);
|
||||
}
|
||||
|
||||
private _addonChecked(ev) {
|
||||
const { idx, checked } = ev.currentTarget!;
|
||||
this._addonList = this._addonList.map((addon, curIdx) =>
|
||||
curIdx === idx ? { ...addon, checked } : addon
|
||||
);
|
||||
}
|
||||
|
||||
private async _updateSnapshots() {
|
||||
try {
|
||||
this._snapshots = await fetchHassioSnapshots(this.hass);
|
||||
this._snapshots.sort((a, b) => (a.date < b.date ? 1 : -1));
|
||||
} catch (err) {
|
||||
this._error = extractApiErrorMessage(err);
|
||||
}
|
||||
}
|
||||
|
||||
private async _createSnapshot(ev: CustomEvent): Promise<void> {
|
||||
if (this.supervisor.info.state !== "running") {
|
||||
await showAlertDialog(this, {
|
||||
title: this.supervisor.localize("snapshot.could_not_create"),
|
||||
text: this.supervisor.localize(
|
||||
"snapshot.create_blocked_not_running",
|
||||
"state",
|
||||
this.supervisor.info.state
|
||||
),
|
||||
});
|
||||
}
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
|
||||
this._error = "";
|
||||
if (this._snapshotHasPassword && !this._snapshotPassword.length) {
|
||||
this._error = this.supervisor.localize("snapshot.enter_password");
|
||||
button.progress = false;
|
||||
return;
|
||||
}
|
||||
await this.updateComplete;
|
||||
|
||||
const name =
|
||||
this._snapshotName ||
|
||||
new Date().toLocaleDateString(navigator.language, {
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
try {
|
||||
if (this._snapshotType === "full") {
|
||||
const data: HassioFullSnapshotCreateParams = { name };
|
||||
if (this._snapshotHasPassword) {
|
||||
data.password = this._snapshotPassword;
|
||||
}
|
||||
await createHassioFullSnapshot(this.hass, data);
|
||||
} else {
|
||||
const addons = this._addonList
|
||||
.filter((addon) => addon.checked)
|
||||
.map((addon) => addon.slug);
|
||||
const folders = this._folderList
|
||||
.filter((folder) => folder.checked)
|
||||
.map((folder) => folder.slug);
|
||||
|
||||
const data: HassioPartialSnapshotCreateParams = {
|
||||
name,
|
||||
folders,
|
||||
addons,
|
||||
};
|
||||
if (this._snapshotHasPassword) {
|
||||
data.password = this._snapshotPassword;
|
||||
}
|
||||
await createHassioPartialSnapshot(this.hass, data);
|
||||
}
|
||||
this._updateSnapshots();
|
||||
} catch (err) {
|
||||
this._error = extractApiErrorMessage(err);
|
||||
}
|
||||
button.progress = false;
|
||||
}
|
||||
|
||||
private _computeDetails(snapshot: HassioSnapshot) {
|
||||
const type =
|
||||
snapshot.type === "full"
|
||||
? this.supervisor.localize("snapshot.full_snapshot")
|
||||
: this.supervisor.localize("snapshot.partial_snapshot");
|
||||
return snapshot.protected ? `${type}, password protected` : type;
|
||||
}
|
||||
|
||||
private _snapshotClicked(ev) {
|
||||
showHassioSnapshotDialog(this, {
|
||||
slug: ev.currentTarget!.snapshot.slug,
|
||||
supervisor: this.supervisor,
|
||||
onDelete: () => this._updateSnapshots(),
|
||||
});
|
||||
}
|
||||
|
||||
private _showUploadSnapshotDialog() {
|
||||
showSnapshotUploadDialog(this, {
|
||||
showSnapshot: (slug: string) =>
|
||||
showHassioSnapshotDialog(this, {
|
||||
slug,
|
||||
supervisor: this.supervisor,
|
||||
onDelete: () => this._updateSnapshots(),
|
||||
onDelete: () => this.fetchSnapshots(),
|
||||
}),
|
||||
reloadSnapshot: () => this.refreshData(),
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
css`
|
||||
paper-radio-group {
|
||||
display: block;
|
||||
}
|
||||
paper-radio-button {
|
||||
padding: 0 0 2px 2px;
|
||||
}
|
||||
paper-radio-button,
|
||||
paper-checkbox,
|
||||
paper-input[type="password"] {
|
||||
display: block;
|
||||
margin: 4px 0 4px 48px;
|
||||
}
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
`,
|
||||
];
|
||||
private async fetchSnapshots() {
|
||||
await reloadHassioSnapshots(this.hass);
|
||||
this._snapshots = await fetchHassioSnapshots(this.hass);
|
||||
}
|
||||
|
||||
private _handleRowClicked(ev: HASSDomEvent<RowClickedEvent>) {
|
||||
const slug = ev.detail.id;
|
||||
showHassioSnapshotDialog(this, {
|
||||
slug,
|
||||
supervisor: this.supervisor,
|
||||
onDelete: () => this.fetchSnapshots(),
|
||||
});
|
||||
}
|
||||
|
||||
private _createSnapshot() {
|
||||
if (this.supervisor!.info.state !== "running") {
|
||||
showAlertDialog(this, {
|
||||
title: this.supervisor!.localize("snapshot.could_not_create"),
|
||||
text: this.supervisor!.localize(
|
||||
"snapshot.create_blocked_not_running",
|
||||
"state",
|
||||
this.supervisor!.info.state
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
showHassioCreateSnapshotDialog(this, {
|
||||
supervisor: this.supervisor!,
|
||||
onCreate: () => this.fetchSnapshots(),
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [haStyle, hassioStyle];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { Collection, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { LitElement, PropertyValues } from "lit";
|
||||
import { property, state } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../src/common/config/version";
|
||||
import { computeLocalize } from "../../src/common/translations/localize";
|
||||
import { fetchHassioAddonsInfo } from "../../src/data/hassio/addon";
|
||||
@ -46,14 +42,11 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
||||
localize: () => "",
|
||||
};
|
||||
|
||||
@internalProperty() private _unsubs: Record<string, UnsubscribeFunc> = {};
|
||||
@state() private _unsubs: Record<string, UnsubscribeFunc> = {};
|
||||
|
||||
@internalProperty() private _collections: Record<
|
||||
string,
|
||||
Collection<unknown>
|
||||
> = {};
|
||||
@state() private _collections: Record<string, Collection<unknown>> = {};
|
||||
|
||||
@internalProperty() private _language = "en";
|
||||
@state() private _language = "en";
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
@ -1,15 +1,7 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
@ -39,7 +31,7 @@ class HassioCoreInfo extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _metrics?: HassioStats;
|
||||
@state() private _metrics?: HassioStats;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
const metrics = [
|
||||
@ -189,7 +181,7 @@ class HassioCoreInfo extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -2,16 +2,9 @@ import "@material/mwc-button";
|
||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import { safeDump } from "js-yaml";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { dump } from "js-yaml";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
@ -240,7 +233,7 @@ class HassioHostInfo extends LitElement {
|
||||
const content = await fetchHassioHardwareInfo(this.hass);
|
||||
showHassioMarkdownDialog(this, {
|
||||
title: this.supervisor.localize("system.host.hardware"),
|
||||
content: `<pre>${safeDump(content, { indent: 2 })}</pre>`,
|
||||
content: `<pre>${dump(content, { indent: 2 })}</pre>`,
|
||||
});
|
||||
} catch (err) {
|
||||
showAlertDialog(this, {
|
||||
@ -415,7 +408,7 @@ class HassioHostInfo extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,13 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
@ -67,7 +59,7 @@ class HassioSupervisorInfo extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _metrics?: HassioStats;
|
||||
@state() private _metrics?: HassioStats;
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
const metrics = [
|
||||
@ -504,7 +496,7 @@ class HassioSupervisorInfo extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -2,16 +2,8 @@ import "@material/mwc-button";
|
||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../src/components/ha-card";
|
||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||
@ -61,11 +53,11 @@ class HassioSupervisorLog extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
@state() private _error?: string;
|
||||
|
||||
@internalProperty() private _selectedLogProvider = "supervisor";
|
||||
@state() private _selectedLogProvider = "supervisor";
|
||||
|
||||
@internalProperty() private _content?: string;
|
||||
@state() private _content?: string;
|
||||
|
||||
public async connectedCallback(): Promise<void> {
|
||||
super.connectedCallback();
|
||||
@ -146,7 +138,7 @@ class HassioSupervisorLog extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
@ -1,12 +1,5 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
import "../../../src/layouts/hass-tabs-subpage";
|
||||
import { haStyle } from "../../../src/resources/styles";
|
||||
@ -64,7 +57,7 @@ class HassioSystem extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
hassioStyle,
|
||||
|
5
lint-staged.config.js
Normal file
5
lint-staged.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
"*.ts": () => "tsc -p tsconfig.json",
|
||||
"*.{js,ts}": "eslint --fix",
|
||||
"!(/translations)*.{js,ts,json,css,md,html}": "prettier --write",
|
||||
};
|
132
package.json
132
package.json
@ -16,13 +16,13 @@
|
||||
"lint:lit": "lit-analyzer \"**/src/**/*.ts\" --format markdown --outFile result.md",
|
||||
"lint": "yarn run lint:eslint && yarn run lint:prettier && yarn run lint:types",
|
||||
"format": "yarn run format:eslint && yarn run format:prettier",
|
||||
"mocha": "node_modules/.bin/ts-mocha -p test-mocha/tsconfig.test.json --opts test-mocha/mocha.opts",
|
||||
"mocha": "ts-mocha -p test-mocha/tsconfig.test.json \"test-mocha/**/*.ts\"",
|
||||
"test": "yarn run lint && yarn run mocha"
|
||||
},
|
||||
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^5.0.0",
|
||||
"@braintree/sanitize-url": "^5.0.1",
|
||||
"@codemirror/commands": "^0.18.0",
|
||||
"@codemirror/gutter": "^0.18.0",
|
||||
"@codemirror/highlight": "^0.18.0",
|
||||
@ -34,33 +34,34 @@
|
||||
"@codemirror/stream-parser": "^0.18.0",
|
||||
"@codemirror/text": "^0.18.0",
|
||||
"@codemirror/view": "^0.18.0",
|
||||
"@formatjs/intl-getcanonicallocales": "^1.4.6",
|
||||
"@formatjs/intl-pluralrules": "^3.4.10",
|
||||
"@formatjs/intl-getcanonicallocales": "^1.5.10",
|
||||
"@formatjs/intl-locale": "^2.4.28",
|
||||
"@formatjs/intl-pluralrules": "^4.0.22",
|
||||
"@fullcalendar/common": "5.1.0",
|
||||
"@fullcalendar/core": "5.1.0",
|
||||
"@fullcalendar/daygrid": "5.1.0",
|
||||
"@fullcalendar/interaction": "5.1.0",
|
||||
"@fullcalendar/list": "5.1.0",
|
||||
"@material/chips": "=9.0.0-canary.1c156d69d.0",
|
||||
"@material/mwc-button": "^0.20.0",
|
||||
"@material/mwc-checkbox": "^0.20.0",
|
||||
"@material/mwc-circular-progress": "^0.20.0",
|
||||
"@material/mwc-dialog": "^0.20.0",
|
||||
"@material/mwc-fab": "^0.20.0",
|
||||
"@material/mwc-formfield": "^0.20.0",
|
||||
"@material/mwc-icon-button": "^0.20.0",
|
||||
"@material/mwc-list": "^0.20.0",
|
||||
"@material/mwc-menu": "^0.20.0",
|
||||
"@material/mwc-radio": "^0.20.0",
|
||||
"@material/mwc-ripple": "^0.20.0",
|
||||
"@material/mwc-switch": "^0.20.0",
|
||||
"@material/mwc-tab": "^0.20.0",
|
||||
"@material/mwc-tab-bar": "^0.20.0",
|
||||
"@material/top-app-bar": "=9.0.0-canary.1c156d69d.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/top-app-bar": "=12.0.0-canary.1a8d06483.0",
|
||||
"@mdi/js": "5.9.55",
|
||||
"@mdi/svg": "5.9.55",
|
||||
"@polymer/app-layout": "^3.0.2",
|
||||
"@polymer/app-route": "^3.0.2",
|
||||
"@polymer/app-storage": "^3.0.2",
|
||||
"@polymer/iron-autogrow-textarea": "^3.0.1",
|
||||
"@polymer/iron-flex-layout": "^3.0.1",
|
||||
@ -98,29 +99,28 @@
|
||||
"@vibrant/quantizer-mmcq": "^3.2.1-alpha.1",
|
||||
"@vue/web-component-wrapper": "^1.2.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.2.7",
|
||||
"chart.js": "~2.8.0",
|
||||
"chartjs-chart-timeline": "^0.3.0",
|
||||
"comlink": "^4.3.0",
|
||||
"chart.js": "^2.9.4",
|
||||
"chartjs-chart-timeline": "^0.4.0",
|
||||
"comlink": "^4.3.1",
|
||||
"core-js": "^3.6.5",
|
||||
"cropperjs": "^1.5.7",
|
||||
"cropperjs": "^1.5.11",
|
||||
"deep-clone-simple": "^1.1.1",
|
||||
"deep-freeze": "^0.0.1",
|
||||
"fecha": "^4.2.0",
|
||||
"fuse.js": "^6.0.0",
|
||||
"google-timezones-json": "^1.0.2",
|
||||
"hls.js": "^1.0.1",
|
||||
"home-assistant-js-websocket": "^5.9.0",
|
||||
"idb-keyval": "^3.2.0",
|
||||
"intl-messageformat": "^8.3.9",
|
||||
"js-yaml": "^3.13.1",
|
||||
"leaflet": "^1.4.0",
|
||||
"hls.js": "^1.0.4",
|
||||
"home-assistant-js-websocket": "^5.10.0",
|
||||
"idb-keyval": "^5.0.5",
|
||||
"intl-messageformat": "^9.6.16",
|
||||
"js-yaml": "^4.1.0",
|
||||
"leaflet": "^1.7.1",
|
||||
"leaflet-draw": "^1.0.4",
|
||||
"lit-element": "^2.5.0",
|
||||
"lit-html": "^1.4.0",
|
||||
"lit-virtualizer": "^0.4.2",
|
||||
"marked": "2.0.0",
|
||||
"lit": "^2.0.0-rc.2",
|
||||
"lit-vaadin-helpers": "^0.1.3",
|
||||
"marked": "^2.0.5",
|
||||
"mdn-polyfills": "^5.16.0",
|
||||
"memoize-one": "^5.0.2",
|
||||
"memoize-one": "^5.2.1",
|
||||
"node-vibrant": "3.2.1-alpha.1",
|
||||
"proxy-polyfill": "^0.3.1",
|
||||
"punycode": "^2.1.1",
|
||||
@ -129,13 +129,13 @@
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"roboto-fontface": "^0.10.0",
|
||||
"sortablejs": "^1.10.2",
|
||||
"superstruct": "^0.10.13",
|
||||
"tinykeys": "^1.1.1",
|
||||
"superstruct": "^0.15.2",
|
||||
"tinykeys": "^1.1.3",
|
||||
"tsparticles": "^1.19.2",
|
||||
"unfetch": "^4.1.0",
|
||||
"vis-data": "^7.1.1",
|
||||
"vis-data": "^7.1.2",
|
||||
"vis-network": "^8.5.4",
|
||||
"vue": "^2.6.11",
|
||||
"vue": "^2.6.12",
|
||||
"vue2-daterange-picker": "^0.5.1",
|
||||
"web-animations-js": "^2.3.2",
|
||||
"workbox-cacheable-response": "^6.1.5",
|
||||
@ -144,10 +144,10 @@
|
||||
"workbox-precaching": "^6.1.5",
|
||||
"workbox-routing": "^6.1.5",
|
||||
"workbox-strategies": "^6.1.5",
|
||||
"xss": "^1.0.6"
|
||||
"xss": "^1.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.0",
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/plugin-external-helpers": "^7.12.13",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.13.15",
|
||||
@ -156,7 +156,7 @@
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.13.12",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
||||
"@babel/preset-env": "^7.14.0",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@koa/cors": "^3.1.0",
|
||||
"@open-wc/dev-server-hmr": "^0.0.2",
|
||||
@ -165,16 +165,13 @@
|
||||
"@rollup/plugin-json": "^4.0.3",
|
||||
"@rollup/plugin-node-resolve": "^7.1.3",
|
||||
"@rollup/plugin-replace": "^2.3.2",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/chromecast-caf-receiver": "^5.0.11",
|
||||
"@types/chromecast-caf-receiver": "5.0.12",
|
||||
"@types/chromecast-caf-sender": "^1.0.3",
|
||||
"@types/js-yaml": "^3.12.1",
|
||||
"@types/leaflet": "^1.4.3",
|
||||
"@types/leaflet-draw": "^1.0.1",
|
||||
"@types/marked": "^1.2.2",
|
||||
"@types/memoize-one": "4.1.0",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/resize-observer-browser": "^0.1.3",
|
||||
"@types/js-yaml": "^4.0.1",
|
||||
"@types/leaflet": "^1.7.0",
|
||||
"@types/leaflet-draw": "^1.0.3",
|
||||
"@types/marked": "^2.0.3",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@types/sortablejs": "^1.10.6",
|
||||
"@types/webspeechapi": "^0.0.29",
|
||||
"@typescript-eslint/eslint-plugin": "^4.22.0",
|
||||
@ -182,7 +179,7 @@
|
||||
"@web/dev-server": "^0.0.24",
|
||||
"@web/dev-server-rollup": "^0.2.11",
|
||||
"babel-loader": "^8.1.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai": "^4.3.4",
|
||||
"cpx": "^1.5.0",
|
||||
"del": "^4.0.0",
|
||||
"eslint": "^7.25.0",
|
||||
@ -196,7 +193,7 @@
|
||||
"eslint-plugin-wc": "^1.3.0",
|
||||
"fancy-log": "^1.3.3",
|
||||
"fs-extra": "^7.0.1",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-foreach": "^0.1.0",
|
||||
"gulp-json-transform": "^0.4.6",
|
||||
"gulp-merge-json": "^1.3.1",
|
||||
@ -204,13 +201,13 @@
|
||||
"gulp-zopfli-green": "^3.0.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"husky": "^1.3.1",
|
||||
"lint-staged": "^8.1.5",
|
||||
"lint-staged": "^10.5.4",
|
||||
"lit-analyzer": "^1.2.1",
|
||||
"lodash.template": "^4.5.0",
|
||||
"magic-string": "^0.25.7",
|
||||
"map-stream": "^0.0.7",
|
||||
"merge-stream": "^1.0.1",
|
||||
"mocha": "^7.2.0",
|
||||
"mocha": "^8.4.0",
|
||||
"object-hash": "^2.0.3",
|
||||
"open": "^7.0.4",
|
||||
"prettier": "^2.0.4",
|
||||
@ -220,13 +217,13 @@
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"rollup-plugin-terser": "^5.3.0",
|
||||
"rollup-plugin-visualizer": "^4.0.4",
|
||||
"serve": "^11.3.0",
|
||||
"sinon": "^7.3.1",
|
||||
"serve": "^11.3.2",
|
||||
"sinon": "^11.0.0",
|
||||
"source-map-url": "^0.4.0",
|
||||
"systemjs": "^6.3.2",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"terser-webpack-plugin": "^5.1.2",
|
||||
"ts-lit-plugin": "^1.2.1",
|
||||
"ts-mocha": "^7.0.0",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"typescript": "^4.2.4",
|
||||
"vinyl-buffer": "^1.0.1",
|
||||
"vinyl-source-stream": "^2.0.0",
|
||||
@ -241,8 +238,8 @@
|
||||
"resolutions": {
|
||||
"@webcomponents/webcomponentsjs": "^2.2.10",
|
||||
"@polymer/polymer": "3.1.0",
|
||||
"lit-html": "1.4.0",
|
||||
"lit-element": "2.5.0"
|
||||
"lit-html": "2.0.0-rc.3",
|
||||
"lit-element": "3.0.0-rc.2"
|
||||
},
|
||||
"main": "src/home-assistant.js",
|
||||
"husky": {
|
||||
@ -250,17 +247,6 @@
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"linters": {
|
||||
"*.{js,ts,json,css,md}": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"ignore": [
|
||||
"translations/**"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "always"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user