mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-24 21:37:21 +00:00
Add Counter to Helpers (#7346)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
874f3b32b3
commit
cbef909657
51
src/data/counter.ts
Normal file
51
src/data/counter.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
export interface Counter {
|
||||
id: string;
|
||||
name: string;
|
||||
icon?: string;
|
||||
initial?: number;
|
||||
restore?: boolean;
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
step?: number;
|
||||
}
|
||||
|
||||
export interface CounterMutableParams {
|
||||
name: string;
|
||||
icon: string;
|
||||
initial: number;
|
||||
restore: boolean;
|
||||
minimum: number;
|
||||
maximum: number;
|
||||
step: number;
|
||||
}
|
||||
|
||||
export const fetchCounter = (hass: HomeAssistant) =>
|
||||
hass.callWS<Counter[]>({ type: "counter/list" });
|
||||
|
||||
export const createCounter = (
|
||||
hass: HomeAssistant,
|
||||
values: CounterMutableParams
|
||||
) =>
|
||||
hass.callWS<Counter>({
|
||||
type: "counter/create",
|
||||
...values,
|
||||
});
|
||||
|
||||
export const updateCounter = (
|
||||
hass: HomeAssistant,
|
||||
id: string,
|
||||
updates: Partial<CounterMutableParams>
|
||||
) =>
|
||||
hass.callWS<Counter>({
|
||||
type: "counter/update",
|
||||
counter_id: id,
|
||||
...updates,
|
||||
});
|
||||
|
||||
export const deleteCounter = (hass: HomeAssistant, id: string) =>
|
||||
hass.callWS({
|
||||
type: "counter/delete",
|
||||
counter_id: id,
|
||||
});
|
@ -5,4 +5,5 @@ export const PLATFORMS_WITH_SETTINGS_TAB = {
|
||||
input_text: "entity-settings-helper-tab",
|
||||
input_boolean: "entity-settings-helper-tab",
|
||||
input_datetime: "entity-settings-helper-tab",
|
||||
counter: "entity-settings-helper-tab",
|
||||
};
|
||||
|
@ -42,6 +42,11 @@ import {
|
||||
fetchInputText,
|
||||
updateInputText,
|
||||
} from "../../../../../data/input_text";
|
||||
import {
|
||||
deleteCounter,
|
||||
fetchCounter,
|
||||
updateCounter,
|
||||
} from "../../../../../data/counter";
|
||||
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
import type { HomeAssistant } from "../../../../../types";
|
||||
import type { Helper } from "../../../helpers/const";
|
||||
@ -50,6 +55,7 @@ import "../../../helpers/forms/ha-input_datetime-form";
|
||||
import "../../../helpers/forms/ha-input_number-form";
|
||||
import "../../../helpers/forms/ha-input_select-form";
|
||||
import "../../../helpers/forms/ha-input_text-form";
|
||||
import "../../../helpers/forms/ha-counter-form";
|
||||
import "../../entity-registry-basic-editor";
|
||||
import type { HaEntityRegistryBasicEditor } from "../../entity-registry-basic-editor";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
@ -80,6 +86,11 @@ const HELPERS = {
|
||||
update: updateInputSelect,
|
||||
delete: deleteInputSelect,
|
||||
},
|
||||
counter: {
|
||||
fetch: fetchCounter,
|
||||
update: updateCounter,
|
||||
delete: deleteCounter,
|
||||
},
|
||||
};
|
||||
|
||||
@customElement("entity-settings-helper-tab")
|
||||
|
@ -3,6 +3,7 @@ import { InputDateTime } from "../../../data/input_datetime";
|
||||
import { InputNumber } from "../../../data/input_number";
|
||||
import { InputSelect } from "../../../data/input_select";
|
||||
import { InputText } from "../../../data/input_text";
|
||||
import { Counter } from "../../../data/counter";
|
||||
|
||||
export const HELPER_DOMAINS = [
|
||||
"input_boolean",
|
||||
@ -10,6 +11,7 @@ export const HELPER_DOMAINS = [
|
||||
"input_number",
|
||||
"input_datetime",
|
||||
"input_select",
|
||||
"counter",
|
||||
];
|
||||
|
||||
export type Helper =
|
||||
@ -17,4 +19,5 @@ export type Helper =
|
||||
| InputText
|
||||
| InputNumber
|
||||
| InputSelect
|
||||
| InputDateTime;
|
||||
| InputDateTime
|
||||
| Counter;
|
||||
|
@ -22,6 +22,7 @@ import { createInputDateTime } from "../../../data/input_datetime";
|
||||
import { createInputNumber } from "../../../data/input_number";
|
||||
import { createInputSelect } from "../../../data/input_select";
|
||||
import { createInputText } from "../../../data/input_text";
|
||||
import { createCounter } from "../../../data/counter";
|
||||
import { haStyleDialog } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { Helper } from "./const";
|
||||
@ -30,6 +31,7 @@ import "./forms/ha-input_datetime-form";
|
||||
import "./forms/ha-input_number-form";
|
||||
import "./forms/ha-input_select-form";
|
||||
import "./forms/ha-input_text-form";
|
||||
import "./forms/ha-counter-form";
|
||||
|
||||
const HELPERS = {
|
||||
input_boolean: createInputBoolean,
|
||||
@ -37,6 +39,7 @@ const HELPERS = {
|
||||
input_number: createInputNumber,
|
||||
input_datetime: createInputDateTime,
|
||||
input_select: createInputSelect,
|
||||
counter: createCounter,
|
||||
};
|
||||
|
||||
@customElement("dialog-helper-detail")
|
||||
|
210
src/panels/config/helpers/forms/ha-counter-form.ts
Normal file
210
src/panels/config/helpers/forms/ha-counter-form.ts
Normal file
@ -0,0 +1,210 @@
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
internalProperty,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import "../../../../components/ha-icon-input";
|
||||
import "../../../../components/ha-switch";
|
||||
import type { HaSwitch } from "../../../../components/ha-switch";
|
||||
import { Counter } from "../../../../data/counter";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
|
||||
@customElement("ha-counter-form")
|
||||
class HaCounterForm extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public new?: boolean;
|
||||
|
||||
private _item?: Partial<Counter>;
|
||||
|
||||
@internalProperty() private _name!: string;
|
||||
|
||||
@internalProperty() private _icon!: string;
|
||||
|
||||
@internalProperty() private _maximum?: number;
|
||||
|
||||
@internalProperty() private _minimum?: number;
|
||||
|
||||
@internalProperty() private _restore?: boolean;
|
||||
|
||||
@internalProperty() private _initial?: number;
|
||||
|
||||
@internalProperty() private _step?: number;
|
||||
|
||||
set item(item: Counter) {
|
||||
this._item = item;
|
||||
if (item) {
|
||||
this._name = item.name || "";
|
||||
this._icon = item.icon || "";
|
||||
this._maximum = item.maximum;
|
||||
this._minimum = item.minimum;
|
||||
this._restore = item.restore ?? true;
|
||||
this._step = item.step ?? 1;
|
||||
this._initial = item.initial ?? 0;
|
||||
} else {
|
||||
this._name = "";
|
||||
this._icon = "";
|
||||
this._maximum = undefined;
|
||||
this._minimum = undefined;
|
||||
this._restore = true;
|
||||
this._step = 1;
|
||||
this._initial = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public focus() {
|
||||
this.updateComplete.then(() =>
|
||||
(this.shadowRoot?.querySelector(
|
||||
"[dialogInitialFocus]"
|
||||
) as HTMLElement)?.focus()
|
||||
);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass) {
|
||||
return html``;
|
||||
}
|
||||
const nameInvalid = !this._name || this._name.trim() === "";
|
||||
|
||||
return html`
|
||||
<div class="form">
|
||||
<paper-input
|
||||
.value=${this._name}
|
||||
.configValue=${"name"}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.generic.name"
|
||||
)}
|
||||
.errorMessage="${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.required_error_msg"
|
||||
)}"
|
||||
.invalid=${nameInvalid}
|
||||
dialogInitialFocus
|
||||
></paper-input>
|
||||
<ha-icon-input
|
||||
.value=${this._icon}
|
||||
.configValue=${"icon"}
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.generic.icon"
|
||||
)}
|
||||
></ha-icon-input>
|
||||
<paper-input
|
||||
.value=${this._minimum}
|
||||
.configValue=${"minimum"}
|
||||
type="number"
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.counter.minimum"
|
||||
)}
|
||||
></paper-input>
|
||||
<paper-input
|
||||
.value=${this._maximum}
|
||||
.configValue=${"maximum"}
|
||||
type="number"
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.counter.maximum"
|
||||
)}
|
||||
></paper-input>
|
||||
<paper-input
|
||||
.value=${this._initial}
|
||||
.configValue=${"initial"}
|
||||
type="number"
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.counter.initial"
|
||||
)}
|
||||
></paper-input>
|
||||
${this.hass.userData?.showAdvanced
|
||||
? html`
|
||||
<paper-input
|
||||
.value=${this._step}
|
||||
.configValue=${"step"}
|
||||
type="number"
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${this.hass!.localize(
|
||||
"ui.dialogs.helper_settings.counter.step"
|
||||
)}
|
||||
></paper-input>
|
||||
<div class="row">
|
||||
<ha-switch
|
||||
.checked=${this._restore}
|
||||
.configValue=${"restore"}
|
||||
@change=${this._valueChanged}
|
||||
>
|
||||
</ha-switch>
|
||||
<div>
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.helper_settings.counter.restore"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
if (!this.new && !this._item) {
|
||||
return;
|
||||
}
|
||||
ev.stopPropagation();
|
||||
const target = ev.target as any;
|
||||
const configValue = target.configValue;
|
||||
const value =
|
||||
target.type === "number"
|
||||
? Number(ev.detail.value)
|
||||
: target.localName === "ha-switch"
|
||||
? (ev.target as HaSwitch).checked
|
||||
: ev.detail.value;
|
||||
if (this[`_${configValue}`] === value) {
|
||||
return;
|
||||
}
|
||||
const newValue = { ...this._item };
|
||||
if (value === undefined || value === "") {
|
||||
delete newValue[configValue];
|
||||
} else {
|
||||
newValue[configValue] = value;
|
||||
}
|
||||
fireEvent(this, "value-changed", {
|
||||
value: newValue,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.form {
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.row {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--primary-text-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.row div {
|
||||
margin-left: 16px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-counter-form": HaCounterForm;
|
||||
}
|
||||
}
|
@ -601,6 +601,13 @@
|
||||
"add_option": "Add option",
|
||||
"no_options": "There are no options yet.",
|
||||
"add": "Add"
|
||||
},
|
||||
"counter": {
|
||||
"minimum": "Minimum value",
|
||||
"maximum": "Maximum value",
|
||||
"initial": "Initial value",
|
||||
"restore": "Restore the last known value when Home Assistant starts",
|
||||
"step": "Step size"
|
||||
}
|
||||
},
|
||||
"options_flow": {
|
||||
@ -784,7 +791,8 @@
|
||||
"input_number": "Number",
|
||||
"input_select": "Dropdown",
|
||||
"input_boolean": "Toggle",
|
||||
"input_datetime": "Date and/or time"
|
||||
"input_datetime": "Date and/or time",
|
||||
"counter": "Counter"
|
||||
},
|
||||
"picker": {
|
||||
"headers": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user