diff --git a/src/components/viewer.ts b/src/components/viewer.ts index 72475a53..5f3c3d39 100644 --- a/src/components/viewer.ts +++ b/src/components/viewer.ts @@ -4,7 +4,7 @@ import { EmblaCarouselType } from 'embla-carousel'; import { HomeAssistant } from 'custom-card-helpers'; import { createRef, Ref, ref } from 'lit/directives/ref.js'; import { customElement, property } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { until } from 'lit/directives/until.js'; import type { diff --git a/src/editor.ts b/src/editor.ts index 22311120..4e14fcb7 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { CSSResultGroup, LitElement, TemplateResult, html, unsafeCSS } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { HomeAssistant, LovelaceCardEditor, fireEvent } from 'custom-card-helpers'; import { localize } from './localize/localize.js'; @@ -165,6 +166,111 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor return entities; } + /** + * Render an option set header + * @param optionSetName The name of the EditorOptionsSet. + * @returns A rendered template. + */ + protected _renderOptionSetHeader(optionSetName: string): TemplateResult { + const optionSet = options[optionSetName]; + + return html` +
+
+ +
${optionSet.name}
+
+
${optionSet.secondary}
+
+ `; + } + + /** + * Render a dropdown menu. + * @param configPath The configuration path to set/read. + * @param dropdown The downdown in an array or key/value dictionary. + * @returns A rendered template. + */ + protected _renderDropdown( + configPath: string, + dropdown: string[] | Record, + ): TemplateResult | void { + if (!this._config) { + return; + } + const keys = Array.isArray(dropdown) ? dropdown : Object.keys(dropdown); + + return html` + + + ${keys.map( + (key) => html` + ${Array.isArray(dropdown) ? key : dropdown[key]} + `, + )} + + + `; + } + + /** + * Render a string input field. + * @param configPath The configuration path to set/read. + * @param allowedPattern An allowed input pattern. + * @returns A rendered template. + */ + protected _renderStringInput( + configPath: string, + allowedPattern?: string, + ): TemplateResult | void { + if (!this._config) { + return; + } + return html` `; + } + + /** + * Render a switch. + * @param configPath The configuration path to set/read. + * @param valueDefault The default switch value if unset. + * @param label An optional switch label. + * @returns A rendered template. + */ + protected _renderSwitch( + configPath: string, + valueDefault: boolean, + label?: string, + ): TemplateResult | void { + if (!this._config) { + return; + } + return html` + + `; + } + protected render(): TemplateResult | void { if (!this.hass || !this._helpers || !this._config) { return html``; @@ -233,16 +339,19 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor none: localize('config.event_viewer.controls.thumbnails.modes.none'), above: localize('config.event_viewer.controls.thumbnails.modes.above'), below: localize('config.event_viewer.controls.thumbnails.modes.below'), - } + }; const thumbnailMedias = { '': '', clips: localize('config.live.controls.thumbnails.medias.clips'), snapshots: localize('config.live.controls.thumbnails.medias.snapshots'), - } + }; const defaults = frigateCardConfigDefaults; + const getShowButtonLabel = (configPath: string) => + localize('editor.show_button') + ': ' + localize(`config.${configPath}`); + return html` ${this._configUpgradeable ? html`
@@ -268,606 +377,143 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
` : html``}
-
-
- -
${options.basic.name}
-
-
${options.basic.secondary}
-
+ ${this._renderOptionSetHeader('basic')} ${options.basic.show ? html`
- - - ${cameraEntities.map((entity) => { - return html` ${entity} `; - })} - - + ${this._renderDropdown(CONF_CAMERA_ENTITY, cameraEntities)}
` : ''} -
-
- -
${options.frigate.name}
-
-
${options.frigate.secondary}
-
+ ${this._renderOptionSetHeader('frigate')} ${options.frigate.show ? html`
- - - - - + ${this._renderStringInput(CONF_FRIGATE_CAMERA_NAME)} + ${this._renderStringInput(CONF_FRIGATE_URL)} + ${this._renderStringInput(CONF_FRIGATE_LABEL)} + ${this._renderStringInput(CONF_FRIGATE_ZONE)} + ${this._renderStringInput(CONF_FRIGATE_CLIENT_ID)}
` : ''} -
-
- -
${options.view.name}
-
-
${options.view.secondary}
-
+ ${this._renderOptionSetHeader('view')} ${options.view.show ? html`
- - - ${Object.keys(viewModes).map((key) => { - return html` - ${viewModes[key]} - `; - })} - - - + ${this._renderDropdown(CONF_VIEW_DEFAULT, viewModes)} + ${this._renderStringInput(CONF_VIEW_TIMEOUT, '[0-9]')}
` : ''} -
-
- -
${options.menu.name}
-
-
${options.menu.secondary}
-
+ ${this._renderOptionSetHeader('menu')} ${options.menu.show ? html`
- - - ${Object.keys(menuModes).map((key) => { - return html` - ${menuModes[key]} - `; - })} - - - - - - - - - - - - - - - - - - - - - - - - - - - + ${this._renderDropdown(CONF_MENU_MODE, menuModes)} + ${this._renderStringInput(CONF_MENU_BUTTON_SIZE)} + ${this._renderSwitch( + CONF_MENU_BUTTONS_FRIGATE, + defaults.menu.buttons.frigate, + getShowButtonLabel(CONF_MENU_BUTTONS_FRIGATE), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_LIVE, + defaults.menu.buttons.live, + getShowButtonLabel('view.views.live'), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_CLIPS, + defaults.menu.buttons.clips, + getShowButtonLabel('view.views.clips'), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_SNAPSHOTS, + defaults.menu.buttons.snapshots, + getShowButtonLabel('view.views.snapshots'), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_IMAGE, + defaults.menu.buttons.image, + getShowButtonLabel('view.views.image'), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_FRIGATE_DOWNLOAD, + defaults.menu.buttons.download, + getShowButtonLabel(CONF_MENU_BUTTONS_FRIGATE_DOWNLOAD), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_FRIGATE_UI, + defaults.menu.buttons.frigate_ui, + getShowButtonLabel(CONF_MENU_BUTTONS_FRIGATE_UI), + )} + ${this._renderSwitch( + CONF_MENU_BUTTONS_FRIGATE_FULLSCREEN, + defaults.menu.buttons.fullscreen, + getShowButtonLabel(CONF_MENU_BUTTONS_FRIGATE_FULLSCREEN), + )}
` : ''} -
-
- -
${options.live.name}
-
-
${options.live.secondary}
-
+ ${this._renderOptionSetHeader('live')} ${options.live.show ? html`
-
- - - - - - ${Object.keys(liveProviders).map((key) => { - return html` - ${liveProviders[key]} - `; - })} - - - - - ${cameraEntities.map((entity) => { - return html` ${entity} `; - })} - - - - - - ${Object.keys(thumbnailModes).map((key) => { - return html` - - ${thumbnailModes[key]} - - `; - })} - - - - - ${Object.keys(thumbnailMedias).map((key) => { - return html` - - ${thumbnailMedias[key]} - - `; - })} - - - + ${this._renderStringInput(CONF_LIVE_CONTROLS_THUMBNAILS_SIZE)}
` : ''} -
-
- -
${options.event_viewer.name}
-
-
${options.event_viewer.secondary}
-
+ ${this._renderOptionSetHeader('event_viewer')} ${options.event_viewer.show ? html`
-
- - - - - - - - - - - - ${Object.keys(eventViewerNextPreviousControlStyles).map((key) => { - return html` - - ${eventViewerNextPreviousControlStyles[key]} - - `; - })} - - - - - - ${Object.keys(thumbnailModes).map((key) => { - return html` - - ${thumbnailModes[key]} - - `; - })} - - - + ${this._renderSwitch( + CONF_EVENT_VIEWER_AUTOPLAY_CLIP, + defaults.event_viewer.autoplay_clip, + )} + ${this._renderSwitch( + CONF_EVENT_VIEWER_DRAGGABLE, + defaults.event_viewer.draggable, + )} + ${this._renderSwitch( + CONF_EVENT_VIEWER_LAZY_LOAD, + defaults.event_viewer.lazy_load, + )} + ${this._renderDropdown( + CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_STYLE, + eventViewerNextPreviousControlStyles, + )} + ${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_NEXT_PREVIOUS_SIZE)} + ${this._renderDropdown( + CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_MODE, + thumbnailModes, + )} + ${this._renderStringInput(CONF_EVENT_VIEWER_CONTROLS_THUMBNAILS_SIZE)}
` : ''} -
-
- -
${options.image.name}
-
-
${options.image.secondary}
-
+ ${this._renderOptionSetHeader('image')} ${options.image.show - ? html`
- -
` + ? html`
${this._renderStringInput(CONF_IMAGE_SRC)}
` : ''} -
-
- -
${options.dimensions.name}
-
-
${options.dimensions.secondary}
-
+ ${this._renderOptionSetHeader('dimensions')} ${options.dimensions.show ? html`
- - - ${Object.keys(aspectRatioModes).map((key) => { - return html` - ${aspectRatioModes[key]} - `; - })} - - - + ${this._renderDropdown( + CONF_DIMENSIONS_ASPECT_RATIO_MODE, + aspectRatioModes, + )} + ${this._renderStringInput(CONF_DIMENSIONS_ASPECT_RATIO)}
` : ''}
diff --git a/src/scss/editor.scss b/src/scss/editor.scss index 76d0be76..92e45bc4 100644 --- a/src/scss/editor.scss +++ b/src/scss/editor.scss @@ -18,7 +18,8 @@ pointer-events: none; } .values { - padding-left: 16px; + padding-left: 32px; + padding-top: 10px; background: var(--secondary-background-color); display: grid; }