Skip to content

Commit

Permalink
Merge pull request #6 from flixlix/feat-add-ui-editor
Browse files Browse the repository at this point in the history
feat: add ui editor
  • Loading branch information
flixlix authored May 20, 2023
2 parents d3595fb + 52789c7 commit 7d1b045
Show file tree
Hide file tree
Showing 9 changed files with 435 additions and 51 deletions.
30 changes: 28 additions & 2 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,37 @@ const plugins = [

export default [
{
input: 'src/energy-period-selector-plus.ts',
input: ['src/energy-period-selector-plus.ts'],
output: {
dir: 'dist',
format: 'es',
inlineDynamicImports: true,
},
plugins: [
minifyHTML(),
terser({ output: { comments: false } }),
typescript({
declaration: false,
}),
nodeResolve(),
json({
compact: true,
}),
commonjs(),
babel({
exclude: "node_modules/**",
babelHelpers: "bundled",
}),
...(dev ? [serve(serveOptions)] : [terser()]),
],
moduleContext: (id) => {
const thisAsWindowForModules = [
"node_modules/@formatjs/intl-utils/lib/src/diff.js",
"node_modules/@formatjs/intl-utils/lib/src/resolve-locale.js",
];
if (thisAsWindowForModules.some((id_) => id.trimRight().endsWith(id_))) {
return "window";
}
},
plugins: [...plugins],
},
];
37 changes: 24 additions & 13 deletions src/energy-period-selector-plus-base.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { mdiCompare, mdiCompareRemove } from '@mdi/js';
import { mdiCompare, mdiCompareRemove, mdiCalendarToday } from '@mdi/js';
import {
addDays,
addMonths,
Expand All @@ -17,7 +17,6 @@ import {
startOfToday,
startOfWeek,
startOfYear,
format,
} from 'date-fns/esm';
import { UnsubscribeFunc } from 'home-assistant-js-websocket';
import { html, LitElement, nothing } from 'lit';
Expand Down Expand Up @@ -77,7 +76,7 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
return this.hass.localize(`ui.panel.lovelace.components.energy_period_selector.${period}`) || localize(`toggleButtons.${period}`);
};

const viewButtons: ToggleButton[] = !this._config?.period_buttons
const periodButtons: ToggleButton[] = !this._config?.period_buttons
? [
{
label: this.hass.localize('ui.panel.lovelace.components.energy_period_selector.day'),
Expand Down Expand Up @@ -127,6 +126,22 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
</ha-date-input>
</div>
`;

const todayButtonText = html` <mwc-button dense outlined @click=${this._pickToday}>
${this.hass.localize('ui.panel.lovelace.components.energy_period_selector.today')}
</mwc-button>`;

const todayButtonIcon = html` <ha-icon-button
@click=${this._pickToday}
class="today-icon"
.label=${this.hass.localize('ui.panel.lovelace.components.energy_period_selector.today')}
.path=${mdiCalendarToday}
>
</ha-icon-button>`;

const todayButton =
this._config?.today_button_type === false ? nothing : this._config?.today_button_type === 'icon' ? todayButtonIcon : todayButtonText;

return html`
<div class="row">
${this._period === 'custom'
Expand All @@ -152,34 +167,30 @@ export class EnergyPeriodSelectorBase extends SubscribeMixin(LitElement) {
></ha-icon-button-next>
`
: nothing}
${this._config?.today_button !== false
? html`<mwc-button dense outlined @click=${this._pickToday}>
${this.hass.localize('ui.panel.lovelace.components.energy_period_selector.today')}
</mwc-button>`
: nothing}
${todayButton}
</div>
`}
<div class="period">
<ha-button-toggle-group
.buttons=${viewButtons}
.buttons=${periodButtons}
.active=${this._period}
dense
@value-changed=${this._handleView}
.dir=${computeRTLDirection(this.hass)}
></ha-button-toggle-group>
${this._config?.compare_button === 'icon'
${this._config?.compare_button_type === 'icon'
? html`<ha-icon-button
class="compare ${this._compare ? 'active' : ''}"
.path=${this._compare ? mdiCompareRemove : mdiCompare}
@click=${this._toggleCompare}
dense
outlined
>
${this.hass.localize('ui.panel.lovelace.components.energy_period_selector.compare')}
${this._config.compare_button_label ?? this.hass.localize('ui.panel.lovelace.components.energy_period_selector.compare')}
</ha-icon-button>`
: this._config?.compare_button === 'text'
: this._config?.compare_button_type === 'text'
? html`<mwc-button class="compare ${this._compare ? 'active' : ''}" @click=${this._toggleCompare} dense outlined>
${this.hass.localize('ui.panel.lovelace.components.energy_period_selector.compare')}
${this._config.compare_button_label ?? this.hass.localize('ui.panel.lovelace.components.energy_period_selector.compare')}
</mwc-button>`
: nothing}
</div>
Expand Down
5 changes: 3 additions & 2 deletions src/energy-period-selector-plus-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { EnergyCardBaseConfig } from './type/energy-card-base-config';

export interface EnergyPeriodSelectorPlusConfig extends LovelaceCardConfig, EnergyCardBaseConfig {
card_background?: boolean;
today_button?: boolean;
prev_next_buttons?: boolean;
compare_button?: string;
compare_button_type?: string;
compare_button_label?: string;
today_button_type?: string | boolean;
period_buttons?: string[];
custom_period_label?: string;
}
8 changes: 7 additions & 1 deletion src/energy-period-selector-plus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import './energy-period-selector-plus-base';
import { localize } from './localize/localize';
import { logError } from './logging';
import { styles } from './style';
import { LovelaceCardEditor } from 'custom-card-helpers';

registerCustomCard({
type: 'energy-period-selector-plus',
Expand All @@ -25,13 +26,18 @@ export class EnergyPeriodSelectorPlus extends LitElement implements LovelaceCard
return 1;
}

public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import('./ui-editor/ui-editor');
return document.createElement('energy-period-selector-editor');
}

public setConfig(config: EnergyPeriodSelectorPlusConfig): void {
this._config = config;
}

protected render() {
if (!this.hass || !this._config) {
logError(localize('common.invalid_configuration'));
logError(localize('common.invalid_configuration') || 'Invalid configuration');
return nothing;
}
const EnergyPeriodSelectorBase = html`
Expand Down
38 changes: 11 additions & 27 deletions src/localize/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,17 @@
"entity_editor": "Entity editor",
"decimals": "decimals",
"fields": {
"autoconfig": "Autoconfig",
"print_yaml": "Print auto generated config yaml",
"show_names": "Show names",
"show_icons": "Show icons",
"show_states": "Show states",
"show_units": "Show units",
"energy_date_selection": "Sync with energy_date_selection component",
"height": "Height",
"wide": "Wide",
"min_box_height": "Min box height",
"min_box_distance": "Min box distance",
"min_state": "Min state",
"round": "Round",
"throttle": "Throttle",
"unit_prefix": "Unit prefix",
"entity": "Entity",
"type": "Type",
"children": "Children",
"name": "Name",
"icon": "Icon",
"color": "Color",
"unit_of_measurement": "Unit of measurement",
"tap_action": "Tap action",
"color_on_state": "Change color based on state",
"color_limit": "State limit for color change",
"color_above": "Color above limit",
"color_below": "Color below limit"
"card_background": "Card Background",
"prev_next_buttons": "Show Previous/Next Buttons",
"compare_button_type": "Compare Button Type",
"custom_period_label": "Custom Period Label",
"compare_button_options": {
"icon": "Icon",
"text": "Text"
},
"period_buttons": "Period Buttons",
"today_button_type": "Today Button Type",
"compare_button_label": "Compare Button Label"
},
"entity_types": {
"entity": "Entity",
Expand Down
8 changes: 4 additions & 4 deletions src/localize/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const languages: any = {
'pt-PT': pt_PT,
};

export function localize(string: string, search = '', replace = ''): string {
export function localize(string: string, search = '', replace = '') {
const lang = (localStorage.getItem('selectedLanguage') || 'en').replace(/['"]+/g, '').replace('-', '_');

let translated: string;
let translated: string | undefined;

try {
translated = string.split('.').reduce((o, i) => o[i], languages[lang]);
Expand All @@ -23,7 +23,7 @@ export function localize(string: string, search = '', replace = ''): string {
if (translated === undefined) translated = string.split('.').reduce((o, i) => o && o[i], languages['en']);

if (search !== '' && replace !== '') {
translated = translated.replace(search, replace);
translated = translated?.replace(search, replace);
}
return translated || string;
return translated;
}
4 changes: 2 additions & 2 deletions src/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const stylesBase = css`
mwc-button {
margin-left: 8px;
}
ha-icon-button {
ha-icon-button:not(.today-icon) {
margin-left: 4px;
--mdc-icon-size: 20px;
}
Expand Down Expand Up @@ -81,7 +81,7 @@ export const stylesBase = css`
--mdc-button-disabled-ink-color: var(--disabled-text-color);
--mdc-icon-button-ripple-opacity: 0.2;
}
ha-icon-button {
ha-icon-button:not(.today-icon) {
--mdc-icon-button-size: 28px;
}
ha-button-toggle-group {
Expand Down
132 changes: 132 additions & 0 deletions src/ui-editor/types/schema-union.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { LitElement } from "lit";



export type HaFormSchema =
| HaFormConstantSchema
| HaFormStringSchema
| HaFormIntegerSchema
| HaFormFloatSchema
| HaFormBooleanSchema
| HaFormSelectSchema
| HaFormMultiSelectSchema
| HaFormTimeSchema
| HaFormSelector
| HaFormGridSchema
| HaFormExpandableSchema;

export interface HaFormBaseSchema {
name: string;
// This value is applied if no data is submitted for this field
default?: HaFormData;
required?: boolean;
disabled?: boolean;
description?: {
suffix?: string;
// This value will be set initially when form is loaded
suggested_value?: HaFormData;
};
context?: Record<string, string>;
}

export interface HaFormGridSchema extends HaFormBaseSchema {
type: "grid";
name: string;
column_min_width?: string;
schema: readonly HaFormSchema[];
}

export interface HaFormExpandableSchema extends HaFormBaseSchema {
type: "expandable";
name: "";
title: string;
icon?: string;
iconPath?: string;
expanded?: boolean;
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
schema: readonly HaFormSchema[];
}

export interface HaFormSelector extends HaFormBaseSchema {
type?: never;
selector: any;
}

export interface HaFormConstantSchema extends HaFormBaseSchema {
type: "constant";
value?: string;
}

export interface HaFormIntegerSchema extends HaFormBaseSchema {
type: "integer";
default?: HaFormIntegerData;
valueMin?: number;
valueMax?: number;
}

export interface HaFormSelectSchema extends HaFormBaseSchema {
type: "select";
options: ReadonlyArray<readonly [string, string]>;
}

export interface HaFormMultiSelectSchema extends HaFormBaseSchema {
type: "multi_select";
options:
| Record<string, string>
| readonly string[]
| ReadonlyArray<readonly [string, string]>;
}

export interface HaFormFloatSchema extends HaFormBaseSchema {
type: "float";
}

export interface HaFormStringSchema extends HaFormBaseSchema {
type: "string";
format?: string;
autocomplete?: string;
}

export interface HaFormBooleanSchema extends HaFormBaseSchema {
type: "boolean";
}

export interface HaFormTimeSchema extends HaFormBaseSchema {
type: "positive_time_period_dict";
}

// Type utility to unionize a schema array by flattening any grid schemas
export type SchemaUnion<
SchemaArray extends readonly HaFormSchema[],
Schema = SchemaArray[number]
> = Schema extends HaFormGridSchema | HaFormExpandableSchema
? SchemaUnion<Schema["schema"]>
: Schema;

export interface HaFormDataContainer {
[key: string]: HaFormData;
}

export type HaFormData =
| HaFormStringData
| HaFormIntegerData
| HaFormFloatData
| HaFormBooleanData
| HaFormSelectData
| HaFormMultiSelectData
| HaFormTimeData;

export type HaFormStringData = string;
export type HaFormIntegerData = number;
export type HaFormFloatData = number;
export type HaFormBooleanData = boolean;
export type HaFormSelectData = string;
export type HaFormMultiSelectData = string[];
export type HaFormTimeData = any;

export interface HaFormElement extends LitElement {
schema: HaFormSchema | readonly HaFormSchema[];
data?: HaFormDataContainer | HaFormData;
label?: string;
}
Loading

0 comments on commit 7d1b045

Please sign in to comment.