mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-13 21:10:37 +00:00
Compare commits
66 Commits
fix_generi
...
update-typ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cea80d9830 | ||
|
|
fd279ea2b4 | ||
|
|
335b876fec | ||
|
|
b36b4d734b | ||
|
|
514b6568e5 | ||
|
|
4750a59719 | ||
|
|
92521d4565 | ||
|
|
66dbafb5f5 | ||
|
|
7c46d2d2f4 | ||
|
|
ca642d46cc | ||
|
|
404d6c75b5 | ||
|
|
9a52185e13 | ||
|
|
39a73774b0 | ||
|
|
b25b170539 | ||
|
|
6442606fc5 | ||
|
|
1b79869c87 | ||
|
|
672fbc6007 | ||
|
|
e1899836bf | ||
|
|
e90967d200 | ||
|
|
631bfe46ba | ||
|
|
a5762f07ac | ||
|
|
bf7422e4c5 | ||
|
|
45994e7989 | ||
|
|
995e3f10ad | ||
|
|
6464c2b602 | ||
|
|
8901c1fb31 | ||
|
|
1f5f18f7e7 | ||
|
|
51ca3e277c | ||
|
|
ee495a432f | ||
|
|
d75ea3bb8d | ||
|
|
40fbeaae1c | ||
|
|
dc2c6cee21 | ||
|
|
3b0cd9e3ae | ||
|
|
834ece8547 | ||
|
|
b7aa296be7 | ||
|
|
0cab6c9e2e | ||
|
|
94c8665528 | ||
|
|
c7ca654926 | ||
|
|
488599905b | ||
|
|
221e1d9ed8 | ||
|
|
0229f67751 | ||
|
|
3a0c367f76 | ||
|
|
af0854e480 | ||
|
|
14f4120926 | ||
|
|
e2bd464001 | ||
|
|
eb9f81d9a1 | ||
|
|
078209d154 | ||
|
|
7a617600ad | ||
|
|
ae74e3496c | ||
|
|
c0f304ad40 | ||
|
|
c794a2734b | ||
|
|
e156dd36f4 | ||
|
|
c40bf8f3cd | ||
|
|
93485d8b57 | ||
|
|
ce5cdaa496 | ||
|
|
dcbaa31c96 | ||
|
|
71b2e5f827 | ||
|
|
d58590b534 | ||
|
|
b2044e88b6 | ||
|
|
94b5ed97c6 | ||
|
|
11b8f6210f | ||
|
|
8e778cfc32 | ||
|
|
4c6a5ed2e3 | ||
|
|
48c90267df | ||
|
|
fcab356639 | ||
|
|
a70a0d4b4a |
@@ -21,7 +21,8 @@
|
||||
"esbenp.prettier-vscode",
|
||||
"runem.lit-plugin",
|
||||
"github.vscode-pull-request-github",
|
||||
"eamodio.gitlens"
|
||||
"eamodio.gitlens",
|
||||
"yeion7.styled-global-variables-autocomplete"
|
||||
],
|
||||
"settings": {
|
||||
"files.eol": "\n",
|
||||
|
||||
10
.github/workflows/cast_deployment.yaml
vendored
10
.github/workflows/cast_deployment.yaml
vendored
@@ -41,9 +41,8 @@ jobs:
|
||||
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=cast/dist --alias dev
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=cast/dist --alias dev
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
|
||||
@@ -77,9 +76,8 @@ jobs:
|
||||
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=cast/dist --prod
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=cast/dist --prod
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_CAST_SITE_ID }}
|
||||
|
||||
10
.github/workflows/demo_deployment.yaml
vendored
10
.github/workflows/demo_deployment.yaml
vendored
@@ -42,9 +42,8 @@ jobs:
|
||||
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=demo/dist --prod
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_DEV_SITE_ID }}
|
||||
@@ -78,9 +77,8 @@ jobs:
|
||||
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=demo/dist --prod
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=demo/dist --prod
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DEMO_SITE_ID }}
|
||||
|
||||
5
.github/workflows/design_deployment.yaml
vendored
5
.github/workflows/design_deployment.yaml
vendored
@@ -34,9 +34,8 @@ jobs:
|
||||
|
||||
- name: Deploy to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=gallery/dist --prod
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=gallery/dist --prod
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
|
||||
|
||||
9
.github/workflows/design_preview.yaml
vendored
9
.github/workflows/design_preview.yaml
vendored
@@ -39,13 +39,14 @@ jobs:
|
||||
|
||||
- name: Deploy preview to Netlify
|
||||
id: deploy
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}"
|
||||
run: |
|
||||
npx -y netlify-cli deploy --dir=gallery/dist --alias "deploy-preview-${{ github.event.number }}" \
|
||||
--json > deploy_output.json
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GALLERY_SITE_ID }}
|
||||
|
||||
- name: Generate summary
|
||||
run: |
|
||||
echo "${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }}" >> "$GITHUB_STEP_SUMMARY"
|
||||
NETLIFY_LIVE_URL=$(jq -r '.deploy_url' deploy_output.json)
|
||||
echo "$NETLIFY_LIVE_URL" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@@ -5,6 +5,7 @@
|
||||
"runem.lit-plugin",
|
||||
"github.vscode-pull-request-github",
|
||||
"eamodio.gitlens",
|
||||
"vitest.explorer"
|
||||
"vitest.explorer",
|
||||
"yeion7.styled-global-variables-autocomplete"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
diff --git a/mwc-formfield-base.js b/mwc-formfield-base.js
|
||||
index 7b763326d7d51835ad52646bfbc80fe21989abd3..f2baa8224e6d03df1fdb0b9fd03f5c6d77fc8747 100644
|
||||
--- a/mwc-formfield-base.js
|
||||
+++ b/mwc-formfield-base.js
|
||||
@@ -9,7 +9,7 @@ import { BaseElement } from '@material/mwc-base/base-element.js';
|
||||
import { FormElement } from '@material/mwc-base/form-element.js';
|
||||
import { observer } from '@material/mwc-base/observer.js';
|
||||
import { html } from 'lit';
|
||||
-import { property, query, queryAssignedNodes } from 'lit/decorators.js';
|
||||
+import { property, query, queryAssignedElements } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
export class FormfieldBase extends BaseElement {
|
||||
constructor() {
|
||||
@@ -96,7 +96,7 @@ __decorate([
|
||||
query('.mdc-form-field')
|
||||
], FormfieldBase.prototype, "mdcRoot", void 0);
|
||||
__decorate([
|
||||
- queryAssignedNodes('', true, '*')
|
||||
+ queryAssignedElements({ slot: "", flatten: true, selector: "*" })
|
||||
], FormfieldBase.prototype, "slottedInputs", void 0);
|
||||
__decorate([
|
||||
query('label')
|
||||
26
.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch
Normal file
26
.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
diff --git a/mwc-list-base.js b/mwc-list-base.js
|
||||
index 1ba95b6a01dcecea4d85b5cbbbcc3dfb04c40d5f..dced13fdb7929c490d6661b1bbe7e9f96dcd2285 100644
|
||||
--- a/mwc-list-base.js
|
||||
+++ b/mwc-list-base.js
|
||||
@@ -11,7 +11,7 @@ import { BaseElement } from '@material/mwc-base/base-element.js';
|
||||
import { observer } from '@material/mwc-base/observer.js';
|
||||
import { deepActiveElementPath, doesElementContainFocus, isNodeElement } from '@material/mwc-base/utils.js';
|
||||
import { html } from 'lit';
|
||||
-import { property, query, queryAssignedNodes } from 'lit/decorators.js';
|
||||
+import { property, query, queryAssignedElements } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import MDCListFoundation, { isIndexSet } from './mwc-list-foundation.js';
|
||||
export { createSetFromIndex, isEventMulti, isIndexSet } from './mwc-list-foundation.js';
|
||||
@@ -425,10 +425,10 @@ __decorate([
|
||||
query('.mdc-deprecated-list')
|
||||
], ListBase.prototype, "mdcRoot", void 0);
|
||||
__decorate([
|
||||
- queryAssignedNodes('', true, '*')
|
||||
+ queryAssignedElements({ flatten: true, selector: "*" })
|
||||
], ListBase.prototype, "assignedElements", void 0);
|
||||
__decorate([
|
||||
- queryAssignedNodes('', true, '[tabindex="0"]')
|
||||
+ queryAssignedElements({ flatten: true, selector: '[tabindex="0"]' })
|
||||
], ListBase.prototype, "tabbableElements", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean }),
|
||||
@@ -73,6 +73,19 @@ module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({
|
||||
sourceMap: !isTestBuild,
|
||||
});
|
||||
|
||||
/** @type {import('@rspack/core').SwcLoaderOptions} */
|
||||
module.exports.swcOptions = () => ({
|
||||
jsc: {
|
||||
loose: true,
|
||||
externalHelpers: true,
|
||||
target: "ES2021",
|
||||
parser: {
|
||||
syntax: "typescript",
|
||||
decorators: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
module.exports.babelOptions = ({
|
||||
latestBuild,
|
||||
isProdBuild,
|
||||
@@ -97,7 +110,6 @@ module.exports.babelOptions = ({
|
||||
shippedProposals: true,
|
||||
},
|
||||
],
|
||||
"@babel/preset-typescript",
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
@@ -134,12 +146,6 @@ module.exports.babelOptions = ({
|
||||
"@babel/plugin-transform-runtime",
|
||||
{ version: dependencies["@babel/runtime"] },
|
||||
],
|
||||
// Transpile decorators (still in TC39 process)
|
||||
// Modern browsers support class fields and private methods, but transform is required with the older decorator version dictated by Lit
|
||||
[
|
||||
"@babel/plugin-proposal-decorators",
|
||||
{ version: "2018-09", decoratorsBeforeExport: true },
|
||||
],
|
||||
"@babel/plugin-transform-class-properties",
|
||||
"@babel/plugin-transform-private-methods",
|
||||
].filter(Boolean),
|
||||
|
||||
@@ -16,6 +16,7 @@ const detailsClose = "</details>\n";
|
||||
|
||||
const dummyAPI = {
|
||||
version: babelVersion,
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
assertVersion: () => {},
|
||||
caller: (callback) =>
|
||||
callback({
|
||||
|
||||
@@ -65,19 +65,26 @@ const createRspackConfig = ({
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js$|\.ts$/,
|
||||
use: (info) => ({
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
...bundle.babelOptions({
|
||||
latestBuild,
|
||||
isProdBuild,
|
||||
isTestBuild,
|
||||
sw: info.issuerLayer === "sw",
|
||||
}),
|
||||
cacheDirectory: !isProdBuild,
|
||||
cacheCompression: false,
|
||||
exclude: /node_modules[\\/]core-js/,
|
||||
use: (info) => [
|
||||
{
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
...bundle.babelOptions({
|
||||
latestBuild,
|
||||
isProdBuild,
|
||||
isTestBuild,
|
||||
sw: info.issuerLayer === "sw",
|
||||
}),
|
||||
cacheDirectory: !isProdBuild,
|
||||
cacheCompression: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
{
|
||||
loader: "builtin:swc-loader",
|
||||
options: bundle.swcOptions(),
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
@@ -136,7 +143,8 @@ const createRspackConfig = ({
|
||||
// calling define.amd will call require("!!webpack amd options")
|
||||
resource.startsWith("!!webpack") ||
|
||||
// loaded by webpack dev server but doesn't exist.
|
||||
resource === "webpack/hot"
|
||||
resource === "webpack/hot" ||
|
||||
resource.startsWith("@swc/helpers")
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import "./layout/hc-connect";
|
||||
|
||||
import("../../../src/resources/ha-style");
|
||||
import("../../../src/resources/append-ha-style");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list";
|
||||
import { mdiCast, mdiCastConnected, mdiViewDashboard } from "@mdi/js";
|
||||
import type { Auth, Connection } from "home-assistant-js-websocket";
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||
import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute";
|
||||
import "../../../../src/components/ha-icon";
|
||||
import "../../../../src/components/ha-list";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import {
|
||||
getLegacyLovelaceCollection,
|
||||
@@ -29,7 +31,6 @@ import type { LovelaceViewConfig } from "../../../../src/data/lovelace/config/vi
|
||||
import "../../../../src/layouts/hass-loading-screen";
|
||||
import { generateDefaultViewConfig } from "../../../../src/panels/lovelace/common/generate-lovelace-config";
|
||||
import "./hc-layout";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
|
||||
@customElement("hc-cast")
|
||||
class HcCast extends LitElement {
|
||||
@@ -85,7 +86,7 @@ class HcCast extends LitElement {
|
||||
`
|
||||
: html`
|
||||
<div class="section-header">PICK A VIEW</div>
|
||||
<mwc-list @action=${this._handlePickView} activatable>
|
||||
<ha-list @action=${this._handlePickView} activatable>
|
||||
${(
|
||||
this.lovelaceViews ?? [
|
||||
generateDefaultViewConfig({}, {}, {}, {}, () => ""),
|
||||
@@ -113,7 +114,7 @@ class HcCast extends LitElement {
|
||||
></ha-svg-icon>`}
|
||||
</ha-list-item>
|
||||
`
|
||||
)}</mwc-list
|
||||
)}</ha-list
|
||||
>
|
||||
`}
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ export class HcConnect extends LitElement {
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
|
||||
.error a {
|
||||
|
||||
@@ -86,9 +86,9 @@ class HcLayout extends LitElement {
|
||||
.card-header {
|
||||
color: var(--ha-card-header-color, var(--primary-text-color));
|
||||
font-family: var(--ha-card-header-font-family, inherit);
|
||||
font-size: var(--ha-card-header-font-size, 24px);
|
||||
font-size: var(--ha-card-header-font-size, var(--ha-font-size-2xl));
|
||||
letter-spacing: -0.012em;
|
||||
line-height: 32px;
|
||||
line-height: var(--ha-line-height-normal);
|
||||
padding: 24px 16px 16px;
|
||||
display: block;
|
||||
margin: 0;
|
||||
@@ -98,7 +98,7 @@ class HcLayout extends LitElement {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
font-size: var(--ha-font-size-m);
|
||||
color: var(--secondary-text-color);
|
||||
line-height: initial;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ class HcLayout extends LitElement {
|
||||
}
|
||||
|
||||
:host ::slotted(.section-header) {
|
||||
font-weight: 500;
|
||||
font-weight: var(--ha-font-weight-semibold);
|
||||
padding: 4px 16px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ class HcLayout extends LitElement {
|
||||
|
||||
.footer {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-size: var(--ha-font-size-s);
|
||||
padding: 8px 0 24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class HcLaunchScreen extends LitElement {
|
||||
display: block;
|
||||
height: 100vh;
|
||||
background-color: #f2f4f9;
|
||||
font-size: 24px;
|
||||
font-size: var(--ha-font-size-2xl);
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
|
||||
@@ -109,7 +109,7 @@ export class HcMain extends HassElement {
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
import("./hc-lovelace");
|
||||
import("../../../../src/resources/ha-style");
|
||||
import("../../../../src/resources/append-ha-style");
|
||||
|
||||
window.addEventListener("location-changed", () => {
|
||||
const panelPath = `/${this._urlPath || "lovelace"}/`;
|
||||
|
||||
@@ -1,36 +1,28 @@
|
||||
export const demoThemeJimpower = () => ({
|
||||
"text-primary-color": "var(--primary-text-color)",
|
||||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#5294E2",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#383C45",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
"paper-item-selected_-_background-color": "#434954",
|
||||
"secondary-background-color": "#383C45",
|
||||
"disabled-text-color": "#7F848E",
|
||||
"paper-item-icon_-_color": "green",
|
||||
"paper-grey-200": "#414A59",
|
||||
"label-badge-background-color": "#2E333A",
|
||||
"paper-card-header-color": "var(--accent-color)",
|
||||
"sidebar-icon-color": "var(--paper-item-icon-color)",
|
||||
"paper-listbox-background-color": "#2E333A",
|
||||
"sidebar-icon-color": "var(--state-icon-color)",
|
||||
"table-row-background-color": "#353840",
|
||||
"paper-grey-50": "var(--primary-text-color)",
|
||||
"switch-checked-color": "var(--accent-color)",
|
||||
"paper-dialog-background-color": "#434954",
|
||||
"secondary-text-color": "#5294E2",
|
||||
"error-color": "#E45E65",
|
||||
"divider-color": "rgba(0, 0, 0, .12)",
|
||||
"success-color": "#39E949",
|
||||
"switch-unchecked-button-color": "var(--disabled-text-color)",
|
||||
"label-badge-border-color": "green",
|
||||
"paper-listbox-color": "var(--primary-color)",
|
||||
"card-background-color": "#434954",
|
||||
"label-badge-text-color": "var(--primary-text-color)",
|
||||
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
||||
"dark-primary-color": "var(--accent-color)",
|
||||
"paper-item-icon-active-color": "#F9C536",
|
||||
"accent-color": "#E45E65",
|
||||
"table-row-alternative-background-color": "#3E424B",
|
||||
});
|
||||
|
||||
@@ -1,37 +1,29 @@
|
||||
// https://community.home-assistant.io/t/slate-a-new-dark-theme/86410
|
||||
export const demoThemeKernehed = () => ({
|
||||
"text-primary-color": "var(--primary-text-color)",
|
||||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#2980b9",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#222222",
|
||||
"sidebar-icon-color": "#777777",
|
||||
"paper-item-selected_-_background-color": "#292929",
|
||||
"secondary-background-color": "#222222",
|
||||
"disabled-text-color": "#777777",
|
||||
"paper-item-icon_-_color": "green",
|
||||
"paper-grey-200": "#222222",
|
||||
"label-badge-background-color": "#222222",
|
||||
"paper-card-header-color": "var(--accent-color)",
|
||||
"paper-listbox-background-color": "#141414",
|
||||
"table-row-background-color": "#292929",
|
||||
"paper-grey-50": "var(--primary-text-color)",
|
||||
"switch-checked-color": "var(--accent-color)",
|
||||
"paper-dialog-background-color": "#292929",
|
||||
"secondary-text-color": "#b58e31",
|
||||
"error-color": "#b58e31",
|
||||
"divider-color": "rgba(0, 0, 0, .12)",
|
||||
"success-color": "#2980b9",
|
||||
"switch-unchecked-button-color": "var(--disabled-text-color)",
|
||||
"label-badge-border-color": "green",
|
||||
"paper-listbox-color": "#777777",
|
||||
"card-background-color": "#292929",
|
||||
"label-badge-text-color": "var(--primary-text-color)",
|
||||
"switch-unchecked-track-color": "var(--disabled-text-color)",
|
||||
"dark-primary-color": "var(--accent-color)",
|
||||
"paper-item-icon-active-color": "#b58e31",
|
||||
"accent-color": "#2980b9",
|
||||
"table-row-alternative-background-color": "#292929",
|
||||
});
|
||||
|
||||
@@ -1,26 +1,18 @@
|
||||
export const demoThemeTeachingbirds = () => ({
|
||||
"paper-card-header-color": "var(--paper-item-icon-color)",
|
||||
"paper-listbox-background-color": "#202020",
|
||||
"paper-grey-50": "var(--primary-text-color)",
|
||||
"paper-item-icon-color": "#d3d3d3",
|
||||
"divider-color": "rgba(255, 255, 255, 0.12)",
|
||||
"primary-color": "#389638",
|
||||
"light-primary-color": "#6f956f",
|
||||
"label-badge-red": "var(--primary-color)",
|
||||
"paper-listbox-color": "#FFFFFF",
|
||||
"paper-toggle-button-checked-bar-color": "var(--light-primary-color)",
|
||||
"switch-unchecked-track-color": "var(--primary-text-color)",
|
||||
"card-background-color": "#4e4e4e",
|
||||
"label-badge-text-color": "var(--text-primary-color)",
|
||||
"primary-background-color": "#303030",
|
||||
"sidebar-icon-color": "var(--paper-item-icon-color)",
|
||||
"sidebar-icon-color": "#d3d3d3",
|
||||
"secondary-background-color": "#2b2b2b",
|
||||
"paper-item-icon-active-color": "#d8bf50",
|
||||
"switch-checked-color": "var(--primary-color)",
|
||||
"secondary-text-color": "#389638",
|
||||
"disabled-text-color": "#545454",
|
||||
"paper-item-icon_-_color": "var(--primary-text-color)",
|
||||
"paper-grey-200": "#191919",
|
||||
"primary-text-color": "#cfcfcf",
|
||||
"label-badge-background-color": "var(--secondary-background-color)",
|
||||
});
|
||||
|
||||
@@ -73,7 +73,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
|
||||
}
|
||||
ha-svg-icon {
|
||||
padding: 8px;
|
||||
color: var(--paper-item-icon-color);
|
||||
color: var(--state-icon-color);
|
||||
}
|
||||
.flex {
|
||||
flex: 1;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import "./util/is_frontpage";
|
||||
import "./ha-demo";
|
||||
|
||||
import("../../src/resources/ha-style");
|
||||
import("../../src/resources/append-ha-style");
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
font-family: Roboto, Noto, sans-serif;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-weight: 400;
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
@@ -2,26 +2,36 @@ import type { TodoItem } from "../../../src/data/todo";
|
||||
import { TodoItemStatus } from "../../../src/data/todo";
|
||||
import type { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
|
||||
|
||||
export const mockTodo = (hass: MockHomeAssistant) => {
|
||||
hass.mockWS("todo/item/list", () => ({
|
||||
items: [
|
||||
{
|
||||
uid: "12",
|
||||
summary: "Milk",
|
||||
status: TodoItemStatus.NeedsAction,
|
||||
},
|
||||
{
|
||||
uid: "13",
|
||||
summary: "Eggs",
|
||||
status: TodoItemStatus.NeedsAction,
|
||||
},
|
||||
{
|
||||
uid: "14",
|
||||
summary: "Oranges",
|
||||
status: TodoItemStatus.Completed,
|
||||
},
|
||||
] as TodoItem[],
|
||||
}));
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
hass.mockWS("todo/item/subscribe", (_msg, _hass) => () => {});
|
||||
const items = {
|
||||
items: [
|
||||
{
|
||||
uid: "12",
|
||||
summary: "Milk",
|
||||
status: TodoItemStatus.NeedsAction,
|
||||
},
|
||||
{
|
||||
uid: "13",
|
||||
summary: "Eggs",
|
||||
status: TodoItemStatus.NeedsAction,
|
||||
},
|
||||
{
|
||||
uid: "14",
|
||||
summary: "Oranges",
|
||||
status: TodoItemStatus.Completed,
|
||||
},
|
||||
{
|
||||
uid: "15",
|
||||
summary: "Beer",
|
||||
},
|
||||
] as TodoItem[],
|
||||
};
|
||||
|
||||
export const mockTodo = (hass: MockHomeAssistant) => {
|
||||
hass.mockWS("todo/item/list", () => items);
|
||||
hass.mockWS("todo/item/move", () => undefined);
|
||||
hass.mockWS("todo/item/subscribe", (_msg, _hass, onChange) => {
|
||||
onChange!(items);
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
return () => {};
|
||||
});
|
||||
};
|
||||
|
||||
@@ -37,13 +37,13 @@ class PageDescription extends HaMarkdown {
|
||||
border-bottom: 1px solid var(--secondary-background-color);
|
||||
}
|
||||
.title {
|
||||
font-size: 42px;
|
||||
line-height: 56px;
|
||||
font-size: var(--ha-font-size-5xl);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.subtitle {
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
font-size: var(--ha-font-size-l);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
}
|
||||
.root {
|
||||
max-width: 800px;
|
||||
|
||||
@@ -34,7 +34,7 @@ class HaDemoOptions extends LitElement {
|
||||
height: 64px;
|
||||
padding: 0 16px;
|
||||
pointer-events: none;
|
||||
font-size: 20px;
|
||||
font-size: var(--ha-font-size-xl);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@@ -250,14 +250,14 @@ class HaGallery extends LitElement {
|
||||
}
|
||||
|
||||
.page-footer .header {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 28px;
|
||||
font-size: var(--ha-font-size-l);
|
||||
font-weight: var(--ha-font-weight-semibold);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-footer .secondary {
|
||||
line-height: 23px;
|
||||
line-height: var(--ha-line-height-normal);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, html, css } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||
import type { Action } from "../../../../src/data/script";
|
||||
import "../../../../src/panels/config/automation/action/ha-automation-action";
|
||||
import { HaChooseAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-choose";
|
||||
import { HaConditionAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-condition";
|
||||
import { HaDelayAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-delay";
|
||||
import { HaDeviceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-device_id";
|
||||
import { HaEventAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-event";
|
||||
import { HaIfAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-if";
|
||||
import { HaParallelAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-parallel";
|
||||
import { HaPlayMediaAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-play_media";
|
||||
import { HaRepeatAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-repeat";
|
||||
import { HaSequenceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-sequence";
|
||||
import { HaServiceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-service";
|
||||
import { HaStopAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-stop";
|
||||
import { HaWaitForTriggerAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger";
|
||||
import { HaWaitAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-wait_template";
|
||||
import type { Action } from "../../../../src/data/script";
|
||||
import { HaConditionAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-condition";
|
||||
import { HaSequenceAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-sequence";
|
||||
import { HaParallelAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-parallel";
|
||||
import { HaIfAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-if";
|
||||
import { HaStopAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-stop";
|
||||
import { HaPlayMediaAction } from "../../../../src/panels/config/automation/action/types/ha-automation-action-play_media";
|
||||
|
||||
const SCHEMAS: { name: string; actions: Action[] }[] = [
|
||||
{ name: "Event", actions: [HaEventAction.defaultConfig] },
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, html, css } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import type { ConditionWithShorthand } from "../../../../src/data/automation";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import "../../../../src/panels/config/automation/condition/ha-automation-condition";
|
||||
import { HaAndCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-and";
|
||||
import { HaDeviceCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-device";
|
||||
import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not";
|
||||
import HaNumericStateCondition from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-numeric_state";
|
||||
import { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or";
|
||||
import { HaStateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-state";
|
||||
import { HaSunCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-sun";
|
||||
import { HaTemplateCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-template";
|
||||
import { HaTimeCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-time";
|
||||
import { HaTriggerCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-trigger";
|
||||
import { HaZoneCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-zone";
|
||||
import { HaAndCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-and";
|
||||
import { HaOrCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-or";
|
||||
import { HaNotCondition } from "../../../../src/panels/config/automation/condition/types/ha-automation-condition-not";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
|
||||
const SCHEMAS: { name: string; conditions: ConditionWithShorthand[] }[] = [
|
||||
{
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, html, css } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry";
|
||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||
import { mockConfig } from "../../../../demo/src/stubs/config";
|
||||
import { mockTags } from "../../../../demo/src/stubs/tags";
|
||||
import { mockAuth } from "../../../../demo/src/stubs/auth";
|
||||
import { mockConfig } from "../../../../demo/src/stubs/config";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||
import { mockTags } from "../../../../demo/src/stubs/tags";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import type { Trigger } from "../../../../src/data/automation";
|
||||
import { HaGeolocationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import "../../../../src/panels/config/automation/trigger/ha-automation-trigger";
|
||||
import { HaConversationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-conversation";
|
||||
import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device";
|
||||
import { HaEventTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-event";
|
||||
import { HaGeolocationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-geo_location";
|
||||
import { HaHassTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-homeassistant";
|
||||
import { HaTriggerList } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-list";
|
||||
import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt";
|
||||
import { HaNumericStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-numeric_state";
|
||||
import { HaPersistentNotificationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification";
|
||||
import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state";
|
||||
import { HaSunTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-sun";
|
||||
import { HaTagTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-tag";
|
||||
import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-template";
|
||||
import { HaTimeTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time";
|
||||
import { HaTimePatternTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-time_pattern";
|
||||
import { HaWebhookTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-webhook";
|
||||
import { HaPersistentNotificationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification";
|
||||
import { HaZoneTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-zone";
|
||||
import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-device";
|
||||
import { HaStateTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-state";
|
||||
import { HaMQTTTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-mqtt";
|
||||
import "../../../../src/panels/config/automation/trigger/ha-automation-trigger";
|
||||
import { HaConversationTrigger } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-conversation";
|
||||
import { HaTriggerList } from "../../../../src/panels/config/automation/trigger/types/ha-automation-trigger-list";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
|
||||
const SCHEMAS: { name: string; triggers: Trigger[] }[] = [
|
||||
{
|
||||
|
||||
@@ -150,7 +150,7 @@ export class DemoHaBarButton extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
|
||||
@@ -86,7 +86,7 @@ export class DemoHarControlNumberButtons extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
color: #2196f3;
|
||||
|
||||
@@ -125,7 +125,7 @@ export class DemoHaControlSelectMenu extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
--control-button-icon-color: var(--primary-color);
|
||||
|
||||
@@ -181,7 +181,7 @@ export class DemoHaControlSelect extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
--mdc-icon-size: 24px;
|
||||
|
||||
@@ -144,7 +144,7 @@ export class DemoHaBarSlider extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
--control-slider-color: #ffcf4c;
|
||||
|
||||
@@ -112,7 +112,7 @@ export class DemoHaControlSwitch extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.custom {
|
||||
--control-switch-on-color: var(--green-color);
|
||||
|
||||
@@ -105,8 +105,8 @@ export class DemoHaHsColorPicker extends LitElement {
|
||||
width: 400px;
|
||||
}
|
||||
.value {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
font-size: var(--ha-font-size-2xl);
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -123,7 +123,7 @@ export class DemoHaSelectBox extends LitElement {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -6,22 +6,23 @@ import { mockAreaRegistry } from "../../../../demo/src/stubs/area_registry";
|
||||
import { mockConfigEntries } from "../../../../demo/src/stubs/config_entries";
|
||||
import { mockDeviceRegistry } from "../../../../demo/src/stubs/device_registry";
|
||||
import { mockEntityRegistry } from "../../../../demo/src/stubs/entity_registry";
|
||||
import { mockFloorRegistry } from "../../../../demo/src/stubs/floor_registry";
|
||||
import { mockHassioSupervisor } from "../../../../demo/src/stubs/hassio_supervisor";
|
||||
import { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import "../../../../src/components/ha-selector/ha-selector";
|
||||
import "../../../../src/components/ha-settings-row";
|
||||
import type { AreaRegistryEntry } from "../../../../src/data/area_registry";
|
||||
import type { BlueprintInput } from "../../../../src/data/blueprint";
|
||||
import type { DeviceRegistryEntry } from "../../../../src/data/device_registry";
|
||||
import type { FloorRegistryEntry } from "../../../../src/data/floor_registry";
|
||||
import type { LabelRegistryEntry } from "../../../../src/data/label_registry";
|
||||
import { showDialog } from "../../../../src/dialogs/make-dialog-manager";
|
||||
import { getEntity } from "../../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import type { ProvideHassElement } from "../../../../src/mixins/provide-hass-lit-mixin";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import "../../components/demo-black-white-row";
|
||||
import type { FloorRegistryEntry } from "../../../../src/data/floor_registry";
|
||||
import type { LabelRegistryEntry } from "../../../../src/data/label_registry";
|
||||
import { mockFloorRegistry } from "../../../../demo/src/stubs/floor_registry";
|
||||
import { mockLabelRegistry } from "../../../../demo/src/stubs/label_registry";
|
||||
import type { DeviceRegistryEntry } from "../../../../src/data/device_registry";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("alarm_control_panel", "alarm", "disarmed", {
|
||||
@@ -643,9 +644,6 @@ class DemoHaSelector extends LitElement implements ProvideHassElement {
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-settings-row {
|
||||
--paper-item-body-two-line-min-height: 0;
|
||||
}
|
||||
.options {
|
||||
max-width: 800px;
|
||||
margin: 16px auto;
|
||||
|
||||
@@ -18,7 +18,7 @@ Tooltips use `display: contents` so they won't interfere with how elements are p
|
||||
|
||||
## Documentation
|
||||
|
||||
This element is based on sholace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation.
|
||||
This element is based on shoelace `sl-tooltip` it only sets some css tokens and has a custom show/hide animation.
|
||||
|
||||
<a href="https://shoelace.style/components/tooltip" target="_blank" rel="noopener noreferrer">Shoelace documentation</a>
|
||||
|
||||
@@ -28,3 +28,7 @@ In your theme settings use this without the prefixed `--`.
|
||||
|
||||
- `--ha-tooltip-border-radius` (Default: 4px)
|
||||
- `--ha-tooltip-arrow-size` (Default: 8px)
|
||||
- `--sl-tooltip-font-family` (Default: `var(--ha-font-family-body)`)
|
||||
- `--ha-tooltip-font-size` (Default: `var(--ha-font-size-s)`)
|
||||
- `--sl-tooltip-font-weight` (Default: `var(--ha-font-weight-normal)`)
|
||||
- `--sl-tooltip-line-height` (Default: `var(--ha-line-height-condensed)`)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatDateTimeNumeric } from "../../../../src/common/datetime/format_date_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeNumeric extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatDateTimeWithSeconds } from "../../../../src/common/datetime/format_date_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeSeconds extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatShortDateTimeWithYear } from "../../../../src/common/datetime/format_date_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShortYear extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatShortDateTime } from "../../../../src/common/datetime/format_date_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTimeShort extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatDateTime } from "../../../../src/common/datetime/format_date_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeDateTime extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeDateTime extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeDateTime extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import { formatDateNumeric } from "../../../../src/common/datetime/format_date";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -27,7 +27,7 @@ export class DemoDateTimeDate extends LitElement {
|
||||
};
|
||||
const date = new Date();
|
||||
return html`
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -86,13 +86,13 @@ export class DemoDateTimeDate extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatTimeWithSeconds } from "../../../../src/common/datetime/format_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTimeSeconds extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatTimeWeekday } from "../../../../src/common/datetime/format_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTimeWeekday extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { formatTime } from "../../../../src/common/datetime/format_time";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-control-select";
|
||||
import "../../../../src/components/ha-list";
|
||||
import type { FrontendLocaleData } from "../../../../src/data/translation";
|
||||
import {
|
||||
DateFormat,
|
||||
@@ -49,7 +49,7 @@ export class DemoDateTimeTime extends LitElement {
|
||||
@value-changed=${this.handleValueChanged}
|
||||
>
|
||||
</ha-control-select>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
<div class="container header">
|
||||
<div>Language</div>
|
||||
<div class="center">Default (lang)</div>
|
||||
@@ -96,7 +96,7 @@ export class DemoDateTimeTime extends LitElement {
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DemoDateTimeTime extends LitElement {
|
||||
margin: 12px auto;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
}
|
||||
.center {
|
||||
text-align: center;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { PropertyValues, TemplateResult } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, query } from "lit/decorators";
|
||||
import { mockIcons } from "../../../../demo/src/stubs/icons";
|
||||
import { mockTodo } from "../../../../demo/src/stubs/todo";
|
||||
import { getEntity } from "../../../../src/fake_data/entity";
|
||||
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||
import "../../components/demo-cards";
|
||||
import { getEntity } from "../../../../src/fake_data/entity";
|
||||
import { mockTodo } from "../../../../demo/src/stubs/todo";
|
||||
import { mockIcons } from "../../../../demo/src/stubs/icons";
|
||||
|
||||
const ENTITIES = [
|
||||
getEntity("todo", "shopping_list", "2", {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import type { PropertyValues, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -11,6 +11,7 @@ import { navigate } from "../../../src/common/navigate";
|
||||
import { extractSearchParam } from "../../../src/common/url/search-params";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-icon-button";
|
||||
import "../../../src/components/ha-list-item";
|
||||
import "../../../src/components/search-input";
|
||||
import type { HassioAddonRepository } from "../../../src/data/hassio/addon";
|
||||
import { reloadHassioAddons } from "../../../src/data/hassio/addon";
|
||||
@@ -89,17 +90,17 @@ export class HassioAddonStore extends LitElement {
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item>
|
||||
<ha-list-item>
|
||||
${this.supervisor.localize("store.check_updates")}
|
||||
</mwc-list-item>
|
||||
<mwc-list-item>
|
||||
</ha-list-item>
|
||||
<ha-list-item>
|
||||
${this.supervisor.localize("store.repositories")}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
${this.hass.userData?.showAdvanced &&
|
||||
atLeastVersion(this.hass.config.version, 0, 117)
|
||||
? html`<mwc-list-item>
|
||||
? html`<ha-list-item>
|
||||
${this.supervisor.localize("store.registries")}
|
||||
</mwc-list-item>`
|
||||
</ha-list-item>`
|
||||
: ""}
|
||||
</ha-button-menu>
|
||||
${repos.length === 0
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-select";
|
||||
import type {
|
||||
HassioAddonDetails,
|
||||
@@ -29,6 +28,8 @@ class HassioAddonAudio extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
@state() private _inputDevices?: HassioHardwareAudioDevice[];
|
||||
@@ -48,7 +49,7 @@ class HassioAddonAudio extends LitElement {
|
||||
<div class="card-content">
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this._inputDevices &&
|
||||
html`<ha-select
|
||||
.label=${this.supervisor.localize(
|
||||
@@ -59,12 +60,13 @@ class HassioAddonAudio extends LitElement {
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
.value=${this._selectedInput!}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
${this._inputDevices.map(
|
||||
(item) => html`
|
||||
<mwc-list-item .value=${item.device || ""}>
|
||||
<ha-list-item .value=${item.device || ""}>
|
||||
${item.name}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</ha-select>`}
|
||||
@@ -78,18 +80,22 @@ class HassioAddonAudio extends LitElement {
|
||||
fixedMenuPosition
|
||||
naturalMenuWidth
|
||||
.value=${this._selectedOutput!}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
${this._outputDevices.map(
|
||||
(item) => html`
|
||||
<mwc-list-item .value=${item.device || ""}
|
||||
>${item.name}</mwc-list-item
|
||||
<ha-list-item .value=${item.device || ""}
|
||||
>${item.name}</ha-list-item
|
||||
>
|
||||
`
|
||||
)}
|
||||
</ha-select>`}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-progress-button @click=${this._saveSettings}>
|
||||
<ha-progress-button
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._saveSettings}
|
||||
>
|
||||
${this.supervisor.localize("common.save")}
|
||||
</ha-progress-button>
|
||||
</div>
|
||||
@@ -171,6 +177,10 @@ class HassioAddonAudio extends LitElement {
|
||||
}
|
||||
|
||||
private async _saveSettings(ev: CustomEvent): Promise<void> {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
@@ -7,6 +7,7 @@ import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
import { haStyle } from "../../../../src/resources/styles";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import { hassioStyle } from "../../resources/hassio-style";
|
||||
import "../info/hassio-addon-system-managed";
|
||||
import "./hassio-addon-audio";
|
||||
import "./hassio-addon-config";
|
||||
import "./hassio-addon-network";
|
||||
@@ -19,6 +20,11 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ type: Boolean, attribute: "control-enabled" })
|
||||
public controlEnabled = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-spinner></ha-spinner>`;
|
||||
@@ -29,6 +35,16 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
|
||||
return html`
|
||||
<div class="content">
|
||||
${this.addon.system_managed &&
|
||||
(hasConfiguration || this.addon.network || this.addon.audio)
|
||||
? html`
|
||||
<hassio-addon-system-managed
|
||||
.supervisor=${this.supervisor}
|
||||
.narrow=${this.narrow}
|
||||
.hideButton=${this.controlEnabled}
|
||||
></hassio-addon-system-managed>
|
||||
`
|
||||
: nothing}
|
||||
${hasConfiguration || this.addon.network || this.addon.audio
|
||||
? html`
|
||||
${hasConfiguration
|
||||
@@ -37,27 +53,33 @@ class HassioAddonConfigDashboard extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.addon=${this.addon}
|
||||
.supervisor=${this.supervisor}
|
||||
.disabled=${this.addon.system_managed &&
|
||||
!this.controlEnabled}
|
||||
></hassio-addon-config>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.network
|
||||
? html`
|
||||
<hassio-addon-network
|
||||
.hass=${this.hass}
|
||||
.addon=${this.addon}
|
||||
.supervisor=${this.supervisor}
|
||||
.disabled=${this.addon.system_managed &&
|
||||
!this.controlEnabled}
|
||||
></hassio-addon-network>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.audio
|
||||
? html`
|
||||
<hassio-addon-audio
|
||||
.hass=${this.hass}
|
||||
.addon=${this.addon}
|
||||
.supervisor=${this.supervisor}
|
||||
.disabled=${this.addon.system_managed &&
|
||||
!this.controlEnabled}
|
||||
></hassio-addon-audio>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
`
|
||||
: this.supervisor.localize("addon.configuration.no_configuration")}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import "@material/mwc-button";
|
||||
import type { ActionDetail } from "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import { DEFAULT_SCHEMA, Type } from "js-yaml";
|
||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
@@ -16,6 +14,7 @@ import "../../../../src/components/ha-form/ha-form";
|
||||
import type { HaFormSchema } from "../../../../src/components/ha-form/types";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import "../../../../src/components/ha-icon-button";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-switch";
|
||||
import "../../../../src/components/ha-yaml-editor";
|
||||
import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
|
||||
@@ -61,6 +60,8 @@ class HassioAddonConfig extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@state() private _configHasChanged = false;
|
||||
|
||||
@state() private _valid = true;
|
||||
@@ -176,7 +177,7 @@ class HassioAddonConfig extends LitElement {
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item .disabled=${!this._canShowSchema}>
|
||||
<ha-list-item .disabled=${!this._canShowSchema || this.disabled}>
|
||||
${this._yamlMode
|
||||
? this.supervisor.localize(
|
||||
"addon.configuration.options.edit_in_ui"
|
||||
@@ -184,10 +185,13 @@ class HassioAddonConfig extends LitElement {
|
||||
: this.supervisor.localize(
|
||||
"addon.configuration.options.edit_in_yaml"
|
||||
)}
|
||||
</mwc-list-item>
|
||||
<mwc-list-item class="warning">
|
||||
</ha-list-item>
|
||||
<ha-list-item
|
||||
class=${!this.disabled ? "warning" : ""}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
${this.supervisor.localize("common.reset_defaults")}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</div>
|
||||
</div>
|
||||
@@ -195,6 +199,7 @@ class HassioAddonConfig extends LitElement {
|
||||
<div class="card-content">
|
||||
${showForm
|
||||
? html`<ha-form
|
||||
.disabled=${this.disabled}
|
||||
.data=${this._options!}
|
||||
@value-changed=${this._configChanged}
|
||||
.computeLabel=${this.computeLabel}
|
||||
@@ -208,7 +213,7 @@ class HassioAddonConfig extends LitElement {
|
||||
)
|
||||
)}
|
||||
></ha-form>`
|
||||
: html` <ha-yaml-editor
|
||||
: html`<ha-yaml-editor
|
||||
@value-changed=${this._configChanged}
|
||||
.yamlSchema=${ADDON_YAML_SCHEMA}
|
||||
></ha-yaml-editor>`}
|
||||
@@ -244,7 +249,9 @@ class HassioAddonConfig extends LitElement {
|
||||
<div class="card-actions right">
|
||||
<ha-progress-button
|
||||
@click=${this._saveTapped}
|
||||
.disabled=${!this._configHasChanged || !this._valid}
|
||||
.disabled=${this.disabled ||
|
||||
!this._configHasChanged ||
|
||||
!this._valid}
|
||||
>
|
||||
${this.supervisor.localize("common.save")}
|
||||
</ha-progress-button>
|
||||
@@ -346,6 +353,10 @@ class HassioAddonConfig extends LitElement {
|
||||
}
|
||||
|
||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||
if (this.disabled || !this._configHasChanged || !this._valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
const options: Record<string, unknown> = this._yamlMode
|
||||
? this._editor?.value
|
||||
@@ -407,7 +418,7 @@ class HassioAddonConfig extends LitElement {
|
||||
z-index: 3;
|
||||
--mdc-theme-text-primary-on-background: var(--primary-text-color);
|
||||
}
|
||||
mwc-list-item[disabled] {
|
||||
ha-list-item[disabled] {
|
||||
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
|
||||
}
|
||||
.header {
|
||||
@@ -417,13 +428,13 @@ class HassioAddonConfig extends LitElement {
|
||||
.header h2 {
|
||||
color: var(--ha-card-header-color, var(--primary-text-color));
|
||||
font-family: var(--ha-card-header-font-family, inherit);
|
||||
font-size: var(--ha-card-header-font-size, 24px);
|
||||
font-size: var(--ha-card-header-font-size, var(--ha-font-size-2xl));
|
||||
letter-spacing: -0.012em;
|
||||
line-height: 48px;
|
||||
line-height: var(--ha-line-height-expanded);
|
||||
padding: 12px 16px 16px;
|
||||
display: block;
|
||||
margin-block: 0px;
|
||||
font-weight: normal;
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
}
|
||||
.card-actions.right {
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import "../../../../src/components/ha-form/ha-form";
|
||||
import type { HaFormSchema } from "../../../../src/components/ha-form/types";
|
||||
import type {
|
||||
@@ -28,6 +29,8 @@ class HassioAddonNetwork extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon!: HassioAddonDetails;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@state() private _showOptional = false;
|
||||
|
||||
@state() private _configHasChanged = false;
|
||||
@@ -65,9 +68,10 @@ class HassioAddonNetwork extends LitElement {
|
||||
</p>
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
: nothing}
|
||||
|
||||
<ha-form
|
||||
.disabled=${this.disabled}
|
||||
.data=${this._config}
|
||||
@value-changed=${this._configChanged}
|
||||
.computeLabel=${this._computeLabel}
|
||||
@@ -92,14 +96,18 @@ class HassioAddonNetwork extends LitElement {
|
||||
>
|
||||
</ha-switch>
|
||||
</ha-formfield>`
|
||||
: ""}
|
||||
: nothing}
|
||||
<div class="card-actions">
|
||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
||||
<ha-progress-button
|
||||
class="warning"
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._resetTapped}
|
||||
>
|
||||
${this.supervisor.localize("common.reset_defaults")}
|
||||
</ha-progress-button>
|
||||
<ha-progress-button
|
||||
@click=${this._saveTapped}
|
||||
.disabled=${!this._configHasChanged}
|
||||
.disabled=${!this._configHasChanged || this.disabled}
|
||||
>
|
||||
${this.supervisor.localize("common.save")}
|
||||
</ha-progress-button>
|
||||
@@ -155,6 +163,10 @@ class HassioAddonNetwork extends LitElement {
|
||||
}
|
||||
|
||||
private async _resetTapped(ev: CustomEvent): Promise<void> {
|
||||
if (this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
const data: HassioAddonSetOptionParams = {
|
||||
network: null,
|
||||
@@ -186,6 +198,10 @@ class HassioAddonNetwork extends LitElement {
|
||||
}
|
||||
|
||||
private async _saveTapped(ev: CustomEvent): Promise<void> {
|
||||
if (!this._configHasChanged || this.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
|
||||
this._error = undefined;
|
||||
|
||||
@@ -52,6 +52,9 @@ class HassioAddonDashboard extends LitElement {
|
||||
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@state()
|
||||
private _controlEnabled = false;
|
||||
|
||||
@state() private _error?: string;
|
||||
|
||||
private _backPath = new URLSearchParams(window.parent.location.search).get(
|
||||
@@ -134,11 +137,17 @@ class HassioAddonDashboard extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this.supervisor}
|
||||
.addon=${this.addon}
|
||||
.controlEnabled=${this._controlEnabled}
|
||||
@system-managed-take-control=${this._enableControl}
|
||||
></hassio-addon-router>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
private _enableControl() {
|
||||
this._controlEnabled = true;
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
|
||||
@@ -23,6 +23,9 @@ class HassioAddonRouter extends HassRouterPage {
|
||||
| HassioAddonDetails
|
||||
| StoreAddonDetails;
|
||||
|
||||
@property({ type: Boolean, attribute: "control-enabled" })
|
||||
public controlEnabled = false;
|
||||
|
||||
protected routerOptions: RouterOptions = {
|
||||
defaultPage: "info",
|
||||
showLoading: true,
|
||||
@@ -48,6 +51,7 @@ class HassioAddonRouter extends HassRouterPage {
|
||||
el.supervisor = this.supervisor;
|
||||
el.addon = this.addon;
|
||||
el.narrow = this.narrow;
|
||||
el.controlEnabled = this.controlEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ class HassioAddonInfoDashboard extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public addon?: HassioAddonDetails;
|
||||
|
||||
@property({ type: Boolean, attribute: "control-enabled" })
|
||||
public controlEnabled = false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.addon) {
|
||||
return html`<ha-spinner></ha-spinner>`;
|
||||
@@ -34,6 +37,7 @@ class HassioAddonInfoDashboard extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.supervisor=${this.supervisor}
|
||||
.addon=${this.addon}
|
||||
.controlEnabled=${this.controlEnabled}
|
||||
></hassio-addon-info>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import "@material/mwc-button";
|
||||
import {
|
||||
mdiCheckCircle,
|
||||
mdiChip,
|
||||
mdiPlayCircle,
|
||||
mdiCircleOffOutline,
|
||||
mdiCursorDefaultClickOutline,
|
||||
mdiDocker,
|
||||
@@ -19,27 +17,30 @@ import {
|
||||
mdiNumeric6,
|
||||
mdiNumeric7,
|
||||
mdiNumeric8,
|
||||
mdiPlayCircle,
|
||||
mdiPound,
|
||||
mdiShield,
|
||||
} from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { LitElement, css, html } from "lit";
|
||||
import { LitElement, css, html, nothing } 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";
|
||||
import { navigate } from "../../../../src/common/navigate";
|
||||
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/chips/ha-chip-set";
|
||||
import "../../../../src/components/chips/ha-assist-chip";
|
||||
import "../../../../src/components/chips/ha-chip-set";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-button";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import "../../../../src/components/ha-markdown";
|
||||
import "../../../../src/components/ha-settings-row";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import "../../../../src/components/ha-switch";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import type { HaSwitch } from "../../../../src/components/ha-switch";
|
||||
import type {
|
||||
AddonCapability,
|
||||
@@ -81,10 +82,11 @@ import { bytesToString } from "../../../../src/util/bytes-to-string";
|
||||
import "../../components/hassio-card-content";
|
||||
import "../../components/supervisor-metric";
|
||||
import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
|
||||
import { showSystemManagedDialog } from "../../dialogs/system-managed/show-dialog-system-managed";
|
||||
import { hassioStyle } from "../../resources/hassio-style";
|
||||
import "../../update-available/update-available-card";
|
||||
import { addonArchIsSupported, extractChangelog } from "../../util/addon";
|
||||
import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter";
|
||||
import "./hassio-addon-system-managed";
|
||||
|
||||
const STAGE_ICON = {
|
||||
stable: mdiCheckCircle,
|
||||
@@ -117,6 +119,9 @@ class HassioAddonInfo extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@property({ type: Boolean, attribute: "control-enabled" })
|
||||
public controlEnabled = false;
|
||||
|
||||
@state() private _metrics?: HassioStats;
|
||||
|
||||
@state() private _error?: string;
|
||||
@@ -155,6 +160,9 @@ class HassioAddonInfo extends LitElement {
|
||||
)}`,
|
||||
},
|
||||
];
|
||||
|
||||
const systemManaged = this._isSystemManaged(this.addon);
|
||||
|
||||
return html`
|
||||
${this.addon.update_available
|
||||
? html`
|
||||
@@ -166,7 +174,7 @@ class HassioAddonInfo extends LitElement {
|
||||
@update-complete=${this._updateComplete}
|
||||
></update-available-card>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${"protected" in this.addon && !this.addon.protected
|
||||
? html`
|
||||
<ha-alert
|
||||
@@ -178,22 +186,31 @@ class HassioAddonInfo extends LitElement {
|
||||
${this.supervisor.localize(
|
||||
"addon.dashboard.protection_mode.content"
|
||||
)}
|
||||
<mwc-button
|
||||
<ha-button
|
||||
slot="action"
|
||||
.label=${this.supervisor.localize(
|
||||
"addon.dashboard.protection_mode.enable"
|
||||
)}
|
||||
@click=${this._protectionToggled}
|
||||
>
|
||||
</mwc-button>
|
||||
</ha-button>
|
||||
</ha-alert>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${systemManaged
|
||||
? html`
|
||||
<hassio-addon-system-managed
|
||||
.supervisor=${this.supervisor}
|
||||
.narrow=${this.narrow}
|
||||
.hideButton=${this.controlEnabled}
|
||||
></hassio-addon-system-managed>
|
||||
`
|
||||
: nothing}
|
||||
|
||||
<ha-card outlined>
|
||||
<div class="card-content">
|
||||
<div class="addon-header">
|
||||
${!this.narrow ? this.addon.name : ""}
|
||||
${!this.narrow ? this.addon.name : nothing}
|
||||
<div class="addon-version light-color">
|
||||
${this.addon.version
|
||||
? html`
|
||||
@@ -266,7 +283,7 @@ class HassioAddonInfo extends LitElement {
|
||||
</ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
|
||||
<ha-assist-chip
|
||||
filled
|
||||
@@ -301,7 +318,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiNetwork}> </ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.full_access
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -317,7 +334,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiChip}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.homeassistant_api
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -336,7 +353,7 @@ class HassioAddonInfo extends LitElement {
|
||||
></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this._computeHassioApi
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -355,7 +372,7 @@ class HassioAddonInfo extends LitElement {
|
||||
></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.docker_api
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -371,7 +388,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiDocker}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.host_pid
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -387,7 +404,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiPound}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.apparmor !== "default"
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -404,7 +421,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiShield}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.auth_api
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -420,7 +437,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiKey}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.ingress
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -439,7 +456,7 @@ class HassioAddonInfo extends LitElement {
|
||||
></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.signed
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
@@ -455,7 +472,24 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-svg-icon slot="icon" .path=${mdiLinkLock}></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${systemManaged
|
||||
? html`
|
||||
<ha-assist-chip
|
||||
filled
|
||||
@click=${this._showSystemManagedDialog}
|
||||
id="system_managed"
|
||||
.label=${capitalizeFirstLetter(
|
||||
this.supervisor.localize("addon.system_managed.badge")
|
||||
)}
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="icon"
|
||||
.path=${mdiHomeAssistant}
|
||||
></ha-svg-icon>
|
||||
</ha-assist-chip>
|
||||
`
|
||||
: nothing}
|
||||
</ha-chip-set>
|
||||
|
||||
<div class="description light-color">
|
||||
@@ -479,7 +513,7 @@ class HassioAddonInfo extends LitElement {
|
||||
src="/api/hassio/addons/${this.addon.slug}/logo"
|
||||
/>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.version
|
||||
? html`
|
||||
<div
|
||||
@@ -500,6 +534,7 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.disabled=${systemManaged && !this.controlEnabled}
|
||||
@change=${this._startOnBootToggled}
|
||||
.checked=${this.addon.boot === "auto"}
|
||||
haptic
|
||||
@@ -520,13 +555,15 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.disabled=${systemManaged &&
|
||||
!this.controlEnabled}
|
||||
@change=${this._watchdogToggled}
|
||||
.checked=${this.addon.watchdog}
|
||||
.checked=${this.addon.watchdog || false}
|
||||
haptic
|
||||
></ha-switch>
|
||||
</ha-settings-row>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this.addon.auto_update ||
|
||||
this.hass.userData?.showAdvanced
|
||||
? html`
|
||||
@@ -542,13 +579,15 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.disabled=${systemManaged &&
|
||||
!this.controlEnabled}
|
||||
@change=${this._autoUpdateToggled}
|
||||
.checked=${this.addon.auto_update}
|
||||
haptic
|
||||
></ha-switch>
|
||||
</ha-settings-row>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${!this._computeCannotIngressSidebar && this.addon.ingress
|
||||
? html`
|
||||
<ha-settings-row ?three-line=${this.narrow}>
|
||||
@@ -563,13 +602,15 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.disabled=${systemManaged &&
|
||||
!this.controlEnabled}
|
||||
@change=${this._panelToggled}
|
||||
.checked=${this.addon.ingress_panel}
|
||||
haptic
|
||||
></ha-switch>
|
||||
</ha-settings-row>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this._computeUsesProtectedOptions
|
||||
? html`
|
||||
<ha-settings-row ?three-line=${this.narrow}>
|
||||
@@ -584,16 +625,18 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</span>
|
||||
<ha-switch
|
||||
.disabled=${systemManaged &&
|
||||
!this.controlEnabled}
|
||||
@change=${this._protectionToggled}
|
||||
.checked=${this.addon.protected}
|
||||
haptic
|
||||
></ha-switch>
|
||||
</ha-settings-row>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
</div>
|
||||
<div>
|
||||
${this.addon.version && this.addon.state === "started"
|
||||
@@ -612,12 +655,12 @@ class HassioAddonInfo extends LitElement {
|
||||
></supervisor-metric>
|
||||
`
|
||||
)}`
|
||||
: ""}
|
||||
: nothing}
|
||||
</div>
|
||||
</div>
|
||||
${this._error
|
||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||
: ""}
|
||||
: nothing}
|
||||
${!this.addon.version && addonStoreInfo && !this.addon.available
|
||||
? !addonArchIsSupported(
|
||||
this.supervisor.info.supported_arch,
|
||||
@@ -641,7 +684,7 @@ class HassioAddonInfo extends LitElement {
|
||||
)}
|
||||
</ha-alert>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<div>
|
||||
@@ -651,6 +694,7 @@ class HassioAddonInfo extends LitElement {
|
||||
<ha-progress-button
|
||||
class="warning"
|
||||
@click=${this._stopClicked}
|
||||
.disabled=${systemManaged && !this.controlEnabled}
|
||||
>
|
||||
${this.supervisor.localize("addon.dashboard.stop")}
|
||||
</ha-progress-button>
|
||||
@@ -688,26 +732,27 @@ class HassioAddonInfo extends LitElement {
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<mwc-button>
|
||||
<ha-button>
|
||||
${this.supervisor.localize(
|
||||
"addon.dashboard.open_web_ui"
|
||||
)}
|
||||
</mwc-button>
|
||||
</ha-button>
|
||||
</a>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
${this._computeShowIngressUI
|
||||
? html`
|
||||
<mwc-button @click=${this._openIngress}>
|
||||
<ha-button @click=${this._openIngress}>
|
||||
${this.supervisor.localize(
|
||||
"addon.dashboard.open_web_ui"
|
||||
)}
|
||||
</mwc-button>
|
||||
</ha-button>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
<ha-progress-button
|
||||
class="warning"
|
||||
@click=${this._uninstallClicked}
|
||||
.disabled=${systemManaged && !this.controlEnabled}
|
||||
>
|
||||
${this.supervisor.localize("addon.dashboard.uninstall")}
|
||||
</ha-progress-button>
|
||||
@@ -720,8 +765,8 @@ class HassioAddonInfo extends LitElement {
|
||||
${this.supervisor.localize("addon.dashboard.rebuild")}
|
||||
</ha-progress-button>
|
||||
`
|
||||
: ""}`
|
||||
: ""}
|
||||
: nothing}`
|
||||
: nothing}
|
||||
</div>
|
||||
</div>
|
||||
</ha-card>
|
||||
@@ -737,7 +782,7 @@ class HassioAddonInfo extends LitElement {
|
||||
</div>
|
||||
</ha-card>
|
||||
`
|
||||
: ""}
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -822,6 +867,13 @@ class HassioAddonInfo extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _showSystemManagedDialog() {
|
||||
showSystemManagedDialog(this, {
|
||||
addon: this.addon as HassioAddonDetails,
|
||||
supervisor: this.supervisor,
|
||||
});
|
||||
}
|
||||
|
||||
private get _computeIsRunning(): boolean {
|
||||
return (this.addon as HassioAddonDetails)?.state === "started";
|
||||
}
|
||||
@@ -1014,6 +1066,10 @@ class HassioAddonInfo extends LitElement {
|
||||
}
|
||||
|
||||
private async _stopClicked(ev: CustomEvent): Promise<void> {
|
||||
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
|
||||
@@ -1125,6 +1181,10 @@ class HassioAddonInfo extends LitElement {
|
||||
}
|
||||
|
||||
private async _uninstallClicked(ev: CustomEvent): Promise<void> {
|
||||
if (this._isSystemManaged(this.addon) && !this.controlEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
let removeData = false;
|
||||
@@ -1179,6 +1239,11 @@ class HassioAddonInfo extends LitElement {
|
||||
button.progress = false;
|
||||
}
|
||||
|
||||
private _isSystemManaged = memoizeOne(
|
||||
(addon: HassioAddonDetails | StoreAddonDetails) =>
|
||||
"system_managed" in addon && addon.system_managed
|
||||
);
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
@@ -1201,7 +1266,7 @@ class HassioAddonInfo extends LitElement {
|
||||
ha-card.warning .card-content {
|
||||
color: white;
|
||||
}
|
||||
ha-card.warning mwc-button {
|
||||
ha-card.warning ha-button {
|
||||
--mdc-theme-primary: white !important;
|
||||
}
|
||||
.warning {
|
||||
@@ -1215,12 +1280,12 @@ class HassioAddonInfo extends LitElement {
|
||||
padding-left: 8px;
|
||||
padding-inline-start: 8px;
|
||||
padding-inline-end: initial;
|
||||
font-size: 24px;
|
||||
font-size: var(--ha-font-size-2xl);
|
||||
color: var(--ha-card-header-color, var(--primary-text-color));
|
||||
}
|
||||
.addon-version {
|
||||
float: var(--float-end);
|
||||
font-size: 15px;
|
||||
font-size: var(--ha-font-size-m);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.errors {
|
||||
@@ -1246,7 +1311,7 @@ class HassioAddonInfo extends LitElement {
|
||||
ha-svg-icon.stopped {
|
||||
color: var(--error-color);
|
||||
}
|
||||
protection-enable mwc-button {
|
||||
protection-enable ha-button {
|
||||
--mdc-theme-primary: white;
|
||||
}
|
||||
.description a {
|
||||
@@ -1328,7 +1393,7 @@ class HassioAddonInfo extends LitElement {
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
ha-alert mwc-button {
|
||||
ha-alert ha-button {
|
||||
--mdc-theme-primary: var(--primary-text-color);
|
||||
}
|
||||
|
||||
|
||||
60
hassio/src/addon-view/info/hassio-addon-system-managed.ts
Normal file
60
hassio/src/addon-view/info/hassio-addon-system-managed.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import "@material/mwc-button";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-button";
|
||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
|
||||
@customElement("hassio-addon-system-managed")
|
||||
class HassioAddonSystemManaged extends LitElement {
|
||||
@property({ type: Boolean }) public narrow = false;
|
||||
|
||||
@property({ attribute: false }) public supervisor!: Supervisor;
|
||||
|
||||
@property({ type: Boolean, attribute: "hide-button" }) public hideButton =
|
||||
false;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ha-alert
|
||||
alert-type="warning"
|
||||
.title=${this.supervisor.localize("addon.system_managed.title")}
|
||||
.narrow=${this.narrow}
|
||||
>
|
||||
${this.supervisor.localize("addon.system_managed.description")}
|
||||
${!this.hideButton
|
||||
? html`
|
||||
<ha-button slot="action" @click=${this._takeControl}>
|
||||
${this.supervisor.localize("addon.system_managed.take_control")}
|
||||
</ha-button>
|
||||
`
|
||||
: nothing}
|
||||
</ha-alert>
|
||||
`;
|
||||
}
|
||||
|
||||
private _takeControl() {
|
||||
fireEvent(this, "system-managed-take-control");
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
ha-alert {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
ha-button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
`;
|
||||
}
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hassio-addon-system-managed": HassioAddonSystemManaged;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
"system-managed-take-control": undefined;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import "@material/mwc-button";
|
||||
import type { ActionDetail } from "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import { mdiBackupRestore, mdiDelete, mdiDotsVertical, mdiPlus } from "@mdi/js";
|
||||
import type { CSSResultGroup, PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-fab";
|
||||
import "../../../src/components/ha-icon-button";
|
||||
import "../../../src/components/ha-list-item";
|
||||
import "../../../src/components/ha-svg-icon";
|
||||
import type { HassioBackup } from "../../../src/data/hassio/backup";
|
||||
import {
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../src/dialogs/generic/show-dialog-box";
|
||||
import "../../../src/layouts/hass-loading-screen";
|
||||
import "../../../src/layouts/hass-tabs-subpage-data-table";
|
||||
import type { HaTabsSubpageDataTable } from "../../../src/layouts/hass-tabs-subpage-data-table";
|
||||
import { haStyle } from "../../../src/resources/styles";
|
||||
@@ -42,7 +44,6 @@ import { showHassioBackupDialog } from "../dialogs/backup/show-dialog-hassio-bac
|
||||
import { showHassioCreateBackupDialog } from "../dialogs/backup/show-dialog-hassio-create-backup";
|
||||
import { supervisorTabs } from "../hassio-tabs";
|
||||
import { hassioStyle } from "../resources/hassio-style";
|
||||
import "../../../src/layouts/hass-loading-screen";
|
||||
|
||||
type BackupItem = HassioBackup & {
|
||||
secondary: string;
|
||||
@@ -211,16 +212,16 @@ export class HassioBackups extends LitElement {
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item>
|
||||
<ha-list-item>
|
||||
${this.supervisor.localize("common.reload")}
|
||||
</mwc-list-item>
|
||||
<mwc-list-item>
|
||||
</ha-list-item>
|
||||
<ha-list-item>
|
||||
${this.supervisor.localize("dialog.backup_location.title")}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
${atLeastVersion(this.hass.config.version, 0, 116)
|
||||
? html`<mwc-list-item>
|
||||
? html`<ha-list-item>
|
||||
${this.supervisor.localize("backup.upload_backup")}
|
||||
</mwc-list-item>`
|
||||
</ha-list-item>`
|
||||
: ""}
|
||||
</ha-button-menu>
|
||||
|
||||
@@ -390,7 +391,7 @@ export class HassioBackups extends LitElement {
|
||||
top: -4px;
|
||||
}
|
||||
.selected-txt {
|
||||
font-weight: bold;
|
||||
font-weight: var(--ha-font-weight-bold);
|
||||
padding-left: 16px;
|
||||
padding-inline-start: 16px;
|
||||
padding-inline-end: initial;
|
||||
@@ -400,7 +401,7 @@ export class HassioBackups extends LitElement {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.header-toolbar .selected-txt {
|
||||
font-size: 16px;
|
||||
font-size: var(--ha-font-size-l);
|
||||
}
|
||||
.header-toolbar .header-btns {
|
||||
margin-right: -12px;
|
||||
|
||||
@@ -85,7 +85,7 @@ class HassioCardContent extends LitElement {
|
||||
}
|
||||
ha-svg-icon.hassupdate,
|
||||
ha-svg-icon.backup {
|
||||
color: var(--paper-item-icon-color);
|
||||
color: var(--state-icon-color);
|
||||
}
|
||||
ha-svg-icon.not_available {
|
||||
color: var(--error-color);
|
||||
@@ -101,7 +101,7 @@ class HassioCardContent extends LitElement {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: 2.4em;
|
||||
line-height: 1.2em;
|
||||
line-height: var(--ha-line-height-condensed);
|
||||
}
|
||||
.icon_image img {
|
||||
max-height: 40px;
|
||||
|
||||
@@ -130,8 +130,8 @@ export class HassioUpdate extends LitElement {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.update-heading {
|
||||
font-size: var(--paper-font-subhead_-_font-size);
|
||||
font-weight: 500;
|
||||
font-size: var(--ha-font-size-l);
|
||||
font-weight: var(--ha-font-weight-semibold);
|
||||
margin-bottom: 0.5em;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ActionDetail } from "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import { mdiClose, mdiDotsVertical } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -8,15 +8,17 @@ import { atLeastVersion } from "../../../../src/common/config/version";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../../src/common/dom/stop_propagation";
|
||||
import { slugify } from "../../../../src/common/string/slugify";
|
||||
import "../../../../src/components/ha-md-dialog";
|
||||
import "../../../../src/components/ha-dialog-header";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-alert";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import "../../../../src/components/ha-button";
|
||||
import "../../../../src/components/ha-button-menu";
|
||||
import "../../../../src/components/ha-dialog-header";
|
||||
import "../../../../src/components/ha-header-bar";
|
||||
import "../../../../src/components/ha-icon-button";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import { getSignedPath } from "../../../../src/data/auth";
|
||||
import type { HassioBackupDetail } from "../../../../src/data/hassio/backup";
|
||||
import {
|
||||
@@ -36,7 +38,6 @@ import { fileDownload } from "../../../../src/util/file_download";
|
||||
import "../../components/supervisor-backup-content";
|
||||
import type { SupervisorBackupContent } from "../../components/supervisor-backup-content";
|
||||
import type { HassioBackupDialogParams } from "./show-dialog-hassio-backup";
|
||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||
|
||||
@customElement("dialog-hassio-backup")
|
||||
class HassioBackupDialog
|
||||
@@ -121,15 +122,15 @@ class HassioBackupDialog
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item
|
||||
<ha-list-item
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.download_backup"
|
||||
)}</mwc-list-item
|
||||
)}</ha-list-item
|
||||
>
|
||||
<mwc-list-item class="error"
|
||||
<ha-list-item class="error"
|
||||
>${this._dialogParams.supervisor.localize(
|
||||
"backup.delete_backup_title"
|
||||
)}</mwc-list-item
|
||||
)}</ha-list-item
|
||||
>
|
||||
</ha-button-menu>`
|
||||
: nothing}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import "../../../../src/components/ha-select";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-select";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import {
|
||||
extractApiErrorMessage,
|
||||
ignoreSupervisorError,
|
||||
@@ -95,8 +95,8 @@ class HassioDatadiskDialog extends LitElement {
|
||||
>
|
||||
${this.devices.map(
|
||||
(device) =>
|
||||
html`<mwc-list-item .value=${device}
|
||||
>${device}</mwc-list-item
|
||||
html`<ha-list-item .value=${device}
|
||||
>${device}</ha-list-item
|
||||
>`
|
||||
)}
|
||||
</ha-select>
|
||||
|
||||
@@ -169,8 +169,8 @@ class HassioHardwareDialog extends LitElement {
|
||||
pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
line-height: 1.45;
|
||||
font-family: var(--code-font-family, monospace);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
font-family: var(--ha-font-family-code);
|
||||
}
|
||||
code {
|
||||
font-size: 85%;
|
||||
|
||||
@@ -38,6 +38,7 @@ class HassioMarkdownDialog extends LitElement {
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(this.hass, this.title)}
|
||||
hideactions
|
||||
>
|
||||
<ha-markdown
|
||||
.content=${this.content || ""}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import "@material/mwc-tab";
|
||||
import "@material/mwc-tab-bar";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
@@ -10,14 +6,16 @@ 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-alert";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import "../../../../src/components/ha-dialog";
|
||||
import "../../../../src/components/ha-expansion-panel";
|
||||
import "../../../../src/components/ha-formfield";
|
||||
import "../../../../src/components/ha-header-bar";
|
||||
import "../../../../src/components/ha-icon-button";
|
||||
import "../../../../src/components/ha-list";
|
||||
import "../../../../src/components/ha-list-item";
|
||||
import "../../../../src/components/ha-password-field";
|
||||
import "../../../../src/components/ha-radio";
|
||||
import "../../../../src/components/ha-spinner";
|
||||
import "../../../../src/components/ha-textfield";
|
||||
import type { HaTextField } from "../../../../src/components/ha-textfield";
|
||||
import { extractApiErrorMessage } from "../../../../src/data/hassio/common";
|
||||
@@ -39,6 +37,7 @@ import type { HassDialog } from "../../../../src/dialogs/make-dialog-manager";
|
||||
import { haStyleDialog } from "../../../../src/resources/styles";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import type { HassioNetworkDialogParams } from "./show-dialog-network";
|
||||
import "../../../../src/components/sl-tab-group";
|
||||
|
||||
const IP_VERSIONS = ["ipv4", "ipv6"];
|
||||
|
||||
@@ -116,19 +115,19 @@ export class DialogHassioNetwork
|
||||
></ha-icon-button>
|
||||
</ha-header-bar>
|
||||
${this._interfaces.length > 1
|
||||
? html`<mwc-tab-bar
|
||||
.activeIndex=${this._curTabIndex}
|
||||
@MDCTabBar:activated=${this._handleTabActivated}
|
||||
? html`<sl-tab-group @sl-tab-show=${this._handleTabActivated}
|
||||
>${this._interfaces.map(
|
||||
(device) =>
|
||||
html`<mwc-tab
|
||||
(device, index) =>
|
||||
html`<sl-tab
|
||||
slot="nav"
|
||||
.id=${device.interface}
|
||||
.label=${device.interface}
|
||||
dialogInitialFocus
|
||||
.panel=${index.toString()}
|
||||
.active=${this._curTabIndex === index}
|
||||
>
|
||||
</mwc-tab>`
|
||||
${device.interface}
|
||||
</sl-tab>`
|
||||
)}
|
||||
</mwc-tab-bar>`
|
||||
</sl-tab-group>`
|
||||
: ""}
|
||||
</div>
|
||||
${cache(this._renderTab())}
|
||||
@@ -169,12 +168,12 @@ export class DialogHassioNetwork
|
||||
this._accessPoints.accesspoints &&
|
||||
this._accessPoints.accesspoints.length !== 0
|
||||
? html`
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
${this._accessPoints.accesspoints
|
||||
.filter((ap) => ap.ssid)
|
||||
.map(
|
||||
(ap) => html`
|
||||
<mwc-list-item
|
||||
<ha-list-item
|
||||
twoline
|
||||
@click=${this._selectAP}
|
||||
.activated=${ap.ssid ===
|
||||
@@ -189,10 +188,10 @@ export class DialogHassioNetwork
|
||||
)}:
|
||||
${ap.signal}
|
||||
</span>
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`
|
||||
: ""}
|
||||
${this._wifiConfiguration
|
||||
@@ -485,8 +484,8 @@ export class DialogHassioNetwork
|
||||
return;
|
||||
}
|
||||
}
|
||||
this._curTabIndex = ev.detail.index;
|
||||
this._interface = { ...this._interfaces[ev.detail.index] };
|
||||
this._curTabIndex = Number(ev.detail.name);
|
||||
this._interface = { ...this._interfaces[this._curTabIndex] };
|
||||
}
|
||||
|
||||
private _handleRadioValueChanged(ev: CustomEvent): void {
|
||||
@@ -560,11 +559,6 @@ export class DialogHassioNetwork
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
mwc-tab-bar {
|
||||
border-bottom: 1px solid
|
||||
var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
|
||||
}
|
||||
|
||||
ha-dialog {
|
||||
--dialog-content-position: static;
|
||||
--dialog-content-padding: 0;
|
||||
@@ -634,9 +628,17 @@ export class DialogHassioNetwork
|
||||
ha-textfield {
|
||||
padding: 0 14px;
|
||||
}
|
||||
mwc-list-item {
|
||||
ha-list-item {
|
||||
--mdc-list-side-padding: 10px;
|
||||
}
|
||||
|
||||
sl-tab {
|
||||
flex: 1;
|
||||
}
|
||||
sl-tab::part(base) {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -183,9 +183,6 @@ class HassioRepositoriesDialog extends LitElement {
|
||||
ha-dialog.button-left {
|
||||
--justify-action-buttons: flex-start;
|
||||
}
|
||||
paper-icon-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
.form {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
192
hassio/src/dialogs/system-managed/dialog-system-managed.ts
Normal file
192
hassio/src/dialogs/system-managed/dialog-system-managed.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import { mdiClose, mdiPuzzle, mdiSwapHorizontal } from "@mdi/js";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../../../src/common/config/version";
|
||||
import "../../../../src/components/ha-dialog-header";
|
||||
import "../../../../src/components/ha-icon-button";
|
||||
import "../../../../src/components/ha-icon-next";
|
||||
import "../../../../src/components/ha-md-dialog";
|
||||
import type { HaMdDialog } from "../../../../src/components/ha-md-dialog";
|
||||
import "../../../../src/components/ha-md-list";
|
||||
import "../../../../src/components/ha-md-list-item";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import {
|
||||
getConfigEntry,
|
||||
type ConfigEntry,
|
||||
} from "../../../../src/data/config_entries";
|
||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg";
|
||||
import { haStyle } from "../../../../src/resources/styles";
|
||||
import type { HomeAssistant } from "../../../../src/types";
|
||||
import { brandsUrl } from "../../../../src/util/brands-url";
|
||||
import type { SystemManagedDialogParams } from "./show-dialog-system-managed";
|
||||
|
||||
@customElement("dialog-system-managed")
|
||||
class HassioSystemManagedDialog extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _supervisor?: Supervisor;
|
||||
|
||||
@state() private _addon?: HassioAddonDetails;
|
||||
|
||||
@state() private _open = false;
|
||||
|
||||
@state() private _configEntry?: ConfigEntry;
|
||||
|
||||
@query("ha-md-dialog") private _dialog?: HaMdDialog;
|
||||
|
||||
public async showDialog(
|
||||
dialogParams: SystemManagedDialogParams
|
||||
): Promise<void> {
|
||||
this._addon = dialogParams.addon;
|
||||
this._supervisor = dialogParams.supervisor;
|
||||
this._open = true;
|
||||
this._loadConfigEntry();
|
||||
}
|
||||
|
||||
private _dialogClosed() {
|
||||
this._addon = undefined;
|
||||
this._supervisor = undefined;
|
||||
this._configEntry = undefined;
|
||||
this._open = false;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
this._dialog?.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._addon || !this._open || !this._supervisor) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const addonImage =
|
||||
atLeastVersion(this.hass.config.version, 0, 105) && this._addon.icon
|
||||
? `/api/hassio/addons/${this._addon.slug}/icon`
|
||||
: undefined;
|
||||
|
||||
return html`
|
||||
<ha-md-dialog open @closed=${this._dialogClosed}>
|
||||
<ha-dialog-header slot="headline">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
.path=${mdiClose}
|
||||
@click=${this.closeDialog}
|
||||
></ha-icon-button>
|
||||
<span slot="title">${this._addon?.name}</span>
|
||||
</ha-dialog-header>
|
||||
<div slot="content">
|
||||
<div class="icons">
|
||||
<ha-svg-icon
|
||||
class="primary"
|
||||
.path=${mdiHomeAssistant}
|
||||
></ha-svg-icon>
|
||||
<ha-svg-icon .path=${mdiSwapHorizontal}></ha-svg-icon>
|
||||
${addonImage
|
||||
? html`<img src=${addonImage} alt=${this._addon.name} />`
|
||||
: html`<ha-svg-icon .path=${mdiPuzzle}></ha-svg-icon>`}
|
||||
</div>
|
||||
${this._supervisor.localize("addon.system_managed.title")}.<br />
|
||||
${this._supervisor.localize("addon.system_managed.description")}
|
||||
${this._configEntry
|
||||
? html`
|
||||
<h3>
|
||||
${this._supervisor.localize(
|
||||
"addon.system_managed.managed_by"
|
||||
)}:
|
||||
</h3>
|
||||
<ha-md-list>
|
||||
<ha-md-list-item
|
||||
type="link"
|
||||
href=${`/config/integrations/integration/${this._configEntry.domain}`}
|
||||
>
|
||||
<img
|
||||
slot="start"
|
||||
class="integration-icon"
|
||||
alt=${this._configEntry.title}
|
||||
src=${brandsUrl({
|
||||
domain: this._configEntry.domain,
|
||||
type: "icon",
|
||||
darkOptimized: this.hass.themes?.darkMode,
|
||||
})}
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
@error=${this._onImageError}
|
||||
@load=${this._onImageLoad}
|
||||
/>
|
||||
${this._configEntry.title}
|
||||
<ha-icon-next slot="end"></ha-icon-next>
|
||||
</ha-md-list-item>
|
||||
</ha-md-list>
|
||||
`
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-md-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _onImageLoad(ev) {
|
||||
ev.target.style.visibility = "initial";
|
||||
}
|
||||
|
||||
private _onImageError(ev) {
|
||||
ev.target.style.visibility = "hidden";
|
||||
}
|
||||
|
||||
private async _loadConfigEntry() {
|
||||
if (this._addon?.system_managed_config_entry) {
|
||||
try {
|
||||
const { config_entry } = await getConfigEntry(
|
||||
this.hass,
|
||||
this._addon.system_managed_config_entry
|
||||
);
|
||||
this._configEntry = config_entry;
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.icons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
--mdc-icon-size: 48px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.icons img {
|
||||
width: 48px;
|
||||
}
|
||||
.icons .primary {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.integration-icon {
|
||||
width: 24px;
|
||||
}
|
||||
ha-md-list-item {
|
||||
--md-list-item-leading-space: 4px;
|
||||
--md-list-item-trailing-space: 4px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-system-managed": HassioSystemManagedDialog;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { fireEvent } from "../../../../src/common/dom/fire_event";
|
||||
import type { HassioAddonDetails } from "../../../../src/data/hassio/addon";
|
||||
import type { Supervisor } from "../../../../src/data/supervisor/supervisor";
|
||||
|
||||
export interface SystemManagedDialogParams {
|
||||
addon: HassioAddonDetails;
|
||||
supervisor: Supervisor;
|
||||
}
|
||||
|
||||
export const showSystemManagedDialog = (
|
||||
element: HTMLElement,
|
||||
dialogParams: SystemManagedDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-system-managed",
|
||||
dialogImport: () => import("./dialog-system-managed"),
|
||||
dialogParams,
|
||||
});
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import "./hassio-main";
|
||||
|
||||
import("../../src/resources/ha-style");
|
||||
import("../../src/resources/append-ha-style");
|
||||
|
||||
const styleEl = document.createElement("style");
|
||||
styleEl.textContent = `
|
||||
@@ -8,7 +8,7 @@ body {
|
||||
font-family: Roboto, sans-serif;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-weight: 400;
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
|
||||
@@ -340,12 +340,12 @@ class HassioIngressView extends LitElement {
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-size: var(--ha-font-size-l);
|
||||
height: 40px;
|
||||
padding: 0 16px;
|
||||
pointer-events: none;
|
||||
background-color: var(--app-header-background-color);
|
||||
font-weight: 400;
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
color: var(--app-header-text-color, white);
|
||||
border-bottom: var(--app-header-border-bottom, none);
|
||||
box-sizing: border-box;
|
||||
@@ -354,7 +354,7 @@ class HassioIngressView extends LitElement {
|
||||
|
||||
.main-title {
|
||||
margin: var(--margin-title);
|
||||
line-height: 20px;
|
||||
line-height: var(--ha-line-height-normal);
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,11 @@ export const hassioStyle = css`
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin-bottom: 8px;
|
||||
font-family: var(--paper-font-headline_-_font-family);
|
||||
-webkit-font-smoothing: var(--paper-font-headline_-_-webkit-font-smoothing);
|
||||
font-size: var(--paper-font-headline_-_font-size);
|
||||
font-weight: var(--paper-font-headline_-_font-weight);
|
||||
letter-spacing: var(--paper-font-headline_-_letter-spacing);
|
||||
line-height: var(--paper-font-headline_-_line-height);
|
||||
font-family: var(--ha-font-family-body);
|
||||
-webkit-font-smoothing: var(--ha-font-smoothing);
|
||||
font-size: var(--ha-font-size-2xl);
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
line-height: var(--ha-line-height-condensed);
|
||||
padding-left: 8px;
|
||||
padding-inline-start: 8px;
|
||||
padding-inline-end: initial;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@@ -197,9 +197,6 @@ class HassioCoreInfo extends LitElement {
|
||||
color: var(--secondary-text-color);
|
||||
--mdc-menu-min-width: 200px;
|
||||
}
|
||||
mwc-list-item ha-svg-icon {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import { mdiDotsVertical } from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
@@ -10,6 +10,7 @@ import { fireEvent } from "../../../src/common/dom/fire_event";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-list-item";
|
||||
import "../../../src/components/ha-icon-button";
|
||||
import "../../../src/components/ha-settings-row";
|
||||
import {
|
||||
@@ -188,31 +189,31 @@ class HassioHostInfo extends LitElement {
|
||||
.path=${mdiDotsVertical}
|
||||
slot="trigger"
|
||||
></ha-icon-button>
|
||||
<mwc-list-item
|
||||
<ha-list-item
|
||||
.action=${"hardware"}
|
||||
@click=${this._handleMenuAction}
|
||||
>
|
||||
${this.supervisor.localize("system.host.hardware")}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
${this.supervisor.host.features.includes("haos")
|
||||
? html`
|
||||
<mwc-list-item
|
||||
<ha-list-item
|
||||
.action=${"import_from_usb"}
|
||||
@click=${this._handleMenuAction}
|
||||
>
|
||||
${this.supervisor.localize("system.host.import_from_usb")}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
${this.supervisor.host.features.includes("os_agent") &&
|
||||
atLeastVersion(this.supervisor.host.agent_version, 1, 2, 0)
|
||||
? html`
|
||||
<mwc-list-item
|
||||
<ha-list-item
|
||||
.action=${"move_datadisk"}
|
||||
@click=${this._handleMenuAction}
|
||||
>
|
||||
${this.supervisor.localize(
|
||||
"system.host.move_datadisk"
|
||||
)}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
`
|
||||
: ""}
|
||||
`
|
||||
@@ -438,7 +439,7 @@ class HassioHostInfo extends LitElement {
|
||||
color: var(--secondary-text-color);
|
||||
--mdc-menu-min-width: 200px;
|
||||
}
|
||||
mwc-list-item ha-svg-icon {
|
||||
ha-list-item ha-svg-icon {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
a {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@@ -8,6 +8,7 @@ import "../../../src/components/ha-alert";
|
||||
import "../../../src/components/ha-ansi-to-html";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-select";
|
||||
import "../../../src/components/ha-list-item";
|
||||
import { extractApiErrorMessage } from "../../../src/data/hassio/common";
|
||||
import { fetchHassioLogs } from "../../../src/data/hassio/supervisor";
|
||||
import type { Supervisor } from "../../../src/data/supervisor/supervisor";
|
||||
@@ -80,9 +81,9 @@ class HassioSupervisorLog extends LitElement {
|
||||
>
|
||||
${logProviders.map(
|
||||
(provider) => html`
|
||||
<mwc-list-item .value=${provider.key}>
|
||||
<ha-list-item .value=${provider.key}>
|
||||
${provider.name}
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</ha-select>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import {
|
||||
css,
|
||||
type CSSResultGroup,
|
||||
|
||||
@@ -2,6 +2,8 @@ import "@material/mwc-linear-progress";
|
||||
import { type PropertyValues, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../../src/components/ha-alert";
|
||||
import "../../src/components/ha-fade-in";
|
||||
import "../../src/components/ha-spinner";
|
||||
import { haStyle } from "../../src/resources/styles";
|
||||
import "../../src/onboarding/onboarding-welcome-links";
|
||||
import "./components/landing-page-network";
|
||||
@@ -40,6 +42,14 @@ class HaLandingPage extends LandingPageBaseElement {
|
||||
render() {
|
||||
const networkIssue = this._networkInfo && !this._networkInfo.host_internet;
|
||||
|
||||
if (!this.localize) {
|
||||
return html`
|
||||
<ha-fade-in>
|
||||
<ha-spinner size="large"></ha-spinner>
|
||||
</ha-fade-in>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
@@ -229,6 +239,12 @@ class HaLandingPage extends LandingPageBaseElement {
|
||||
margin-inline-end: 16px;
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
ha-fade-in {
|
||||
min-height: calc(100vh - 64px - 88px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -6,23 +6,23 @@ import {
|
||||
type LandingPageKeys,
|
||||
type LocalizeFunc,
|
||||
} from "../../src/common/translations/localize";
|
||||
import { computeDirectionStyles } from "../../src/common/util/compute_rtl";
|
||||
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
||||
import { translationMetadata } from "../../src/resources/translations-metadata";
|
||||
import type { HassBaseEl } from "../../src/state/hass-base-mixin";
|
||||
import themesMixin from "../../src/state/themes-mixin";
|
||||
import type { Constructor, Resources } from "../../src/types";
|
||||
import {
|
||||
getLocalLanguage,
|
||||
getTranslation,
|
||||
} from "../../src/util/common-translation";
|
||||
import { computeDirectionStyles } from "../../src/common/util/compute_rtl";
|
||||
import themesMixin from "../../src/state/themes-mixin";
|
||||
import { translationMetadata } from "../../src/resources/translations-metadata";
|
||||
import type { HassBaseEl } from "../../src/state/hass-base-mixin";
|
||||
|
||||
export class LandingPageBaseElement extends themesMixin(
|
||||
ProvideHassLitMixin(LitElement) as unknown as Constructor<HassBaseEl>
|
||||
) {
|
||||
// Initialized to empty will prevent undefined errors if called before connected to DOM.
|
||||
@property({ attribute: false })
|
||||
public localize: LocalizeFunc<LandingPageKeys> = () => "";
|
||||
public localize?: LocalizeFunc<LandingPageKeys>;
|
||||
|
||||
// Use browser language setup before login.
|
||||
@property() public language?: string = getLocalLanguage();
|
||||
|
||||
49
package.json
49
package.json
@@ -31,10 +31,10 @@
|
||||
"@codemirror/autocomplete": "6.18.6",
|
||||
"@codemirror/commands": "6.8.1",
|
||||
"@codemirror/language": "6.11.0",
|
||||
"@codemirror/legacy-modes": "6.5.0",
|
||||
"@codemirror/legacy-modes": "6.5.1",
|
||||
"@codemirror/search": "6.5.10",
|
||||
"@codemirror/state": "6.5.2",
|
||||
"@codemirror/view": "6.36.5",
|
||||
"@codemirror/view": "6.36.6",
|
||||
"@egjs/hammerjs": "2.0.17",
|
||||
"@formatjs/intl-datetimeformat": "6.18.0",
|
||||
"@formatjs/intl-displaynames": "6.8.11",
|
||||
@@ -52,10 +52,11 @@
|
||||
"@fullcalendar/luxon3": "6.1.17",
|
||||
"@fullcalendar/timegrid": "6.1.17",
|
||||
"@lezer/highlight": "1.2.1",
|
||||
"@lit-labs/context": "0.4.1",
|
||||
"@lit-labs/motion": "1.0.8",
|
||||
"@lit-labs/observers": "2.0.5",
|
||||
"@lit-labs/virtualizer": "2.1.0",
|
||||
"@lit/context": "1.1.5",
|
||||
"@lit/reactive-element": "2.1.0",
|
||||
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
|
||||
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
|
||||
"@material/mwc-base": "0.27.0",
|
||||
@@ -65,17 +66,15 @@
|
||||
"@material/mwc-drawer": "0.27.0",
|
||||
"@material/mwc-fab": "0.27.0",
|
||||
"@material/mwc-floating-label": "0.27.0",
|
||||
"@material/mwc-formfield": "0.27.0",
|
||||
"@material/mwc-formfield": "patch:@material/mwc-formfield@npm%3A0.27.0#~/.yarn/patches/@material-mwc-formfield-npm-0.27.0-9528cb60f6.patch",
|
||||
"@material/mwc-icon-button": "0.27.0",
|
||||
"@material/mwc-linear-progress": "0.27.0",
|
||||
"@material/mwc-list": "0.27.0",
|
||||
"@material/mwc-list": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch",
|
||||
"@material/mwc-menu": "0.27.0",
|
||||
"@material/mwc-radio": "0.27.0",
|
||||
"@material/mwc-select": "0.27.0",
|
||||
"@material/mwc-snackbar": "0.27.0",
|
||||
"@material/mwc-switch": "0.27.0",
|
||||
"@material/mwc-tab": "0.27.0",
|
||||
"@material/mwc-tab-bar": "0.27.0",
|
||||
"@material/mwc-textarea": "0.27.0",
|
||||
"@material/mwc-textfield": "0.27.0",
|
||||
"@material/mwc-top-app-bar": "0.27.0",
|
||||
@@ -86,11 +85,12 @@
|
||||
"@mdi/svg": "7.4.47",
|
||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||
"@shoelace-style/shoelace": "2.20.1",
|
||||
"@swc/helpers": "0.5.17",
|
||||
"@thomasloven/round-slider": "0.6.0",
|
||||
"@tsparticles/engine": "3.8.1",
|
||||
"@tsparticles/preset-links": "3.2.0",
|
||||
"@vaadin/combo-box": "24.7.3",
|
||||
"@vaadin/vaadin-themable-mixin": "24.7.3",
|
||||
"@vaadin/combo-box": "24.7.4",
|
||||
"@vaadin/vaadin-themable-mixin": "24.7.4",
|
||||
"@vibrant/color": "4.0.0",
|
||||
"@vue/web-component-wrapper": "1.3.0",
|
||||
"@webcomponents/scoped-custom-element-registry": "0.0.10",
|
||||
@@ -119,10 +119,10 @@
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
|
||||
"leaflet.markercluster": "1.5.3",
|
||||
"lit": "2.8.0",
|
||||
"lit-html": "2.8.0",
|
||||
"lit": "3.3.0",
|
||||
"lit-html": "3.3.0",
|
||||
"luxon": "3.6.1",
|
||||
"marked": "15.0.8",
|
||||
"marked": "15.0.11",
|
||||
"memoize-one": "6.0.0",
|
||||
"node-vibrant": "4.0.3",
|
||||
"object-hash": "3.0.0",
|
||||
@@ -152,18 +152,16 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.26.10",
|
||||
"@babel/helper-define-polyfill-provider": "0.6.4",
|
||||
"@babel/plugin-proposal-decorators": "7.25.9",
|
||||
"@babel/plugin-transform-runtime": "7.26.10",
|
||||
"@babel/preset-env": "7.26.9",
|
||||
"@babel/preset-typescript": "7.27.0",
|
||||
"@bundle-stats/plugin-webpack-filter": "4.19.1",
|
||||
"@lokalise/node-api": "14.4.0",
|
||||
"@octokit/auth-oauth-device": "7.1.5",
|
||||
"@octokit/plugin-retry": "7.2.1",
|
||||
"@octokit/rest": "21.1.1",
|
||||
"@rsdoctor/rspack-plugin": "1.0.2",
|
||||
"@rspack/cli": "1.3.5",
|
||||
"@rspack/core": "1.3.5",
|
||||
"@rspack/cli": "1.3.7",
|
||||
"@rspack/core": "1.3.7",
|
||||
"@types/babel__plugin-transform-runtime": "7.9.5",
|
||||
"@types/chromecast-caf-receiver": "6.0.21",
|
||||
"@types/chromecast-caf-sender": "1.0.11",
|
||||
@@ -182,12 +180,12 @@
|
||||
"@types/tar": "6.1.13",
|
||||
"@types/ua-parser-js": "0.7.39",
|
||||
"@types/webspeechapi": "0.0.29",
|
||||
"@vitest/coverage-v8": "3.1.1",
|
||||
"@vitest/coverage-v8": "3.1.2",
|
||||
"babel-loader": "10.0.0",
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"browserslist-useragent-regexp": "4.1.3",
|
||||
"del": "8.0.0",
|
||||
"eslint": "9.25.0",
|
||||
"eslint": "9.25.1",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "10.1.2",
|
||||
"eslint-import-resolver-webpack": "0.13.10",
|
||||
@@ -198,7 +196,7 @@
|
||||
"eslint-plugin-wc": "3.0.0",
|
||||
"fancy-log": "2.0.0",
|
||||
"fs-extra": "11.3.0",
|
||||
"glob": "11.0.1",
|
||||
"glob": "11.0.2",
|
||||
"gulp": "5.0.0",
|
||||
"gulp-brotli": "3.0.0",
|
||||
"gulp-json-transform": "0.5.0",
|
||||
@@ -221,22 +219,23 @@
|
||||
"terser-webpack-plugin": "5.3.14",
|
||||
"ts-lit-plugin": "2.0.2",
|
||||
"typescript": "5.8.3",
|
||||
"typescript-eslint": "8.30.1",
|
||||
"typescript-eslint": "8.31.0",
|
||||
"vite-tsconfig-paths": "5.1.4",
|
||||
"vitest": "3.1.1",
|
||||
"vitest": "3.1.2",
|
||||
"webpack-stats-plugin": "1.1.3",
|
||||
"webpackbar": "7.0.0",
|
||||
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
|
||||
},
|
||||
"resolutions": {
|
||||
"@material/mwc-button@^0.25.3": "^0.27.0",
|
||||
"lit": "2.8.0",
|
||||
"lit-html": "2.8.0",
|
||||
"lit": "3.3.0",
|
||||
"lit-html": "3.3.0",
|
||||
"clean-css": "5.3.3",
|
||||
"@lit/reactive-element": "1.6.3",
|
||||
"@lit/reactive-element": "2.1.0",
|
||||
"@fullcalendar/daygrid": "6.1.17",
|
||||
"globals": "16.0.0",
|
||||
"tslib": "2.8.1"
|
||||
"tslib": "2.8.1",
|
||||
"@material/mwc-list@^0.27.0": "patch:@material/mwc-list@npm%3A0.27.0#~/.yarn/patches/@material-mwc-list-npm-0.27.0-5344fc9de4.patch"
|
||||
},
|
||||
"packageManager": "yarn@4.9.1"
|
||||
}
|
||||
|
||||
17
public/static/images/form/view_header_badges_wrap_scroll.svg
Normal file
17
public/static/images/form/view_header_badges_wrap_scroll.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg width="94" height="24" viewBox="0 0 94 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1349_5726)">
|
||||
<rect width="94" height="24" rx="8" fill="white"/>
|
||||
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="black" fill-opacity="0.32"/>
|
||||
<path d="M24.5 13C24.5 14.6569 25.8431 16 27.5 16H33.5C35.1569 16 36.5 14.6569 36.5 13V11C36.5 9.34315 35.1569 8 33.5 8H27.5C25.8431 8 24.5 9.34315 24.5 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M41 13C41 14.6569 42.3431 16 44 16H50C51.6569 16 53 14.6569 53 13V11C53 9.34315 51.6569 8 50 8H44C42.3431 8 41 9.34315 41 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M57.5 13C57.5 14.6569 58.8431 16 60.5 16H66.5C68.1569 16 69.5 14.6569 69.5 13V11C69.5 9.34315 68.1569 8 66.5 8H60.5C58.8431 8 57.5 9.34315 57.5 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M74 13C74 14.6569 75.3431 16 77 16H83C84.6569 16 86 14.6569 86 13V11C86 9.34315 84.6569 8 83 8H77C75.3431 8 74 9.34315 74 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M90 13C90 14.6569 91.3431 16 93 16H99C100.657 16 102 14.6569 102 13V11C102 9.34315 100.657 8 99 8H93C91.3431 8 90 9.34315 90 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
</g>
|
||||
<rect x="0.5" y="0.5" width="93" height="23" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||
<defs>
|
||||
<clipPath id="clip0_1349_5726">
|
||||
<rect width="94" height="24" rx="8" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,17 @@
|
||||
<svg width="94" height="24" viewBox="0 0 94 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1349_5798)">
|
||||
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V16C94 20.4183 90.4183 24 86 24H8C3.58172 24 0 20.4183 0 16V8Z" fill="#1C1C1C"/>
|
||||
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="white" fill-opacity="0.48"/>
|
||||
<path d="M24.5 12C24.5 14.2091 26.2909 16 28.5 16H32.5C34.7091 16 36.5 14.2091 36.5 12C36.5 9.79086 34.7091 8 32.5 8H28.5C26.2909 8 24.5 9.79086 24.5 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M41 12C41 14.2091 42.7909 16 45 16H49C51.2091 16 53 14.2091 53 12C53 9.79086 51.2091 8 49 8H45C42.7909 8 41 9.79086 41 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M57.5 12C57.5 14.2091 59.2909 16 61.5 16H65.5C67.7091 16 69.5 14.2091 69.5 12C69.5 9.79086 67.7091 8 65.5 8H61.5C59.2909 8 57.5 9.79086 57.5 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M74 12C74 14.2091 75.7909 16 78 16H82C84.2091 16 86 14.2091 86 12C86 9.79086 84.2091 8 82 8H78C75.7909 8 74 9.79086 74 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M90 12C90 14.2091 91.7909 16 94 16H98C100.209 16 102 14.2091 102 12V12C102 9.79086 100.209 8 98 8H94C91.7909 8 90 9.79086 90 12V12Z" fill="white" fill-opacity="0.24"/>
|
||||
</g>
|
||||
<path d="M1.34748 20.4449C0.772837 19.5866 0.359906 18.6109 0.152272 17.5613L0.642766 17.4643C0.549158 16.9911 0.5 16.5015 0.5 16V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V16C93.5 16.5015 93.4508 16.9911 93.3572 17.4643L93.8477 17.5613C93.6401 18.6109 93.2272 19.5866 92.6525 20.4449L92.237 20.1668C91.6893 20.9849 90.9849 21.6893 90.1668 22.237L90.4449 22.6525C89.5866 23.2272 88.6108 23.6401 87.5613 23.8477L87.4643 23.3572C86.9911 23.4508 86.5015 23.5 86 23.5H84.05V24H80.15V23.5H76.25V24H72.35V23.5H68.45V24H64.55V23.5H60.65V24H56.75V23.5H52.85V24H48.95V23.5H45.05V24H41.15V23.5H37.25V24H33.35V23.5H29.45V24H25.55V23.5H21.65V24H17.75V23.5H13.85V24H9.95V23.5H8C7.49847 23.5 7.00892 23.4508 6.53574 23.3572L6.4387 23.8477C5.38915 23.6401 4.41341 23.2272 3.55507 22.6525L3.83323 22.237C3.01513 21.6893 2.31067 20.9849 1.76296 20.1668L1.34748 20.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||
<defs>
|
||||
<clipPath id="clip0_1349_5798">
|
||||
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V16C94 20.4183 90.4183 24 86 24H8C3.58172 24 0 20.4183 0 16V8Z" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
11
public/static/images/form/view_header_badges_wrap_wrap.svg
Normal file
11
public/static/images/form/view_header_badges_wrap_wrap.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="94" height="40" rx="8" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="93" height="39" rx="7.5" stroke="black" stroke-opacity="0.12" stroke-dasharray="4 4"/>
|
||||
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="black" fill-opacity="0.32"/>
|
||||
<path d="M24.5 13C24.5 14.6569 25.8431 16 27.5 16H33.5C35.1569 16 36.5 14.6569 36.5 13V11C36.5 9.34315 35.1569 8 33.5 8H27.5C25.8431 8 24.5 9.34315 24.5 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M41 13C41 14.6569 42.3431 16 44 16H50C51.6569 16 53 14.6569 53 13V11C53 9.34315 51.6569 8 50 8H44C42.3431 8 41 9.34315 41 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M57.5 13C57.5 14.6569 58.8431 16 60.5 16H66.5C68.1569 16 69.5 14.6569 69.5 13V11C69.5 9.34315 68.1569 8 66.5 8H60.5C58.8431 8 57.5 9.34315 57.5 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M74 13C74 14.6569 75.3431 16 77 16H83C84.6569 16 86 14.6569 86 13V11C86 9.34315 84.6569 8 83 8H77C75.3431 8 74 9.34315 74 11V13Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M8 29C8 30.6569 9.34315 32 11 32H17C18.6569 32 20 30.6569 20 29V27C20 25.3431 18.6569 24 17 24H11C9.34315 24 8 25.3431 8 27V29Z" fill="black" fill-opacity="0.12"/>
|
||||
<path d="M24.5 29C24.5 30.6569 25.8431 32 27.5 32H33.5C35.1569 32 36.5 30.6569 36.5 29V27C36.5 25.3431 35.1569 24 33.5 24H27.5C25.8431 24 24.5 25.3431 24.5 27V29Z" fill="black" fill-opacity="0.12"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,11 @@
|
||||
<svg width="94" height="40" viewBox="0 0 94 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 8C0 3.58172 3.58172 0 8 0H86C90.4183 0 94 3.58172 94 8V32C94 36.4183 90.4183 40 86 40H8C3.58172 40 0 36.4183 0 32V8Z" fill="#1C1C1C"/>
|
||||
<path d="M1.34748 36.4449C0.772837 35.5866 0.359906 34.6109 0.152272 33.5613L0.642766 33.4643C0.549158 32.9911 0.5 32.5015 0.5 32V30H0V26H0.5V22H0V18H0.5V14H0V10H0.5V8C0.5 7.49847 0.549158 7.00892 0.642766 6.53574L0.152272 6.4387C0.359906 5.38915 0.772837 4.41341 1.34748 3.55508L1.76296 3.83324C2.31067 3.01513 3.01513 2.31067 3.83323 1.76296L3.55507 1.34748C4.41341 0.772837 5.38915 0.359906 6.4387 0.152272L6.53574 0.642766C7.00892 0.549158 7.49847 0.5 8 0.5H9.94999V0H13.85V0.5H17.75V0H21.65V0.5H25.55V0H29.45V0.5H33.35V0H37.25V0.5H41.15V0H45.05V0.5H48.95V0H52.85V0.5H56.75V0H60.65V0.5H64.55V0H68.45V0.5H72.35V0H76.25V0.5H80.15V0H84.05V0.5H86C86.5015 0.5 86.9911 0.549158 87.4643 0.642766L87.5613 0.152273C88.6108 0.359907 89.5866 0.772837 90.4449 1.34747L90.1668 1.76296C90.9849 2.31067 91.6893 3.01513 92.237 3.83323L92.6525 3.55507C93.2272 4.41341 93.6401 5.38915 93.8477 6.4387L93.3572 6.53574C93.4508 7.00892 93.5 7.49847 93.5 8V10H94V14H93.5V18H94V22H93.5V26H94V30H93.5V32C93.5 32.5015 93.4508 32.9911 93.3572 33.4643L93.8477 33.5613C93.6401 34.6109 93.2272 35.5866 92.6525 36.4449L92.237 36.1668C91.6893 36.9849 90.9849 37.6893 90.1668 38.237L90.4449 38.6525C89.5866 39.2272 88.6108 39.6401 87.5613 39.8477L87.4643 39.3572C86.9911 39.4508 86.5015 39.5 86 39.5H84.05V40H80.15V39.5H76.25V40H72.35V39.5H68.45V40H64.55V39.5H60.65V40H56.75V39.5H52.85V40H48.95V39.5H45.05V40H41.15V39.5H37.25V40H33.35V39.5H29.45V40H25.55V39.5H21.65V40H17.75V39.5H13.85V40H9.95V39.5H8C7.49847 39.5 7.00892 39.4508 6.53574 39.3572L6.4387 39.8477C5.38915 39.6401 4.41341 39.2272 3.55508 38.6525L3.83323 38.237C3.01513 37.6893 2.31067 36.9849 1.76296 36.1668L1.34748 36.4449Z" stroke="white" stroke-opacity="0.24" stroke-dasharray="4 4"/>
|
||||
<path d="M8 12C8 14.2091 9.79086 16 12 16H16C18.2091 16 20 14.2091 20 12C20 9.79086 18.2091 8 16 8H12C9.79086 8 8 9.79086 8 12Z" fill="white" fill-opacity="0.48"/>
|
||||
<path d="M24.5 12C24.5 14.2091 26.2909 16 28.5 16H32.5C34.7091 16 36.5 14.2091 36.5 12C36.5 9.79086 34.7091 8 32.5 8H28.5C26.2909 8 24.5 9.79086 24.5 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M41 12C41 14.2091 42.7909 16 45 16H49C51.2091 16 53 14.2091 53 12C53 9.79086 51.2091 8 49 8H45C42.7909 8 41 9.79086 41 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M57.5 12C57.5 14.2091 59.2909 16 61.5 16H65.5C67.7091 16 69.5 14.2091 69.5 12C69.5 9.79086 67.7091 8 65.5 8H61.5C59.2909 8 57.5 9.79086 57.5 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M74 12C74 14.2091 75.7909 16 78 16H82C84.2091 16 86 14.2091 86 12C86 9.79086 84.2091 8 82 8H78C75.7909 8 74 9.79086 74 12Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M8 28C8 30.2091 9.79086 32 12 32H16C18.2091 32 20 30.2091 20 28C20 25.7909 18.2091 24 16 24H12C9.79086 24 8 25.7909 8 28Z" fill="white" fill-opacity="0.24"/>
|
||||
<path d="M24.5 28C24.5 30.2091 26.2909 32 28.5 32H32.5C34.7091 32 36.5 30.2091 36.5 28C36.5 25.7909 34.7091 24 32.5 24H28.5C26.2909 24 24.5 25.7909 24.5 28Z" fill="white" fill-opacity="0.24"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -101,7 +101,7 @@ export class HaAuthFlow extends LitElement {
|
||||
a.forgot-password {
|
||||
color: var(--primary-color);
|
||||
text-decoration: none;
|
||||
font-size: 0.875rem;
|
||||
font-size: var(--ha-font-size-s);
|
||||
}
|
||||
.space-between {
|
||||
display: flex;
|
||||
|
||||
@@ -93,8 +93,8 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||
background-color: var(--primary-background-color, #fafafa);
|
||||
}
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-size: var(--ha-font-size-m);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
}
|
||||
.card-content {
|
||||
background: var(
|
||||
@@ -151,8 +151,8 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||
margin-inline-start: initial;
|
||||
}
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 400;
|
||||
font-size: var(--ha-font-size-3xl);
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import "@material/mwc-list";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../common/translations/localize";
|
||||
import "../components/ha-icon-next";
|
||||
import "../components/ha-list";
|
||||
import "../components/ha-list-item";
|
||||
import type { AuthProvider } from "../data/auth";
|
||||
|
||||
@@ -29,7 +29,7 @@ export class HaPickAuthProvider extends LitElement {
|
||||
>${this.localize("ui.panel.page-authorize.pick_auth_provider")}</span
|
||||
>
|
||||
</h3>
|
||||
<mwc-list>
|
||||
<ha-list>
|
||||
${this.authProviders.map(
|
||||
(provider) => html`
|
||||
<ha-list-item
|
||||
@@ -43,7 +43,7 @@ export class HaPickAuthProvider extends LitElement {
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
</mwc-list>
|
||||
</ha-list>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -57,9 +57,9 @@ export class HaPickAuthProvider extends LitElement {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
font-size: var(--ha-font-size-m);
|
||||
font-weight: var(--ha-font-weight-normal);
|
||||
line-height: var(--ha-line-height-normal);
|
||||
}
|
||||
h3:before {
|
||||
border-top: 1px solid var(--divider-color);
|
||||
@@ -77,7 +77,7 @@ export class HaPickAuthProvider extends LitElement {
|
||||
background: var(--card-background-color);
|
||||
padding: 0 15px;
|
||||
}
|
||||
mwc-list {
|
||||
ha-list {
|
||||
margin: 16px -16px 0;
|
||||
--mdc-list-side-padding: 24px;
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ export function theme2hex(themeColor: string): string {
|
||||
return themeColor;
|
||||
}
|
||||
|
||||
const rgbFromColorName = colors[themeColor];
|
||||
const rgbFromColorName = colors[themeColor.toLowerCase()];
|
||||
if (rgbFromColorName) {
|
||||
return rgb2hex(rgbFromColorName);
|
||||
}
|
||||
|
||||
102
src/common/controllers/drag-scroll-controller.ts
Normal file
102
src/common/controllers/drag-scroll-controller.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import type {
|
||||
ReactiveController,
|
||||
ReactiveControllerHost,
|
||||
} from "@lit/reactive-element/reactive-controller";
|
||||
import type { LitElement } from "lit";
|
||||
|
||||
/**
|
||||
* The config options for a DragScrollController.
|
||||
*/
|
||||
export interface DragScrollControllerConfig {
|
||||
selector: string;
|
||||
}
|
||||
|
||||
export class DragScrollController implements ReactiveController {
|
||||
public mouseIsDown = false;
|
||||
|
||||
public scrolled = false;
|
||||
|
||||
public scrolling = false;
|
||||
|
||||
public scrollStartX = 0;
|
||||
|
||||
public scrollLeft = 0;
|
||||
|
||||
private _host: ReactiveControllerHost & LitElement;
|
||||
|
||||
private _selector: string;
|
||||
|
||||
private _scrollContainer?: HTMLElement | null;
|
||||
|
||||
constructor(
|
||||
host: ReactiveControllerHost & LitElement,
|
||||
{ selector }: DragScrollControllerConfig
|
||||
) {
|
||||
this._selector = selector;
|
||||
this._host = host;
|
||||
host.addController(this);
|
||||
}
|
||||
|
||||
hostUpdated() {
|
||||
if (this._scrollContainer) {
|
||||
return;
|
||||
}
|
||||
this._scrollContainer = this._host.renderRoot?.querySelector(
|
||||
this._selector
|
||||
);
|
||||
if (this._scrollContainer) {
|
||||
this._scrollContainer.addEventListener("mousedown", this._mouseDown);
|
||||
}
|
||||
}
|
||||
|
||||
hostDisconnected() {
|
||||
window.removeEventListener("mousemove", this._mouseMove);
|
||||
window.removeEventListener("mouseup", this._mouseUp);
|
||||
}
|
||||
|
||||
private _mouseDown = (event: MouseEvent) => {
|
||||
const scrollContainer = this._scrollContainer;
|
||||
|
||||
if (!scrollContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.scrollStartX = event.pageX - scrollContainer.offsetLeft;
|
||||
this.scrollLeft = scrollContainer.scrollLeft;
|
||||
this.mouseIsDown = true;
|
||||
this.scrolled = false;
|
||||
|
||||
window.addEventListener("mousemove", this._mouseMove);
|
||||
window.addEventListener("mouseup", this._mouseUp, { once: true });
|
||||
};
|
||||
|
||||
private _mouseUp = () => {
|
||||
this.mouseIsDown = false;
|
||||
this.scrolling = false;
|
||||
this._host.requestUpdate();
|
||||
window.removeEventListener("mousemove", this._mouseMove);
|
||||
};
|
||||
|
||||
private _mouseMove = (event: MouseEvent) => {
|
||||
if (!this.mouseIsDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scrollContainer = this._scrollContainer;
|
||||
|
||||
if (!scrollContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const x = event.pageX - scrollContainer.offsetLeft;
|
||||
const scroll = x - this.scrollStartX;
|
||||
|
||||
if (!this.scrolled) {
|
||||
this.scrolled = Math.abs(scroll) > 1;
|
||||
this.scrolling = this.scrolled;
|
||||
this._host.requestUpdate();
|
||||
}
|
||||
|
||||
scrollContainer.scrollLeft = this.scrollLeft - scroll;
|
||||
};
|
||||
}
|
||||
@@ -1,46 +1,65 @@
|
||||
import type { LitElement } from "lit";
|
||||
import type { ClassElement } from "../../types";
|
||||
import type { ReactiveElement } from "lit";
|
||||
import { throttle } from "../util/throttle";
|
||||
|
||||
const throttleReplaceState = throttle((value) => {
|
||||
history.replaceState({ scrollPosition: value }, "");
|
||||
}, 300);
|
||||
|
||||
export const restoreScroll =
|
||||
(selector: string): any =>
|
||||
(element: ClassElement) => ({
|
||||
kind: "method",
|
||||
placement: "prototype",
|
||||
key: element.key,
|
||||
descriptor: {
|
||||
set(this: LitElement, value: number) {
|
||||
throttleReplaceState(value);
|
||||
this[`__${String(element.key)}`] = value;
|
||||
},
|
||||
get(this: LitElement) {
|
||||
return (
|
||||
this[`__${String(element.key)}`] || history.state?.scrollPosition
|
||||
);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
},
|
||||
finisher(cls: typeof LitElement) {
|
||||
const connectedCallback = cls.prototype.connectedCallback;
|
||||
cls.prototype.connectedCallback = function () {
|
||||
connectedCallback.call(this);
|
||||
const scrollPos = this[element.key];
|
||||
if (scrollPos) {
|
||||
this.updateComplete.then(() => {
|
||||
const target = this.renderRoot.querySelector(selector);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
target.scrollTop = scrollPos;
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
export function restoreScroll(selector: string) {
|
||||
return <ElemClass extends ReactiveElement>(
|
||||
proto: ElemClass,
|
||||
propertyKey: string
|
||||
) => {
|
||||
if (typeof propertyKey === "object") {
|
||||
throw new Error("This decorator does not support this compilation type.");
|
||||
}
|
||||
|
||||
const connectedCallback = proto.connectedCallback;
|
||||
proto.connectedCallback = function () {
|
||||
connectedCallback.call(this);
|
||||
|
||||
const scrollPos = this[propertyKey];
|
||||
|
||||
if (scrollPos) {
|
||||
this.updateComplete.then(() => {
|
||||
const target = this.renderRoot.querySelector(selector);
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
target.scrollTop = scrollPos;
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
|
||||
let newDescriptor: PropertyDescriptor;
|
||||
if (descriptor === undefined) {
|
||||
newDescriptor = {
|
||||
get(this: ReactiveElement) {
|
||||
return (
|
||||
this[`__${String(propertyKey)}`] || history.state?.scrollPosition
|
||||
);
|
||||
},
|
||||
set(this: ReactiveElement, value) {
|
||||
throttleReplaceState(value);
|
||||
this[`__${String(propertyKey)}`] = value;
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const oldSetter = descriptor.set;
|
||||
newDescriptor = {
|
||||
...descriptor,
|
||||
set(this: ReactiveElement, value) {
|
||||
throttleReplaceState(value);
|
||||
this[`__${String(propertyKey)}`] = value;
|
||||
oldSetter?.call(this, value);
|
||||
},
|
||||
};
|
||||
}
|
||||
Object.defineProperty(proto, propertyKey, newDescriptor);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import type { ReactiveElement } from "lit";
|
||||
import { ReactiveElement } from "lit";
|
||||
import type { InternalPropertyDeclaration } from "lit/decorators";
|
||||
import type { ClassElement } from "../../types";
|
||||
|
||||
type Callback = (oldValue: any, newValue: any) => void;
|
||||
|
||||
type ReactiveStorageElement = ReactiveElement & {
|
||||
__unbsubLocalStorage: UnsubscribeFunc | undefined;
|
||||
__initialized: boolean;
|
||||
};
|
||||
|
||||
class StorageClass {
|
||||
constructor(storage = window.localStorage) {
|
||||
this.storage = storage;
|
||||
if (storage !== window.localStorage) {
|
||||
constructor(store = window.localStorage) {
|
||||
this.storage = store;
|
||||
if (this.storage !== window.localStorage) {
|
||||
// storage events only work for localStorage
|
||||
return;
|
||||
}
|
||||
@@ -99,17 +103,23 @@ class StorageClass {
|
||||
|
||||
const storages: Record<string, StorageClass> = {};
|
||||
|
||||
export const storage =
|
||||
(options: {
|
||||
key?: string;
|
||||
storage?: "localStorage" | "sessionStorage";
|
||||
subscribe?: boolean;
|
||||
state?: boolean;
|
||||
stateOptions?: InternalPropertyDeclaration;
|
||||
serializer?: (value: any) => any;
|
||||
deserializer?: (value: any) => any;
|
||||
}): any =>
|
||||
(clsElement: ClassElement) => {
|
||||
export function storage(options: {
|
||||
key?: string;
|
||||
storage?: "localStorage" | "sessionStorage";
|
||||
subscribe?: boolean;
|
||||
state?: boolean;
|
||||
stateOptions?: InternalPropertyDeclaration;
|
||||
serializer?: (value: any) => any;
|
||||
deserializer?: (value: any) => any;
|
||||
}) {
|
||||
return <ElemClass extends ReactiveElement>(
|
||||
proto: ElemClass,
|
||||
propertyKey: string
|
||||
) => {
|
||||
if (typeof propertyKey === "object") {
|
||||
throw new Error("This decorator does not support this compilation type.");
|
||||
}
|
||||
|
||||
const storageName = options.storage || "localStorage";
|
||||
|
||||
let storageInstance: StorageClass;
|
||||
@@ -120,11 +130,7 @@ export const storage =
|
||||
storages[storageName] = storageInstance;
|
||||
}
|
||||
|
||||
const key = String(clsElement.key);
|
||||
const storageKey = options.key || String(clsElement.key);
|
||||
const initVal = clsElement.initializer
|
||||
? clsElement.initializer()
|
||||
: undefined;
|
||||
const storageKey = options.key || String(propertyKey);
|
||||
|
||||
storageInstance.addFromStorage(storageKey);
|
||||
|
||||
@@ -134,7 +140,7 @@ export const storage =
|
||||
storageInstance.subscribeChanges(
|
||||
storageKey!,
|
||||
(oldValue, _newValue) => {
|
||||
el.requestUpdate(clsElement.key, oldValue);
|
||||
el.requestUpdate(propertyKey, oldValue);
|
||||
}
|
||||
)
|
||||
: undefined;
|
||||
@@ -144,7 +150,7 @@ export const storage =
|
||||
? options.deserializer
|
||||
? options.deserializer(storageInstance.getValue(storageKey!))
|
||||
: storageInstance.getValue(storageKey!)
|
||||
: initVal;
|
||||
: undefined;
|
||||
|
||||
const setValue = (el: ReactiveElement, value: any) => {
|
||||
let oldValue: unknown | undefined;
|
||||
@@ -156,44 +162,74 @@ export const storage =
|
||||
options.serializer ? options.serializer(value) : value
|
||||
);
|
||||
if (options.state) {
|
||||
el.requestUpdate(clsElement.key, oldValue);
|
||||
el.requestUpdate(propertyKey, oldValue);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
kind: "method",
|
||||
placement: "prototype",
|
||||
key: clsElement.key,
|
||||
descriptor: {
|
||||
set(this: ReactiveElement, value: unknown) {
|
||||
setValue(this, value);
|
||||
},
|
||||
get() {
|
||||
// @ts-ignore
|
||||
const performUpdate = proto.performUpdate;
|
||||
// @ts-ignore
|
||||
proto.performUpdate = function () {
|
||||
(this as unknown as ReactiveStorageElement).__initialized = true;
|
||||
performUpdate.call(this);
|
||||
};
|
||||
|
||||
if (options.state && options.subscribe) {
|
||||
const connectedCallback = proto.connectedCallback;
|
||||
const disconnectedCallback = proto.disconnectedCallback;
|
||||
|
||||
proto.connectedCallback = function () {
|
||||
connectedCallback.call(this);
|
||||
const el = this as unknown as ReactiveStorageElement;
|
||||
if (!el.__unbsubLocalStorage) {
|
||||
el.__unbsubLocalStorage = subscribeChanges?.(this);
|
||||
}
|
||||
};
|
||||
proto.disconnectedCallback = function () {
|
||||
disconnectedCallback.call(this);
|
||||
const el = this as unknown as ReactiveStorageElement;
|
||||
el.__unbsubLocalStorage?.();
|
||||
el.__unbsubLocalStorage = undefined;
|
||||
};
|
||||
}
|
||||
if (options.state) {
|
||||
ReactiveElement.createProperty(propertyKey, {
|
||||
noAccessor: true,
|
||||
...options.stateOptions,
|
||||
});
|
||||
}
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
|
||||
let newDescriptor: PropertyDescriptor;
|
||||
if (descriptor === undefined) {
|
||||
newDescriptor = {
|
||||
get(this: ReactiveStorageElement) {
|
||||
return getValue();
|
||||
},
|
||||
enumerable: true,
|
||||
set(this: ReactiveStorageElement, value) {
|
||||
// Don't set the initial value if we have a value in localStorage
|
||||
if (this.__initialized || getValue() === undefined) {
|
||||
setValue(this, value);
|
||||
this.requestUpdate(propertyKey, undefined);
|
||||
}
|
||||
},
|
||||
configurable: true,
|
||||
},
|
||||
finisher(cls: typeof ReactiveElement) {
|
||||
if (options.state && options.subscribe) {
|
||||
const connectedCallback = cls.prototype.connectedCallback;
|
||||
const disconnectedCallback = cls.prototype.disconnectedCallback;
|
||||
cls.prototype.connectedCallback = function () {
|
||||
connectedCallback.call(this);
|
||||
this[`__unbsubLocalStorage${key}`] = subscribeChanges?.(this);
|
||||
};
|
||||
cls.prototype.disconnectedCallback = function () {
|
||||
disconnectedCallback.call(this);
|
||||
this[`__unbsubLocalStorage${key}`]?.();
|
||||
this[`__unbsubLocalStorage${key}`] = undefined;
|
||||
};
|
||||
}
|
||||
if (options.state) {
|
||||
cls.createProperty(clsElement.key, {
|
||||
noAccessor: true,
|
||||
...options.stateOptions,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
enumerable: true,
|
||||
};
|
||||
} else {
|
||||
const oldSetter = descriptor.set;
|
||||
newDescriptor = {
|
||||
...descriptor,
|
||||
set(this: ReactiveStorageElement, value) {
|
||||
// Don't set the initial value if we have a value in localStorage
|
||||
if (this.__initialized || getValue() === undefined) {
|
||||
setValue(this, value);
|
||||
this.requestUpdate(propertyKey, undefined);
|
||||
}
|
||||
oldSetter?.call(this, value);
|
||||
},
|
||||
};
|
||||
}
|
||||
Object.defineProperty(proto, propertyKey, newDescriptor);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,39 +1,103 @@
|
||||
import type { PropertyDeclaration, PropertyValues, ReactiveElement } from "lit";
|
||||
import type { ClassElement } from "../../types";
|
||||
import {
|
||||
ReactiveElement,
|
||||
type PropertyDeclaration,
|
||||
type PropertyValues,
|
||||
} from "lit";
|
||||
import { shallowEqual } from "../util/shallow-equal";
|
||||
|
||||
/**
|
||||
* Transform function type.
|
||||
*/
|
||||
export type Transformer<T = any, V = any> = (value: V) => T;
|
||||
export type Transformer<T = any, V = any> = (value: T) => V | undefined;
|
||||
|
||||
type ReactiveTransformElement = ReactiveElement & {
|
||||
_transformers: Map<PropertyKey, Transformer>;
|
||||
_watching: Map<PropertyKey, Set<PropertyKey>>;
|
||||
};
|
||||
|
||||
type ReactiveElementClassWithTransformers = typeof ReactiveElement & {
|
||||
prototype: ReactiveTransformElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies a transformer callback that is run when the value of the decorated property, or any of the properties in the watching array, changes.
|
||||
* The result of the transformer is assigned to the decorated property.
|
||||
* The transformer receives the current as argument.
|
||||
*/
|
||||
export const transform =
|
||||
<T, V>(config: {
|
||||
transformer: Transformer<T, V>;
|
||||
watch?: PropertyKey[];
|
||||
propertyOptions?: PropertyDeclaration;
|
||||
}): any =>
|
||||
(clsElement: ClassElement) => {
|
||||
const key = String(clsElement.key);
|
||||
return {
|
||||
...clsElement,
|
||||
kind: "method",
|
||||
descriptor: {
|
||||
set(this: ReactiveTransformElement, value: V) {
|
||||
export function transform<T, V>(config: {
|
||||
transformer: Transformer<T, V>;
|
||||
watch?: PropertyKey[];
|
||||
propertyOptions?: PropertyDeclaration;
|
||||
}) {
|
||||
return <ElemClass extends ReactiveElement>(
|
||||
proto: ElemClass,
|
||||
propertyKey: string
|
||||
) => {
|
||||
if (typeof propertyKey === "object") {
|
||||
throw new Error("This decorator does not support this compilation type.");
|
||||
}
|
||||
|
||||
const key = String(propertyKey);
|
||||
|
||||
const el = proto as unknown as ReactiveTransformElement;
|
||||
|
||||
// if we haven't wrapped `willUpdate` in this class, do so
|
||||
if (!el._transformers) {
|
||||
el._transformers = new Map<PropertyKey, Transformer>();
|
||||
el._watching = new Map<PropertyKey, Set<PropertyKey>>();
|
||||
// @ts-ignore
|
||||
const userWillUpdate = el.willUpdate;
|
||||
// @ts-ignore
|
||||
el.willUpdate = function (
|
||||
this: ReactiveTransformElement,
|
||||
changedProperties: PropertyValues
|
||||
) {
|
||||
userWillUpdate.call(this, changedProperties);
|
||||
const keys = new Set<PropertyKey>();
|
||||
changedProperties.forEach((_v, k) => {
|
||||
const watchers = this._watching;
|
||||
const ks: Set<PropertyKey> | undefined = watchers.get(k);
|
||||
if (ks !== undefined) {
|
||||
ks.forEach((wk) => keys.add(wk));
|
||||
}
|
||||
});
|
||||
keys.forEach((k) => {
|
||||
// trigger setter
|
||||
this[k] = this[`__original_${String(k)}`];
|
||||
});
|
||||
};
|
||||
// clone any existing observers (superclasses)
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
} else if (!el.hasOwnProperty("_transformers")) {
|
||||
const tranformers = el._transformers;
|
||||
el._transformers = new Map();
|
||||
tranformers.forEach((v: any, k: PropertyKey) =>
|
||||
el._transformers.set(k, v)
|
||||
);
|
||||
}
|
||||
// set this method
|
||||
el._transformers.set(propertyKey, config.transformer);
|
||||
if (config.watch) {
|
||||
// store watchers
|
||||
config.watch.forEach((k) => {
|
||||
let curWatch = el._watching.get(k);
|
||||
if (!curWatch) {
|
||||
curWatch = new Set();
|
||||
el._watching.set(k, curWatch);
|
||||
}
|
||||
curWatch.add(propertyKey);
|
||||
});
|
||||
}
|
||||
ReactiveElement.createProperty(propertyKey, {
|
||||
noAccessor: true,
|
||||
hasChanged: (v: any, o: any) => !shallowEqual(v, o),
|
||||
...config.propertyOptions,
|
||||
});
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
|
||||
let newDescriptor: PropertyDescriptor;
|
||||
if (descriptor === undefined) {
|
||||
newDescriptor = {
|
||||
get(this: ReactiveTransformElement): V {
|
||||
return this[`__transform_${key}`];
|
||||
},
|
||||
set(this: ReactiveTransformElement, value: T) {
|
||||
const oldValue = this[`__transform_${key}`];
|
||||
const trnsformr: Transformer<T, V> | undefined =
|
||||
this._transformers.get(key);
|
||||
@@ -45,65 +109,28 @@ export const transform =
|
||||
this[`__original_${key}`] = value;
|
||||
this.requestUpdate(key, oldValue);
|
||||
},
|
||||
get(): T {
|
||||
return this[`__transform_${key}`];
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
},
|
||||
finisher(cls: ReactiveElementClassWithTransformers) {
|
||||
// if we haven't wrapped `willUpdate` in this class, do so
|
||||
if (!cls.prototype._transformers) {
|
||||
cls.prototype._transformers = new Map<PropertyKey, Transformer>();
|
||||
cls.prototype._watching = new Map<PropertyKey, Set<PropertyKey>>();
|
||||
// @ts-ignore
|
||||
const userWillUpdate = cls.prototype.willUpdate;
|
||||
// @ts-ignore
|
||||
cls.prototype.willUpdate = function (
|
||||
this: ReactiveTransformElement,
|
||||
changedProperties: PropertyValues
|
||||
) {
|
||||
userWillUpdate.call(this, changedProperties);
|
||||
const keys = new Set<PropertyKey>();
|
||||
changedProperties.forEach((_v, k) => {
|
||||
const watchers = this._watching;
|
||||
const ks: Set<PropertyKey> | undefined = watchers.get(k);
|
||||
if (ks !== undefined) {
|
||||
ks.forEach((wk) => keys.add(wk));
|
||||
}
|
||||
});
|
||||
keys.forEach((k) => {
|
||||
// trigger setter
|
||||
this[k] = this[`__original_${String(k)}`];
|
||||
});
|
||||
};
|
||||
// clone any existing observers (superclasses)
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
} else if (!cls.prototype.hasOwnProperty("_transformers")) {
|
||||
const tranformers = cls.prototype._transformers;
|
||||
cls.prototype._transformers = new Map();
|
||||
tranformers.forEach((v: any, k: PropertyKey) =>
|
||||
cls.prototype._transformers.set(k, v)
|
||||
);
|
||||
}
|
||||
// set this method
|
||||
cls.prototype._transformers.set(clsElement.key, config.transformer);
|
||||
if (config.watch) {
|
||||
// store watchers
|
||||
config.watch.forEach((k) => {
|
||||
let curWatch = cls.prototype._watching.get(k);
|
||||
if (!curWatch) {
|
||||
curWatch = new Set();
|
||||
cls.prototype._watching.set(k, curWatch);
|
||||
}
|
||||
curWatch.add(clsElement.key);
|
||||
});
|
||||
}
|
||||
cls.createProperty(clsElement.key, {
|
||||
noAccessor: true,
|
||||
hasChanged: (v: any, o: any) => !shallowEqual(v, o),
|
||||
...config.propertyOptions,
|
||||
});
|
||||
},
|
||||
};
|
||||
enumerable: true,
|
||||
};
|
||||
} else {
|
||||
const oldSetter = descriptor.set;
|
||||
newDescriptor = {
|
||||
...descriptor,
|
||||
set(this: ReactiveTransformElement, value: T) {
|
||||
const oldValue = this[`__transform_${key}`];
|
||||
const trnsformr: Transformer | undefined =
|
||||
this._transformers.get(key);
|
||||
if (trnsformr) {
|
||||
this[`__transform_${key}`] = trnsformr.call(this, value);
|
||||
} else {
|
||||
this[`__transform_${key}`] = value;
|
||||
}
|
||||
this[`__original_${key}`] = value;
|
||||
this.requestUpdate(key, oldValue);
|
||||
oldSetter?.call(this, value);
|
||||
},
|
||||
};
|
||||
}
|
||||
Object.defineProperty(proto, propertyKey, newDescriptor);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ThemeVars } from "../../data/ws-themes";
|
||||
import { darkStyles, derivedStyles } from "../../resources/styles-data";
|
||||
import { darkColorVariables } from "../../resources/theme/color.globals";
|
||||
import { derivedStyles } from "../../resources/theme/theme";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import {
|
||||
hex2rgb,
|
||||
@@ -50,7 +51,7 @@ export const applyThemesOnElement = (
|
||||
|
||||
if (themeToApply && darkMode) {
|
||||
cacheKey = `${cacheKey}__dark`;
|
||||
themeRules = { ...darkStyles };
|
||||
themeRules = { ...darkColorVariables };
|
||||
}
|
||||
|
||||
if (themeToApply === "default") {
|
||||
|
||||
@@ -7,6 +7,15 @@ interface AreaContext {
|
||||
floor: FloorRegistryEntry | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the context of a specific area, including its associated area registry entry
|
||||
* and floor registry entry, if available.
|
||||
*
|
||||
* @param areaId - The unique identifier of the area to retrieve context for.
|
||||
* @param hass - The Home Assistant instance containing area and floor registry data.
|
||||
* @returns An object containing the area registry entry and the associated floor registry entry,
|
||||
* or `null` values if the area or floor is not found.
|
||||
*/
|
||||
export const getAreaContext = (
|
||||
areaId: string,
|
||||
hass: HomeAssistant
|
||||
|
||||
@@ -11,6 +11,19 @@ interface EntityContext {
|
||||
floor: FloorRegistryEntry | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the context of an entity, including its associated device, area, and floor.
|
||||
*
|
||||
* @param entityId - The unique identifier of the entity to retrieve the context for.
|
||||
* @param hass - The Home Assistant object containing the registry data for entities, devices, areas, and floors.
|
||||
* @returns An object containing the entity, its associated device, area, and floor, or `null` for each if not found.
|
||||
*
|
||||
* The returned `EntityContext` object includes:
|
||||
* - `entity`: The entity registry entry, or `null` if the entity is not found.
|
||||
* - `device`: The device registry entry associated with the entity, or `null` if not found.
|
||||
* - `area`: The area registry entry associated with the entity or device, or `null` if not found.
|
||||
* - `floor`: The floor registry entry associated with the area, or `null` if not found.
|
||||
*/
|
||||
export const getEntityContext = (
|
||||
entityId: string,
|
||||
hass: HomeAssistant
|
||||
|
||||
@@ -96,7 +96,7 @@ const customGenerator = (colors: Swatch[]) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
"%cPicked colors",
|
||||
`color: ${foregroundColor}; background-color: ${backgroundColor.hex}; font-weight: bold; padding: 16px;`
|
||||
`color: ${foregroundColor}; background-color: ${backgroundColor.hex}; font-weight: var(--ha-font-weight-bold); padding: 16px;`
|
||||
);
|
||||
colors.forEach((color) => logColor(color));
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
45
src/common/style/derived-css-vars.ts
Normal file
45
src/common/style/derived-css-vars.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import type { CSSResult } from "lit";
|
||||
|
||||
const _extractCssVars = (
|
||||
cssString: string,
|
||||
condition: (string) => boolean = () => true
|
||||
) => {
|
||||
const variables: Record<string, string> = {};
|
||||
|
||||
cssString.split(";").forEach((rawLine) => {
|
||||
const line = rawLine.substring(rawLine.indexOf("--")).trim();
|
||||
if (line.startsWith("--") && condition(line)) {
|
||||
const [name, value] = line.split(":").map((part) => part.trim());
|
||||
variables[name.substring(2, name.length)] = value;
|
||||
}
|
||||
});
|
||||
return variables;
|
||||
};
|
||||
|
||||
export const extractVar = (css: CSSResult, varName: string) => {
|
||||
const cssString = css.toString();
|
||||
const search = `--${varName}:`;
|
||||
const startIndex = cssString.indexOf(search);
|
||||
if (startIndex === -1) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const endIndex = cssString.indexOf(";", startIndex + search.length);
|
||||
return cssString.substring(startIndex + search.length, endIndex).trim();
|
||||
};
|
||||
|
||||
export const extractVars = (css: CSSResult) => {
|
||||
const cssString = css.toString();
|
||||
|
||||
return _extractCssVars(cssString);
|
||||
};
|
||||
|
||||
export const extractDerivedVars = (css: CSSResult) => {
|
||||
const cssString = css.toString();
|
||||
|
||||
if (!cssString.includes("var(")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return _extractCssVars(cssString, (line) => line.includes("var("));
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { consume } from "@lit-labs/context";
|
||||
import { consume } from "@lit/context";
|
||||
import { ResizeController } from "@lit-labs/observers/resize-controller";
|
||||
import { mdiChevronDown, mdiChevronUp, mdiRestart } from "@mdi/js";
|
||||
import { differenceInMinutes } from "date-fns";
|
||||
@@ -590,6 +590,10 @@ export class HaChartBase extends LitElement {
|
||||
lineStyle: { color: style.getPropertyValue("--info-color") },
|
||||
crossStyle: { color: style.getPropertyValue("--info-color") },
|
||||
},
|
||||
extraCssText:
|
||||
"direction:" +
|
||||
style.getPropertyValue("--direction") +
|
||||
";margin-inline-start:3px;margin-inline-end:8px;",
|
||||
},
|
||||
timeline: {},
|
||||
};
|
||||
@@ -715,7 +719,7 @@ export class HaChartBase extends LitElement {
|
||||
max-height: 60%;
|
||||
overflow-y: auto;
|
||||
padding: 12px 0 0;
|
||||
font-size: 12px;
|
||||
font-size: var(--ha-font-size-s);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.chart-legend ul {
|
||||
|
||||
@@ -135,7 +135,7 @@ export class StateHistoryChartLine extends LitElement {
|
||||
seriesIndex: index,
|
||||
value: lastData,
|
||||
// HTML copied from echarts. May change based on options
|
||||
marker: `<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${dataset.color};"></span>`,
|
||||
marker: `<span style="display:inline-block;margin-right:4px;margin-inline-end:4px;margin-inline-start:initial;border-radius:10px;width:10px;height:10px;background-color:${dataset.color};"></span>`,
|
||||
});
|
||||
});
|
||||
const unit = this.unit
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user