UNPKG

meteoalarm-card

Version:

Meteoalarm card for Home Assistant Lovelace UI

344 lines (310 loc) 10.7 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import { ScopedRegistryHost } from '@lit-labs/scoped-registry-mixin'; import { EntityConfig, fireEvent, HomeAssistant, LovelaceCardEditor } from 'custom-card-helpers'; import { css, CSSResultGroup, html, LitElement, TemplateResult } from 'lit'; import { customElement, property, state } from 'lit/decorators'; import { formfieldDefinition } from '../elements/formfield'; import { selectDefinition } from '../elements/select'; import { switchDefinition } from '../elements/switch'; import { textfieldDefinition } from '../elements/textfield'; import { generateEditorWarnings } from './editor-warnings'; import { processEditorEntities } from './helpers/process-editor-entities'; import { localize } from './localize/localize'; import { MeteoalarmCard } from './meteoalarm-card'; import { MeteoalarmCardConfig, MeteoalarmIntegrationEntityType, MeteoalarmScalingMode, } from './types'; @customElement('meteoalarm-card-editor') export class MeteoalarmCardCardEditor extends ScopedRegistryHost(LitElement) implements LovelaceCardEditor { @property({ attribute: false }) public hass?: HomeAssistant; @state() private _config?: MeteoalarmCardConfig; @state() private _helpers?: any; private _initialized = false; @state() private _configEntities?: EntityConfig[]; static elementDefinitions = { ...textfieldDefinition, ...selectDefinition, ...switchDefinition, ...formfieldDefinition, }; public setConfig(config: MeteoalarmCardConfig): void { this._config = config; this._configEntities = processEditorEntities(config.entities!); } protected firstUpdated(): void { this.loadLovelaceElements(); } protected shouldUpdate(): boolean { if (!this._initialized) { this._initialize(); } return true; } get _integration(): string { return this._config?.integration || ''; } get _override_headline(): boolean { return this._config?.override_headline || false; } get _hide_when_no_warning(): boolean { return this._config?.hide_when_no_warning || false; } get _hide_caption(): boolean { return this._config?.hide_caption || false; } get _disable_swiper(): boolean { return this._config?.disable_swiper || false; } get _scaling_mode(): string { return this._config?.scaling_mode || 'headline_and_scale'; } protected render(): TemplateResult | void { if (!this.hass) { return html``; } const integration = MeteoalarmCard.integrations.find( (i) => i.metadata.key === this._integration, ); return html` <!-- Warnings--> ${generateEditorWarnings(integration, this._configEntities)} <!-- Integration select --> <mwc-select naturalMenuWidth fixedMenuPosition label=${`${localize('editor.integration')} (${localize('editor.required')})`} .configValue=${'integration'} .value=${this._integration} @selected=${this._valueChanged} @closed=${(ev) => ev.stopPropagation()} > ${MeteoalarmCard.integrations.map((integration) => { return html`<mwc-list-item .value=${integration.metadata.key} >${integration.metadata.name}</mwc-list-item >`; })} </mwc-select> <!-- Entity selector --> ${integration?.metadata.type == MeteoalarmIntegrationEntityType.SingleEntity ? html` <ha-entity-picker label=${`${localize('editor.entity')} (${localize('editor.required')})`} allow-custom-entity hideClearIcon .hass=${this.hass} .configValue=${'entities'} .value=${(this._configEntities?.length || 0) > 0 ? this._configEntities![0].entity : ''} @value-changed=${this._valueChanged} ></ha-entity-picker> ` : html` <h3>${localize('editor.entity')} (${localize('editor.required')})</h3> <p> ${localize('editor.description.start')} ${' '} ${integration?.metadata.type == MeteoalarmIntegrationEntityType.CurrentExpected ? html` ${localize('editor.description.current_expected')}</p> ` : ''} ${integration?.metadata.type == MeteoalarmIntegrationEntityType.Slots ? html` ${localize('editor.description.slots')}</p> ` : ''} ${integration?.metadata.type == MeteoalarmIntegrationEntityType.WarningWatchStatementAdvisory ? html` ${localize('editor.description.warning_watch_statement_advisory')}</p> ` : ''} ${integration?.metadata.type == MeteoalarmIntegrationEntityType.SeparateEvents ? html` ${localize('editor.description.separate_events')}</p> ` : ''} ${' '} ${localize('editor.description.end')} </p> <hui-entity-editor .label=${' '} .hass=${this.hass} .entities=${this._configEntities} @entities-changed=${this._entitiesChanged} ></hui-entity-editor> `} <!-- Switches section --> <div class="options"> <!-- Disable slider --> ${integration?.metadata.returnMultipleAlerts ? html` <mwc-formfield .label=${localize('editor.disable_swiper')}> <mwc-switch .checked=${this._disable_swiper !== false} .configValue=${'disable_swiper'} @change=${this._valueChanged} ></mwc-switch> </mwc-formfield> ` : ''} <!-- Override headline --> ${integration?.metadata.returnHeadline ? html` <mwc-formfield .label=${localize('editor.override_headline')}> <mwc-switch .checked=${this._override_headline !== false} .configValue=${'override_headline'} @change=${this._valueChanged} ></mwc-switch> </mwc-formfield> ` : ''} <!-- Hide caption --> ${integration?.metadata.type == MeteoalarmIntegrationEntityType.CurrentExpected ? html` <mwc-formfield .label=${localize('editor.hide_caption')}> <mwc-switch .checked=${this._hide_caption !== false} .configValue=${'hide_caption'} @change=${this._valueChanged} ></mwc-switch> </mwc-formfield> ` : ''} <!-- Hide when no warning --> <mwc-formfield .label=${localize('editor.hide_when_no_warning')}> <mwc-switch .checked=${this._hide_when_no_warning !== false} .configValue=${'hide_when_no_warning'} @change=${this._valueChanged} ></mwc-switch> </mwc-formfield> </div> <!-- Card scaling mode select --> <div class="options"> <div> <mwc-select naturalMenuWidth fixedMenuPosition label=${`${localize('editor.scaling_mode')}`} .configValue=${'scaling_mode'} .value=${this._scaling_mode} @selected=${this._valueChanged} @closed=${(ev) => ev.stopPropagation()} > ${Object.values(MeteoalarmScalingMode).map((mode) => { return html` <mwc-list-item .value=${mode}> ${localize(`editor.scaling_mode_options.${mode}`)} </mwc-list-item>`; })} </mwc-select> <a href="https://github.com/MrBartusek/MeteoalarmCard/blob/master/dosc/scaling-mode.md" target="_blank" > Scaling mode documentation </a> </div> </div> `; } private _initialize(): void { if (this.hass === undefined) return; if (this._config === undefined) return; if (this._helpers === undefined) return; this._initialized = true; } private async loadLovelaceElements(): Promise<void> { // This function load card helpers and pre-loads all pre-made // custom elements from Lovelace like ha-entity-picker // Read more on why and code explanation: // Pre-loading elements: // https://github.com/thomasloven/hass-config/wiki/PreLoading-Lovelace-Elements // Pre-loading elements in ScopedRegistryHost: // https://gist.github.com/thomasloven/5f965bd26e5f69876890886c09dd9ba8 const registry = (this.shadowRoot as any)?.customElements; if (!registry) return; if (registry.get('ha-entity-picker')) return; this._helpers = await (window as any).loadCardHelpers(); const entitiesCard = await this._helpers.createCardElement({ type: 'entities', entities: [] }); await entitiesCard.constructor.getConfigElement(); const glanceCard = await this._helpers.createCardElement({ type: 'glance', entities: [] }); await glanceCard.constructor.getConfigElement(); registry.define('ha-entity-picker', window.customElements.get('ha-entity-picker')); registry.define('hui-entity-editor', window.customElements.get('hui-entity-editor')); registry.define('ha-alert', window.customElements.get('ha-alert')); } private _valueChanged(ev): void { if (!this._config || !this.hass) { return; } const target = ev.target; if (this[`_${target.configValue}`] === target.value) { return; } if (target.configValue) { if (target.value === '') { const tmpConfig = { ...this._config }; delete tmpConfig[target.configValue]; this._config = tmpConfig; } else { // Set value to config this._config = { ...this._config, [target.configValue]: target.checked !== undefined ? target.checked : target.value, }; // Convert entity format this._config = { ...this._config, entities: processEditorEntities(this._config.entities), }; const integration = MeteoalarmCard.integrations.find( (i) => i.metadata.key === this._integration, ); if (integration?.metadata.type == MeteoalarmIntegrationEntityType.SingleEntity) { const entities = this._config.entities as EntityConfig[]; this._config.entities = [entities[0]]; } } } fireEvent(this, 'config-changed', { config: this._config }); } private _entitiesChanged(ev: CustomEvent): void { // Change in entities from multiple entities selector let config = this._config!; config = { ...config, entities: ev.detail.entities! }; this._configEntities = processEditorEntities(this._config!.entities!); fireEvent(this, 'config-changed', { config }); } static styles: CSSResultGroup = css` mwc-select, mwc-textfield, ha-entity-picker, hui-entity-editor, ha-alert { margin-bottom: 16px; display: block; } mwc-formfield { padding-bottom: 8px; } mwc-switch { --mdc-theme-secondary: var(--switch-checked-color); --mdc-theme-surface: #999999; } .options { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin: 24px 0; } p { max-width: 600px; } `; }