diff --git a/package-lock.json b/package-lock.json index 50b58fcd3..398522a71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,6 @@ "@material/mwc-select": "^0.25.3", "@material/mwc-textfield": "^0.25.3", "color": "^4.2.3", - "custom-card-helpers": "^1.9.0", "hammerjs": "^2.0.8", "home-assistant-js-websocket": "^7.0.3", "lit": "^2.2.3", @@ -564,58 +563,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@formatjs/ecma402-abstract": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.1.tgz", - "integrity": "sha512-tgtNODZUGuUI6PAcnvaLZpGrZLVkXnnAvgzOiueYMzFdOdcOw4iH1WKhCe3+r6VR8rHKToJ2HksUGNCB+zt/bg==", - "dependencies": { - "@formatjs/intl-localematcher": "0.2.22", - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/fast-memoize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", - "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.16.tgz", - "integrity": "sha512-sYg0ImXsAqBbjU/LotoCD9yKC5nUpWVy3s4DwWerHXD4sm62FcjMF8mekwudRk3eZLHqSO+M21MpFUUjDQ+Q5Q==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.11.1", - "@formatjs/icu-skeleton-parser": "1.3.3", - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.3.tgz", - "integrity": "sha512-ifWnzjmHPHUF89UpCvClTP66sXYFc8W/qg7Qt+qtTUB9BqRWlFeUsevAzaMYDJsRiOy4S2WJFrJoZgRKUFfPGQ==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.11.1", - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/intl-localematcher": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.22.tgz", - "integrity": "sha512-z+TvbHW8Q/g2l7/PnfUl0mV9gWxV4d0HT6GQyzkO5QI6QjCvCZGiztnmLX7zoyS16uSMvZ2PoMDfSK9xvZkRRA==", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/@formatjs/intl-utils": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-3.8.4.tgz", - "integrity": "sha512-j5C6NyfKevIxsfLK8KwO1C0vvP7k1+h4A9cFpc+cr6mEwCc1sPkr17dzh0Ke6k9U5pQccAQoXdcNBl3IYa4+ZQ==", - "dependencies": { - "emojis-list": "^3.0.0" - } - }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", @@ -2416,25 +2363,6 @@ "node": ">= 8" } }, - "node_modules/custom-card-helpers": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/custom-card-helpers/-/custom-card-helpers-1.9.0.tgz", - "integrity": "sha512-5IW4OXq3MiiCqDvqeu+MYsM1NmntKW1WfJhyJFsdP2tbzqEI4BOnqRz2qzdp08lE4QLVhYfRLwe0WAqgQVNeFg==", - "dependencies": { - "@formatjs/intl-utils": "^3.8.4", - "home-assistant-js-websocket": "^6.0.1", - "intl-messageformat": "^9.11.1", - "lit": "^2.1.1", - "rollup": "^2.63.0", - "superstruct": "^0.15.3", - "typescript": "^4.5.4" - } - }, - "node_modules/custom-card-helpers/node_modules/home-assistant-js-websocket": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/home-assistant-js-websocket/-/home-assistant-js-websocket-6.1.1.tgz", - "integrity": "sha512-TnZFzF4mn5F/v0XKUTK2GMQXrn/+eQpgaSDSELl6U0HSwSbFwRhGWLz330YT+hiKMspDflamsye//RPL+zwhDw==" - }, "node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -2485,14 +2413,6 @@ "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", "dev": true }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2736,6 +2656,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -2897,17 +2818,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/intl-messageformat": { - "version": "9.11.2", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.11.2.tgz", - "integrity": "sha512-4wsinP2ObVK1Rz5C4121lgVeHeOCW32FOsqcVXtJNdlow+NypJKmnrije9rOc0bKxPwtto9IkXdgakXUmYXVHw==", - "dependencies": { - "@formatjs/ecma402-abstract": "1.11.1", - "@formatjs/fast-memoize": "1.2.1", - "@formatjs/icu-messageformat-parser": "2.0.16", - "tslib": "^2.1.0" - } - }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -3339,6 +3249,7 @@ "version": "2.72.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.72.1.tgz", "integrity": "sha512-NTc5UGy/NWFGpSqF1lFY8z9Adri6uhyMLI6LvPAXdBKoPRFhIIiBUpt+Qg2awixqO3xvzSijjhnb4+QEZwJmxA==", + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -3580,6 +3491,7 @@ "version": "4.6.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4030,58 +3942,6 @@ "strip-json-comments": "^3.1.1" } }, - "@formatjs/ecma402-abstract": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.1.tgz", - "integrity": "sha512-tgtNODZUGuUI6PAcnvaLZpGrZLVkXnnAvgzOiueYMzFdOdcOw4iH1WKhCe3+r6VR8rHKToJ2HksUGNCB+zt/bg==", - "requires": { - "@formatjs/intl-localematcher": "0.2.22", - "tslib": "^2.1.0" - } - }, - "@formatjs/fast-memoize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", - "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", - "requires": { - "tslib": "^2.1.0" - } - }, - "@formatjs/icu-messageformat-parser": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.0.16.tgz", - "integrity": "sha512-sYg0ImXsAqBbjU/LotoCD9yKC5nUpWVy3s4DwWerHXD4sm62FcjMF8mekwudRk3eZLHqSO+M21MpFUUjDQ+Q5Q==", - "requires": { - "@formatjs/ecma402-abstract": "1.11.1", - "@formatjs/icu-skeleton-parser": "1.3.3", - "tslib": "^2.1.0" - } - }, - "@formatjs/icu-skeleton-parser": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.3.tgz", - "integrity": "sha512-ifWnzjmHPHUF89UpCvClTP66sXYFc8W/qg7Qt+qtTUB9BqRWlFeUsevAzaMYDJsRiOy4S2WJFrJoZgRKUFfPGQ==", - "requires": { - "@formatjs/ecma402-abstract": "1.11.1", - "tslib": "^2.1.0" - } - }, - "@formatjs/intl-localematcher": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.22.tgz", - "integrity": "sha512-z+TvbHW8Q/g2l7/PnfUl0mV9gWxV4d0HT6GQyzkO5QI6QjCvCZGiztnmLX7zoyS16uSMvZ2PoMDfSK9xvZkRRA==", - "requires": { - "tslib": "^2.1.0" - } - }, - "@formatjs/intl-utils": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-3.8.4.tgz", - "integrity": "sha512-j5C6NyfKevIxsfLK8KwO1C0vvP7k1+h4A9cFpc+cr6mEwCc1sPkr17dzh0Ke6k9U5pQccAQoXdcNBl3IYa4+ZQ==", - "requires": { - "emojis-list": "^3.0.0" - } - }, "@humanwhocodes/config-array": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", @@ -5791,27 +5651,6 @@ "which": "^2.0.1" } }, - "custom-card-helpers": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/custom-card-helpers/-/custom-card-helpers-1.9.0.tgz", - "integrity": "sha512-5IW4OXq3MiiCqDvqeu+MYsM1NmntKW1WfJhyJFsdP2tbzqEI4BOnqRz2qzdp08lE4QLVhYfRLwe0WAqgQVNeFg==", - "requires": { - "@formatjs/intl-utils": "^3.8.4", - "home-assistant-js-websocket": "^6.0.1", - "intl-messageformat": "^9.11.1", - "lit": "^2.1.1", - "rollup": "^2.63.0", - "superstruct": "^0.15.3", - "typescript": "^4.5.4" - }, - "dependencies": { - "home-assistant-js-websocket": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/home-assistant-js-websocket/-/home-assistant-js-websocket-6.1.1.tgz", - "integrity": "sha512-TnZFzF4mn5F/v0XKUTK2GMQXrn/+eQpgaSDSELl6U0HSwSbFwRhGWLz330YT+hiKMspDflamsye//RPL+zwhDw==" - } - } - }, "debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -5848,11 +5687,6 @@ "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", "dev": true }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -6041,6 +5875,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { @@ -6156,17 +5991,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "intl-messageformat": { - "version": "9.11.2", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.11.2.tgz", - "integrity": "sha512-4wsinP2ObVK1Rz5C4121lgVeHeOCW32FOsqcVXtJNdlow+NypJKmnrije9rOc0bKxPwtto9IkXdgakXUmYXVHw==", - "requires": { - "@formatjs/ecma402-abstract": "1.11.1", - "@formatjs/fast-memoize": "1.2.1", - "@formatjs/icu-messageformat-parser": "2.0.16", - "tslib": "^2.1.0" - } - }, "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", @@ -6502,6 +6326,7 @@ "version": "2.72.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.72.1.tgz", "integrity": "sha512-NTc5UGy/NWFGpSqF1lFY8z9Adri6uhyMLI6LvPAXdBKoPRFhIIiBUpt+Qg2awixqO3xvzSijjhnb4+QEZwJmxA==", + "dev": true, "requires": { "fsevents": "~2.3.2" } @@ -6684,7 +6509,8 @@ "typescript": { "version": "4.6.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==" + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "dev": true }, "uri-js": { "version": "4.4.1", diff --git a/package.json b/package.json index f3a0be9c1..8dc4934bd 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "@material/mwc-select": "^0.25.3", "@material/mwc-textfield": "^0.25.3", "color": "^4.2.3", - "custom-card-helpers": "^1.9.0", "hammerjs": "^2.0.8", "home-assistant-js-websocket": "^7.0.3", "lit": "^2.2.3", diff --git a/src/cards/alarm-control-panel-card/alarm-control-panel-card-config.ts b/src/cards/alarm-control-panel-card/alarm-control-panel-card-config.ts index 3f4f224e5..41e029043 100644 --- a/src/cards/alarm-control-panel-card/alarm-control-panel-card-config.ts +++ b/src/cards/alarm-control-panel-card/alarm-control-panel-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { array, assign, boolean, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type AlarmControlPanelCardConfig = LovelaceCardConfig & diff --git a/src/cards/alarm-control-panel-card/alarm-control-panel-card-editor.ts b/src/cards/alarm-control-panel-card/alarm-control-panel-card-editor.ts index 20c7bc91c..c7e467e1a 100644 --- a/src/cards/alarm-control-panel-card/alarm-control-panel-card-editor.ts +++ b/src/cards/alarm-control-panel-card/alarm-control-panel-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { Action } from "../../utils/form/custom/ha-selector-mushroom-action"; diff --git a/src/cards/alarm-control-panel-card/alarm-control-panel-card.ts b/src/cards/alarm-control-panel-card/alarm-control-panel-card.ts index 51ebca14c..a8c2eb729 100644 --- a/src/cards/alarm-control-panel-card/alarm-control-panel-card.ts +++ b/src/cards/alarm-control-panel-card/alarm-control-panel-card.ts @@ -1,18 +1,19 @@ +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, query, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, query, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/button-group"; @@ -23,7 +24,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { alarmPanelIconAction } from "../../utils/icons/alarm-panel-icon"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; diff --git a/src/cards/alarm-control-panel-card/utils.ts b/src/cards/alarm-control-panel-card/utils.ts index a7316852e..b18a7dbee 100644 --- a/src/cards/alarm-control-panel-card/utils.ts +++ b/src/cards/alarm-control-panel-card/utils.ts @@ -1,5 +1,5 @@ import { HassEntity } from "home-assistant-js-websocket"; -import { UNAVAILABLE } from "../../ha/data/entity"; +import { UNAVAILABLE } from "../../ha"; import { ALARM_CONTROL_PANEL_CARD_DEFAULT_STATE_COLOR, ALARM_CONTROL_PANEL_CARD_STATE_COLOR, diff --git a/src/cards/chips-card/chips-card-chips-editor.ts b/src/cards/chips-card/chips-card-chips-editor.ts index 7dda47a43..7603ed06f 100644 --- a/src/cards/chips-card/chips-card-chips-editor.ts +++ b/src/cards/chips-card/chips-card-chips-editor.ts @@ -1,15 +1,14 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { guard } from "lit/directives/guard.js"; import type { SortableEvent } from "sortablejs"; +import { fireEvent, sortableStyles } from "../../ha"; import setupCustomlocalize from "../../localize"; +import "../../shared/form/mushroom-select"; +import { MushroomBaseElement } from "../../utils/base-element"; import { getChipElementClass } from "../../utils/lovelace/chip-element-editor"; import { CHIP_LIST, LovelaceChipConfig } from "../../utils/lovelace/chip/types"; import { EditorTarget } from "../../utils/lovelace/editor/types"; -import { sortableStyles } from "../../utils/sortable-styles"; -import "../../shared/form/mushroom-select"; -import { MushroomBaseElement } from "../../utils/base-element"; let Sortable; diff --git a/src/cards/chips-card/chips-card-editor.ts b/src/cards/chips-card/chips-card-editor.ts index 86b70018d..424f650f0 100644 --- a/src/cards/chips-card/chips-card-editor.ts +++ b/src/cards/chips-card/chips-card-editor.ts @@ -1,4 +1,3 @@ -import { fireEvent, HASSDomEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import { @@ -14,10 +13,10 @@ import { string, union, } from "superstruct"; +import { actionConfigStruct, fireEvent, HASSDomEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; import "../../shared/editor/alignment-picker"; -import { actionConfigStruct } from "../../utils/action-struct"; import { MushroomBaseElement } from "../../utils/base-element"; import { loadHaComponents } from "../../utils/loader"; import { LovelaceChipConfig } from "../../utils/lovelace/chip/types"; diff --git a/src/cards/chips-card/chips-card.ts b/src/cards/chips-card/chips-card.ts index caeaf59d9..7f01efcba 100644 --- a/src/cards/chips-card/chips-card.ts +++ b/src/cards/chips-card/chips-card.ts @@ -1,15 +1,14 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; import { computeRTL, HomeAssistant, LovelaceCard, LovelaceCardConfig, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; +} from "../../ha"; import "../../shared/chip"; import { computeDarkMode, MushroomBaseElement } from "../../utils/base-element"; -import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; import { createChipElement } from "../../utils/lovelace/chip/chip-element"; import { LovelaceChip, LovelaceChipConfig } from "../../utils/lovelace/chip/types"; diff --git a/src/cards/chips-card/chips/action-chip-editor.ts b/src/cards/chips-card/chips/action-chip-editor.ts index 0a5cd0e68..181710471 100644 --- a/src/cards/chips-card/chips/action-chip-editor.ts +++ b/src/cards/chips-card/chips/action-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { Action } from "../../../utils/form/custom/ha-selector-mushroom-action"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; diff --git a/src/cards/chips-card/chips/action-chip.ts b/src/cards/chips-card/chips/action-chip.ts index becee7670..61fb6d541 100644 --- a/src/cards/chips-card/chips/action-chip.ts +++ b/src/cards/chips-card/chips/action-chip.ts @@ -1,15 +1,15 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { styleMap } from "lit/directives/style-map.js"; +} from "../../../ha"; import { computeRgbColor } from "../../../utils/colors"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; import { computeChipComponentName, computeChipEditorComponentName, diff --git a/src/cards/chips-card/chips/alarm-control-panel-chip-editor.ts b/src/cards/chips-card/chips/alarm-control-panel-chip-editor.ts index a7b840914..9629c27c3 100644 --- a/src/cards/chips-card/chips/alarm-control-panel-chip-editor.ts +++ b/src/cards/chips-card/chips/alarm-control-panel-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { Action } from "../../../utils/form/custom/ha-selector-mushroom-action"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; diff --git a/src/cards/chips-card/chips/alarm-control-panel-chip.ts b/src/cards/chips-card/chips/alarm-control-panel-chip.ts index 6fca3b6c5..1c72aec88 100644 --- a/src/cards/chips-card/chips/alarm-control-panel-chip.ts +++ b/src/cards/chips-card/chips/alarm-control-panel-chip.ts @@ -1,17 +1,17 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../../ha/common/entity/compute-state-display"; +} from "../../../ha"; import { computeRgbColor } from "../../../utils/colors"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; import { animation } from "../../../utils/entity-styles"; import { stateIcon } from "../../../utils/icons/state-icon"; import { getInfo } from "../../../utils/info"; diff --git a/src/cards/chips-card/chips/back-chip-editor.ts b/src/cards/chips-card/chips/back-chip-editor.ts index ef178b8e6..97dab66ab 100644 --- a/src/cards/chips-card/chips/back-chip-editor.ts +++ b/src/cards/chips-card/chips/back-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import { HaFormSchema } from "../../../utils/form/ha-form"; import { computeChipEditorComponentName } from "../../../utils/lovelace/chip/chip-element"; import { EntityChipConfig } from "../../../utils/lovelace/chip/types"; diff --git a/src/cards/chips-card/chips/back-chip.ts b/src/cards/chips-card/chips/back-chip.ts index c5707575b..50d637dbf 100644 --- a/src/cards/chips-card/chips/back-chip.ts +++ b/src/cards/chips-card/chips/back-chip.ts @@ -1,7 +1,6 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; +import { actionHandler, computeRTL, HomeAssistant } from "../../../ha"; import { computeChipComponentName, computeChipEditorComponentName, diff --git a/src/cards/chips-card/chips/conditional-chip-editor.ts b/src/cards/chips-card/chips/conditional-chip-editor.ts index 7f4c10b21..0d06a74ef 100644 --- a/src/cards/chips-card/chips/conditional-chip-editor.ts +++ b/src/cards/chips-card/chips/conditional-chip-editor.ts @@ -1,13 +1,7 @@ import type { MDCTabBarActivatedEvent } from "@material/tab-bar"; -import { - computeRTL, - fireEvent, - HASSDomEvent, - HomeAssistant, - LovelaceConfig, -} from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, query, state } from "lit/decorators.js"; +import { computeRTL, fireEvent, HASSDomEvent, HomeAssistant, LovelaceConfig } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import "../../../shared/form/mushroom-select"; import "../../../shared/form/mushroom-textfield"; diff --git a/src/cards/chips-card/chips/conditional-chip.ts b/src/cards/chips-card/chips/conditional-chip.ts index 25337cbf9..728b4b537 100644 --- a/src/cards/chips-card/chips/conditional-chip.ts +++ b/src/cards/chips-card/chips/conditional-chip.ts @@ -1,4 +1,3 @@ -import { HomeAssistant } from "custom-card-helpers"; import { customElement } from "lit/decorators.js"; import { ConditionalBase } from "../../../utils/conditional/conditional-base"; import { diff --git a/src/cards/chips-card/chips/entity-chip-editor.ts b/src/cards/chips-card/chips/entity-chip-editor.ts index 778061464..0a6fd9ef2 100644 --- a/src/cards/chips-card/chips/entity-chip-editor.ts +++ b/src/cards/chips-card/chips/entity-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; import { HaFormSchema } from "../../../utils/form/ha-form"; diff --git a/src/cards/chips-card/chips/entity-chip.ts b/src/cards/chips-card/chips/entity-chip.ts index 029dd02c8..91400d6a3 100644 --- a/src/cards/chips-card/chips/entity-chip.ts +++ b/src/cards/chips-card/chips/entity-chip.ts @@ -1,18 +1,19 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, + getEntityPicture, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../../ha/common/entity/compute-state-display"; -import { getEntityPicture, isActive } from "../../../ha/data/entity"; + isActive, +} from "../../../ha"; import { computeRgbColor } from "../../../utils/colors"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; import { stateIcon } from "../../../utils/icons/state-icon"; import { getInfo } from "../../../utils/info"; import { diff --git a/src/cards/chips-card/chips/light-chip-editor.ts b/src/cards/chips-card/chips/light-chip-editor.ts index ae0b470e2..174ecb7b5 100644 --- a/src/cards/chips-card/chips/light-chip-editor.ts +++ b/src/cards/chips-card/chips/light-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; import { HaFormSchema } from "../../../utils/form/ha-form"; diff --git a/src/cards/chips-card/chips/light-chip.ts b/src/cards/chips-card/chips/light-chip.ts index bce20c077..e24491430 100644 --- a/src/cards/chips-card/chips/light-chip.ts +++ b/src/cards/chips-card/chips/light-chip.ts @@ -1,18 +1,18 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../../ha/common/entity/compute-state-display"; -import { isActive } from "../../../ha/data/entity"; -import { LightEntity } from "../../../ha/data/light"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; + isActive, + LightEntity, +} from "../../../ha"; import { stateIcon } from "../../../utils/icons/state-icon"; import { getInfo } from "../../../utils/info"; import { diff --git a/src/cards/chips-card/chips/menu-chip-editor.ts b/src/cards/chips-card/chips/menu-chip-editor.ts index 99aa9e63c..59d735a32 100644 --- a/src/cards/chips-card/chips/menu-chip-editor.ts +++ b/src/cards/chips-card/chips/menu-chip-editor.ts @@ -1,7 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; +import { fireEvent, HomeAssistant } from "../../../ha"; import { HaFormSchema } from "../../../utils/form/ha-form"; import { computeChipEditorComponentName } from "../../../utils/lovelace/chip/chip-element"; import { EntityChipConfig } from "../../../utils/lovelace/chip/types"; diff --git a/src/cards/chips-card/chips/menu-chip.ts b/src/cards/chips-card/chips/menu-chip.ts index 3a5c53649..3dfbe67aa 100644 --- a/src/cards/chips-card/chips/menu-chip.ts +++ b/src/cards/chips-card/chips/menu-chip.ts @@ -1,7 +1,6 @@ -import { computeRTL, fireEvent, HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; +import { actionHandler, computeRTL, fireEvent, HomeAssistant } from "../../../ha"; import { computeChipComponentName, computeChipEditorComponentName, diff --git a/src/cards/chips-card/chips/template-chip-editor.ts b/src/cards/chips-card/chips/template-chip-editor.ts index 792de8b66..6841667af 100644 --- a/src/cards/chips-card/chips/template-chip-editor.ts +++ b/src/cards/chips-card/chips/template-chip-editor.ts @@ -1,8 +1,7 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; -import { atLeastHaVersion } from "../../../ha/util"; +import { atLeastHaVersion, fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; import { HaFormSchema } from "../../../utils/form/ha-form"; diff --git a/src/cards/chips-card/chips/template-chip.ts b/src/cards/chips-card/chips/template-chip.ts index e5e6426e8..24dbbbfe6 100644 --- a/src/cards/chips-card/chips/template-chip.ts +++ b/src/cards/chips-card/chips/template-chip.ts @@ -1,23 +1,24 @@ +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { Connection, UnsubscribeFunc } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { styleMap } from "lit/directives/style-map.js"; + RenderTemplateResult, + subscribeRenderTemplate, +} from "../../../ha"; import { computeRgbColor } from "../../../utils/colors"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; import { computeChipComponentName, computeChipEditorComponentName, } from "../../../utils/lovelace/chip/chip-element"; import { LovelaceChip, TemplateChipConfig } from "../../../utils/lovelace/chip/types"; import { LovelaceChipEditor } from "../../../utils/lovelace/types"; -import { RenderTemplateResult, subscribeRenderTemplate } from "../../../utils/ws-templates"; const TEMPLATE_KEYS = ["content", "icon", "icon_color"] as const; type TemplateKey = typeof TEMPLATE_KEYS[number]; @@ -152,7 +153,7 @@ export class TemplateChip extends LitElement implements LovelaceChip { try { const sub = subscribeRenderTemplate( - this.hass.connection as any as Connection, + this.hass.connection, (result) => { this._templateResults = { ...this._templateResults, diff --git a/src/cards/chips-card/chips/weather-chip-editor.ts b/src/cards/chips-card/chips/weather-chip-editor.ts index 7aabc3045..60f040c9e 100644 --- a/src/cards/chips-card/chips/weather-chip-editor.ts +++ b/src/cards/chips-card/chips/weather-chip-editor.ts @@ -1,6 +1,6 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators.js"; +import { fireEvent, HomeAssistant } from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { Action } from "../../../utils/form/custom/ha-selector-mushroom-action"; import { GENERIC_LABELS } from "../../../utils/form/generic-fields"; diff --git a/src/cards/chips-card/chips/weather-chip.ts b/src/cards/chips-card/chips/weather-chip.ts index e2e4b22a5..f1e6eca4e 100644 --- a/src/cards/chips-card/chips/weather-chip.ts +++ b/src/cards/chips-card/chips/weather-chip.ts @@ -1,15 +1,15 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property, state } from "lit/decorators.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, formatNumber, handleAction, hasAction, HomeAssistant, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators.js"; -import { computeStateDisplay } from "../../../ha/common/entity/compute-state-display"; -import { actionHandler } from "../../../utils/directives/action-handler-directive"; +} from "../../../ha"; import { computeChipComponentName, computeChipEditorComponentName, diff --git a/src/cards/cover-card/controls/cover-buttons-control.ts b/src/cards/cover-card/controls/cover-buttons-control.ts index 3e2fa3a28..addb26d2f 100644 --- a/src/cards/cover-card/controls/cover-buttons-control.ts +++ b/src/cards/cover-card/controls/cover-buttons-control.ts @@ -1,19 +1,19 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { supportsFeature } from "../../../ha/common/entity/supports-feature"; import { + computeRTL, CoverEntity, COVER_SUPPORT_CLOSE, COVER_SUPPORT_OPEN, COVER_SUPPORT_STOP, + HomeAssistant, + isAvailable, isClosing, isFullyClosed, isFullyOpen, isOpening, -} from "../../../ha/data/cover"; -import { isAvailable } from "../../../ha/data/entity"; + supportsFeature, +} from "../../../ha"; import "../../../shared/button"; import "../../../shared/button-group"; import { computeCloseIcon, computeOpenIcon } from "../../../utils/icons/cover-icon"; diff --git a/src/cards/cover-card/controls/cover-position-control.ts b/src/cards/cover-card/controls/cover-position-control.ts index 1264d2a4c..0f1292088 100644 --- a/src/cards/cover-card/controls/cover-position-control.ts +++ b/src/cards/cover-card/controls/cover-position-control.ts @@ -1,8 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { CoverEntity } from "../../../ha/data/cover"; -import { isAvailable } from "../../../ha/data/entity"; +import { CoverEntity, HomeAssistant, isAvailable } from "../../../ha"; import "../../../shared/slider"; import { getPosition } from "../utils"; diff --git a/src/cards/cover-card/cover-card-config.ts b/src/cards/cover-card/cover-card-config.ts index 7e347bb58..d325a4681 100644 --- a/src/cards/cover-card/cover-card-config.ts +++ b/src/cards/cover-card/cover-card-config.ts @@ -1,9 +1,9 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; +import { LovelaceCardConfig } from "../../ha"; export type CoverCardConfig = LovelaceCardConfig & EntitySharedConfig & diff --git a/src/cards/cover-card/cover-card-editor.ts b/src/cards/cover-card/cover-card-editor.ts index 464b2b0c9..5cf881884 100644 --- a/src/cards/cover-card/cover-card-editor.ts +++ b/src/cards/cover-card/cover-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/cover-card/cover-card.ts b/src/cards/cover-card/cover-card.ts index cee323843..08ab96b9f 100644 --- a/src/cards/cover-card/cover-card.ts +++ b/src/cards/cover-card/cover-card.ts @@ -1,20 +1,21 @@ +import { HassEntity } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, + CoverEntity, handleAction, hasAction, HomeAssistant, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { HassEntity } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { CoverEntity } from "../../ha/data/cover"; -import { isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/card"; @@ -24,7 +25,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig, Layout } from "../../utils/layout"; import { COVER_CARD_EDITOR_NAME, COVER_CARD_NAME, COVER_ENTITY_DOMAINS } from "./const"; diff --git a/src/cards/cover-card/utils.ts b/src/cards/cover-card/utils.ts index afa164c2c..ae14c291e 100644 --- a/src/cards/cover-card/utils.ts +++ b/src/cards/cover-card/utils.ts @@ -1,4 +1,4 @@ -import { CoverEntity } from "../../ha/data/cover"; +import { CoverEntity } from "../../ha"; export function getPosition(entity: CoverEntity) { return entity.attributes.current_position != null diff --git a/src/cards/entity-card/entity-card-config.ts b/src/cards/entity-card/entity-card-config.ts index b38fb4ed9..1cf209e89 100644 --- a/src/cards/entity-card/entity-card-config.ts +++ b/src/cards/entity-card/entity-card-config.ts @@ -1,10 +1,10 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional, string } from "superstruct"; import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; import { infosSharedConfigStruct, InfosSharedConfig } from "../../shared/config/infos-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; +import { LovelaceCardConfig } from "../../ha"; export type EntityCardConfig = LovelaceCardConfig & EntitySharedConfig & diff --git a/src/cards/entity-card/entity-card-editor.ts b/src/cards/entity-card/entity-card-editor.ts index e8661a496..727301825 100644 --- a/src/cards/entity-card/entity-card-editor.ts +++ b/src/cards/entity-card/entity-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/entity-card/entity-card.ts b/src/cards/entity-card/entity-card.ts index e177e2461..e3f3e772c 100644 --- a/src/cards/entity-card/entity-card.ts +++ b/src/cards/entity-card/entity-card.ts @@ -1,18 +1,21 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, + getEntityPicture, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { getEntityPicture, isActive, isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/card"; import "../../shared/shape-avatar"; @@ -23,7 +26,6 @@ import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { computeRgbColor } from "../../utils/colors"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getInfo } from "../../utils/info"; import { getLayoutFromConfig } from "../../utils/layout"; diff --git a/src/cards/fan-card/controls/fan-oscillate-control.ts b/src/cards/fan-card/controls/fan-oscillate-control.ts index e3d0054ae..ddac2fccb 100644 --- a/src/cards/fan-card/controls/fan-oscillate-control.ts +++ b/src/cards/fan-card/controls/fan-oscillate-control.ts @@ -1,9 +1,8 @@ -import { HomeAssistant } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; import { classMap } from "lit/directives/class-map.js"; -import { isActive } from "../../../ha/data/entity"; +import { HomeAssistant, isActive } from "../../../ha"; import "../../../shared/slider"; import { isOscillating } from "../utils"; diff --git a/src/cards/fan-card/controls/fan-percentage-control.ts b/src/cards/fan-card/controls/fan-percentage-control.ts index cb9dea292..1579af444 100644 --- a/src/cards/fan-card/controls/fan-percentage-control.ts +++ b/src/cards/fan-card/controls/fan-percentage-control.ts @@ -1,8 +1,7 @@ -import { HomeAssistant } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { isActive, isAvailable } from "../../../ha/data/entity"; +import { HomeAssistant, isActive, isAvailable } from "../../../ha"; import "../../../shared/slider"; import { computePercentageStep, getPercentage } from "../utils"; diff --git a/src/cards/fan-card/fan-card-config.ts b/src/cards/fan-card/fan-card-config.ts index a8509d108..dd028e03f 100644 --- a/src/cards/fan-card/fan-card-config.ts +++ b/src/cards/fan-card/fan-card-config.ts @@ -1,9 +1,9 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; +import { LovelaceCardConfig } from "../../ha"; export type FanCardConfig = LovelaceCardConfig & EntitySharedConfig & diff --git a/src/cards/fan-card/fan-card-editor.ts b/src/cards/fan-card/fan-card-editor.ts index d55c866a7..1153be49e 100644 --- a/src/cards/fan-card/fan-card-editor.ts +++ b/src/cards/fan-card/fan-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/fan-card/fan-card.ts b/src/cards/fan-card/fan-card.ts index 4ce34960b..256d749ef 100644 --- a/src/cards/fan-card/fan-card.ts +++ b/src/cards/fan-card/fan-card.ts @@ -1,18 +1,20 @@ +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { isActive, isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/card"; @@ -22,7 +24,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { FAN_CARD_EDITOR_NAME, FAN_CARD_NAME, FAN_ENTITY_DOMAINS } from "./const"; diff --git a/src/cards/humidifier-card/controls/humidifier-humidity-control.ts b/src/cards/humidifier-card/controls/humidifier-humidity-control.ts index 332dc2f62..f05e07e13 100644 --- a/src/cards/humidifier-card/controls/humidifier-humidity-control.ts +++ b/src/cards/humidifier-card/controls/humidifier-humidity-control.ts @@ -1,8 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { isActive, isAvailable } from "../../../ha/data/entity"; -import { HumidifierEntity } from "../../../ha/data/humidifier"; +import { HomeAssistant, HumidifierEntity, isActive, isAvailable } from "../../../ha"; import "../../../shared/slider"; @customElement("mushroom-humidifier-humidity-control") diff --git a/src/cards/humidifier-card/humidifier-card-config.ts b/src/cards/humidifier-card/humidifier-card-config.ts index 9d1910a3a..2f820ad67 100644 --- a/src/cards/humidifier-card/humidifier-card-config.ts +++ b/src/cards/humidifier-card/humidifier-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type HumidifierCardConfig = LovelaceCardConfig & diff --git a/src/cards/humidifier-card/humidifier-card-editor.ts b/src/cards/humidifier-card/humidifier-card-editor.ts index e3e56d7da..a4b15cb47 100644 --- a/src/cards/humidifier-card/humidifier-card-editor.ts +++ b/src/cards/humidifier-card/humidifier-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; -import { CSSResultGroup, html, TemplateResult } from "lit"; +import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/humidifier-card/humidifier-card.ts b/src/cards/humidifier-card/humidifier-card.ts index c74bc15c4..7bbc2a47a 100644 --- a/src/cards/humidifier-card/humidifier-card.ts +++ b/src/cards/humidifier-card/humidifier-card.ts @@ -1,27 +1,28 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { isActive, isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/card"; import "../../shared/shape-icon"; import "../../shared/state-info"; import "../../shared/state-item"; +import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; -import { computeRgbColor } from "../../utils/colors"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { @@ -31,8 +32,6 @@ import { } from "./const"; import "./controls/humidifier-humidity-control"; import { HumidifierCardConfig } from "./humidifier-card-config"; -import { MushroomBaseElement } from "../../utils/base-element"; -import { classMap } from "lit/directives/class-map.js"; registerCustomCard({ type: HUMIDIFIER_CARD_NAME, diff --git a/src/cards/light-card/controls/light-brightness-control.ts b/src/cards/light-card/controls/light-brightness-control.ts index c2424b28d..41158d688 100644 --- a/src/cards/light-card/controls/light-brightness-control.ts +++ b/src/cards/light-card/controls/light-brightness-control.ts @@ -1,8 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { isActive, isAvailable } from "../../../ha/data/entity"; -import { LightEntity } from "../../../ha/data/light"; +import { HomeAssistant, isActive, isAvailable, LightEntity } from "../../../ha"; import "../../../shared/slider"; import { getBrightness } from "../utils"; diff --git a/src/cards/light-card/controls/light-color-control.ts b/src/cards/light-card/controls/light-color-control.ts index 2e5f445dc..e6457a5bd 100644 --- a/src/cards/light-card/controls/light-color-control.ts +++ b/src/cards/light-card/controls/light-color-control.ts @@ -1,10 +1,9 @@ -import { HomeAssistant } from "custom-card-helpers"; +import * as Color from "color"; import { HassEntity } from "home-assistant-js-websocket"; -import { css, unsafeCSS, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { css, CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; -import * as Color from "color"; +import { HomeAssistant, isActive, isAvailable } from "../../../ha"; import "../../../shared/slider"; -import { isActive, isAvailable } from "../../../ha/data/entity"; const GRADIENT = [ [0, "#f00"], diff --git a/src/cards/light-card/controls/light-color-temp-control.ts b/src/cards/light-card/controls/light-color-temp-control.ts index 3eab1e223..0c516ea5f 100644 --- a/src/cards/light-card/controls/light-color-temp-control.ts +++ b/src/cards/light-card/controls/light-color-temp-control.ts @@ -1,8 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { isActive, isAvailable } from "../../../ha/data/entity"; -import { LightEntity } from "../../../ha/data/light"; +import { HomeAssistant, isActive, isAvailable, LightEntity } from "../../../ha"; import "../../../shared/slider"; import { getColorTemp } from "../utils"; diff --git a/src/cards/light-card/light-card-config.ts b/src/cards/light-card/light-card-config.ts index 3f81c3838..04a91a425 100644 --- a/src/cards/light-card/light-card-config.ts +++ b/src/cards/light-card/light-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; +import { LovelaceCardConfig } from "../../ha"; import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; -import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type LightCardConfig = LovelaceCardConfig & diff --git a/src/cards/light-card/light-card-editor.ts b/src/cards/light-card/light-card-editor.ts index 4953cf4c7..c5650f563 100644 --- a/src/cards/light-card/light-card-editor.ts +++ b/src/cards/light-card/light-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/light-card/light-card.ts b/src/cards/light-card/light-card.ts index 27040ba5d..658fce68c 100644 --- a/src/cards/light-card/light-card.ts +++ b/src/cards/light-card/light-card.ts @@ -1,19 +1,21 @@ +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, + LightEntity, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { isActive, isAvailable } from "../../ha/data/entity"; -import { LightEntity } from "../../ha/data/light"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/card"; @@ -23,7 +25,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { LIGHT_CARD_EDITOR_NAME, LIGHT_CARD_NAME, LIGHT_ENTITY_DOMAINS } from "./const"; diff --git a/src/cards/light-card/utils.ts b/src/cards/light-card/utils.ts index 68b5bd122..c79daf1fa 100644 --- a/src/cards/light-card/utils.ts +++ b/src/cards/light-card/utils.ts @@ -1,11 +1,5 @@ -import { HassEntity } from "home-assistant-js-websocket"; import * as Color from "color"; -import { - LightColorModes, - LightEntity, - lightSupportsColor, - lightSupportsDimming, -} from "../../ha/data/light"; +import { LightColorModes, LightEntity, lightSupportsColor, lightSupportsDimming } from "../../ha"; export function getBrightness(entity: LightEntity): number | undefined { return entity.attributes.brightness != null diff --git a/src/cards/lock-card/controls/lock-buttons-control.ts b/src/cards/lock-card/controls/lock-buttons-control.ts index e3f01b0ef..c627b6f92 100644 --- a/src/cards/lock-card/controls/lock-buttons-control.ts +++ b/src/cards/lock-card/controls/lock-buttons-control.ts @@ -1,9 +1,13 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { supportsFeature } from "../../../ha/common/entity/supports-feature"; -import { isAvailable } from "../../../ha/data/entity"; -import { LockEntity, LOCK_SUPPORT_OPEN } from "../../../ha/data/lock"; +import { + computeRTL, + HomeAssistant, + isAvailable, + LockEntity, + LOCK_SUPPORT_OPEN, + supportsFeature, +} from "../../../ha"; import setupCustomlocalize from "../../../localize"; import { isActionPending, isLocked, isUnlocked } from "../utils"; diff --git a/src/cards/lock-card/lock-card-config.ts b/src/cards/lock-card/lock-card-config.ts index 6d1c019f1..71289d4cd 100644 --- a/src/cards/lock-card/lock-card-config.ts +++ b/src/cards/lock-card/lock-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type LockCardConfig = LovelaceCardConfig & diff --git a/src/cards/lock-card/lock-card-editor.ts b/src/cards/lock-card/lock-card-editor.ts index 2c19a2491..a533d4e2c 100644 --- a/src/cards/lock-card/lock-card-editor.ts +++ b/src/cards/lock-card/lock-card-editor.ts @@ -1,9 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; -import { LOCK_ENTITY_DOMAINS } from "../../ha/data/lock"; +import { fireEvent, LOCK_ENTITY_DOMAINS, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/lock-card/lock-card.ts b/src/cards/lock-card/lock-card.ts index 5024bb5be..c11464315 100644 --- a/src/cards/lock-card/lock-card.ts +++ b/src/cards/lock-card/lock-card.ts @@ -1,19 +1,21 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, computeStateDisplay, handleAction, hasAction, HomeAssistant, + isAvailable, + LockEntity, + LOCK_ENTITY_DOMAINS, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { isAvailable } from "../../ha/data/entity"; -import { LockEntity, LOCK_ENTITY_DOMAINS } from "../../ha/data/lock"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/button"; import "../../shared/card"; @@ -23,7 +25,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { LOCK_CARD_EDITOR_NAME, LOCK_CARD_NAME } from "./const"; diff --git a/src/cards/lock-card/utils.ts b/src/cards/lock-card/utils.ts index 874dbd65b..65fc99db8 100644 --- a/src/cards/lock-card/utils.ts +++ b/src/cards/lock-card/utils.ts @@ -4,7 +4,7 @@ import { LOCK_STATE_LOCKING, LOCK_STATE_UNLOCKED, LOCK_STATE_UNLOCKING, -} from "../../ha/data/lock"; +} from "../../ha"; export function isUnlocked(entity: LockEntity) { return entity.state === LOCK_STATE_UNLOCKED; diff --git a/src/cards/media-player-card/controls/media-player-media-control.ts b/src/cards/media-player-card/controls/media-player-media-control.ts index 42a5611bc..cda8ec7d7 100644 --- a/src/cards/media-player-card/controls/media-player-media-control.ts +++ b/src/cards/media-player-card/controls/media-player-media-control.ts @@ -1,7 +1,6 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { MediaPlayerEntity } from "../../../ha/data/media-player"; +import { computeRTL, HomeAssistant, MediaPlayerEntity } from "../../../ha"; import { MediaPlayerMediaControl } from "../media-player-card-config"; import { computeMediaControls, handleMediaControlClick } from "../utils"; diff --git a/src/cards/media-player-card/controls/media-player-volume-control.ts b/src/cards/media-player-card/controls/media-player-volume-control.ts index b8e82bb31..fa32514d9 100644 --- a/src/cards/media-player-card/controls/media-player-volume-control.ts +++ b/src/cards/media-player-card/controls/media-player-volume-control.ts @@ -1,14 +1,17 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { supportsFeature } from "../../../ha/common/entity/supports-feature"; -import { isActive, isAvailable, isOff } from "../../../ha/data/entity"; import { + computeRTL, + HomeAssistant, + isActive, + isAvailable, + isOff, MediaPlayerEntity, MEDIA_PLAYER_SUPPORT_VOLUME_BUTTONS, MEDIA_PLAYER_SUPPORT_VOLUME_MUTE, MEDIA_PLAYER_SUPPORT_VOLUME_SET, -} from "../../../ha/data/media-player"; + supportsFeature, +} from "../../../ha"; import { MediaPlayerVolumeControl } from "../media-player-card-config"; import { getVolumeLevel, handleMediaControlClick } from "../utils"; diff --git a/src/cards/media-player-card/media-player-card-config.ts b/src/cards/media-player-card/media-player-card-config.ts index 0969c4824..1baefa95f 100644 --- a/src/cards/media-player-card/media-player-card-config.ts +++ b/src/cards/media-player-card/media-player-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { array, assign, boolean, enums, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export const MEDIA_LAYER_MEDIA_CONTROLS = [ diff --git a/src/cards/media-player-card/media-player-card-editor.ts b/src/cards/media-player-card/media-player-card-editor.ts index 29cac323d..9d06e0a0e 100644 --- a/src/cards/media-player-card/media-player-card-editor.ts +++ b/src/cards/media-player-card/media-player-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/media-player-card/media-player-card.ts b/src/cards/media-player-card/media-player-card.ts index 32b7a7c1e..576e26135 100644 --- a/src/cards/media-player-card/media-player-card.ts +++ b/src/cards/media-player-card/media-player-card.ts @@ -1,17 +1,19 @@ +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + getEntityPicture, handleAction, hasAction, HomeAssistant, + isActive, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { getEntityPicture, isActive } from "../../ha/data/entity"; -import { MediaPlayerEntity } from "../../ha/data/media-player"; + MediaPlayerEntity, +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/card"; import "../../shared/shape-avatar"; @@ -19,7 +21,6 @@ import "../../shared/shape-icon"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { getLayoutFromConfig, Layout } from "../../utils/layout"; import { MEDIA_PLAYER_CARD_EDITOR_NAME, @@ -37,10 +38,6 @@ import { computeMediaStateDisplay, getVolumeLevel, } from "./utils"; -import "../../shared/badge-icon"; -import "../../shared/card"; -import "../../shared/shape-avatar"; -import "../../shared/shape-icon"; type MediaPlayerCardControl = "media_control" | "volume_control"; diff --git a/src/cards/media-player-card/utils.ts b/src/cards/media-player-card/utils.ts index f6cd51d82..ba725cd17 100644 --- a/src/cards/media-player-card/utils.ts +++ b/src/cards/media-player-card/utils.ts @@ -1,9 +1,8 @@ -import { computeStateDisplay, HomeAssistant, stateIcon } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; -import { supportsFeature } from "../../ha/common/entity/supports-feature"; -import { OFF, UNAVAILABLE, UNKNOWN } from "../../ha/data/entity"; import { computeMediaDescription, + computeStateDisplay, + HomeAssistant, MediaPlayerEntity, MEDIA_PLAYER_SUPPORT_NEXT_TRACK, MEDIA_PLAYER_SUPPORT_PAUSE, @@ -14,8 +13,12 @@ import { MEDIA_PLAYER_SUPPORT_STOP, MEDIA_PLAYER_SUPPORT_TURN_OFF, MEDIA_PLAYER_SUPPORT_TURN_ON, - MEDIA_PLAYER_SUPPORT_VOLUME_SET, -} from "../../ha/data/media-player"; + OFF, + supportsFeature, + UNAVAILABLE, + UNKNOWN, +} from "../../ha"; +import { stateIcon } from "../../utils/icons/state-icon"; import { MediaPlayerCardConfig, MediaPlayerMediaControl } from "./media-player-card-config"; export function callService( diff --git a/src/cards/person-card/person-card-config.ts b/src/cards/person-card/person-card-config.ts index 218d76929..22a11afce 100644 --- a/src/cards/person-card/person-card-config.ts +++ b/src/cards/person-card/person-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type PersonCardConfig = LovelaceCardConfig & diff --git a/src/cards/person-card/person-card-editor.ts b/src/cards/person-card/person-card-editor.ts index 89a56203f..e175d5e5f 100644 --- a/src/cards/person-card/person-card-editor.ts +++ b/src/cards/person-card/person-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { Action } from "../../utils/form/custom/ha-selector-mushroom-action"; diff --git a/src/cards/person-card/person-card.ts b/src/cards/person-card/person-card.ts index 6b404d780..a3a6782c2 100644 --- a/src/cards/person-card/person-card.ts +++ b/src/cards/person-card/person-card.ts @@ -1,18 +1,21 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, computeStateDisplay, + getEntityPicture, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { getEntityPicture, isActive, isAvailable } from "../../ha/data/entity"; +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/card"; import "../../shared/shape-avatar"; @@ -22,7 +25,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon as stateIconHelper } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { PERSON_CARD_EDITOR_NAME, PERSON_CARD_NAME, PERSON_ENTITY_DOMAINS } from "./const"; diff --git a/src/cards/person-card/utils.ts b/src/cards/person-card/utils.ts index b25c0d3ed..5032f988a 100644 --- a/src/cards/person-card/utils.ts +++ b/src/cards/person-card/utils.ts @@ -1,12 +1,12 @@ import { HassEntity } from "home-assistant-js-websocket"; -import { UNKNOWN } from "../../ha/data/entity"; +import { UNKNOWN } from "../../ha"; export function getStateIcon(entity: HassEntity, zones: HassEntity[]) { const state = entity.state; if (state === UNKNOWN) { return "mdi:help"; - } else if(state === "not_home") { - return "mdi:home-export-outline" + } else if (state === "not_home") { + return "mdi:home-export-outline"; } else if (state === "home") { return "mdi:home"; } @@ -23,7 +23,7 @@ export function getStateColor(entity: HassEntity, zones: HassEntity[]) { const state = entity.state; if (state === UNKNOWN) { return "var(--rgb-state-person-unknown)"; - } else if (state === "not_home"){ + } else if (state === "not_home") { return "var(--rgb-state-person-not-home)"; } else if (state === "home") { return "var(--rgb-state-person-home)"; diff --git a/src/cards/template-card/template-card-config.ts b/src/cards/template-card/template-card-config.ts index f049511b4..810bace83 100644 --- a/src/cards/template-card/template-card-config.ts +++ b/src/cards/template-card/template-card-config.ts @@ -1,7 +1,7 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { array, assign, boolean, object, optional, string, union } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type TemplateCardConfig = LovelaceCardConfig & diff --git a/src/cards/template-card/template-card-editor.ts b/src/cards/template-card/template-card-editor.ts index 8031c608e..ed8adf175 100644 --- a/src/cards/template-card/template-card-editor.ts +++ b/src/cards/template-card/template-card-editor.ts @@ -1,9 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; -import { atLeastHaVersion } from "../../ha/util"; +import { atLeastHaVersion, fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/template-card/template-card.ts b/src/cards/template-card/template-card.ts index 3d159b89d..7a583dbc8 100644 --- a/src/cards/template-card/template-card.ts +++ b/src/cards/template-card/template-card.ts @@ -1,4 +1,10 @@ +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, handleAction, @@ -6,12 +12,9 @@ import { HomeAssistant, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { Connection, UnsubscribeFunc } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; + RenderTemplateResult, + subscribeRenderTemplate, +} from "../../ha"; import "../../shared/shape-icon"; import "../../shared/state-info"; import "../../shared/state-item"; @@ -19,9 +22,7 @@ import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { computeRgbColor } from "../../utils/colors"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { getLayoutFromConfig } from "../../utils/layout"; -import { RenderTemplateResult, subscribeRenderTemplate } from "../../utils/ws-templates"; import { TEMPLATE_CARD_EDITOR_NAME, TEMPLATE_CARD_NAME } from "./const"; import { TemplateCardConfig } from "./template-card-config"; @@ -195,7 +196,7 @@ export class TemplateCard extends MushroomBaseElement implements LovelaceCard { try { const sub = subscribeRenderTemplate( - this.hass.connection as any as Connection, + this.hass.connection, (result) => { this._templateResults = { ...this._templateResults, diff --git a/src/cards/title-card/title-card-config.ts b/src/cards/title-card/title-card-config.ts index 2a6a64233..1a16160d4 100644 --- a/src/cards/title-card/title-card-config.ts +++ b/src/cards/title-card/title-card-config.ts @@ -1,5 +1,5 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, object, optional, string } from "superstruct"; +import { LovelaceCardConfig } from "../../ha"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export interface TitleCardConfig extends LovelaceCardConfig { diff --git a/src/cards/title-card/title-card-editor.ts b/src/cards/title-card/title-card-editor.ts index bcf2e7b1c..0e3681628 100644 --- a/src/cards/title-card/title-card-editor.ts +++ b/src/cards/title-card/title-card-editor.ts @@ -1,9 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; -import { atLeastHaVersion } from "../../ha/util"; +import { atLeastHaVersion, fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { HaFormSchema } from "../../utils/form/ha-form"; diff --git a/src/cards/title-card/title-card.ts b/src/cards/title-card/title-card.ts index 7fd17c0ae..175945af4 100644 --- a/src/cards/title-card/title-card.ts +++ b/src/cards/title-card/title-card.ts @@ -1,14 +1,19 @@ -import { HomeAssistant, LovelaceCard, LovelaceCardEditor } from "custom-card-helpers"; -import { Connection, UnsubscribeFunc } from "home-assistant-js-websocket"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, PropertyValues, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; +import { + HomeAssistant, + LovelaceCard, + LovelaceCardEditor, + RenderTemplateResult, + subscribeRenderTemplate, +} from "../../ha"; import "../../shared/shape-icon"; import "../../shared/state-info"; import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { RenderTemplateResult, subscribeRenderTemplate } from "../../utils/ws-templates"; import { TITLE_CARD_EDITOR_NAME, TITLE_CARD_NAME } from "./const"; import { TitleCardConfig } from "./title-card-config"; @@ -121,7 +126,7 @@ export class TitleCard extends MushroomBaseElement implements LovelaceCard { try { const sub = subscribeRenderTemplate( - this.hass.connection as any as Connection, + this.hass.connection, (result) => { this._templateResults = { ...this._templateResults, diff --git a/src/cards/update-card/controls/update-buttons-control.ts b/src/cards/update-card/controls/update-buttons-control.ts index 958ec4003..0ee6e8101 100644 --- a/src/cards/update-card/controls/update-buttons-control.ts +++ b/src/cards/update-card/controls/update-buttons-control.ts @@ -1,8 +1,13 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { isActive, isAvailable } from "../../../ha/data/entity"; -import { UpdateEntity, updateIsInstalling } from "../../../ha/data/update"; +import { + computeRTL, + HomeAssistant, + isActive, + isAvailable, + UpdateEntity, + updateIsInstalling, +} from "../../../ha"; import "../../../shared/button"; import "../../../shared/button-group"; diff --git a/src/cards/update-card/update-card-config.ts b/src/cards/update-card/update-card-config.ts index 36f2251f5..bfa05d173 100644 --- a/src/cards/update-card/update-card-config.ts +++ b/src/cards/update-card/update-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { assign, boolean, object, optional } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export type UpdateCardConfig = LovelaceCardConfig & diff --git a/src/cards/update-card/update-card-editor.ts b/src/cards/update-card/update-card-editor.ts index c516402a4..978fd14b3 100644 --- a/src/cards/update-card/update-card-editor.ts +++ b/src/cards/update-card/update-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { Action } from "../../utils/form/custom/ha-selector-mushroom-action"; diff --git a/src/cards/update-card/update-card.ts b/src/cards/update-card/update-card.ts index 61e78cbdd..e08947ede 100644 --- a/src/cards/update-card/update-card.ts +++ b/src/cards/update-card/update-card.ts @@ -1,20 +1,25 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; +import { styleMap } from "lit/directives/style-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, + getEntityPicture, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { styleMap } from "lit/directives/style-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { supportsFeature } from "../../ha/common/entity/supports-feature"; -import { getEntityPicture, isActive, isAvailable } from "../../ha/data/entity"; -import { UpdateEntity, updateIsInstalling, UPDATE_SUPPORT_INSTALL } from "../../ha/data/update"; + supportsFeature, + UpdateEntity, + updateIsInstalling, + UPDATE_SUPPORT_INSTALL, +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/card"; import "../../shared/shape-icon"; @@ -23,7 +28,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { UPDATE_CARD_EDITOR_NAME, UPDATE_CARD_NAME, UPDATE_ENTITY_DOMAINS } from "./const"; diff --git a/src/cards/vacuum-card/controls/vacuum-commands-control.ts b/src/cards/vacuum-card/controls/vacuum-commands-control.ts index 7478797f3..3d8552236 100644 --- a/src/cards/vacuum-card/controls/vacuum-commands-control.ts +++ b/src/cards/vacuum-card/controls/vacuum-commands-control.ts @@ -1,9 +1,10 @@ -import { computeRTL, HomeAssistant } from "custom-card-helpers"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { supportsFeature } from "../../../ha/common/entity/supports-feature"; -import { isAvailable } from "../../../ha/data/entity"; import { + computeRTL, + HomeAssistant, + isAvailable, + supportsFeature, VacuumEntity, VACUUM_SUPPORT_CLEAN_SPOT, VACUUM_SUPPORT_LOCATE, @@ -11,7 +12,7 @@ import { VACUUM_SUPPORT_RETURN_HOME, VACUUM_SUPPORT_START, VACUUM_SUPPORT_STOP, -} from "../../../ha/data/vacuum"; +} from "../../../ha"; import { isCleaning, isReturningHome, isStopped } from "../utils"; import { VacuumCommand } from "../vacuum-card-config"; diff --git a/src/cards/vacuum-card/utils.ts b/src/cards/vacuum-card/utils.ts index 71cdc2d15..405f9369d 100644 --- a/src/cards/vacuum-card/utils.ts +++ b/src/cards/vacuum-card/utils.ts @@ -6,7 +6,7 @@ import { STATE_OFF, STATE_ON, STATE_RETURNING, -} from "../../ha/data/vacuum"; +} from "../../ha"; export function isCleaning(entity: HassEntity): boolean { switch (entity.state) { diff --git a/src/cards/vacuum-card/vacuum-card-config.ts b/src/cards/vacuum-card/vacuum-card-config.ts index 49a0ecdc0..7c8dd4fbb 100644 --- a/src/cards/vacuum-card/vacuum-card-config.ts +++ b/src/cards/vacuum-card/vacuum-card-config.ts @@ -1,8 +1,8 @@ -import { LovelaceCardConfig } from "custom-card-helpers"; import { array, assign, boolean, object, optional, string } from "superstruct"; -import { actionsSharedConfigStruct, ActionsSharedConfig } from "../../shared/config/actions-config"; -import { layoutSharedConfigStruct, LayoutSharedConfig } from "../../shared/config/layout-config"; -import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config"; +import { LovelaceCardConfig } from "../../ha"; +import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config"; +import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config"; +import { LayoutSharedConfig, layoutSharedConfigStruct } from "../../shared/config/layout-config"; import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config"; export const VACUUM_COMMANDS = [ diff --git a/src/cards/vacuum-card/vacuum-card-editor.ts b/src/cards/vacuum-card/vacuum-card-editor.ts index 7837aec0b..b7d416caa 100644 --- a/src/cards/vacuum-card/vacuum-card-editor.ts +++ b/src/cards/vacuum-card/vacuum-card-editor.ts @@ -1,8 +1,8 @@ -import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "custom-card-helpers"; import { html, TemplateResult } from "lit"; import { customElement, state } from "lit/decorators.js"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; +import { fireEvent, LocalizeFunc, LovelaceCardEditor } from "../../ha"; import setupCustomlocalize from "../../localize"; import { MushroomBaseElement } from "../../utils/base-element"; import { GENERIC_LABELS } from "../../utils/form/generic-fields"; diff --git a/src/cards/vacuum-card/vacuum-card.ts b/src/cards/vacuum-card/vacuum-card.ts index 71656e422..c73733bc0 100644 --- a/src/cards/vacuum-card/vacuum-card.ts +++ b/src/cards/vacuum-card/vacuum-card.ts @@ -1,18 +1,20 @@ +import { css, CSSResultGroup, html, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import { classMap } from "lit/directives/class-map.js"; import { + actionHandler, ActionHandlerEvent, computeRTL, + computeStateDisplay, handleAction, hasAction, HomeAssistant, + isActive, + isAvailable, LovelaceCard, LovelaceCardEditor, -} from "custom-card-helpers"; -import { css, CSSResultGroup, html, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators.js"; -import { classMap } from "lit/directives/class-map.js"; -import { computeStateDisplay } from "../../ha/common/entity/compute-state-display"; -import { isActive, isAvailable } from "../../ha/data/entity"; -import { VacuumEntity } from "../../ha/data/vacuum"; + VacuumEntity, +} from "../../ha"; import "../../shared/badge-icon"; import "../../shared/card"; import "../../shared/shape-icon"; @@ -21,7 +23,6 @@ import "../../shared/state-item"; import { MushroomBaseElement } from "../../utils/base-element"; import { cardStyle } from "../../utils/card-styles"; import { registerCustomCard } from "../../utils/custom-cards"; -import { actionHandler } from "../../utils/directives/action-handler-directive"; import { stateIcon } from "../../utils/icons/state-icon"; import { getLayoutFromConfig } from "../../utils/layout"; import { VACUUM_CARD_EDITOR_NAME, VACUUM_CARD_NAME, VACUUM_ENTITY_DOMAINS } from "./const"; diff --git a/src/ha/common/const.ts b/src/ha/common/const.ts index 00f224c6e..d51649f0b 100644 --- a/src/ha/common/const.ts +++ b/src/ha/common/const.ts @@ -1,3 +1,6 @@ +/** States that we consider "off". */ +export const STATES_OFF = ["closed", "locked", "off"]; + /** Temperature units. */ export const UNIT_C = "°C"; export const UNIT_F = "°F"; diff --git a/src/ha/common/datetime/format_date.ts b/src/ha/common/datetime/format_date.ts new file mode 100644 index 000000000..855c5a10e --- /dev/null +++ b/src/ha/common/datetime/format_date.ts @@ -0,0 +1,87 @@ +import memoizeOne from "memoize-one"; +import { FrontendLocaleData } from "../../data/translation"; + +// Tuesday, August 10 +export const formatDateWeekday = (dateObj: Date, locale: FrontendLocaleData) => + formatDateWeekdayMem(locale).format(dateObj); + +const formatDateWeekdayMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + weekday: "long", + month: "long", + day: "numeric", + }) +); + +// August 10, 2021 +export const formatDate = (dateObj: Date, locale: FrontendLocaleData) => + formatDateMem(locale).format(dateObj); + +const formatDateMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + month: "long", + day: "numeric", + }) +); + +// 10/08/2021 +export const formatDateNumeric = (dateObj: Date, locale: FrontendLocaleData) => + formatDateNumericMem(locale).format(dateObj); + +const formatDateNumericMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + month: "numeric", + day: "numeric", + }) +); + +// Aug 10 +export const formatDateShort = (dateObj: Date, locale: FrontendLocaleData) => + formatDateShortMem(locale).format(dateObj); + +const formatDateShortMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + day: "numeric", + month: "short", + }) +); + +// August 2021 +export const formatDateMonthYear = (dateObj: Date, locale: FrontendLocaleData) => + formatDateMonthYearMem(locale).format(dateObj); + +const formatDateMonthYearMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + month: "long", + year: "numeric", + }) +); + +// August +export const formatDateMonth = (dateObj: Date, locale: FrontendLocaleData) => + formatDateMonthMem(locale).format(dateObj); + +const formatDateMonthMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + month: "long", + }) +); + +// 2021 +export const formatDateYear = (dateObj: Date, locale: FrontendLocaleData) => + formatDateYearMem(locale).format(dateObj); + +const formatDateYearMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + }) +); diff --git a/src/ha/common/datetime/format_date_time.ts b/src/ha/common/datetime/format_date_time.ts new file mode 100644 index 000000000..f8503aff0 --- /dev/null +++ b/src/ha/common/datetime/format_date_time.ts @@ -0,0 +1,61 @@ +import memoizeOne from "memoize-one"; +import { FrontendLocaleData } from "../../data/translation"; +import { useAmPm } from "./use_am_pm"; + +// August 9, 2021, 8:23 AM +export const formatDateTime = (dateObj: Date, locale: FrontendLocaleData) => + formatDateTimeMem(locale).format(dateObj); + +const formatDateTimeMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + year: "numeric", + month: "long", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hour12: useAmPm(locale), + } + ) +); + +// August 9, 2021, 8:23:15 AM +export const formatDateTimeWithSeconds = (dateObj: Date, locale: FrontendLocaleData) => + formatDateTimeWithSecondsMem(locale).format(dateObj); + +const formatDateTimeWithSecondsMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + year: "numeric", + month: "long", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: useAmPm(locale), + } + ) +); + +// 9/8/2021, 8:23 AM +export const formatDateTimeNumeric = (dateObj: Date, locale: FrontendLocaleData) => + formatDateTimeNumericMem(locale).format(dateObj); + +const formatDateTimeNumericMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "2-digit", + hour12: useAmPm(locale), + } + ) +); diff --git a/src/ha/common/datetime/format_time.ts b/src/ha/common/datetime/format_time.ts new file mode 100644 index 000000000..1fbbf5f15 --- /dev/null +++ b/src/ha/common/datetime/format_time.ts @@ -0,0 +1,53 @@ +import memoizeOne from "memoize-one"; +import { FrontendLocaleData } from "../../data/translation"; +import { useAmPm } from "./use_am_pm"; + +// 9:15 PM || 21:15 +export const formatTime = (dateObj: Date, locale: FrontendLocaleData) => + formatTimeMem(locale).format(dateObj); + +const formatTimeMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + hour: "numeric", + minute: "2-digit", + hour12: useAmPm(locale), + } + ) +); + +// 9:15:24 PM || 21:15:24 +export const formatTimeWithSeconds = (dateObj: Date, locale: FrontendLocaleData) => + formatTimeWithSecondsMem(locale).format(dateObj); + +const formatTimeWithSecondsMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: useAmPm(locale), + } + ) +); + +// Tuesday 7:00 PM || Tuesday 19:00 +export const formatTimeWeekday = (dateObj: Date, locale: FrontendLocaleData) => + formatTimeWeekdayMem(locale).format(dateObj); + +const formatTimeWeekdayMem = memoizeOne( + (locale: FrontendLocaleData) => + new Intl.DateTimeFormat( + locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" : locale.language, + { + weekday: "long", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hour12: useAmPm(locale), + } + ) +); diff --git a/src/ha/common/datetime/use_am_pm.ts b/src/ha/common/datetime/use_am_pm.ts new file mode 100644 index 000000000..dd53415b7 --- /dev/null +++ b/src/ha/common/datetime/use_am_pm.ts @@ -0,0 +1,13 @@ +import memoizeOne from "memoize-one"; +import { FrontendLocaleData, TimeFormat } from "../../data/translation"; + +export const useAmPm = memoizeOne((locale: FrontendLocaleData): boolean => { + if (locale.time_format === TimeFormat.language || locale.time_format === TimeFormat.system) { + const testLanguage = + locale.time_format === TimeFormat.language ? locale.language : undefined; + const test = new Date().toLocaleString(testLanguage); + return test.includes("AM") || test.includes("PM"); + } + + return locale.time_format === TimeFormat.am_pm; +}); diff --git a/src/ha/common/dom/fire_event.ts b/src/ha/common/dom/fire_event.ts new file mode 100644 index 000000000..686ca825a --- /dev/null +++ b/src/ha/common/dom/fire_event.ts @@ -0,0 +1,78 @@ +// Polymer legacy event helpers used courtesy of the Polymer project. +// +// Copyright (c) 2017 The Polymer Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +declare global { + // eslint-disable-next-line + interface HASSDomEvents {} +} + +export type ValidHassDomEvent = keyof HASSDomEvents; + +export interface HASSDomEvent extends Event { + detail: T; +} + +/** + * Dispatches a custom event with an optional detail value. + * + * @param {string} type Name of event type. + * @param {*=} detail Detail value containing event-specific + * payload. + * @param {{ bubbles: (boolean|undefined), + * cancelable: (boolean|undefined), + * composed: (boolean|undefined) }=} + * options Object specifying options. These may include: + * `bubbles` (boolean, defaults to `true`), + * `cancelable` (boolean, defaults to false), and + * `node` on which to fire the event (HTMLElement, defaults to `this`). + * @return {Event} The new event that was fired. + */ +export const fireEvent = ( + node: HTMLElement | Window, + type: HassEvent, + detail?: HASSDomEvents[HassEvent], + options?: { + bubbles?: boolean; + cancelable?: boolean; + composed?: boolean; + } +) => { + options = options || {}; + // @ts-ignore + detail = detail === null || detail === undefined ? {} : detail; + const event = new Event(type, { + bubbles: options.bubbles === undefined ? true : options.bubbles, + cancelable: Boolean(options.cancelable), + composed: options.composed === undefined ? true : options.composed, + }); + (event as any).detail = detail; + node.dispatchEvent(event); + return event; +}; diff --git a/src/ha/common/dom/get_main_window.ts b/src/ha/common/dom/get_main_window.ts new file mode 100644 index 000000000..e7262c6e4 --- /dev/null +++ b/src/ha/common/dom/get_main_window.ts @@ -0,0 +1,4 @@ +import { MAIN_WINDOW_NAME } from "../../data/main_window"; + +export const mainWindow = + window.name === MAIN_WINDOW_NAME ? window : parent.name === MAIN_WINDOW_NAME ? parent : top!; diff --git a/src/ha/common/entity/compute-state-display.ts b/src/ha/common/entity/compute-state-display.ts index 7e2b83bfb..456b0a639 100644 --- a/src/ha/common/entity/compute-state-display.ts +++ b/src/ha/common/entity/compute-state-display.ts @@ -1,15 +1,12 @@ -import { - formatDate, - formatDateTime, - formatNumber, - formatTime, - FrontendLocaleData, - isNumericState, - LocalizeFunc, -} from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; import { UNAVAILABLE, UNKNOWN } from "../../data/entity"; +import { FrontendLocaleData } from "../../data/translation"; import { updateIsInstalling, UpdateEntity, UPDATE_SUPPORT_PROGRESS } from "../../data/update"; +import { formatDate } from "../datetime/format_date"; +import { formatDateTime } from "../datetime/format_date_time"; +import { formatTime } from "../datetime/format_time"; +import { formatNumber, isNumericState } from "../number/format_number"; +import { LocalizeFunc } from "../translations/localize"; import { computeStateDomain } from "./compute-state-domain"; import { supportsFeature } from "./supports-feature"; diff --git a/src/ha/common/navigate.ts b/src/ha/common/navigate.ts new file mode 100644 index 000000000..0b4f1945c --- /dev/null +++ b/src/ha/common/navigate.ts @@ -0,0 +1,29 @@ +import { fireEvent } from "./dom/fire_event"; +import { mainWindow } from "./dom/get_main_window"; + +declare global { + interface HASSDomEvents { + "location-changed": NavigateOptions; + } +} + +export interface NavigateOptions { + replace?: boolean; +} + +export const navigate = (path: string, options?: NavigateOptions) => { + const replace = options?.replace || false; + + if (replace) { + mainWindow.history.replaceState( + mainWindow.history.state?.root ? { root: true } : null, + "", + path + ); + } else { + mainWindow.history.pushState(null, "", path); + } + fireEvent(mainWindow, "location-changed", { + replace, + }); +}; diff --git a/src/ha/common/number/format_number.ts b/src/ha/common/number/format_number.ts new file mode 100644 index 000000000..6f3c69f45 --- /dev/null +++ b/src/ha/common/number/format_number.ts @@ -0,0 +1,101 @@ +import { HassEntity } from "home-assistant-js-websocket"; +import { FrontendLocaleData, NumberFormat } from "../../data/translation"; +import { round } from "./round"; + +/** + * Returns true if the entity is considered numeric based on the attributes it has + * @param stateObj The entity state object + */ +export const isNumericState = (stateObj: HassEntity): boolean => + isNumericFromAttributes(stateObj.attributes); + +export const isNumericFromAttributes = (attributes: { [key: string]: any }): boolean => + !!attributes.unit_of_measurement || !!attributes.state_class; + +export const numberFormatToLocale = ( + localeOptions: FrontendLocaleData +): string | string[] | undefined => { + switch (localeOptions.number_format) { + case NumberFormat.comma_decimal: + return ["en-US", "en"]; // Use United States with fallback to English formatting 1,234,567.89 + case NumberFormat.decimal_comma: + return ["de", "es", "it"]; // Use German with fallback to Spanish then Italian formatting 1.234.567,89 + case NumberFormat.space_comma: + return ["fr", "sv", "cs"]; // Use French with fallback to Swedish and Czech formatting 1 234 567,89 + case NumberFormat.system: + return undefined; + default: + return localeOptions.language; + } +}; + +/** + * Formats a number based on the user's preference with thousands separator(s) and decimal character for better legibility. + * + * @param num The number to format + * @param locale The user-selected language and number format, from `hass.locale` + * @param options Intl.NumberFormatOptions to use + */ +export const formatNumber = ( + num: string | number, + localeOptions?: FrontendLocaleData, + options?: Intl.NumberFormatOptions +): string => { + const locale = localeOptions ? numberFormatToLocale(localeOptions) : undefined; + + // Polyfill for Number.isNaN, which is more reliable than the global isNaN() + Number.isNaN = + Number.isNaN || + function isNaN(input) { + return typeof input === "number" && isNaN(input); + }; + + if (localeOptions?.number_format !== NumberFormat.none && !Number.isNaN(Number(num)) && Intl) { + try { + return new Intl.NumberFormat(locale, getDefaultFormatOptions(num, options)).format( + Number(num) + ); + } catch (err: any) { + // Don't fail when using "TEST" language + // eslint-disable-next-line no-console + console.error(err); + return new Intl.NumberFormat(undefined, getDefaultFormatOptions(num, options)).format( + Number(num) + ); + } + } + if (typeof num === "string") { + return num; + } + return `${round(num, options?.maximumFractionDigits).toString()}${ + options?.style === "currency" ? ` ${options.currency}` : "" + }`; +}; + +/** + * Generates default options for Intl.NumberFormat + * @param num The number to be formatted + * @param options The Intl.NumberFormatOptions that should be included in the returned options + */ +const getDefaultFormatOptions = ( + num: string | number, + options?: Intl.NumberFormatOptions +): Intl.NumberFormatOptions => { + const defaultOptions: Intl.NumberFormatOptions = { + maximumFractionDigits: 2, + ...options, + }; + + if (typeof num !== "string") { + return defaultOptions; + } + + // Keep decimal trailing zeros if they are present in a string numeric value + if (!options || (!options.minimumFractionDigits && !options.maximumFractionDigits)) { + const digits = num.indexOf(".") > -1 ? num.split(".")[1].length : 0; + defaultOptions.minimumFractionDigits = digits; + defaultOptions.maximumFractionDigits = digits; + } + + return defaultOptions; +}; diff --git a/src/ha/common/number/round.ts b/src/ha/common/number/round.ts new file mode 100644 index 000000000..ee84f6b45 --- /dev/null +++ b/src/ha/common/number/round.ts @@ -0,0 +1,2 @@ +export const round = (value: number, precision = 2): number => + Math.round(value * 10 ** precision) / 10 ** precision; diff --git a/src/ha/common/structs/handle-errors.ts b/src/ha/common/structs/handle-errors.ts new file mode 100644 index 000000000..96c82081c --- /dev/null +++ b/src/ha/common/structs/handle-errors.ts @@ -0,0 +1,59 @@ +import { StructError } from "superstruct"; +import type { HomeAssistant } from "../../types"; + +export const handleStructError = ( + hass: HomeAssistant, + err: Error +): { warnings: string[]; errors?: string[] } => { + if (!(err instanceof StructError)) { + return { warnings: [err.message], errors: undefined }; + } + const errors: string[] = []; + const warnings: string[] = []; + for (const failure of err.failures()) { + if (failure.value === undefined) { + errors.push( + hass.localize( + "ui.errors.config.key_missing", + "key", + failure.path.join(".") + ) + ); + } else if (failure.type === "never") { + warnings.push( + hass.localize( + "ui.errors.config.key_not_expected", + "key", + failure.path.join(".") + ) + ); + } else if (failure.type === "union") { + continue; + } else if (failure.type === "enums") { + warnings.push( + hass.localize( + "ui.errors.config.key_wrong_type", + "key", + failure.path.join("."), + "type_correct", + failure.message.replace("Expected ", "").split(", ")[0], + "type_wrong", + JSON.stringify(failure.value) + ) + ); + } else { + warnings.push( + hass.localize( + "ui.errors.config.key_wrong_type", + "key", + failure.path.join("."), + "type_correct", + failure.refinement || failure.type, + "type_wrong", + JSON.stringify(failure.value) + ) + ); + } + } + return { warnings, errors }; +}; diff --git a/src/ha/common/translations/localize.ts b/src/ha/common/translations/localize.ts new file mode 100644 index 000000000..f68bfae50 --- /dev/null +++ b/src/ha/common/translations/localize.ts @@ -0,0 +1 @@ +export type LocalizeFunc = (key: string, ...args: any[]) => string; diff --git a/src/ha/common/util/compute_rtl.ts b/src/ha/common/util/compute_rtl.ts new file mode 100644 index 000000000..fd5f24517 --- /dev/null +++ b/src/ha/common/util/compute_rtl.ts @@ -0,0 +1,30 @@ +import { LitElement } from "lit"; +import { HomeAssistant } from "../../types"; + +export function computeRTL(hass: HomeAssistant) { + const lang = hass.language || "en"; + if (hass.translationMetadata.translations[lang]) { + return hass.translationMetadata.translations[lang].isRTL || false; + } + return false; +} + +export function computeRTLDirection(hass: HomeAssistant) { + return emitRTLDirection(computeRTL(hass)); +} + +export function emitRTLDirection(rtl: boolean) { + return rtl ? "rtl" : "ltr"; +} + +export function computeDirectionStyles(isRTL: boolean, element: LitElement) { + const direction: string = emitRTLDirection(isRTL); + setDirectionStyles(direction, element); +} + +export function setDirectionStyles(direction: string, element: LitElement) { + element.style.direction = direction; + element.style.setProperty("--direction", direction); + element.style.setProperty("--float-start", direction === "ltr" ? "left" : "right"); + element.style.setProperty("--float-end", direction === "ltr" ? "right" : "left"); +} diff --git a/src/utils/debounce.ts b/src/ha/common/util/debounce.ts similarity index 100% rename from src/utils/debounce.ts rename to src/ha/common/util/debounce.ts diff --git a/src/ha/common/util/deep-equal.ts b/src/ha/common/util/deep-equal.ts new file mode 100644 index 000000000..780aef695 --- /dev/null +++ b/src/ha/common/util/deep-equal.ts @@ -0,0 +1,107 @@ +// From https://github.com/epoberezkin/fast-deep-equal +// MIT License - Copyright (c) 2017 Evgeny Poberezkin +export const deepEqual = (a: any, b: any): boolean => { + if (a === b) { + return true; + } + + if (a && b && typeof a === "object" && typeof b === "object") { + if (a.constructor !== b.constructor) { + return false; + } + + let i: number | [any, any]; + let length: number; + if (Array.isArray(a)) { + length = a.length; + if (length !== b.length) { + return false; + } + for (i = length; i-- !== 0; ) { + if (!deepEqual(a[i], b[i])) { + return false; + } + } + return true; + } + + if (a instanceof Map && b instanceof Map) { + if (a.size !== b.size) { + return false; + } + for (i of a.entries()) { + if (!b.has(i[0])) { + return false; + } + } + for (i of a.entries()) { + if (!deepEqual(i[1], b.get(i[0]))) { + return false; + } + } + return true; + } + + if (a instanceof Set && b instanceof Set) { + if (a.size !== b.size) { + return false; + } + for (i of a.entries()) { + if (!b.has(i[0])) { + return false; + } + } + return true; + } + + if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { + // @ts-ignore + length = a.length; + // @ts-ignore + if (length !== b.length) { + return false; + } + for (i = length; i-- !== 0; ) { + if (a[i] !== b[i]) { + return false; + } + } + return true; + } + + if (a.constructor === RegExp) { + return a.source === b.source && a.flags === b.flags; + } + if (a.valueOf !== Object.prototype.valueOf) { + return a.valueOf() === b.valueOf(); + } + if (a.toString !== Object.prototype.toString) { + return a.toString() === b.toString(); + } + + const keys = Object.keys(a); + length = keys.length; + if (length !== Object.keys(b).length) { + return false; + } + for (i = length; i-- !== 0; ) { + if (!Object.prototype.hasOwnProperty.call(b, keys[i])) { + return false; + } + } + + for (i = length; i-- !== 0; ) { + const key = keys[i]; + + if (!deepEqual(a[key], b[key])) { + return false; + } + } + + return true; + } + + // true if both NaN, false otherwise + // eslint-disable-next-line no-self-compare + return a !== a && b !== b; +}; diff --git a/src/utils/render-status.ts b/src/ha/common/util/render-status.ts similarity index 100% rename from src/utils/render-status.ts rename to src/ha/common/util/render-status.ts diff --git a/src/ha/data/haptics.ts b/src/ha/data/haptics.ts new file mode 100644 index 000000000..a59dc8a1b --- /dev/null +++ b/src/ha/data/haptics.ts @@ -0,0 +1,32 @@ +/** + * Broadcast haptic feedback requests + */ + +import { fireEvent, HASSDomEvent } from "../common/dom/fire_event"; + +// Allowed types are from iOS HIG. +// https://developer.apple.com/design/human-interface-guidelines/ios/user-interaction/feedback/#haptics +// Implementors on platforms other than iOS should attempt to match the patterns (shown in HIG) as closely as possible. +export type HapticType = + | "success" + | "warning" + | "failure" + | "light" + | "medium" + | "heavy" + | "selection"; + +declare global { + // for fire event + interface HASSDomEvents { + haptic: HapticType; + } + + interface GlobalEventHandlersEventMap { + haptic: HASSDomEvent; + } +} + +export const forwardHaptic = (hapticType: HapticType) => { + fireEvent(window, "haptic", hapticType); +}; diff --git a/src/ha/data/integration.ts b/src/ha/data/integration.ts new file mode 100644 index 000000000..7ec5cd7b2 --- /dev/null +++ b/src/ha/data/integration.ts @@ -0,0 +1,25 @@ +import { LocalizeFunc } from "../common/translations/localize"; + +export interface IntegrationManifest { + is_built_in: boolean; + domain: string; + name: string; + config_flow: boolean; + documentation: string; + issue_tracker?: string; + dependencies?: string[]; + after_dependencies?: string[]; + codeowners?: string[]; + requirements?: string[]; + ssdp?: Array<{ manufacturer?: string; modelName?: string; st?: string }>; + zeroconf?: string[]; + homekit?: { models: string[] }; + quality_scale?: "gold" | "internal" | "platinum" | "silver"; + iot_class: "assumed_state" | "cloud_polling" | "cloud_push" | "local_polling" | "local_push"; +} + +export const domainToName = ( + localize: LocalizeFunc, + domain: string, + manifest?: IntegrationManifest +) => localize(`component.${domain}.title`) || manifest?.name || domain; diff --git a/src/ha/data/lovelace.ts b/src/ha/data/lovelace.ts new file mode 100644 index 000000000..3b31bebce --- /dev/null +++ b/src/ha/data/lovelace.ts @@ -0,0 +1,324 @@ +import { + Connection, + getCollection, + HassEventBase, + HassServiceTarget, +} from "home-assistant-js-websocket"; +import { HASSDomEvent } from "../common/dom/fire_event"; +import { Lovelace, LovelaceCard } from "../panels/lovelace/types"; +import { HomeAssistant } from "../types"; + +export interface LovelacePanelConfig { + mode: "yaml" | "storage"; +} + +export interface LovelaceConfig { + title?: string; + strategy?: { + type: string; + options?: Record; + }; + views: LovelaceViewConfig[]; + background?: string; +} + +export interface LegacyLovelaceConfig extends LovelaceConfig { + resources?: LovelaceResource[]; +} + +export interface LovelaceResource { + id: string; + type: "css" | "js" | "module" | "html"; + url: string; +} + +export interface LovelaceResourcesMutableParams { + res_type: LovelaceResource["type"]; + url: string; +} + +export type LovelaceDashboard = LovelaceYamlDashboard | LovelaceStorageDashboard; + +interface LovelaceGenericDashboard { + id: string; + url_path: string; + require_admin: boolean; + show_in_sidebar: boolean; + icon?: string; + title: string; +} + +export interface LovelaceYamlDashboard extends LovelaceGenericDashboard { + mode: "yaml"; + filename: string; +} + +export interface LovelaceStorageDashboard extends LovelaceGenericDashboard { + mode: "storage"; +} + +export interface LovelaceDashboardMutableParams { + require_admin: boolean; + show_in_sidebar: boolean; + icon?: string; + title: string; +} + +export interface LovelaceDashboardCreateParams extends LovelaceDashboardMutableParams { + url_path: string; + mode: "storage"; +} + +export interface LovelaceViewConfig { + index?: number; + title?: string; + type?: string; + strategy?: { + type: string; + options?: Record; + }; + cards?: LovelaceCardConfig[]; + path?: string; + icon?: string; + theme?: string; + panel?: boolean; + background?: string; + visible?: boolean | ShowViewConfig[]; +} + +export interface LovelaceViewElement extends HTMLElement { + hass?: HomeAssistant; + lovelace?: Lovelace; + narrow?: boolean; + index?: number; + cards?: Array; + isStrategy: boolean; + setConfig(config: LovelaceViewConfig): void; +} + +export interface ShowViewConfig { + user?: string; +} + +export interface LovelaceBadgeConfig { + type?: string; + [key: string]: any; +} + +export interface LovelaceCardConfig { + index?: number; + view_index?: number; + view_layout?: any; + type: string; + [key: string]: any; +} + +export interface ToggleActionConfig extends BaseActionConfig { + action: "toggle"; +} + +export interface CallServiceActionConfig extends BaseActionConfig { + action: "call-service"; + service: string; + target?: HassServiceTarget; + // "service_data" is kept for backwards compatibility. Replaced by "data". + service_data?: Record; + data?: Record; +} + +export interface NavigateActionConfig extends BaseActionConfig { + action: "navigate"; + navigation_path: string; +} + +export interface UrlActionConfig extends BaseActionConfig { + action: "url"; + url_path: string; +} + +export interface MoreInfoActionConfig extends BaseActionConfig { + action: "more-info"; +} + +export interface NoActionConfig extends BaseActionConfig { + action: "none"; +} + +export interface CustomActionConfig extends BaseActionConfig { + action: "fire-dom-event"; +} + +export interface BaseActionConfig { + action: string; + confirmation?: ConfirmationRestrictionConfig; +} + +export interface ConfirmationRestrictionConfig { + text?: string; + exemptions?: RestrictionConfig[]; +} + +export interface RestrictionConfig { + user: string; +} + +export type ActionConfig = + | ToggleActionConfig + | CallServiceActionConfig + | NavigateActionConfig + | UrlActionConfig + | MoreInfoActionConfig + | NoActionConfig + | CustomActionConfig; + +type LovelaceUpdatedEvent = HassEventBase & { + event_type: "lovelace_updated"; + data: { + url_path: string | null; + mode: "yaml" | "storage"; + }; +}; + +export const fetchResources = (conn: Connection): Promise => + conn.sendMessagePromise({ + type: "lovelace/resources", + }); + +export const createResource = (hass: HomeAssistant, values: LovelaceResourcesMutableParams) => + hass.callWS({ + type: "lovelace/resources/create", + ...values, + }); + +export const updateResource = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "lovelace/resources/update", + resource_id: id, + ...updates, + }); + +export const deleteResource = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "lovelace/resources/delete", + resource_id: id, + }); + +export const fetchDashboards = (hass: HomeAssistant): Promise => + hass.callWS({ + type: "lovelace/dashboards/list", + }); + +export const createDashboard = (hass: HomeAssistant, values: LovelaceDashboardCreateParams) => + hass.callWS({ + type: "lovelace/dashboards/create", + ...values, + }); + +export const updateDashboard = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "lovelace/dashboards/update", + dashboard_id: id, + ...updates, + }); + +export const deleteDashboard = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "lovelace/dashboards/delete", + dashboard_id: id, + }); + +export const fetchConfig = ( + conn: Connection, + urlPath: string | null, + force: boolean +): Promise => + conn.sendMessagePromise({ + type: "lovelace/config", + url_path: urlPath, + force, + }); + +export const saveConfig = ( + hass: HomeAssistant, + urlPath: string | null, + config: LovelaceConfig +): Promise => + hass.callWS({ + type: "lovelace/config/save", + url_path: urlPath, + config, + }); + +export const deleteConfig = (hass: HomeAssistant, urlPath: string | null): Promise => + hass.callWS({ + type: "lovelace/config/delete", + url_path: urlPath, + }); + +export const subscribeLovelaceUpdates = ( + conn: Connection, + urlPath: string | null, + onChange: () => void +) => + conn.subscribeEvents((ev) => { + if (ev.data.url_path === urlPath) { + onChange(); + } + }, "lovelace_updated"); + +export const getLovelaceCollection = (conn: Connection, urlPath: string | null = null) => + getCollection( + conn, + `_lovelace_${urlPath ?? ""}`, + (conn2) => fetchConfig(conn2, urlPath, false), + (_conn, store) => + subscribeLovelaceUpdates(conn, urlPath, () => + fetchConfig(conn, urlPath, false).then((config) => store.setState(config, true)) + ) + ); + +// Legacy functions to support cast for Home Assistion < 0.107 +const fetchLegacyConfig = (conn: Connection, force: boolean): Promise => + conn.sendMessagePromise({ + type: "lovelace/config", + force, + }); + +const subscribeLegacyLovelaceUpdates = (conn: Connection, onChange: () => void) => + conn.subscribeEvents(onChange, "lovelace_updated"); + +export const getLegacyLovelaceCollection = (conn: Connection) => + getCollection( + conn, + "_lovelace", + (conn2) => fetchLegacyConfig(conn2, false), + (_conn, store) => + subscribeLegacyLovelaceUpdates(conn, () => + fetchLegacyConfig(conn, false).then((config) => store.setState(config, true)) + ) + ); + +export interface WindowWithLovelaceProm extends Window { + llConfProm?: Promise; + llResProm?: Promise; +} + +export interface ActionHandlerOptions { + hasHold?: boolean; + hasDoubleClick?: boolean; + disabled?: boolean; +} + +export interface ActionHandlerDetail { + action: "hold" | "tap" | "double_tap"; +} + +export type ActionHandlerEvent = HASSDomEvent; diff --git a/src/ha/data/main_window.ts b/src/ha/data/main_window.ts new file mode 100644 index 000000000..2a6a6d3e3 --- /dev/null +++ b/src/ha/data/main_window.ts @@ -0,0 +1 @@ +export const MAIN_WINDOW_NAME = "ha-main-window"; diff --git a/src/ha/data/media-player.ts b/src/ha/data/media-player.ts index b0df75e93..986df623e 100644 --- a/src/ha/data/media-player.ts +++ b/src/ha/data/media-player.ts @@ -1,6 +1,5 @@ -import { HomeAssistant } from "custom-card-helpers"; import type { HassEntityAttributeBase, HassEntityBase } from "home-assistant-js-websocket"; -import { supportsFeature } from "../common/entity/supports-feature"; +import { HomeAssistant } from "../types"; interface MediaPlayerEntityAttributes extends HassEntityAttributeBase { media_content_id?: string; diff --git a/src/ha/data/translation.ts b/src/ha/data/translation.ts new file mode 100644 index 000000000..ad609d266 --- /dev/null +++ b/src/ha/data/translation.ts @@ -0,0 +1,38 @@ +export enum NumberFormat { + language = "language", + system = "system", + comma_decimal = "comma_decimal", + decimal_comma = "decimal_comma", + space_comma = "space_comma", + none = "none", +} + +export enum TimeFormat { + language = "language", + system = "system", + am_pm = "12", + twenty_four = "24", +} + +export interface FrontendLocaleData { + language: string; + number_format: NumberFormat; + time_format: TimeFormat; +} + +declare global { + interface FrontendUserData { + language: FrontendLocaleData; + } +} + +export type TranslationCategory = + | "title" + | "state" + | "config" + | "config_panel" + | "options" + | "device_automation" + | "mfa_setup" + | "system_health" + | "device_class"; diff --git a/src/ha/data/update.ts b/src/ha/data/update.ts index f89e4c766..a2376dc12 100644 --- a/src/ha/data/update.ts +++ b/src/ha/data/update.ts @@ -1,6 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import type { HassEntityAttributeBase, HassEntityBase } from "home-assistant-js-websocket"; import { supportsFeature } from "../common/entity/supports-feature"; +import { HomeAssistant } from "../types"; import { ON } from "./entity"; export const UPDATE_SUPPORT_INSTALL = 1; diff --git a/src/utils/ws-templates.ts b/src/ha/data/ws-templates.ts similarity index 100% rename from src/utils/ws-templates.ts rename to src/ha/data/ws-templates.ts diff --git a/src/ha/data/ws-themes.ts b/src/ha/data/ws-themes.ts new file mode 100644 index 000000000..900c8417e --- /dev/null +++ b/src/ha/data/ws-themes.ts @@ -0,0 +1,26 @@ +export interface ThemeVars { + // Incomplete + "primary-color": string; + "text-primary-color": string; + "accent-color": string; + [key: string]: string; +} + +export type Theme = ThemeVars & { + modes?: { + light?: ThemeVars; + dark?: ThemeVars; + }; +}; + +export interface Themes { + default_theme: string; + default_dark_theme: string | null; + themes: Record; + // Currently effective dark mode. Will never be undefined. If user selected "auto" + // in theme picker, this property will still contain either true or false based on + // what has been determined via system preferences and support from the selected theme. + darkMode: boolean; + // Currently globally active theme name + theme: string; +} diff --git a/src/ha/index.ts b/src/ha/index.ts new file mode 100644 index 000000000..febc8d234 --- /dev/null +++ b/src/ha/index.ts @@ -0,0 +1,49 @@ +export * from "./common/const"; +export * from "./common/datetime/format_date"; +export * from "./common/datetime/format_date_time"; +export * from "./common/datetime/format_time"; +export * from "./common/datetime/use_am_pm"; +export * from "./common/dom/fire_event"; +export * from "./common/dom/get_main_window"; +export * from "./common/entity/compute-domain"; +export * from "./common/entity/compute-state-display"; +export * from "./common/entity/compute-state-domain"; +export * from "./common/entity/supports-feature"; +export * from "./common/navigate"; +export * from "./common/number/format_number"; +export * from "./common/number/round"; +export * from "./common/structs/handle-errors"; +export * from "./common/translations/localize"; +export * from "./common/util/compute_rtl"; +export * from "./common/util/debounce"; +export * from "./common/util/deep-equal"; +export * from "./common/util/render-status"; +export * from "./data/climate"; +export * from "./data/cover"; +export * from "./data/entity"; +export * from "./data/fan"; +export * from "./data/haptics"; +export * from "./data/humidifier"; +export * from "./data/integration"; +export * from "./data/light"; +export * from "./data/lock"; +export * from "./data/lovelace"; +export * from "./data/main_window"; +export * from "./data/media-player"; +export * from "./data/translation"; +export * from "./data/update"; +export * from "./data/vacuum"; +export * from "./data/ws-templates"; +export * from "./data/ws-themes"; +export * from "./panels/lovelace/common/directives/action-handler-directive"; +export * from "./panels/lovelace/common/entity/toggle-entity"; +export * from "./panels/lovelace/common/entity/turn-on-off-entities"; +export * from "./panels/lovelace/common/entity/turn-on-off-entity"; +export * from "./panels/lovelace/common/handle-actions"; +export * from "./panels/lovelace/common/has-action"; +export * from "./panels/lovelace/common/validate-condition"; +export * from "./panels/lovelace/editor/structs/action-struct"; +export * from "./panels/lovelace/types"; +export * from "./resources/ha-sortable-styles"; +export * from "./types"; +export * from "./util"; diff --git a/src/utils/directives/action-handler-directive.ts b/src/ha/panels/lovelace/common/directives/action-handler-directive.ts similarity index 96% rename from src/utils/directives/action-handler-directive.ts rename to src/ha/panels/lovelace/common/directives/action-handler-directive.ts index 439dff24c..739452da1 100644 --- a/src/utils/directives/action-handler-directive.ts +++ b/src/ha/panels/lovelace/common/directives/action-handler-directive.ts @@ -1,8 +1,9 @@ import type { Ripple } from "@material/mwc-ripple"; -import { ActionHandlerDetail, ActionHandlerOptions, fireEvent } from "custom-card-helpers"; import { noChange } from "lit"; import { AttributePart, directive, Directive, DirectiveParameters } from "lit/directive.js"; -import { deepEqual } from "../deep-equal"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { deepEqual } from "../../../../common/util/deep-equal"; +import { ActionHandlerDetail, ActionHandlerOptions } from "../../../../data/lovelace"; const isTouch = "ontouchstart" in window || @@ -118,9 +119,9 @@ class ActionHandler extends HTMLElement implements ActionHandler { element.actionHandler = { options }; - // if (options.disabled) { - // return; - // } + if (options.disabled) { + return; + } element.actionHandler.start = (ev: Event) => { this.cancelled = false; diff --git a/src/ha/panels/lovelace/common/entity/toggle-entity.ts b/src/ha/panels/lovelace/common/entity/toggle-entity.ts new file mode 100644 index 000000000..c2c406da3 --- /dev/null +++ b/src/ha/panels/lovelace/common/entity/toggle-entity.ts @@ -0,0 +1,11 @@ +import { STATES_OFF } from "../../../../common/const"; +import { HomeAssistant, ServiceCallResponse } from "../../../../types"; +import { turnOnOffEntity } from "./turn-on-off-entity"; + +export const toggleEntity = ( + hass: HomeAssistant, + entityId: string +): Promise => { + const turnOn = STATES_OFF.includes(hass.states[entityId].state); + return turnOnOffEntity(hass, entityId, turnOn); +}; diff --git a/src/ha/panels/lovelace/common/entity/turn-on-off-entities.ts b/src/ha/panels/lovelace/common/entity/turn-on-off-entities.ts new file mode 100644 index 000000000..8a3442709 --- /dev/null +++ b/src/ha/panels/lovelace/common/entity/turn-on-off-entities.ts @@ -0,0 +1,41 @@ +import { STATES_OFF } from "../../../../common/const"; +import { computeDomain } from "../../../../common/entity/compute-domain"; +import { HomeAssistant } from "../../../../types"; + +export const turnOnOffEntities = ( + hass: HomeAssistant, + entityIds: string[], + turnOn = true +): void => { + const domainsToCall = {}; + entityIds.forEach((entityId) => { + if (STATES_OFF.includes(hass.states[entityId].state) === turnOn) { + const stateDomain = computeDomain(entityId); + const serviceDomain = ["cover", "lock"].includes(stateDomain) + ? stateDomain + : "homeassistant"; + + if (!(serviceDomain in domainsToCall)) { + domainsToCall[serviceDomain] = []; + } + domainsToCall[serviceDomain].push(entityId); + } + }); + + Object.keys(domainsToCall).forEach((domain) => { + let service; + switch (domain) { + case "lock": + service = turnOn ? "unlock" : "lock"; + break; + case "cover": + service = turnOn ? "open_cover" : "close_cover"; + break; + default: + service = turnOn ? "turn_on" : "turn_off"; + } + + const entities = domainsToCall[domain]; + hass.callService(domain, service, { entity_id: entities }); + }); +}; diff --git a/src/ha/panels/lovelace/common/entity/turn-on-off-entity.ts b/src/ha/panels/lovelace/common/entity/turn-on-off-entity.ts new file mode 100644 index 000000000..57389b9ad --- /dev/null +++ b/src/ha/panels/lovelace/common/entity/turn-on-off-entity.ts @@ -0,0 +1,32 @@ +import { computeDomain } from "../../../../common/entity/compute-domain"; +import { HomeAssistant, ServiceCallResponse } from "../../../../types"; + +export const turnOnOffEntity = ( + hass: HomeAssistant, + entityId: string, + turnOn = true +): Promise => { + const stateDomain = computeDomain(entityId); + const serviceDomain = stateDomain === "group" ? "homeassistant" : stateDomain; + + let service; + switch (stateDomain) { + case "lock": + service = turnOn ? "unlock" : "lock"; + break; + case "cover": + service = turnOn ? "open_cover" : "close_cover"; + break; + case "button": + case "input_button": + service = "press"; + break; + case "scene": + service = "turn_on"; + break; + default: + service = turnOn ? "turn_on" : "turn_off"; + } + + return hass.callService(serviceDomain, service, { entity_id: entityId }); +}; diff --git a/src/ha/panels/lovelace/common/handle-actions.ts b/src/ha/panels/lovelace/common/handle-actions.ts new file mode 100644 index 000000000..393729d7f --- /dev/null +++ b/src/ha/panels/lovelace/common/handle-actions.ts @@ -0,0 +1,173 @@ +import { fireEvent } from "../../../common/dom/fire_event"; +import { navigate } from "../../../common/navigate"; +import { forwardHaptic } from "../../../data/haptics"; +import { domainToName } from "../../../data/integration"; +import { ActionConfig } from "../../../data/lovelace"; +import { HomeAssistant } from "../../../types"; +import { toggleEntity } from "./entity/toggle-entity"; + +export const handleAction = async ( + node: HTMLElement, + hass: HomeAssistant, + config: { + entity?: string; + camera_image?: string; + hold_action?: ActionConfig; + tap_action?: ActionConfig; + double_tap_action?: ActionConfig; + }, + action: string +): Promise => { + let actionConfig: ActionConfig | undefined; + + if (action === "double_tap" && config.double_tap_action) { + actionConfig = config.double_tap_action; + } else if (action === "hold" && config.hold_action) { + actionConfig = config.hold_action; + } else if (action === "tap" && config.tap_action) { + actionConfig = config.tap_action; + } + + if (!actionConfig) { + actionConfig = { + action: "more-info", + }; + } + + if ( + actionConfig.confirmation && + (!actionConfig.confirmation.exemptions || + !actionConfig.confirmation.exemptions.some((e) => e.user === hass!.user!.id)) + ) { + forwardHaptic("warning"); + + let serviceName; + if (actionConfig.action === "call-service") { + const [domain, service] = actionConfig.service.split(".", 2); + const serviceDomains = hass.services; + if (domain in serviceDomains && service in serviceDomains[domain]) { + const localize = await hass.loadBackendTranslation("title"); + serviceName = `${domainToName(localize, domain)}: ${ + serviceDomains[domain][service].name || service + }`; + } + } + + if ( + !confirm( + actionConfig.confirmation.text || + hass.localize( + "ui.panel.lovelace.cards.actions.action_confirmation", + "action", + serviceName || + hass.localize( + "ui.panel.lovelace.editor.action-editor.actions." + + actionConfig.action + ) || + actionConfig.action + ) + ) + ) { + return; + } + } + + switch (actionConfig.action) { + case "more-info": { + if (config.entity || config.camera_image) { + fireEvent(node, "hass-more-info", { + entityId: config.entity ? config.entity : config.camera_image!, + }); + } else { + showToast(node, { + message: hass.localize("ui.panel.lovelace.cards.actions.no_entity_more_info"), + }); + forwardHaptic("failure"); + } + break; + } + case "navigate": + if (actionConfig.navigation_path) { + navigate(actionConfig.navigation_path); + } else { + showToast(node, { + message: hass.localize("ui.panel.lovelace.cards.actions.no_navigation_path"), + }); + forwardHaptic("failure"); + } + break; + case "url": { + if (actionConfig.url_path) { + window.open(actionConfig.url_path); + } else { + showToast(node, { + message: hass.localize("ui.panel.lovelace.cards.actions.no_url"), + }); + forwardHaptic("failure"); + } + break; + } + case "toggle": { + if (config.entity) { + toggleEntity(hass, config.entity!); + forwardHaptic("light"); + } else { + showToast(node, { + message: hass.localize("ui.panel.lovelace.cards.actions.no_entity_toggle"), + }); + forwardHaptic("failure"); + } + break; + } + case "call-service": { + if (!actionConfig.service) { + showToast(node, { + message: hass.localize("ui.panel.lovelace.cards.actions.no_service"), + }); + forwardHaptic("failure"); + return; + } + const [domain, service] = actionConfig.service.split(".", 2); + hass.callService( + domain, + service, + actionConfig.data ?? actionConfig.service_data, + actionConfig.target + ); + forwardHaptic("light"); + break; + } + case "fire-dom-event": { + fireEvent(node, "ll-custom", actionConfig); + } + } +}; + +interface ToastActionParams { + action: () => void; + text: string; +} +interface ShowToastParams { + message: string; + action?: ToastActionParams; + duration?: number; + dismissable?: boolean; +} +const showToast = (el: HTMLElement, params: ShowToastParams) => + fireEvent(el, "hass-notification", params); + +interface MoreInfoDialogParams { + entityId: string | null; +} + +declare global { + interface HASSDomEvents { + "hass-notification": ShowToastParams; + } + interface HASSDomEvents { + "hass-more-info": MoreInfoDialogParams; + } + interface HASSDomEvents { + "ll-custom": ActionConfig; + } +} diff --git a/src/ha/panels/lovelace/common/has-action.ts b/src/ha/panels/lovelace/common/has-action.ts new file mode 100644 index 000000000..60c85a5de --- /dev/null +++ b/src/ha/panels/lovelace/common/has-action.ts @@ -0,0 +1,5 @@ +import { ActionConfig } from "../../../data/lovelace"; + +export function hasAction(config?: ActionConfig): boolean { + return config !== undefined && config.action !== "none"; +} diff --git a/src/utils/conditional/validate-condition.ts b/src/ha/panels/lovelace/common/validate-condition.ts similarity index 81% rename from src/utils/conditional/validate-condition.ts rename to src/ha/panels/lovelace/common/validate-condition.ts index ca160d59a..6cf3107f8 100644 --- a/src/utils/conditional/validate-condition.ts +++ b/src/ha/panels/lovelace/common/validate-condition.ts @@ -1,4 +1,5 @@ -import { HomeAssistant } from "custom-card-helpers"; +import { UNAVAILABLE } from "../../../data/entity"; +import { HomeAssistant } from "../../../types"; export interface Condition { entity: string; @@ -8,7 +9,8 @@ export interface Condition { export function checkConditionsMet(conditions: Condition[], hass: HomeAssistant): boolean { return conditions.every((c) => { - const state = hass.states[c.entity] ? hass!.states[c.entity].state : "unavailable"; + const state = hass.states[c.entity] ? hass!.states[c.entity].state : UNAVAILABLE; + return c.state ? state === c.state : state !== c.state_not; }); } diff --git a/src/utils/action-struct.ts b/src/ha/panels/lovelace/editor/structs/action-struct.ts similarity index 60% rename from src/utils/action-struct.ts rename to src/ha/panels/lovelace/editor/structs/action-struct.ts index 3f22103c6..c8bc9511b 100644 --- a/src/utils/action-struct.ts +++ b/src/ha/panels/lovelace/editor/structs/action-struct.ts @@ -1,4 +1,16 @@ -import { object, string, union, boolean, optional, array, literal, enums, type } from "superstruct"; +import { + array, + boolean, + dynamic, + enums, + literal, + object, + optional, + string, + type, + union, +} from "superstruct"; +import { BaseActionConfig } from "../../../../data/lovelace"; const actionConfigStructUser = object({ user: string(), @@ -22,6 +34,7 @@ const actionConfigStructService = object({ action: literal("call-service"), service: string(), service_data: optional(object()), + data: optional(object()), target: optional( object({ entity_id: optional(union([string(), array(string())])), @@ -47,10 +60,23 @@ export const actionConfigStructType = object({ confirmation: optional(actionConfigStructConfirmation), }); -export const actionConfigStruct = union([ - actionConfigStructType, - actionConfigStructUrl, - actionConfigStructNavigate, - actionConfigStructService, - actionConfigStructCustom, -]); +export const actionConfigStruct = dynamic((value) => { + if (value && typeof value === "object" && "action" in value) { + switch ((value as BaseActionConfig).action!) { + case "call-service": { + return actionConfigStructService; + } + case "fire-dom-event": { + return actionConfigStructCustom; + } + case "navigate": { + return actionConfigStructNavigate; + } + case "url": { + return actionConfigStructUrl; + } + } + } + + return actionConfigStructType; +}); diff --git a/src/ha/panels/lovelace/types.ts b/src/ha/panels/lovelace/types.ts new file mode 100644 index 000000000..10bbcaece --- /dev/null +++ b/src/ha/panels/lovelace/types.ts @@ -0,0 +1,53 @@ +import { LovelaceCardConfig, LovelaceConfig } from "../../data/lovelace"; +import { FrontendLocaleData } from "../../data/translation"; +import { Constructor, HomeAssistant } from "../../types"; + +declare global { + // eslint-disable-next-line + interface HASSDomEvents { + "ll-rebuild": Record; + "ll-badge-rebuild": Record; + } +} + +export interface Lovelace { + config: LovelaceConfig; + // If not set, a strategy was used to generate everything + rawConfig: LovelaceConfig | undefined; + editMode: boolean; + urlPath: string | null; + mode: "generated" | "yaml" | "storage"; + locale: FrontendLocaleData; + enableFullEditMode: () => void; + setEditMode: (editMode: boolean) => void; + saveConfig: (newConfig: LovelaceConfig) => Promise; + deleteConfig: () => Promise; +} + +export interface LovelaceCard extends HTMLElement { + hass?: HomeAssistant; + isPanel?: boolean; + editMode?: boolean; + getCardSize(): number | Promise; + setConfig(config: LovelaceCardConfig): void; +} + +export interface LovelaceCardConstructor extends Constructor { + getStubConfig?: ( + hass: HomeAssistant, + entities: string[], + entitiesFallback: string[] + ) => LovelaceCardConfig; + getConfigElement?: () => LovelaceCardEditor; +} + +export interface LovelaceCardEditor extends LovelaceGenericElementEditor { + setConfig(config: LovelaceCardConfig): void; +} + +export interface LovelaceGenericElementEditor extends HTMLElement { + hass?: HomeAssistant; + lovelace?: LovelaceConfig; + setConfig(config: any): void; + focusYamlEditor?: () => void; +} diff --git a/src/utils/sortable-styles.ts b/src/ha/resources/ha-sortable-styles.ts similarity index 100% rename from src/utils/sortable-styles.ts rename to src/ha/resources/ha-sortable-styles.ts diff --git a/src/ha/types.ts b/src/ha/types.ts new file mode 100644 index 000000000..f6c275e2a --- /dev/null +++ b/src/ha/types.ts @@ -0,0 +1,182 @@ +import { + Auth, + Connection, + HassConfig, + HassEntities, + HassServices, + HassServiceTarget, + MessageBase, +} from "home-assistant-js-websocket"; +import { LocalizeFunc } from "./common/translations/localize"; +import { FrontendLocaleData, TranslationCategory } from "./data/translation"; +import { Themes } from "./data/ws-themes"; + +declare global { + /* eslint-disable no-var, no-redeclare */ + var __DEV__: boolean; + var __DEMO__: boolean; + var __BUILD__: "latest" | "es5"; + var __VERSION__: string; + var __STATIC_PATH__: string; + var __BACKWARDS_COMPAT__: boolean; + var __SUPERVISOR__: boolean; + /* eslint-enable no-var, no-redeclare */ + + interface Window { + // Custom panel entry point url + customPanelJS: string; + ShadyCSS: { + nativeCss: boolean; + nativeShadow: boolean; + prepareTemplate(templateElement, elementName, elementExtension); + styleElement(element); + styleSubtree(element, overrideProperties); + styleDocument(overrideProperties); + getComputedStyleValue(element, propertyName); + }; + } + // for fire event + interface HASSDomEvents { + "value-changed": { + value: unknown; + }; + change: undefined; + } + + // For loading workers in webpack + interface ImportMeta { + url: string; + } +} + +export interface ThemeSettings { + theme: string; + // Radio box selection for theme picker. Do not use in Lovelace rendering as + // it can be undefined == auto. + // Property hass.themes.darkMode carries effective current mode. + dark?: boolean; + primaryColor?: string; + accentColor?: string; +} + +export interface PanelInfo | null> { + component_name: string; + config: T; + icon: string | null; + title: string | null; + url_path: string; +} + +export interface Panels { + [name: string]: PanelInfo; +} + +export interface Resources { + [language: string]: Record; +} + +export interface Translation { + nativeName: string; + isRTL: boolean; + hash: string; +} + +export interface TranslationMetadata { + fragments: string[]; + translations: { + [lang: string]: Translation; + }; +} + +export interface Credential { + auth_provider_type: string; + auth_provider_id: string; +} + +export interface MFAModule { + id: string; + name: string; + enabled: boolean; +} + +export interface CurrentUser { + id: string; + is_owner: boolean; + is_admin: boolean; + name: string; + credentials: Credential[]; + mfa_modules: MFAModule[]; +} + +export interface ServiceCallRequest { + domain: string; + service: string; + serviceData?: Record; + target?: HassServiceTarget; +} + +export interface Context { + id: string; + parent_id?: string; + user_id?: string | null; +} + +export interface ServiceCallResponse { + context: Context; +} + +export interface HomeAssistant { + auth: Auth; + connection: Connection; + connected: boolean; + states: HassEntities; + services: HassServices; + config: HassConfig; + themes: Themes; + selectedTheme: ThemeSettings | null; + panels: Panels; + panelUrl: string; + // i18n + // current effective language in that order: + // - backend saved user selected language + // - language in local app storage + // - browser language + // - english (en) + language: string; + // local stored language, keep that name for backward compatibility + selectedLanguage: string | null; + locale: FrontendLocaleData; + resources: Resources; + localize: LocalizeFunc; + translationMetadata: TranslationMetadata; + suspendWhenHidden: boolean; + enableShortcuts: boolean; + vibrate: boolean; + dockedSidebar: "docked" | "always_hidden" | "auto"; + defaultPanel: string; + moreInfoEntityId: string | null; + user?: CurrentUser; + hassUrl(path?): string; + callService( + domain: ServiceCallRequest["domain"], + service: ServiceCallRequest["service"], + serviceData?: ServiceCallRequest["serviceData"], + target?: ServiceCallRequest["target"] + ): Promise; + callApi( + method: "GET" | "POST" | "PUT" | "DELETE", + path: string, + parameters?: Record, + headers?: Record + ): Promise; + fetchWithAuth(path: string, init?: Record): Promise; + sendWS(msg: MessageBase): void; + callWS(msg: MessageBase): Promise; + loadBackendTranslation( + category: TranslationCategory, + integration?: string | string[], + configFlow?: boolean + ): Promise; +} + +export type Constructor = new (...args: any[]) => T; diff --git a/src/localize.ts b/src/localize.ts index 403010501..99fd4e0ea 100644 --- a/src/localize.ts +++ b/src/localize.ts @@ -1,7 +1,4 @@ -// Borrowed from: -// https://github.com/custom-cards/boilerplate-card/blob/master/src/localize/localize.ts - -import { HomeAssistant } from "custom-card-helpers"; +import { HomeAssistant } from "./ha"; import * as de from "./translations/de.json"; import * as el from "./translations/el.json"; import * as en from "./translations/en.json"; diff --git a/src/shared/config/actions-config.ts b/src/shared/config/actions-config.ts index b6b3d5dac..5b1a7aaaa 100644 --- a/src/shared/config/actions-config.ts +++ b/src/shared/config/actions-config.ts @@ -1,6 +1,5 @@ -import { ActionConfig } from "custom-card-helpers"; import { object, optional } from "superstruct"; -import { actionConfigStruct } from "../../utils/action-struct"; +import { ActionConfig, actionConfigStruct } from "../../ha"; export const actionsSharedConfigStruct = object({ tap_action: optional(actionConfigStruct), @@ -8,7 +7,6 @@ export const actionsSharedConfigStruct = object({ double_tap_action: optional(actionConfigStruct), }); -// TODO : fix action config type and struct export type ActionsSharedConfig = { tap_action?: ActionConfig; hold_action?: ActionConfig; diff --git a/src/shared/config/lovelace-card-config.ts b/src/shared/config/lovelace-card-config.ts index c6eb62fdb..bcc1ca8df 100644 --- a/src/shared/config/lovelace-card-config.ts +++ b/src/shared/config/lovelace-card-config.ts @@ -6,11 +6,3 @@ export const lovelaceCardConfigStruct = object({ view_layout: any(), type: string(), }); - -export interface LovelaceCardConfig { - index?: number; - view_index?: number; - view_layout?: any; - type: string; - [key: string]: any; -} diff --git a/src/shared/editor/action-picker.ts b/src/shared/editor/action-picker.ts index 4e8939513..47a712d28 100644 --- a/src/shared/editor/action-picker.ts +++ b/src/shared/editor/action-picker.ts @@ -1,6 +1,6 @@ -import { ActionConfig, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { ActionConfig, HomeAssistant } from "../../ha"; const DEFAULT_ACTIONS = ["toggle", "more-info", "navigate", "url", "call-service", "none"]; diff --git a/src/shared/editor/alignment-picker.ts b/src/shared/editor/alignment-picker.ts index 4106534b0..a76005ca8 100644 --- a/src/shared/editor/alignment-picker.ts +++ b/src/shared/editor/alignment-picker.ts @@ -1,6 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { HomeAssistant } from "../../ha"; import setupCustomlocalize from "../../localize"; import "./../form/mushroom-select"; diff --git a/src/shared/editor/base-editor.ts b/src/shared/editor/base-editor.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/shared/editor/color-picker.ts b/src/shared/editor/color-picker.ts index 0ffbb4adb..a0679ca21 100644 --- a/src/shared/editor/color-picker.ts +++ b/src/shared/editor/color-picker.ts @@ -1,7 +1,7 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; import { styleMap } from "lit/directives/style-map.js"; +import { HomeAssistant } from "../../ha"; import setupCustomlocalize from "../../localize"; import { COLORS, computeColorName, computeRgbColor } from "../../utils/colors"; import "./../form/mushroom-select"; diff --git a/src/shared/editor/info-picker.ts b/src/shared/editor/info-picker.ts index c424afd7f..70142abd1 100644 --- a/src/shared/editor/info-picker.ts +++ b/src/shared/editor/info-picker.ts @@ -1,6 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { HomeAssistant } from "../../ha"; import setupCustomlocalize from "../../localize"; import { Info, INFOS } from "../../utils/info"; import "./../form/mushroom-select"; diff --git a/src/shared/editor/layout-picker.ts b/src/shared/editor/layout-picker.ts index 151a56fee..fdc9f0ff7 100644 --- a/src/shared/editor/layout-picker.ts +++ b/src/shared/editor/layout-picker.ts @@ -1,6 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { HomeAssistant } from "../../ha"; import setupCustomlocalize from "../../localize"; import "./../form/mushroom-select"; diff --git a/src/shared/form/mushroom-select.ts b/src/shared/form/mushroom-select.ts index 34538bbea..a63ba04a2 100644 --- a/src/shared/form/mushroom-select.ts +++ b/src/shared/form/mushroom-select.ts @@ -2,8 +2,7 @@ import { SelectBase } from "@material/mwc-select/mwc-select-base"; import { styles } from "@material/mwc-select/mwc-select.css"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators.js"; -import { debounce } from "../../utils/debounce"; -import { nextRender } from "../../utils/render-status"; +import { debounce, nextRender } from "../../ha"; @customElement("mushroom-select") export class MushroomSelect extends SelectBase { diff --git a/src/utils/base-element.ts b/src/utils/base-element.ts index f4406ce51..2474ee00e 100644 --- a/src/utils/base-element.ts +++ b/src/utils/base-element.ts @@ -1,6 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, LitElement, PropertyValues } from "lit"; import { property } from "lit/decorators.js"; +import { HomeAssistant } from "../ha"; import "../shared/badge-icon"; import "../shared/card"; import "../shared/shape-avatar"; diff --git a/src/utils/conditional/conditional-base.ts b/src/utils/conditional/conditional-base.ts index 92964960d..45fdbe694 100644 --- a/src/utils/conditional/conditional-base.ts +++ b/src/utils/conditional/conditional-base.ts @@ -1,9 +1,13 @@ -import { HomeAssistant, LovelaceCard } from "custom-card-helpers"; import { PropertyValues, ReactiveElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { + checkConditionsMet, + HomeAssistant, + LovelaceCard, + validateConditionalConfig, +} from "../../ha"; import { ConditionalChipConfig, LovelaceChip } from "../lovelace/chip/types"; import { ConditionalCardConfig } from "../lovelace/types"; -import { checkConditionsMet, validateConditionalConfig } from "./validate-condition"; @customElement("mushroom-conditional-base") export class ConditionalBase extends ReactiveElement { diff --git a/src/utils/deep-equal.ts b/src/utils/deep-equal.ts deleted file mode 100644 index a272c04df..000000000 --- a/src/utils/deep-equal.ts +++ /dev/null @@ -1,107 +0,0 @@ -// From https://github.com/epoberezkin/fast-deep-equal -// MIT License - Copyright (c) 2017 Evgeny Poberezkin -export const deepEqual = (a: any, b: any): boolean => { - if (a === b) { - return true; - } - - if (a && b && typeof a === "object" && typeof b === "object") { - if (a.constructor !== b.constructor) { - return false; - } - - let i: number | [any, any]; - let length: number; - if (Array.isArray(a)) { - length = a.length; - if (length !== b.length) { - return false; - } - for (i = length; i-- !== 0; ) { - if (!deepEqual(a[i], b[i])) { - return false; - } - } - return true; - } - - if (a instanceof Map && b instanceof Map) { - if (a.size !== b.size) { - return false; - } - for (i of a.entries()) { - if (!b.has(i[0])) { - return false; - } - } - for (i of a.entries()) { - if (!deepEqual(i[1], b.get(i[0]))) { - return false; - } - } - return true; - } - - if (a instanceof Set && b instanceof Set) { - if (a.size !== b.size) { - return false; - } - for (i of a.entries()) { - if (!b.has(i[0])) { - return false; - } - } - return true; - } - - if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { - // @ts-ignore - length = a.length; - // @ts-ignore - if (length !== b.length) { - return false; - } - for (i = length; i-- !== 0; ) { - if (a[i] !== b[i]) { - return false; - } - } - return true; - } - - if (a.constructor === RegExp) { - return a.source === b.source && a.flags === b.flags; - } - if (a.valueOf !== Object.prototype.valueOf) { - return a.valueOf() === b.valueOf(); - } - if (a.toString !== Object.prototype.toString) { - return a.toString() === b.toString(); - } - - const keys = Object.keys(a); - length = keys.length; - if (length !== Object.keys(b).length) { - return false; - } - for (i = length; i-- !== 0; ) { - if (!Object.prototype.hasOwnProperty.call(b, keys[i])) { - return false; - } - } - - for (i = length; i-- !== 0; ) { - const key = keys[i]; - - if (!deepEqual(a[key], b[key])) { - return false; - } - } - - return true; - } - - // true if both NaN, false otherwise - // eslint-disable-next-line no-self-compare - return a !== a && b !== b; -}; diff --git a/src/utils/error-struct.ts b/src/utils/error-struct.ts deleted file mode 100644 index b5e60d6a8..000000000 --- a/src/utils/error-struct.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { HomeAssistant } from "custom-card-helpers"; -import { StructError } from "superstruct"; - -export const handleStructError = ( - hass: HomeAssistant, - err: Error -): { warnings: string[]; errors?: string[] } => { - if (!(err instanceof StructError)) { - return { warnings: [err.message], errors: undefined }; - } - const errors: string[] = []; - const warnings: string[] = []; - for (const failure of err.failures()) { - if (failure.value === undefined) { - errors.push( - hass.localize("ui.errors.config.key_missing", "key", failure.path.join(".")) - ); - } else if (failure.type === "never") { - warnings.push( - hass.localize("ui.errors.config.key_not_expected", "key", failure.path.join(".")) - ); - } else if (failure.type === "union") { - continue; - } else if (failure.type === "enums") { - warnings.push( - hass.localize( - "ui.errors.config.key_wrong_type", - "key", - failure.path.join("."), - "type_correct", - failure.message.replace("Expected ", "").split(", ")[0], - "type_wrong", - JSON.stringify(failure.value) - ) - ); - } else { - warnings.push( - hass.localize( - "ui.errors.config.key_wrong_type", - "key", - failure.path.join("."), - "type_correct", - failure.refinement || failure.type, - "type_wrong", - JSON.stringify(failure.value) - ) - ); - } - } - return { warnings, errors }; -}; diff --git a/src/utils/form/custom/ha-selector-mushroom-action.ts b/src/utils/form/custom/ha-selector-mushroom-action.ts index 801c72a96..31cb9c630 100644 --- a/src/utils/form/custom/ha-selector-mushroom-action.ts +++ b/src/utils/form/custom/ha-selector-mushroom-action.ts @@ -1,6 +1,6 @@ -import { ActionConfig, fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { ActionConfig, fireEvent, HomeAssistant } from "../../../ha"; import "../../../shared/editor/action-picker"; export type Action = ActionConfig["action"]; diff --git a/src/utils/form/custom/ha-selector-mushroom-alignment.ts b/src/utils/form/custom/ha-selector-mushroom-alignment.ts index adcf00b79..27fc5b46f 100644 --- a/src/utils/form/custom/ha-selector-mushroom-alignment.ts +++ b/src/utils/form/custom/ha-selector-mushroom-alignment.ts @@ -1,6 +1,6 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { fireEvent, HomeAssistant } from "../../../ha"; import "../../../shared/editor/alignment-picker"; export type MushAlignementSelector = { diff --git a/src/utils/form/custom/ha-selector-mushroom-color.ts b/src/utils/form/custom/ha-selector-mushroom-color.ts index 1b9a80b80..e0f54f457 100644 --- a/src/utils/form/custom/ha-selector-mushroom-color.ts +++ b/src/utils/form/custom/ha-selector-mushroom-color.ts @@ -1,6 +1,6 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { fireEvent, HomeAssistant } from "../../../ha"; import "../../../shared/editor/color-picker"; export type MushColorSelector = { diff --git a/src/utils/form/custom/ha-selector-mushroom-info.ts b/src/utils/form/custom/ha-selector-mushroom-info.ts index b4678ef50..293d55fad 100644 --- a/src/utils/form/custom/ha-selector-mushroom-info.ts +++ b/src/utils/form/custom/ha-selector-mushroom-info.ts @@ -1,6 +1,6 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { fireEvent, HomeAssistant } from "../../../ha"; import "../../../shared/editor/info-picker"; import { Info } from "../../info"; diff --git a/src/utils/form/custom/ha-selector-mushroom-layout.ts b/src/utils/form/custom/ha-selector-mushroom-layout.ts index db94fb49e..fc3eae211 100644 --- a/src/utils/form/custom/ha-selector-mushroom-layout.ts +++ b/src/utils/form/custom/ha-selector-mushroom-layout.ts @@ -1,6 +1,6 @@ -import { fireEvent, HomeAssistant } from "custom-card-helpers"; import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { fireEvent, HomeAssistant } from "../../../ha"; import "../../../shared/editor/layout-picker"; export type MushLayoutSelector = { diff --git a/src/utils/icons/domain-icon.ts b/src/utils/icons/domain-icon.ts index b3474bbaf..258f57647 100644 --- a/src/utils/icons/domain-icon.ts +++ b/src/utils/icons/domain-icon.ts @@ -1,5 +1,5 @@ import { HassEntity } from "home-assistant-js-websocket"; -import { UpdateEntity, updateIsInstalling } from "../../ha/data/update"; +import { UpdateEntity, updateIsInstalling } from "../../ha"; import { alarmPanelIcon } from "./alarm-panel-icon"; import { binarySensorIcon } from "./binary-sensor-icon"; import { coverIcon } from "./cover-icon"; diff --git a/src/utils/icons/sensor-icon.ts b/src/utils/icons/sensor-icon.ts index b86735227..4306d863b 100644 --- a/src/utils/icons/sensor-icon.ts +++ b/src/utils/icons/sensor-icon.ts @@ -1,5 +1,5 @@ -import { UNIT_C, UNIT_F } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; +import { UNIT_C, UNIT_F } from "../../ha"; const FIXED_DEVICE_CLASS_ICONS = { apparent_power: "mdi:flash", diff --git a/src/utils/icons/state-icon.ts b/src/utils/icons/state-icon.ts index 9ab1f4b29..951970d6a 100644 --- a/src/utils/icons/state-icon.ts +++ b/src/utils/icons/state-icon.ts @@ -1,5 +1,5 @@ -import { computeDomain } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; +import { computeDomain } from "../../ha"; import { domainIcon } from "./domain-icon"; export function stateIcon(entity: HassEntity): string { diff --git a/src/utils/info.ts b/src/utils/info.ts index 575537e81..9f6e68916 100644 --- a/src/utils/info.ts +++ b/src/utils/info.ts @@ -1,7 +1,6 @@ -import { HomeAssistant } from "custom-card-helpers"; import { HassEntity } from "home-assistant-js-websocket"; import { html } from "lit"; -import { isAvailable, isUnknown } from "../ha/data/entity"; +import { HomeAssistant, isAvailable, isUnknown } from "../ha"; export const INFOS = ["name", "state", "last-changed", "last-updated", "none"] as const; const TIMESTAMP_STATE_DOMAINS = ["button", "input_button", "scene"]; diff --git a/src/utils/lovelace/chip/types.ts b/src/utils/lovelace/chip/types.ts index e55f05208..3c8fd6751 100644 --- a/src/utils/lovelace/chip/types.ts +++ b/src/utils/lovelace/chip/types.ts @@ -1,5 +1,4 @@ -import { ActionConfig, HomeAssistant } from "custom-card-helpers"; -import { Condition } from "../../conditional/validate-condition"; +import { ActionConfig, Condition, HomeAssistant } from "../../../ha"; import { Info } from "../../info"; export interface LovelaceChip extends HTMLElement { diff --git a/src/utils/lovelace/editor/types.ts b/src/utils/lovelace/editor/types.ts index 991a377ab..af13fde91 100644 --- a/src/utils/lovelace/editor/types.ts +++ b/src/utils/lovelace/editor/types.ts @@ -1,10 +1,4 @@ -import { - ActionConfig, - EntityConfig, - LovelaceCardConfig, - LovelaceViewConfig, - ShowViewConfig, -} from "custom-card-helpers"; +import { ActionConfig, LovelaceCardConfig, LovelaceViewConfig, ShowViewConfig } from "../../../ha"; import { LovelaceChipConfig } from "../chip/types"; export interface YamlChangedEvent extends Event { @@ -38,6 +32,14 @@ export interface ConfigError { message: string; } +export interface EntityConfig { + entity: string; + type?: string; + name?: string; + icon?: string; + image?: string; +} + export interface EntitiesEditorEvent { detail?: { entities?: EntityConfig[]; diff --git a/src/utils/lovelace/element-editor.ts b/src/utils/lovelace/element-editor.ts index 430414086..7e2f4b35e 100644 --- a/src/utils/lovelace/element-editor.ts +++ b/src/utils/lovelace/element-editor.ts @@ -1,19 +1,19 @@ import { dump, load } from "js-yaml"; import { css, CSSResultGroup, html, LitElement, PropertyValues, TemplateResult } from "lit"; -import { property, state, query } from "lit/decorators.js"; -import { LovelaceGenericElementEditor } from "./types"; -import { deepEqual } from "../deep-equal"; +import { property, query, state } from "lit/decorators.js"; import { computeRTL, + deepEqual, fireEvent, + handleStructError, HomeAssistant, LovelaceCardConfig, LovelaceConfig, -} from "custom-card-helpers"; +} from "../../ha"; import { LovelaceChipConfig } from "./chip/types"; import { EditSubElementEvent, GUIModeChangedEvent } from "./editor/types"; import { GUISupportError } from "./gui-support-error"; -import { handleStructError } from "../error-struct"; +import { LovelaceGenericElementEditor } from "./types"; export interface ConfigChangedEvent { config: LovelaceCardConfig | LovelaceChipConfig; diff --git a/src/utils/lovelace/sub-element-editor.ts b/src/utils/lovelace/sub-element-editor.ts index 22f65c17c..83095f88c 100644 --- a/src/utils/lovelace/sub-element-editor.ts +++ b/src/utils/lovelace/sub-element-editor.ts @@ -1,11 +1,11 @@ -import { fireEvent, HASSDomEvent, HomeAssistant } from "custom-card-helpers"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property, state, query } from "lit/decorators.js"; +import { customElement, property, query, state } from "lit/decorators.js"; +import { fireEvent, HASSDomEvent, HomeAssistant } from "../../ha"; +import setupCustomlocalize from "../../localize"; +import "./chip-element-editor"; import { LovelaceChipConfig } from "./chip/types"; import { GUIModeChangedEvent, SubElementEditorConfig } from "./editor/types"; import type { MushroomElementEditor } from "./element-editor"; -import "./chip-element-editor"; -import setupCustomlocalize from "../../localize"; declare global { interface HASSDomEvents { diff --git a/src/utils/lovelace/types.ts b/src/utils/lovelace/types.ts index cfed9ab8c..bda09303c 100644 --- a/src/utils/lovelace/types.ts +++ b/src/utils/lovelace/types.ts @@ -1,5 +1,4 @@ -import { HomeAssistant, LovelaceCardConfig, LovelaceConfig } from "custom-card-helpers"; -import { Condition } from "../conditional/validate-condition"; +import { Condition, HomeAssistant, LovelaceCardConfig, LovelaceConfig } from "../../ha"; import { LovelaceChipConfig } from "./chip/types"; export interface LovelaceChipEditor extends LovelaceGenericElementEditor {