mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-22 10:32:57 +00:00
Compare commits
4 Commits
use-contro
...
dashboard-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6aec725908 | ||
|
|
787e9bde47 | ||
|
|
64dede3ab4 | ||
|
|
670180df90 |
1
.github/workflows/stale.yml
vendored
1
.github/workflows/stale.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
- cron: "0 * * * *"
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
"lit": "3.3.2",
|
||||
"lit-html": "3.3.2",
|
||||
"luxon": "3.7.2",
|
||||
"marked": "18.0.2",
|
||||
"marked": "18.0.1",
|
||||
"memoize-one": "6.0.0",
|
||||
"node-vibrant": "4.0.4",
|
||||
"object-hash": "3.0.0",
|
||||
@@ -167,7 +167,7 @@
|
||||
"babel-plugin-template-html-minifier": "4.1.0",
|
||||
"browserslist-useragent-regexp": "4.1.4",
|
||||
"del": "8.0.1",
|
||||
"eslint": "10.2.1",
|
||||
"eslint": "10.2.0",
|
||||
"eslint-config-airbnb-base": "15.0.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-import-resolver-webpack": "0.13.11",
|
||||
|
||||
10
public/static/images/logo_mastodon.svg
Normal file
10
public/static/images/logo_mastodon.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="75" height="79" viewBox="0 0 75 79" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M73.8393 17.4898C72.6973 9.00165 65.2994 2.31235 56.5296 1.01614C55.05 0.797115 49.4441 0 36.4582 0H36.3612C23.3717 0 20.585 0.797115 19.1054 1.01614C10.5798 2.27644 2.79399 8.28712 0.904997 16.8758C-0.00358524 21.1056 -0.100549 25.7949 0.0682394 30.0965C0.308852 36.2651 0.355538 42.423 0.91577 48.5665C1.30307 52.6474 1.97872 56.6957 2.93763 60.6812C4.73325 68.042 12.0019 74.1676 19.1233 76.6666C26.7478 79.2728 34.9474 79.7055 42.8039 77.9162C43.6682 77.7151 44.5217 77.4817 45.3645 77.216C47.275 76.6092 49.5123 75.9305 51.1571 74.7385C51.1797 74.7217 51.1982 74.7001 51.2112 74.6753C51.2243 74.6504 51.2316 74.6229 51.2325 74.5948V68.6416C51.2321 68.6154 51.2259 68.5896 51.2142 68.5661C51.2025 68.5426 51.1858 68.522 51.1651 68.5058C51.1444 68.4896 51.1204 68.4783 51.0948 68.4726C51.0692 68.4669 51.0426 68.467 51.0171 68.4729C45.9835 69.675 40.8254 70.2777 35.6502 70.2682C26.7439 70.2682 24.3486 66.042 23.6626 64.2826C23.1113 62.762 22.7612 61.1759 22.6212 59.5646C22.6197 59.5375 22.6247 59.5105 22.6357 59.4857C22.6466 59.4609 22.6633 59.4391 22.6843 59.422C22.7053 59.4048 22.73 59.3929 22.7565 59.3871C22.783 59.3813 22.8104 59.3818 22.8367 59.3886C27.7864 60.5826 32.8604 61.1853 37.9522 61.1839C39.1768 61.1839 40.3978 61.1839 41.6224 61.1516C46.7435 61.008 52.1411 60.7459 57.1796 59.7621C57.3053 59.7369 57.431 59.7154 57.5387 59.6831C65.4861 58.157 73.0493 53.3672 73.8178 41.2381C73.8465 40.7606 73.9184 36.2364 73.9184 35.7409C73.9219 34.0569 74.4606 23.7949 73.8393 17.4898Z" fill="url(#paint0_linear_549_34)"/>
|
||||
<path d="M61.2484 27.0263V48.114H52.8916V27.6475C52.8916 23.3388 51.096 21.1413 47.4437 21.1413C43.4287 21.1413 41.4177 23.7409 41.4177 28.8755V40.0782H33.1111V28.8755C33.1111 23.7409 31.0965 21.1413 27.0815 21.1413C23.4507 21.1413 21.6371 23.3388 21.6371 27.6475V48.114H13.2839V27.0263C13.2839 22.7176 14.384 19.2946 16.5843 16.7572C18.8539 14.2258 21.8311 12.926 25.5264 12.926C29.8036 12.926 33.0357 14.5705 35.1905 17.8559L37.2698 21.346L39.3527 17.8559C41.5074 14.5705 44.7395 12.926 49.0095 12.926C52.7013 12.926 55.6784 14.2258 57.9553 16.7572C60.1531 19.2922 61.2508 22.7152 61.2484 27.0263Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_549_34" x1="37.0692" y1="0" x2="37.0692" y2="79" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6364FF"/>
|
||||
<stop offset="1" stop-color="#563ACC"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
3
public/static/images/logo_x.svg
Normal file
3
public/static/images/logo_x.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="1200" height="1227" viewBox="0 0 1200 1227" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
@@ -13,9 +13,9 @@ import {
|
||||
} from "../../data/entity/entity";
|
||||
import { forwardHaptic } from "../../data/haptics";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../ha-control-switch";
|
||||
import "../ha-formfield";
|
||||
import "../ha-icon-button";
|
||||
import "../ha-switch";
|
||||
|
||||
const isOn = (stateObj?: HassEntity) =>
|
||||
stateObj !== undefined &&
|
||||
@@ -35,7 +35,7 @@ export class HaEntityToggle extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.stateObj) {
|
||||
return html`<ha-control-switch disabled></ha-control-switch> `;
|
||||
return html` <ha-switch disabled></ha-switch> `;
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -62,14 +62,14 @@ export class HaEntityToggle extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
const switchTemplate = html`<ha-control-switch
|
||||
const switchTemplate = html`<ha-switch
|
||||
aria-label=${`Toggle ${computeStateName(this.stateObj)} ${
|
||||
this._isOn ? "off" : "on"
|
||||
}`}
|
||||
.checked=${this._isOn}
|
||||
.disabled=${this.stateObj.state === UNAVAILABLE}
|
||||
@change=${this._toggleChanged}
|
||||
></ha-control-switch>`;
|
||||
></ha-switch>`;
|
||||
|
||||
if (!this.label) {
|
||||
return switchTemplate;
|
||||
@@ -163,9 +163,6 @@ export class HaEntityToggle extends LitElement {
|
||||
white-space: nowrap;
|
||||
min-width: 38px;
|
||||
}
|
||||
ha-control-switch {
|
||||
--control-switch-thickness: 20px;
|
||||
}
|
||||
ha-icon-button {
|
||||
--ha-icon-button-size: 40px;
|
||||
color: var(--ha-icon-button-inactive-color, var(--primary-text-color));
|
||||
@@ -174,6 +171,9 @@ export class HaEntityToggle extends LitElement {
|
||||
ha-icon-button.state-active {
|
||||
color: var(--ha-icon-button-active-color, var(--primary-color));
|
||||
}
|
||||
ha-switch {
|
||||
padding: 13px 5px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,29 +116,11 @@ export class HaControlSwitch extends LitElement {
|
||||
}
|
||||
|
||||
private _keydown(ev: any) {
|
||||
const supportedKeys = ["Enter", " "];
|
||||
if (this.vertical) {
|
||||
supportedKeys.push("ArrowUp", "ArrowDown");
|
||||
} else {
|
||||
supportedKeys.push("ArrowLeft", "ArrowRight");
|
||||
}
|
||||
if (!supportedKeys.includes(ev.key)) {
|
||||
if (ev.key !== "Enter" && ev.key !== " ") {
|
||||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
|
||||
if (
|
||||
ev.key === "Enter" ||
|
||||
ev.key === " " ||
|
||||
(this.vertical &&
|
||||
((this.checked && ev.key === "ArrowDown") ||
|
||||
(!this.checked && ev.key === "ArrowUp"))) ||
|
||||
(!this.vertical &&
|
||||
((!this.checked && ev.key === "ArrowRight") ||
|
||||
(this.checked && ev.key === "ArrowLeft")))
|
||||
) {
|
||||
this._toggle();
|
||||
}
|
||||
this._toggle();
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
@@ -150,7 +132,7 @@ export class HaControlSwitch extends LitElement {
|
||||
aria-checked=${this.checked ? "true" : "false"}
|
||||
aria-label=${ifDefined(this.label)}
|
||||
role="switch"
|
||||
tabindex=${ifDefined(this.disabled ? undefined : "0")}
|
||||
tabindex="0"
|
||||
?checked=${this.checked}
|
||||
?disabled=${this.disabled}
|
||||
>
|
||||
@@ -174,7 +156,6 @@ export class HaControlSwitch extends LitElement {
|
||||
--control-switch-on-color: var(--primary-color);
|
||||
--control-switch-off-color: var(--disabled-color);
|
||||
--control-switch-background-opacity: 0.2;
|
||||
--control-switch-hover-background-opacity: 0.4;
|
||||
--control-switch-thickness: 40px;
|
||||
--control-switch-border-radius: var(--ha-border-radius-lg);
|
||||
--control-switch-padding: 4px;
|
||||
@@ -186,10 +167,10 @@ export class HaControlSwitch extends LitElement {
|
||||
transition: box-shadow 180ms ease-in-out;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.switch:not([disabled]):focus-visible {
|
||||
.switch:focus-visible {
|
||||
box-shadow: 0 0 0 2px var(--control-switch-off-color);
|
||||
}
|
||||
.switch[checked]:not([disabled]):focus-visible {
|
||||
.switch[checked]:focus-visible {
|
||||
box-shadow: 0 0 0 2px var(--control-switch-on-color);
|
||||
}
|
||||
.switch {
|
||||
@@ -218,10 +199,6 @@ export class HaControlSwitch extends LitElement {
|
||||
transition: background-color 180ms ease-in-out;
|
||||
opacity: var(--control-switch-background-opacity);
|
||||
}
|
||||
.switch:not([disabled]):focus-visible .background,
|
||||
.switch:not([disabled]):hover .background {
|
||||
opacity: var(--control-switch-hover-background-opacity);
|
||||
}
|
||||
.switch .button {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
|
||||
@@ -124,7 +124,7 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private _i18n?: ContextType<typeof internationalizationContext>;
|
||||
private _i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
// disabled till iOS app fix the "focus_element" implementation
|
||||
// @state()
|
||||
@@ -176,7 +176,7 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
@wa-after-hide=${this._handleAfterHide}
|
||||
>
|
||||
${!this.withoutHeader
|
||||
? html`<slot name="header">
|
||||
? html` <slot name="header">
|
||||
<ha-dialog-header
|
||||
.subtitlePosition=${this.headerSubtitlePosition}
|
||||
.showBorder=${this._bodyScrolled}
|
||||
@@ -184,8 +184,7 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) {
|
||||
<slot name="headerNavigationIcon" slot="navigationIcon">
|
||||
<ha-icon-button
|
||||
data-dialog="close"
|
||||
.label=${this._i18n?.localize?.("ui.common.close") ??
|
||||
"Close"}
|
||||
.label=${this._i18n?.localize("ui.common.close") ?? "Close"}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
</slot>
|
||||
|
||||
@@ -163,7 +163,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
|
||||
@state()
|
||||
@consume({ context: internationalizationContext, subscribe: true })
|
||||
private i18n?: ContextType<typeof internationalizationContext>;
|
||||
private i18n!: ContextType<typeof internationalizationContext>;
|
||||
|
||||
@state() private _items: PickerComboBoxItem[] = [];
|
||||
|
||||
@@ -218,9 +218,9 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
const searchLabel =
|
||||
this.label ??
|
||||
(this.allowCustomValue
|
||||
? (this.i18n?.localize?.("ui.components.combo-box.search_or_custom") ??
|
||||
? (this.i18n.localize?.("ui.components.combo-box.search_or_custom") ??
|
||||
"Search | Add custom value")
|
||||
: (this.i18n?.localize?.("ui.common.search") ?? "Search"));
|
||||
: (this.i18n.localize?.("ui.common.search") ?? "Search"));
|
||||
|
||||
return html`<ha-input-search
|
||||
appearance="outlined"
|
||||
@@ -347,7 +347,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
return caseInsensitiveStringCompare(
|
||||
sortLabelA,
|
||||
sortLabelB,
|
||||
this.i18n?.locale?.language ?? navigator.language
|
||||
this.i18n.locale?.language ?? navigator.language
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -364,7 +364,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
id: this._search,
|
||||
primary:
|
||||
this.customValueLabel ??
|
||||
this.i18n?.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
this.i18n.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
"Add custom item",
|
||||
secondary: `"${this._search}"`,
|
||||
icon_path: mdiPlus,
|
||||
@@ -398,10 +398,10 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
? typeof this.notFoundLabel === "function"
|
||||
? this.notFoundLabel(this._search)
|
||||
: this.notFoundLabel ||
|
||||
this.i18n?.localize?.("ui.components.combo-box.no_match") ||
|
||||
this.i18n.localize?.("ui.components.combo-box.no_match") ||
|
||||
"No matching items found"
|
||||
: this.emptyLabel ||
|
||||
this.i18n?.localize?.("ui.components.combo-box.no_items") ||
|
||||
this.i18n.localize?.("ui.components.combo-box.no_items") ||
|
||||
"No items available"}</span
|
||||
>
|
||||
</ha-combo-box-item>
|
||||
@@ -493,7 +493,7 @@ export class HaPickerComboBox extends ScrollableFadeMixin(LitElement) {
|
||||
id: searchString,
|
||||
primary:
|
||||
this.customValueLabel ??
|
||||
this.i18n?.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
this.i18n.localize?.("ui.components.combo-box.add_custom_item") ??
|
||||
"Add custom item",
|
||||
secondary: `"${searchString}"`,
|
||||
icon_path: mdiPlus,
|
||||
|
||||
@@ -454,7 +454,8 @@ class HaSidebar extends SubscribeMixin(ScrollableFadeMixin(LitElement)) {
|
||||
if (!this.hass.user?.is_admin) {
|
||||
return nothing;
|
||||
}
|
||||
const isSelected = selectedPanel === "config";
|
||||
const isSelected =
|
||||
selectedPanel === "config" || this.route.path?.startsWith("/hassio/");
|
||||
return html`
|
||||
<ha-md-list-item
|
||||
class="configuration ${classMap({ selected: isSelected })}"
|
||||
|
||||
@@ -607,8 +607,6 @@ export interface TriggerSidebarConfig extends BaseSidebarConfig {
|
||||
description?: TriggerDescription;
|
||||
yamlMode: boolean;
|
||||
uiSupported: boolean;
|
||||
paste: () => void;
|
||||
pasteAvailable: () => boolean;
|
||||
}
|
||||
|
||||
export interface ConditionSidebarConfig extends BaseSidebarConfig {
|
||||
@@ -625,8 +623,6 @@ export interface ConditionSidebarConfig extends BaseSidebarConfig {
|
||||
description?: ConditionDescription;
|
||||
yamlMode: boolean;
|
||||
uiSupported: boolean;
|
||||
paste: () => void;
|
||||
pasteAvailable: () => boolean;
|
||||
}
|
||||
|
||||
export interface ActionSidebarConfig extends BaseSidebarConfig {
|
||||
@@ -645,8 +641,6 @@ export interface ActionSidebarConfig extends BaseSidebarConfig {
|
||||
};
|
||||
yamlMode: boolean;
|
||||
uiSupported: boolean;
|
||||
paste: () => void;
|
||||
pasteAvailable: () => boolean;
|
||||
}
|
||||
|
||||
export interface OptionSidebarConfig extends BaseSidebarConfig {
|
||||
|
||||
@@ -2,12 +2,15 @@ import type { Connection } from "home-assistant-js-websocket";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { LovelaceResource } from "../resource";
|
||||
import type { LovelaceStrategyConfig } from "./strategy";
|
||||
import type { LovelaceViewRawConfig } from "./view";
|
||||
import type {
|
||||
LovelaceDashboardBackgroundConfig,
|
||||
LovelaceViewRawConfig,
|
||||
} from "./view";
|
||||
|
||||
export interface LovelaceDashboardBaseConfig {}
|
||||
|
||||
export interface LovelaceConfig extends LovelaceDashboardBaseConfig {
|
||||
background?: string;
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
views: LovelaceViewRawConfig[];
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@ export interface LovelaceViewBackgroundConfig {
|
||||
attachment?: "scroll" | "fixed";
|
||||
}
|
||||
|
||||
export type LovelaceDashboardBackgroundConfig =
|
||||
| string
|
||||
| LovelaceViewBackgroundConfig;
|
||||
|
||||
export interface LovelaceViewHeaderConfig {
|
||||
card?: LovelaceCardConfig;
|
||||
layout?: "start" | "center" | "responsive";
|
||||
@@ -60,7 +64,7 @@ export interface LovelaceBaseViewConfig {
|
||||
show_icon_and_title?: boolean;
|
||||
theme?: string;
|
||||
panel?: boolean;
|
||||
background?: string | LovelaceViewBackgroundConfig;
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
visible?: boolean | ShowViewConfig[];
|
||||
subview?: boolean;
|
||||
back_path?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { mdiAccountGroup, mdiOpenInNew } from "@mdi/js";
|
||||
import { mdiOpenInNew } from "@mdi/js";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
@@ -92,8 +92,12 @@ class DialogCommunity extends LitElement {
|
||||
href="https://fosstodon.org/@homeassistant"
|
||||
>
|
||||
<ha-list-item hasMeta graphic="icon">
|
||||
<ha-svg-icon .path=${mdiAccountGroup} slot="graphic"></ha-svg-icon>
|
||||
${this.localize("ui.panel.page-onboarding.welcome.social_media")}
|
||||
<img
|
||||
src="/static/images/logo_mastodon.svg"
|
||||
slot="graphic"
|
||||
alt="Mastodon Logo"
|
||||
/>
|
||||
${this.localize("ui.panel.page-onboarding.welcome.mastodon")}
|
||||
<ha-svg-icon slot="meta" .path=${mdiOpenInNew}></ha-svg-icon>
|
||||
</ha-list-item>
|
||||
</a>
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
mdiCheckboxOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiPlay,
|
||||
@@ -386,31 +385,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
|
||||
${this._pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item value="paste">
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
),
|
||||
html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
${!this.optionsInSidebar
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
@@ -795,9 +769,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
|
||||
private _copyAction = () => {
|
||||
this._setClipboard();
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(); // refresh sidebar
|
||||
}
|
||||
showEditorToast(this, {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.copied_to_clipboard"
|
||||
@@ -820,15 +791,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
});
|
||||
};
|
||||
|
||||
private _pasteAction = () => {
|
||||
const action = this._clipboard?.action;
|
||||
if (!action) return;
|
||||
|
||||
fireEvent(this, "paste", { item: action });
|
||||
};
|
||||
|
||||
private _pasteAvailable = () => !!this._clipboard?.action;
|
||||
|
||||
private _moveUp = () => {
|
||||
fireEvent(this, "move-up");
|
||||
};
|
||||
@@ -906,8 +868,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
delete: this._onDelete,
|
||||
copy: this._copyAction,
|
||||
cut: this._cutAction,
|
||||
paste: this._pasteAction,
|
||||
pasteAvailable: this._pasteAvailable,
|
||||
duplicate: this._duplicateAction,
|
||||
insertAfter: this._insertAfter,
|
||||
run: this._runAction,
|
||||
@@ -1001,9 +961,6 @@ export default class HaAutomationActionRow extends LitElement {
|
||||
case "cut":
|
||||
this._cutAction();
|
||||
break;
|
||||
case "paste":
|
||||
this._pasteAction();
|
||||
break;
|
||||
case "move_up":
|
||||
this._moveUp();
|
||||
break;
|
||||
|
||||
@@ -80,7 +80,6 @@ export default class HaAutomationAction extends AutomationSortableListMixin<Acti
|
||||
.narrow=${this.narrow}
|
||||
.disabled=${this.disabled}
|
||||
@duplicate=${this.duplicateItem}
|
||||
@paste=${this.pasteItem}
|
||||
@insert-after=${this.insertAfter}
|
||||
@move-down=${this.moveDown}
|
||||
@move-up=${this.moveUp}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
mdiArrowUp,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiFlask,
|
||||
@@ -279,31 +278,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
|
||||
${this._pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item value="paste">
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
),
|
||||
html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
${!this.optionsInSidebar
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
@@ -691,9 +665,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
|
||||
private _copyCondition = () => {
|
||||
this._setClipboard();
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(); // refresh sidebar
|
||||
}
|
||||
showEditorToast(this, {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.copied_to_clipboard"
|
||||
@@ -716,15 +687,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
});
|
||||
};
|
||||
|
||||
private _pasteCondition = () => {
|
||||
const condition = this._clipboard?.condition;
|
||||
if (!condition) return;
|
||||
|
||||
fireEvent(this, "paste", { item: condition });
|
||||
};
|
||||
|
||||
private _pasteAvailable = () => !!this._clipboard?.condition;
|
||||
|
||||
private _moveUp = () => {
|
||||
fireEvent(this, "move-up");
|
||||
};
|
||||
@@ -828,8 +790,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
insertAfter: this._insertAfter,
|
||||
copy: this._copyCondition,
|
||||
cut: this._cutCondition,
|
||||
paste: this._pasteCondition,
|
||||
pasteAvailable: this._pasteAvailable,
|
||||
test: this._testCondition,
|
||||
config: sidebarCondition,
|
||||
uiSupported: this._uiSupported(
|
||||
@@ -898,9 +858,6 @@ export default class HaAutomationConditionRow extends LitElement {
|
||||
case "cut":
|
||||
this._cutCondition();
|
||||
break;
|
||||
case "paste":
|
||||
this._pasteCondition();
|
||||
break;
|
||||
case "move_up":
|
||||
this._moveUp();
|
||||
break;
|
||||
|
||||
@@ -226,7 +226,6 @@ export default class HaAutomationCondition extends AutomationSortableListMixin<C
|
||||
.disabled=${this.disabled}
|
||||
.narrow=${this.narrow}
|
||||
@duplicate=${this.duplicateItem}
|
||||
@paste=${this.pasteItem}
|
||||
@insert-after=${this.insertAfter}
|
||||
@move-down=${this.moveDown}
|
||||
@move-up=${this.moveUp}
|
||||
|
||||
@@ -104,9 +104,6 @@ declare global {
|
||||
value: Trigger | Condition | Action | Trigger[] | Condition[] | Action[];
|
||||
};
|
||||
"save-automation": undefined;
|
||||
paste: {
|
||||
item: Trigger | Condition | Action;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,21 +165,6 @@ export const AutomationSortableListMixin = <T extends object>(
|
||||
});
|
||||
}
|
||||
|
||||
protected pasteItem(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
if (!ev.detail.item) return;
|
||||
|
||||
const index = (ev.target as any).index;
|
||||
const clonedItem = deepClone(ev.detail.item);
|
||||
|
||||
this.setHighlightedItems(ensureArray(clonedItem));
|
||||
|
||||
fireEvent(this, "value-changed", {
|
||||
// @ts-expect-error Requires library bump to ES2023
|
||||
value: this.items.toSpliced(index + 1, 0, clonedItem),
|
||||
});
|
||||
}
|
||||
|
||||
protected insertAfter(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
const index = (ev.target as any).index;
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
mdiCheckboxOutline,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiPlay,
|
||||
mdiPlayCircleOutline,
|
||||
@@ -229,37 +228,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
${this.config.pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="paste"
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
)}
|
||||
${!this.narrow
|
||||
? html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="toggle_yaml_mode"
|
||||
@@ -423,9 +391,6 @@ export default class HaAutomationSidebarAction extends LitElement {
|
||||
case "cut":
|
||||
this.config.cut();
|
||||
break;
|
||||
case "paste":
|
||||
this.config.paste();
|
||||
break;
|
||||
case "toggle_yaml_mode":
|
||||
this._toggleYamlMode();
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiFlask,
|
||||
mdiPlayCircleOutline,
|
||||
@@ -222,37 +221,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
${this.config.pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="paste"
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
)}
|
||||
${!this.narrow
|
||||
? html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="toggle_yaml_mode"
|
||||
@@ -468,9 +436,6 @@ export default class HaAutomationSidebarCondition extends LitElement {
|
||||
case "cut":
|
||||
this.config.cut();
|
||||
break;
|
||||
case "paste":
|
||||
this.config.paste();
|
||||
break;
|
||||
case "toggle_yaml_mode":
|
||||
this._toggleYamlMode();
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
mdiAppleKeyboardCommand,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiIdentifier,
|
||||
mdiPlayCircleOutline,
|
||||
@@ -210,37 +209,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
${this.config.pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="paste"
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
<div class="overflow-label">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
)}
|
||||
${!this.narrow
|
||||
? html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
: nothing}
|
||||
</div>
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
<ha-dropdown-item
|
||||
slot="menu-items"
|
||||
value="toggle_yaml_mode"
|
||||
@@ -383,9 +351,6 @@ export default class HaAutomationSidebarTrigger extends LitElement {
|
||||
case "cut":
|
||||
this.config.cut();
|
||||
break;
|
||||
case "paste":
|
||||
this.config.paste();
|
||||
break;
|
||||
case "toggle_yaml_mode":
|
||||
this._toggleYamlMode();
|
||||
break;
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
mdiArrowUp,
|
||||
mdiContentCopy,
|
||||
mdiContentCut,
|
||||
mdiContentPaste,
|
||||
mdiDelete,
|
||||
mdiDotsVertical,
|
||||
mdiInformationOutline,
|
||||
@@ -315,31 +314,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
|
||||
${this._pasteAvailable()
|
||||
? html`
|
||||
<ha-dropdown-item value="paste">
|
||||
<ha-svg-icon slot="icon" .path=${mdiContentPaste}></ha-svg-icon>
|
||||
${this._renderOverflowLabel(
|
||||
this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.paste"
|
||||
),
|
||||
html`<span class="shortcut">
|
||||
<span
|
||||
>${isMac
|
||||
? html`<ha-svg-icon
|
||||
.path=${mdiAppleKeyboardCommand}
|
||||
></ha-svg-icon>`
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.ctrl"
|
||||
)}</span
|
||||
>
|
||||
<span>+</span>
|
||||
<span>V</span>
|
||||
</span>`
|
||||
)}
|
||||
</ha-dropdown-item>
|
||||
`
|
||||
: nothing}
|
||||
${!this.optionsInSidebar
|
||||
? html`
|
||||
<ha-dropdown-item
|
||||
@@ -648,8 +622,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
copy: this._copyTrigger,
|
||||
duplicate: this._duplicateTrigger,
|
||||
cut: this._cutTrigger,
|
||||
paste: this._pasteTrigger,
|
||||
pasteAvailable: this._pasteAvailable,
|
||||
insertAfter: this._insertAfter,
|
||||
config: trigger,
|
||||
uiSupported: this._uiSupported(
|
||||
@@ -790,9 +762,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
|
||||
private _copyTrigger = () => {
|
||||
this._setClipboard();
|
||||
if (this._selected && this.optionsInSidebar) {
|
||||
this.openSidebar(); // refresh sidebar
|
||||
}
|
||||
showEditorToast(this, {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.copied_to_clipboard"
|
||||
@@ -815,15 +784,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
});
|
||||
};
|
||||
|
||||
private _pasteTrigger = () => {
|
||||
const trigger = this._clipboard?.trigger;
|
||||
if (!trigger) return;
|
||||
|
||||
fireEvent(this, "paste", { item: trigger });
|
||||
};
|
||||
|
||||
private _pasteAvailable = () => !!this._clipboard?.trigger;
|
||||
|
||||
private _moveUp = () => {
|
||||
fireEvent(this, "move-up");
|
||||
};
|
||||
@@ -896,9 +856,6 @@ export default class HaAutomationTriggerRow extends LitElement {
|
||||
case "cut":
|
||||
this._cutTrigger();
|
||||
break;
|
||||
case "paste":
|
||||
this._pasteTrigger();
|
||||
break;
|
||||
case "move_up":
|
||||
this._moveUp();
|
||||
break;
|
||||
|
||||
@@ -137,7 +137,6 @@ export default class HaAutomationTrigger extends AutomationSortableListMixin<Tri
|
||||
.trigger=${trg}
|
||||
.triggerDescriptions=${this._triggerDescriptions}
|
||||
@duplicate=${this.duplicateItem}
|
||||
@paste=${this.pasteItem}
|
||||
@insert-after=${this.insertAfter}
|
||||
@move-down=${this.moveDown}
|
||||
@move-up=${this.moveUp}
|
||||
|
||||
@@ -13,15 +13,14 @@ import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-dropdown";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
import "../../../components/ha-dropdown-item";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-menu-button";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-tip";
|
||||
import "../../../components/ha-tooltip";
|
||||
import "../../../components/ha-top-app-bar-fixed";
|
||||
import "../../../components/ha-tooltip";
|
||||
import type { CloudStatus } from "../../../data/cloud";
|
||||
import type { RepairsIssue } from "../../../data/repairs";
|
||||
import {
|
||||
@@ -48,6 +47,7 @@ import { configSections } from "../ha-panel-config";
|
||||
import "../repairs/ha-config-repairs";
|
||||
import "./ha-config-navigation";
|
||||
import "./ha-config-updates";
|
||||
import type { HaDropdownSelectEvent } from "../../../components/ha-dropdown";
|
||||
|
||||
const randomTip = (openFn: any, hass: HomeAssistant, narrow: boolean) => {
|
||||
const weighted: string[] = [];
|
||||
@@ -60,11 +60,23 @@ const randomTip = (openFn: any, hass: HomeAssistant, narrow: boolean) => {
|
||||
rel="noreferrer"
|
||||
>${hass.localize("ui.panel.config.tips.join_forums")}</a
|
||||
>`,
|
||||
social_media: html`<a
|
||||
href=${documentationUrl(hass, `/socials`)}
|
||||
twitter: html`<a
|
||||
href=${documentationUrl(hass, `/twitter`)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${hass.localize("ui.panel.config.tips.social_media")}</a
|
||||
>${hass.localize("ui.panel.config.tips.join_x")}</a
|
||||
>`,
|
||||
mastodon: html`<a
|
||||
href=${documentationUrl(hass, `/mastodon`)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${hass.localize("ui.panel.config.tips.join_mastodon")}</a
|
||||
>`,
|
||||
bluesky: html`<a
|
||||
href=${documentationUrl(hass, `/bluesky`)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>${hass.localize("ui.panel.config.tips.join_bluesky")}</a
|
||||
>`,
|
||||
discord: html`<a
|
||||
href=${documentationUrl(hass, `/join-chat`)}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { mdiClose } from "@mdi/js";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { slugify } from "../../../../common/string/slugify";
|
||||
@@ -8,17 +10,28 @@ import "../../../../components/ha-button";
|
||||
import "../../../../components/ha-dialog-footer";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-dialog-header";
|
||||
import "../../../../components/ha-icon-button";
|
||||
import "../../../../components/ha-tab-group";
|
||||
import "../../../../components/ha-tab-group-tab";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import type {
|
||||
LovelaceDashboard,
|
||||
LovelaceDashboardCreateParams,
|
||||
LovelaceDashboardMutableParams,
|
||||
} from "../../../../data/lovelace/dashboard";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
import {
|
||||
haStyleDialog,
|
||||
haStyleDialogFixedTop,
|
||||
} from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import "../../../lovelace/editor/view-editor/hui-view-background-editor";
|
||||
import type { LovelaceDashboardDetailsDialogParams } from "./show-dialog-lovelace-dashboard-detail";
|
||||
import { pickAvailableDashboardUrlPath } from "./pick-available-dashboard-url-path";
|
||||
|
||||
const TABS = ["tab-settings", "tab-background"] as const;
|
||||
|
||||
@customElement("dialog-lovelace-dashboard-detail")
|
||||
export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@@ -35,10 +48,16 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
|
||||
@state() private _submitting = false;
|
||||
|
||||
@state() private _currTab: (typeof TABS)[number] = TABS[0];
|
||||
|
||||
@state() private _backgroundConfig?: LovelaceConfig;
|
||||
|
||||
public showDialog(params: LovelaceDashboardDetailsDialogParams): void {
|
||||
this._params = params;
|
||||
this._error = undefined;
|
||||
this._urlPathChanged = false;
|
||||
this._currTab = TABS[0];
|
||||
this._backgroundConfig = params.lovelaceConfig;
|
||||
this._open = true;
|
||||
if (this._params.dashboard) {
|
||||
this._data = this._params.dashboard;
|
||||
@@ -64,6 +83,7 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
private _dialogClosed(): void {
|
||||
this._params = undefined;
|
||||
this._data = undefined;
|
||||
this._backgroundConfig = undefined;
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
|
||||
@@ -73,6 +93,8 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
|
||||
const titleInvalid = !this._data.title || !this._data.title.trim();
|
||||
const showBackgroundTab =
|
||||
Boolean(this._params.lovelaceConfig) && Boolean(this._params.saveConfig);
|
||||
|
||||
const cancelButton = html`
|
||||
<ha-button
|
||||
@@ -88,38 +110,51 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
<ha-dialog
|
||||
.hass=${this.hass}
|
||||
.open=${this._open}
|
||||
header-title=${this._params.urlPath
|
||||
? this._data.title ||
|
||||
this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.edit_dashboard"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.new_dashboard"
|
||||
)}
|
||||
width=${showBackgroundTab ? "large" : "medium"}
|
||||
prevent-scrim-close
|
||||
@closed=${this._dialogClosed}
|
||||
class=${classMap({
|
||||
"has-background-tab": showBackgroundTab,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
${this._params.dashboard?.mode === "yaml"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.cant_edit_yaml"
|
||||
)
|
||||
: html`
|
||||
<ha-form
|
||||
autofocus
|
||||
.schema=${this._schema(
|
||||
this._params,
|
||||
this._data?.require_admin
|
||||
${showBackgroundTab
|
||||
? html`
|
||||
<ha-dialog-header show-border slot="header">
|
||||
<ha-icon-button
|
||||
slot="navigationIcon"
|
||||
@click=${this.closeDialog}
|
||||
.label=${this.hass.localize("ui.common.close")}
|
||||
.path=${mdiClose}
|
||||
></ha-icon-button>
|
||||
<h2 slot="title">
|
||||
${this._params.urlPath
|
||||
? this._data.title ||
|
||||
this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.edit_dashboard"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.detail.new_dashboard"
|
||||
)}
|
||||
</h2>
|
||||
<ha-tab-group @wa-tab-show=${this._handleTabChanged}>
|
||||
${TABS.map(
|
||||
(tab) => html`
|
||||
<ha-tab-group-tab
|
||||
slot="nav"
|
||||
.panel=${tab}
|
||||
.active=${this._currTab === tab}
|
||||
>
|
||||
${this.hass.localize(
|
||||
`ui.panel.lovelace.editor.edit_view.${tab.replace("-", "_")}`
|
||||
)}
|
||||
</ha-tab-group-tab>
|
||||
`
|
||||
)}
|
||||
.data=${this._data}
|
||||
.hass=${this.hass}
|
||||
.error=${this._error}
|
||||
.computeLabel=${this._computeLabel}
|
||||
.computeHelper=${this._computeHelper}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`}
|
||||
</div>
|
||||
</ha-tab-group>
|
||||
</ha-dialog-header>
|
||||
`
|
||||
: nothing}
|
||||
<div>${this._renderContent(showBackgroundTab)}</div>
|
||||
<ha-dialog-footer slot="footer">
|
||||
${this._params.urlPath
|
||||
? html`
|
||||
@@ -163,6 +198,39 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderContent(
|
||||
showBackgroundTab: boolean
|
||||
): string | TemplateResult<1> | typeof nothing {
|
||||
if (this._params?.dashboard?.mode === "yaml") {
|
||||
return this.hass.localize(
|
||||
"ui.panel.config.lovelace.dashboards.cant_edit_yaml"
|
||||
);
|
||||
}
|
||||
|
||||
if (this._currTab === "tab-background" && showBackgroundTab) {
|
||||
return html`
|
||||
<hui-view-background-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._backgroundConfig}
|
||||
@background-config-changed=${this._backgroundConfigChanged}
|
||||
></hui-view-background-editor>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
autofocus
|
||||
.schema=${this._schema(this._params!, this._data?.require_admin)}
|
||||
.data=${this._data}
|
||||
.hass=${this.hass}
|
||||
.error=${this._error}
|
||||
.computeLabel=${this._computeLabel}
|
||||
.computeHelper=${this._computeHelper}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`;
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(params: LovelaceDashboardDetailsDialogParams, requireAdmin?: boolean) =>
|
||||
[
|
||||
@@ -254,6 +322,12 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _backgroundConfigChanged(
|
||||
ev: CustomEvent<{ config: LovelaceConfig }>
|
||||
) {
|
||||
this._backgroundConfig = ev.detail.config;
|
||||
}
|
||||
|
||||
private _fillUrlPath(title: string) {
|
||||
if (this._urlPathChanged || !title) {
|
||||
return;
|
||||
@@ -280,6 +354,15 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
this._submitting = true;
|
||||
try {
|
||||
if (
|
||||
this._backgroundConfig &&
|
||||
this._params?.saveConfig &&
|
||||
this._params.lovelaceConfig &&
|
||||
this._backgroundConfig.background !==
|
||||
this._params.lovelaceConfig.background
|
||||
) {
|
||||
await this._params.saveConfig(this._backgroundConfig);
|
||||
}
|
||||
if (this._params!.dashboard) {
|
||||
const values: Partial<LovelaceDashboardMutableParams> = {
|
||||
require_admin: this._data!.require_admin,
|
||||
@@ -314,6 +397,18 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _handleTabChanged(
|
||||
ev: CustomEvent<{
|
||||
name: (typeof TABS)[number];
|
||||
}>
|
||||
): void {
|
||||
const newTab = ev.detail.name;
|
||||
if (newTab === this._currTab) {
|
||||
return;
|
||||
}
|
||||
this._currTab = newTab;
|
||||
}
|
||||
|
||||
private async _deleteDashboard() {
|
||||
this._submitting = true;
|
||||
try {
|
||||
@@ -326,7 +421,30 @@ export class DialogLovelaceDashboardDetail extends LitElement {
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [haStyleDialog, css``];
|
||||
return [
|
||||
haStyleDialog,
|
||||
haStyleDialogFixedTop,
|
||||
css`
|
||||
ha-dialog {
|
||||
--dialog-content-padding: var(--ha-space-6);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
ha-tab-group-tab {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
ha-tab-group-tab::part(base) {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import type {
|
||||
LovelaceDashboard,
|
||||
LovelaceDashboardCreateParams,
|
||||
@@ -17,6 +18,8 @@ export interface LovelaceDashboardDetailsDialogParams {
|
||||
* auto-generated paths avoid collisions by appending -2, -3, and so on.
|
||||
*/
|
||||
takenUrlPaths?: ReadonlySet<string>;
|
||||
lovelaceConfig?: LovelaceConfig;
|
||||
saveConfig?: (config: LovelaceConfig) => Promise<void>;
|
||||
createDashboard?: (values: LovelaceDashboardCreateParams) => Promise<unknown>;
|
||||
updateDashboard: (
|
||||
updates: Partial<LovelaceDashboardMutableParams>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
@@ -7,6 +6,7 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import "../../../components/ha-card";
|
||||
import type { CameraEntity } from "../../../data/camera";
|
||||
import type { ImageEntity } from "../../../data/image";
|
||||
import { computeImageUrl } from "../../../data/image";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
@@ -72,8 +72,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||
!["camera", "image", "person"].includes(computeDomain(config.entity)) &&
|
||||
!config.image &&
|
||||
!config.state_image &&
|
||||
!config.camera_image &&
|
||||
!config.show_entity_picture
|
||||
!config.camera_image
|
||||
) {
|
||||
throw new Error("No image source configured");
|
||||
}
|
||||
@@ -115,7 +114,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const stateObj: HassEntity | undefined =
|
||||
const stateObj: CameraEntity | ImageEntity | PersonEntity | undefined =
|
||||
this.hass.states[this._config.entity];
|
||||
|
||||
if (!stateObj) {
|
||||
@@ -144,23 +143,10 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
const domain: string = computeDomain(this._config.entity);
|
||||
let image: string | undefined;
|
||||
|
||||
// When show_entity_picture is enabled, try entity_picture first
|
||||
if (this._config.show_entity_picture) {
|
||||
image =
|
||||
stateObj.attributes.entity_picture_local ||
|
||||
stateObj.attributes.entity_picture;
|
||||
}
|
||||
|
||||
// Fall back to configured image
|
||||
if (!image) {
|
||||
image =
|
||||
(typeof this._config?.image === "object" &&
|
||||
this._config.image.media_content_id) ||
|
||||
(this._config.image as string | undefined);
|
||||
}
|
||||
|
||||
let image: string | undefined =
|
||||
(typeof this._config?.image === "object" &&
|
||||
this._config.image.media_content_id) ||
|
||||
(this._config.image as string | undefined);
|
||||
if (!image) {
|
||||
switch (domain) {
|
||||
case "image":
|
||||
|
||||
@@ -531,7 +531,6 @@ export interface PictureElementsCardConfig extends LovelaceCardConfig {
|
||||
|
||||
export interface PictureEntityCardConfig extends LovelaceCardConfig {
|
||||
entity: string;
|
||||
show_entity_picture?: boolean;
|
||||
name?: string | EntityNameItem | EntityNameItem[];
|
||||
image?: string | MediaSelectorValue;
|
||||
camera_image?: string;
|
||||
|
||||
@@ -35,7 +35,6 @@ const cardConfigStruct = assign(
|
||||
baseLovelaceCardConfig,
|
||||
object({
|
||||
entity: optional(string()),
|
||||
show_entity_picture: optional(boolean()),
|
||||
image: optional(union([string(), object()])),
|
||||
name: optional(entityNameStruct),
|
||||
camera_image: optional(string()),
|
||||
@@ -69,7 +68,6 @@ export class HuiPictureEntityCardEditor
|
||||
(localize: LocalizeFunc) =>
|
||||
[
|
||||
{ name: "entity", required: true, selector: { entity: {} } },
|
||||
{ name: "show_entity_picture", selector: { boolean: {} } },
|
||||
{
|
||||
name: "name",
|
||||
selector: {
|
||||
@@ -216,8 +214,6 @@ export class HuiPictureEntityCardEditor
|
||||
config.entity !== this._config?.entity &&
|
||||
(computeDomain(config.entity) === "image" ||
|
||||
(computeDomain(config.entity) === "person" &&
|
||||
this.hass?.states[config.entity]?.attributes.entity_picture) ||
|
||||
(config.show_entity_picture &&
|
||||
this.hass?.states[config.entity]?.attributes.entity_picture)) &&
|
||||
config.image === STUB_IMAGE
|
||||
) {
|
||||
@@ -251,10 +247,6 @@ export class HuiPictureEntityCardEditor
|
||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
||||
) => {
|
||||
switch (schema.name) {
|
||||
case "show_entity_picture":
|
||||
return this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.show_entity_picture_helper`
|
||||
);
|
||||
case "aspect_ratio":
|
||||
return typeof this._config?.grid_options?.rows === "number"
|
||||
? this.hass!.localize(
|
||||
|
||||
@@ -183,7 +183,7 @@ export class HuiDialogEditView extends LitElement {
|
||||
<hui-view-background-editor
|
||||
.hass=${this.hass}
|
||||
.config=${this._config}
|
||||
@view-config-changed=${this._viewConfigChanged}
|
||||
@background-config-changed=${this._viewConfigChanged}
|
||||
></hui-view-background-editor>
|
||||
`;
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||
import type { LovelaceDashboardBackgroundConfig } from "../../../../data/lovelace/config/view";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
|
||||
@@ -14,18 +14,18 @@ import {
|
||||
resolveMediaSource,
|
||||
} from "../../../../data/media_source";
|
||||
|
||||
export interface BackgroundConfigTarget {
|
||||
background?: LovelaceDashboardBackgroundConfig;
|
||||
}
|
||||
|
||||
@customElement("hui-view-background-editor")
|
||||
export class HuiViewBackgroundEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _config!: LovelaceViewConfig;
|
||||
@property({ attribute: false }) public config!: BackgroundConfigTarget;
|
||||
|
||||
@state({ attribute: false }) private _resolvedImage?: string;
|
||||
|
||||
set config(config: LovelaceViewConfig) {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
private _localizeValueCallback = (key: string) =>
|
||||
this.hass.localize(key as any);
|
||||
|
||||
@@ -125,12 +125,12 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
if (
|
||||
this._config &&
|
||||
this.config &&
|
||||
this.hass &&
|
||||
(changedProps.has("_config") ||
|
||||
(changedProps.has("config") ||
|
||||
(changedProps.has("hass") && !changedProps.get("hass")))
|
||||
) {
|
||||
const background = this._backgroundData(this._config);
|
||||
const background = this._backgroundData(this.config);
|
||||
this.style.setProperty(
|
||||
"--picture-opacity",
|
||||
`${(background.opacity ?? 100) / 100}`
|
||||
@@ -156,7 +156,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const background = this._backgroundData(this._config);
|
||||
const background = this._backgroundData(this.config);
|
||||
|
||||
return html`
|
||||
${this._resolvedImage
|
||||
@@ -181,7 +181,7 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
}
|
||||
|
||||
private _backgroundData = memoizeOne(
|
||||
(backgroundConfig?: LovelaceViewConfig) => {
|
||||
(backgroundConfig?: BackgroundConfigTarget) => {
|
||||
let background = backgroundConfig?.background;
|
||||
if (typeof background === "string") {
|
||||
const backgroundUrl = background.match(
|
||||
@@ -220,10 +220,10 @@ export class HuiViewBackgroundEditor extends LitElement {
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
const config = {
|
||||
...this._config,
|
||||
...this.config,
|
||||
background: ev.detail.value,
|
||||
};
|
||||
fireEvent(this, "view-config-changed", { config });
|
||||
fireEvent(this, "background-config-changed", { config });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
@@ -290,4 +290,10 @@ declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-view-background-editor": HuiViewBackgroundEditor;
|
||||
}
|
||||
|
||||
interface HASSDomEvents {
|
||||
"background-config-changed": {
|
||||
config: BackgroundConfigTarget;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,6 +1045,8 @@ class HUIRoot extends LitElement {
|
||||
showDashboardDetailDialog(this, {
|
||||
dashboard,
|
||||
urlPath,
|
||||
lovelaceConfig: this.lovelace?.config,
|
||||
saveConfig: this.lovelace?.saveConfig,
|
||||
updateDashboard: async (values) => {
|
||||
await updateDashboard(this.hass!, dashboard!.id, values);
|
||||
},
|
||||
|
||||
@@ -336,15 +336,12 @@ export const getMyRedirects = (): Redirects => ({
|
||||
redirect: "/config/info",
|
||||
},
|
||||
supervisor_store: {
|
||||
component: "hassio",
|
||||
redirect: "/config/apps/available",
|
||||
},
|
||||
supervisor_addons: {
|
||||
component: "hassio",
|
||||
redirect: "/config/apps",
|
||||
},
|
||||
supervisor_app: {
|
||||
component: "hassio",
|
||||
redirect: "/config/app",
|
||||
params: {
|
||||
app: "string",
|
||||
@@ -354,7 +351,6 @@ export const getMyRedirects = (): Redirects => ({
|
||||
},
|
||||
},
|
||||
supervisor_addon: {
|
||||
component: "hassio",
|
||||
redirect: "/config/app",
|
||||
params: {
|
||||
addon: "string",
|
||||
@@ -364,7 +360,6 @@ export const getMyRedirects = (): Redirects => ({
|
||||
},
|
||||
},
|
||||
supervisor_add_addon_repository: {
|
||||
component: "hassio",
|
||||
redirect: "/config/apps/available",
|
||||
params: {
|
||||
repository_url: "url",
|
||||
@@ -415,9 +410,21 @@ class HaPanelMy extends LitElement {
|
||||
1,
|
||||
this.route.path.endsWith("/") ? this.route.path.length - 1 : undefined
|
||||
);
|
||||
const hasSupervisor = isComponentLoaded(this.hass.config, "hassio");
|
||||
|
||||
this._redirect = getRedirect(path);
|
||||
|
||||
if (path.startsWith("supervisor") && this._redirect === undefined) {
|
||||
if (!hasSupervisor) {
|
||||
this._error = "no_supervisor";
|
||||
return;
|
||||
}
|
||||
navigate(`/hassio/_my_redirect/${path}${window.location.search}`, {
|
||||
replace: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._redirect) {
|
||||
this._error = "not_supported";
|
||||
return;
|
||||
@@ -437,10 +444,7 @@ class HaPanelMy extends LitElement {
|
||||
!isComponentLoaded(this.hass.config, this._redirect.component)
|
||||
) {
|
||||
this.hass.loadBackendTranslation("title", this._redirect.component);
|
||||
this._error =
|
||||
this._redirect.component === "hassio"
|
||||
? "no_supervisor"
|
||||
: "no_component";
|
||||
this._error = "no_component";
|
||||
const component = this._redirect.component;
|
||||
if ((PROTOCOL_INTEGRATIONS as readonly string[]).includes(component)) {
|
||||
const params = extractSearchParamsObject();
|
||||
|
||||
@@ -340,6 +340,8 @@ export default <T extends Constructor<HassElement>>(superClass: T) =>
|
||||
if (repo && repo.source !== "local") {
|
||||
myParams.append("repository_url", repo.source);
|
||||
}
|
||||
} else if (redirect.redirect === "/hassio/addon") {
|
||||
myParams.append("addon", targetPath.split("/")[3]);
|
||||
}
|
||||
window.open(
|
||||
`https://my.home-assistant.io/create-link/?${myParams.toString()}`,
|
||||
|
||||
@@ -2526,7 +2526,7 @@
|
||||
"my": {
|
||||
"not_supported": "This redirect is not supported by your Home Assistant instance. Check the {link} for the supported redirects and the version they where introduced.",
|
||||
"component_not_loaded": "This redirect is not supported by your Home Assistant instance. You need the integration {integration} to use this redirect.",
|
||||
"no_supervisor": "This redirect is not supported by your Home Assistant installation. It needs the Home Assistant OS installation method. For more information, see the {docs_link}.",
|
||||
"no_supervisor": "This redirect is not supported by your Home Assistant installation. It needs either the Home Assistant OS or Home Assistant Supervised installation method. For more information, see the {docs_link}.",
|
||||
"not_app": "This redirect only works from a mobile device that has the Home Assistant Companion app installed. {link}.",
|
||||
"url_error": "The provided URL is invalid.",
|
||||
"documentation": "documentation",
|
||||
@@ -8011,8 +8011,10 @@
|
||||
},
|
||||
"tips": {
|
||||
"tip": "Tip!",
|
||||
"join": "Join the community on our {forums}, {social_media}, {discord}, {blog} or {newsletter}",
|
||||
"social_media": "Social Media",
|
||||
"join": "Join the community on our {forums}, {mastodon}, {bluesky}, {twitter}, {discord}, {blog} or {newsletter}",
|
||||
"join_x": "X (formerly Twitter)",
|
||||
"join_mastodon": "Mastodon",
|
||||
"join_bluesky": "Bluesky",
|
||||
"join_forums": "Forums",
|
||||
"join_chat": "Chat",
|
||||
"join_blog": "Blog",
|
||||
@@ -9364,8 +9366,6 @@
|
||||
"attribute": "Attribute",
|
||||
"camera_image": "Camera entity",
|
||||
"image_entity": "Image entity",
|
||||
"show_entity_picture": "Show entity picture",
|
||||
"show_entity_picture_helper": "Use the entity's picture if available; falls back to the configured image",
|
||||
"camera_view": "Camera view",
|
||||
"camera_view_options": {
|
||||
"auto": "Auto",
|
||||
@@ -10591,7 +10591,8 @@
|
||||
"forums": "Home Assistant forums",
|
||||
"open_home_newsletter": "Building the Open Home newsletter",
|
||||
"discord": "Discord chat",
|
||||
"social_media": "Social Media",
|
||||
"x": "[%key:ui::panel::config::tips::join_x%]",
|
||||
"mastodon": "Mastodon",
|
||||
"playstore": "Get it on Google Play",
|
||||
"appstore": "Download on the App Store"
|
||||
},
|
||||
@@ -10890,7 +10891,7 @@
|
||||
"forums": "[%key:ui::panel::page-onboarding::welcome::forums%]",
|
||||
"open_home_newsletter": "[%key:ui::panel::page-onboarding::welcome::open_home_newsletter%]",
|
||||
"discord": "[%key:ui::panel::page-onboarding::welcome::discord%]",
|
||||
"social_media": "[%key:ui::panel::page-onboarding::welcome::social_media%]",
|
||||
"mastodon": "[%key:ui::panel::page-onboarding::welcome::mastodon%]",
|
||||
"playstore": "[%key:ui::panel::page-onboarding::welcome::playstore%]",
|
||||
"appstore": "[%key:ui::panel::page-onboarding::welcome::appstore%]"
|
||||
},
|
||||
|
||||
74
yarn.lock
74
yarn.lock
@@ -1501,23 +1501,23 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/config-array@npm:^0.23.5":
|
||||
version: 0.23.5
|
||||
resolution: "@eslint/config-array@npm:0.23.5"
|
||||
"@eslint/config-array@npm:^0.23.4":
|
||||
version: 0.23.4
|
||||
resolution: "@eslint/config-array@npm:0.23.4"
|
||||
dependencies:
|
||||
"@eslint/object-schema": "npm:^3.0.5"
|
||||
"@eslint/object-schema": "npm:^3.0.4"
|
||||
debug: "npm:^4.3.1"
|
||||
minimatch: "npm:^10.2.4"
|
||||
checksum: 10/0e05be2b5c8b9f9fb8094948fd2d35591a32091b9d39205181f2ed9bec0e2c8b2969f019f40a0388755a025408b98929e2d0beccb4fbd6609c1c0d6c9e9a14f0
|
||||
checksum: 10/a42bdf8d66d52703596d5a791eedb1ad79e232dad58e0450b65d8ad48c2fdf50ee62d26fe0e823092384e93378c39adeea30eb1cd12af7ee207a142f9e1996eb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/config-helpers@npm:^0.5.5":
|
||||
version: 0.5.5
|
||||
resolution: "@eslint/config-helpers@npm:0.5.5"
|
||||
"@eslint/config-helpers@npm:^0.5.4":
|
||||
version: 0.5.4
|
||||
resolution: "@eslint/config-helpers@npm:0.5.4"
|
||||
dependencies:
|
||||
"@eslint/core": "npm:^1.2.1"
|
||||
checksum: 10/19072449502b928a716df87b2d9b13c7befb21974b0f93fdbea705ddba098792142808105170ef2183c28ce13ac9fa1713ef0599749f8469434ac2b914fc8f4d
|
||||
"@eslint/core": "npm:^1.2.0"
|
||||
checksum: 10/277c951ac82b28e2f56adae3cf64ddcfa4e0fb07e8beaa853c2070e07fcb6062fc48a257ddfa12027aaead698f031bc81c343e0c9ddf7a8f59b724e119552897
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1530,12 +1530,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/core@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "@eslint/core@npm:1.2.1"
|
||||
"@eslint/core@npm:^1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "@eslint/core@npm:1.2.0"
|
||||
dependencies:
|
||||
"@types/json-schema": "npm:^7.0.15"
|
||||
checksum: 10/e1f9f5534f495b74a4c13c372e8f2feaf0c67f5dd666111c849c97c221d4ba730c98333a2ca94dd28cd7c24e3b1016bd868ca03c42e070732c047053f854cb13
|
||||
checksum: 10/b4e459ea69935cbed0b99f2160631fcabb3489d950dde86989b1da395f7649bedb14c702afc82e7cb64b6d7c62a6a10f8dae8dcf4c92dc3035bcbe531e65603e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1568,10 +1568,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/object-schema@npm:^3.0.5":
|
||||
version: 3.0.5
|
||||
resolution: "@eslint/object-schema@npm:3.0.5"
|
||||
checksum: 10/42e9ec2551d7cafe1825f20494576c9a867dfd26e728b66620f55d954cd5c4c9c4987755d147893985b8d39b49dace31117e59e7bc9564eb411b397e579a50e7
|
||||
"@eslint/object-schema@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "@eslint/object-schema@npm:3.0.4"
|
||||
checksum: 10/16daaf207aea472852465619fd29db29e0ab897353347020c52d526e27d8ceb44516506d4da61ff0a89cb8bd5ad935b882aca255ff1bc44ea9a59b1bd8de75bb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1585,13 +1585,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/plugin-kit@npm:^0.7.1":
|
||||
version: 0.7.1
|
||||
resolution: "@eslint/plugin-kit@npm:0.7.1"
|
||||
"@eslint/plugin-kit@npm:^0.7.0":
|
||||
version: 0.7.0
|
||||
resolution: "@eslint/plugin-kit@npm:0.7.0"
|
||||
dependencies:
|
||||
"@eslint/core": "npm:^1.2.1"
|
||||
"@eslint/core": "npm:^1.2.0"
|
||||
levn: "npm:^0.4.1"
|
||||
checksum: 10/8f923f4cdadadd215e0c2028e6a53101bb148a7780cdb4dc8cd69b0c77fc88496742e87e0605b12905ff715e2c7ad6cbd2d92c5653cdbf91cca1e229b5022c1f
|
||||
checksum: 10/3e435cc19db205f4a70ecba060e22b9b7efa2809426c0b020347b3aea0ae5e3507628486c1bc1a18a32fbad1e8cf0fd2ec11ca6ca6a6b958d141291426257c15
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -7748,16 +7748,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint@npm:10.2.1":
|
||||
version: 10.2.1
|
||||
resolution: "eslint@npm:10.2.1"
|
||||
"eslint@npm:10.2.0":
|
||||
version: 10.2.0
|
||||
resolution: "eslint@npm:10.2.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.8.0"
|
||||
"@eslint-community/regexpp": "npm:^4.12.2"
|
||||
"@eslint/config-array": "npm:^0.23.5"
|
||||
"@eslint/config-helpers": "npm:^0.5.5"
|
||||
"@eslint/core": "npm:^1.2.1"
|
||||
"@eslint/plugin-kit": "npm:^0.7.1"
|
||||
"@eslint/config-array": "npm:^0.23.4"
|
||||
"@eslint/config-helpers": "npm:^0.5.4"
|
||||
"@eslint/core": "npm:^1.2.0"
|
||||
"@eslint/plugin-kit": "npm:^0.7.0"
|
||||
"@humanfs/node": "npm:^0.16.6"
|
||||
"@humanwhocodes/module-importer": "npm:^1.0.1"
|
||||
"@humanwhocodes/retry": "npm:^0.4.2"
|
||||
@@ -7789,7 +7789,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
eslint: bin/eslint.js
|
||||
checksum: 10/954658c846696dc501a2b8e5fb268713e231dd81375dc25d76cd2fb4a1c73094ea73c64197634ece6fca8a54536e89eb44548a11be672544522e7a50eb8aae95
|
||||
checksum: 10/583589ed96922aad9507c94339e843c8929c297d505ae7d70579cef56b435a10d8a48d24616eb4fb53fbe75d8655adb8e44add5d5b2bca100148d31d890ab3a4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -8995,7 +8995,7 @@ __metadata:
|
||||
dialog-polyfill: "npm:0.5.6"
|
||||
echarts: "npm:6.0.0"
|
||||
element-internals-polyfill: "npm:3.0.2"
|
||||
eslint: "npm:10.2.1"
|
||||
eslint: "npm:10.2.0"
|
||||
eslint-config-airbnb-base: "npm:15.0.0"
|
||||
eslint-config-prettier: "npm:10.1.8"
|
||||
eslint-import-resolver-webpack: "npm:0.13.11"
|
||||
@@ -9036,7 +9036,7 @@ __metadata:
|
||||
lodash.template: "npm:4.5.0"
|
||||
luxon: "npm:3.7.2"
|
||||
map-stream: "npm:0.0.7"
|
||||
marked: "npm:18.0.2"
|
||||
marked: "npm:18.0.1"
|
||||
memoize-one: "npm:6.0.0"
|
||||
node-vibrant: "npm:4.0.4"
|
||||
object-hash: "npm:3.0.0"
|
||||
@@ -10727,12 +10727,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"marked@npm:18.0.2":
|
||||
version: 18.0.2
|
||||
resolution: "marked@npm:18.0.2"
|
||||
"marked@npm:18.0.1":
|
||||
version: 18.0.1
|
||||
resolution: "marked@npm:18.0.1"
|
||||
bin:
|
||||
marked: bin/marked.js
|
||||
checksum: 10/3e4953789360ff42be633337a1ad5f440d1941a328f8c23f8ce3fb686554d67c4f5815eb4b7225af370fd3c01f61f3dcf07dda1487ec47dbf8017eaa7e358028
|
||||
checksum: 10/200d99ff0a45c503fe8c0fdcdbae32106dcebb17e06b68aa06ad26eb9c38f84c71c34d239a001d34688dc58a38fb47c7c7edf8bd9d3f31672b3c3980f84bfad6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user