+ `;
+ }
+
+ return html`
+
+
+
+
+ ${this.data.map((row, index) => html`
+
+
+
+
+ `)}
+
+ `;
+ }
+
+ valueChanged(ev) {
+ ev.stopPropagation();
+ if (!this.data || !this.hass) {
+ return;
+ }
+ const value = ev.detail.value || '';
+ const index = (ev.target).index || 0;
+ const newListValue = this.data.concat();
+
+ newListValue[index] = value;
+
+ fireEvent(this, 'value-changed', { value: newListValue });
+ }
+
+ addRow(ev) {
+ ev.stopPropagation();
+ const value = {};
+ if (!this.data) {
+ fireEvent(this, 'value-changed', { value: [value] });
+ return;
+ }
+
+ fireEvent(this, 'value-changed', { value: [...this.data, value] });
+ }
+
+ removeRow(ev) {
+ ev.stopPropagation();
+ if (!this.data || !this.hass) {
+ return;
+ }
+ const index = (ev.currentTarget).index || 0;
+ const newListValue = this.data.concat();
+
+ newListValue.splice(index, 1);
+
+ fireEvent(this, 'value-changed', { value: newListValue });
+ }
+
+ static get styles() {
+ return css`
+ .list-entry {
+ display: flex;
+ align-items: center;
+ margin-bottom: 8px;
+ }
+ .list-entry ha-form {
+ flex-grow: 1;
+ }
+ `;
+ }
+}
+
+customElements.define('ha-form-mgc-list', MGCList);
diff --git a/src/editor/components/stateMapEditor.js b/src/editor/components/stateMapEditor.js
deleted file mode 100644
index c0449ec6..00000000
--- a/src/editor/components/stateMapEditor.js
+++ /dev/null
@@ -1,130 +0,0 @@
-import { fireEvent } from 'custom-card-helpers';
-import { LitElement, css, html } from 'lit-element';
-import { mdiClose } from '@mdi/js';
-import { localize } from '../../localize/localize';
-import './subPageHeader';
-
-const SCHEMA = [
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'value',
- selector: { text: {} },
- },
- {
- name: 'label',
- selector: { text: {} },
- },
- ],
- },
-];
-
-class StateMapEditor extends LitElement {
- static get properties() {
- return {
- hass: { attribute: false },
- config: { attribute: false },
- };
- }
-
- render() {
- if (!this.hass) {
- return html``;
- }
- if (!this.config) {
- return html`
-
- `;
- }
-
- return html`
-
-
- ${this.config.map((state_map, index) => html`
-
-
-
-
- `)}
-
- `;
- }
-
- goBack() {
- fireEvent(this, 'go-back');
- }
-
- addRow() {
- const value = { value: '', label: '' };
- if (!this.config) {
- fireEvent(this, 'config-changed', [value]);
- return;
- }
- fireEvent(this, 'config-changed', [...this.config, value]);
- }
-
- removeRow(ev) {
- ev.stopPropagation();
- if (!this.config || !this.hass) {
- return;
- }
- const index = (ev.currentTarget).index || '';
- const newStateMaps = this.config.concat();
-
- newStateMaps.splice(index, 1);
-
- fireEvent(this, 'config-changed', newStateMaps);
- }
-
- valueChanged(ev) {
- if (!this.config || !this.hass) {
- return;
- }
- const value = ev.detail.value || '';
- const index = (ev.target).index || 0;
- const newStateMaps = this.config.concat();
-
- newStateMaps[index] = value;
-
- fireEvent(this, 'config-changed', newStateMaps);
- }
-
- static get styles() {
- return css`
- .state-map {
- display: flex;
- align-items: center;
- margin-bottom: 8px;
- }
-
- .state-map > ha-form {
- flex-grow: 1;
- }
- `;
- }
-}
-
-customElements.define('state-map-editor', StateMapEditor);
diff --git a/src/editor/components/subPageLink.js b/src/editor/components/subPageLink.js
deleted file mode 100644
index a5c74c39..00000000
--- a/src/editor/components/subPageLink.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import { fireEvent } from 'custom-card-helpers';
-import { LitElement, html, css } from 'lit-element';
-import { mdiChevronRight } from '@mdi/js';
-
-class SubPageLink extends LitElement {
- static get properties() {
- return {
- name: {},
- icon: {},
- };
- }
-
- render() {
- return html`
-
-
-
-
-
- `;
- }
-
- focusChanged(ev) {
- this.shadowRoot.querySelector('.subElementLink').classList.toggle(
- 'focused',
- ev.type === 'focus',
- );
- }
-
- openPage() {
- fireEvent(this, 'click');
- }
-
- static get styles() {
- return css`
- .subElementLink {
- display: flex;
- width: 100%;
- min-height: 48px;
- gap: 1rem;
- align-items: center;
- cursor: pointer;
- margin-top: 24px;
- }
-
- .subElementLink ha-svg-icon {
- color: var(--secondary-text-color);
- margin-left: 1rem;
- }
-
- .subElementLink > .header {
- flex: 1;
- }
- `;
- }
-}
-
-customElements.define('mini-graph-card-subpage-link', SubPageLink);
diff --git a/src/editor/editor.js b/src/editor/editor.js
index 2cb57f41..148f68c5 100644
--- a/src/editor/editor.js
+++ b/src/editor/editor.js
@@ -1,345 +1,11 @@
import { fireEvent } from 'custom-card-helpers';
-import { LitElement, html, css } from 'lit-element';
+import { LitElement, html } from 'lit-element';
import './components/entitiesEditor';
import './components/entityEditor';
-import './components/colorThresholdsEditor';
-import './components/subPageLink';
-import './components/stateMapEditor';
-import {
- mdiAlignHorizontalLeft, mdiArrowExpandVertical, mdiEye,
- mdiFormatColorFill,
- mdiPalette,
- mdiStateMachine,
-} from '@mdi/js';
-import { DEFAULT_SHOW } from '../const';
-import { localize } from '../localize/localize';
-
-const SCHEMA = [
- {
- name: '',
- type: 'expandable',
- iconPath: mdiPalette,
- title: 'Appearance',
- schema: [
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'name',
- label: 'Name',
- selector: { text: {} },
- },
- {
- name: 'icon',
- selector: { icon: {} },
- },
- {
- name: 'unit',
- selector: { text: {} },
- },
- {
- name: 'hour24',
- selector: { boolean: {} },
- },
- {
- name: 'hours_to_show',
- selector: { number: { min: 1 } },
- },
- {
- name: 'points_per_hour',
- selector: { number: { min: 0.1, step: 0.1 } },
- },
- {
- name: 'aggregate_func',
- selector: {
- select: {
- options: [
- { label: 'Average', value: 'avg' },
- { label: 'Median', value: 'median' },
- { label: 'Minimum', value: 'min' },
- { label: 'Maximum', value: 'max' },
- { label: 'First', value: 'first' },
- { label: 'Last', value: 'last' },
- { label: 'Sum', value: 'sum' },
- ],
- mode: 'dropdown',
- },
- },
- },
- {
- name: 'group_by',
- selector: {
- select: {
- options: [
- { label: 'Interval', value: 'interval' },
- { label: 'Date', value: 'date' },
- { label: 'Hour', value: 'hour' },
- ],
- mode: 'dropdown',
- },
- },
- },
- {
- name: 'value_factor',
- selector: { number: {} },
- },
- {
- name: 'bar_spacing',
- selector: { number: { min: 0.1, step: 0.1 } },
- },
- {
- name: 'line_width',
- selector: { number: { min: 0.1, step: 0.1 } },
- },
- {
- name: 'color_thresholds_transition',
- selector: {
- select: {
- options: [
- { label: 'Smooth', value: 'smooth' },
- { label: 'Hard', value: 'hard' },
- ],
- mode: 'dropdown',
- },
- },
- },
- {
- name: 'animate',
- selector: { boolean: {} },
- },
- {
- name: 'logarithmic',
- selector: { boolean: {} },
- },
- ],
- },
- {
- name: '',
- type: 'expandable',
- iconPath: mdiArrowExpandVertical,
- title: 'Bounds',
- schema: [
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'lower_bound',
- selector: { text: {} },
- },
- {
- name: 'upper_bound',
- selector: { text: {} },
- },
- {
- name: 'min_bound_range',
- selector: { number: { step: 0.1 } },
- },
- ],
- },
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'lower_bound_secondary',
- selector: { text: {} },
- },
- {
- name: 'upper_bound_secondary',
- selector: { text: {} },
- },
- {
- name: 'min_bound_range_secondary',
- selector: { number: { step: 0.1 } },
- },
- ],
- },
- ],
- },
- {
- name: '',
- type: 'expandable',
- iconPath: mdiAlignHorizontalLeft,
- title: 'Alignment',
- schema: [
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'align_header',
- selector: {
- select: {
- options: [
- { label: 'Default', value: 'default' },
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'Center', value: 'center' },
- ],
- mode: 'dropdown',
- },
- },
- },
- {
- name: 'align_icon',
- selector: {
- select: {
- options: [
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'State', value: 'state' },
- ],
- mode: 'dropdown',
- default: 'right',
- },
- },
- },
- {
- name: 'align_state',
- selector: {
- select: {
- options: [
- { label: 'Left', value: 'left' },
- { label: 'Right', value: 'right' },
- { label: 'Center', value: 'center' },
- ],
- mode: 'dropdown',
- },
- },
- },
- ],
- },
- ],
- },
- {
- name: 'show',
- type: 'expandable',
- iconPath: mdiEye,
- title: 'Display',
- schema: [
- {
- name: '',
- type: 'grid',
- schema: [
- {
- name: 'name',
- selector: { boolean: {} },
- },
- {
- name: 'icon',
- selector: { boolean: {} },
- },
- {
- name: 'state',
- selector: {
- select: {
- options: [
- { label: 'Show', value: true },
- { label: 'Hide', value: false },
- { label: 'Last', value: 'last' },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'graph',
- selector: {
- select: {
- options: [
- { label: 'Line', value: 'line' },
- { label: 'Bar', value: 'bar' },
- { label: 'Hide', value: false },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'fill',
- selector: {
- select: {
- options: [
- { label: 'Show', value: true },
- { label: 'Hide', value: false },
- { label: 'Fade', value: 'fade' },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'points',
- selector: {
- select: {
- options: [
- { label: 'Show', value: true },
- { label: 'Hide', value: false },
- { label: 'Hover', value: 'hover' },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'legend',
- selector: { boolean: {} },
- },
- {
- name: 'average',
- selector: { boolean: {} },
- },
- {
- name: 'extrema',
- selector: { boolean: {} },
- },
- {
- name: 'labels',
- selector: {
- select: {
- options: [
- { label: 'Show', value: true },
- { label: 'Hide', value: false },
- { label: 'Hover', value: 'hover' },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'labels_secondary',
- selector: {
- select: {
- options: [
- { label: 'Show', value: true },
- { label: 'Hide', value: false },
- { label: 'Hover', value: 'hover' },
- ],
- custom_value: true,
- },
- },
- },
- {
- name: 'name_adaptive_color',
- selector: { boolean: {} },
- },
- {
- name: 'icon_adaptive_color',
- selector: { boolean: {} },
- },
- ],
- },
- ],
- },
- ],
- },
- {
- name: 'tap_action',
- selector: { ui_action: {} },
- },
-];
+import './components/mgc_list';
+import { setupTranslations } from '../localize/localize';
+import { MAINSCHEMA, BOOLEANS } from './editorConst';
+import { booleanToString, stringToBoolean } from './editorUtils';
class MiniGraphCardEditor extends LitElement {
static get properties() {
@@ -353,15 +19,48 @@ class MiniGraphCardEditor extends LitElement {
setConfig(config) {
this._config = config;
this._entities = config.entities;
+ setupTranslations(this.hass);
}
valueChanged(ev) {
- const config = ev.detail.value || '';
+ ev.stopPropagation();
+ const newConfig = ev.detail.value || '';
+ const newShow = {};
+
+ if (typeof newConfig.show !== 'undefined') {
+ Object.keys(newConfig.show).forEach((key) => {
+ if (typeof newConfig.show[key] !== 'undefined') {
+ newShow[key] = stringToBoolean(newConfig.show[key]);
+ }
+ });
+ }
+
if (!this._config || !this.hass) {
return;
}
- // this._config = { config, ...this._entities };
- fireEvent(this, 'config-changed', { config });
+
+ fireEvent(this, 'config-changed', {
+ config:
+ {
+ ...newConfig,
+ show: Object.keys(newShow).length !== 0 ? newShow : undefined,
+ },
+ });
+ }
+
+ buildShowObject(showObject) {
+ if (typeof showObject === 'undefined') {
+ return undefined;
+ }
+ const show = {};
+ Object.keys(showObject).forEach((key) => {
+ if (!BOOLEANS.includes(key)) {
+ show[key] = booleanToString(showObject[key]);
+ } else {
+ show[key] = showObject[key];
+ }
+ });
+ return show;
}
entitiesChanged(ev) {
@@ -374,11 +73,10 @@ class MiniGraphCardEditor extends LitElement {
computeLabel(schema) {
const localized = this.hass.localize(`ui.panel.lovelace.editor.card.generic.${schema.name}`);
- if (localized === '') {
- return localize(`editor.form.card.${schema.name}`, this.hass);
- } else {
+ if (localized !== '') {
return localized;
}
+ return this.hass.localize(`ui.panel.lovelace.editor.card.mgc.${schema.name}`);
}
render() {
@@ -386,34 +84,14 @@ class MiniGraphCardEditor extends LitElement {
return html``;
}
-
if (this.subElementEditorConfig !== undefined) {
return this.renderSubElement();
- // return html`
- //
- //
- // `;
}
- const data = {
- hours_to_show: 24,
- points_per_hour: 0.5,
- aggregate_func: 'avg',
- group_by: 'interval',
- bar_spacing: 4,
- line_width: 5,
- color_thresholds_transition: 'smooth',
- align_header: 'default',
- align_icon: 'right',
- align_state: 'left',
- smoothing: true,
+ const SHOW = this._config.show;
+ const DATA = {
...this._config,
- show: { ...DEFAULT_SHOW, ...this._config.show },
+ show: this.buildShowObject(SHOW),
};
return html`
@@ -426,21 +104,11 @@ class MiniGraphCardEditor extends LitElement {
>
-
-
`;
}
@@ -449,22 +117,6 @@ class MiniGraphCardEditor extends LitElement {
this.subElementEditorConfig = undefined;
}
- editColorThresholds(ev) {
- ev.stopPropagation();
- if (!this._config || !this.hass) {
- return;
- }
- this.subElementEditorConfig = { type: 'thresholds', index: 0 };
- }
-
- editStateMap(ev) {
- ev.stopPropagation();
- if (!this._config || !this.hass) {
- return;
- }
- this.subElementEditorConfig = { type: 'statemap', index: 0 };
- }
-
renderSubElement() {
switch (this.subElementEditorConfig.type) {
case 'entity':
@@ -476,24 +128,6 @@ class MiniGraphCardEditor extends LitElement {
@config-changed=${this.subElementChanged}
>
`;
- case 'thresholds':
- return html`
-