Fix editor structs (#9286)

This commit is contained in:
Bram Kragten 2021-05-31 05:08:46 +02:00 committed by GitHub
parent 92c8bd80b5
commit 93b3b8f985
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 261 additions and 280 deletions

View File

@ -0,0 +1,6 @@
import { refine, string } from "superstruct";
const isCustomType = (value: string) => value.startsWith("custom:");
export const customType = () =>
refine(string(), "custom element type", isCustomType);

View File

@ -1,11 +1,6 @@
import { refine, string } from "superstruct";
const isEntityId = (value: string): boolean => {
if (!value.includes(".")) {
return false;
}
return true;
};
const isEntityId = (value: string): boolean => value.includes(".");
export const entityId = () =>
refine(string(), "entity ID (domain.entity)", isEntityId);

View File

@ -1,10 +1,5 @@
import { refine, string } from "superstruct";
const isIcon = (value: string) => {
if (!value.includes(":")) {
return false;
}
return true;
};
const isIcon = (value: string) => value.includes(":");
export const icon = () => refine(string(), "icon (mdi:icon-name)", isIcon);

View File

@ -15,7 +15,8 @@ import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { actionConfigStruct, EditorTarget } from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -5,15 +5,20 @@ import "@polymer/paper-listbox/paper-listbox";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import {
any,
array,
assert,
boolean,
literal,
number,
object,
optional,
string,
type,
union,
} from "superstruct";
import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { customType } from "../../../../common/structs/is-custom-type";
import { entityId } from "../../../../common/structs/is-entity-id";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import "../../../../components/entity/state-badge";
@ -25,20 +30,127 @@ import type { HomeAssistant } from "../../../../types";
import type { EntitiesCardConfig } from "../../cards/types";
import "../../components/hui-theme-select-editor";
import type { LovelaceRowConfig } from "../../entity-rows/types";
import { headerFooterConfigStructs } from "../../header-footer/types";
import { headerFooterConfigStructs } from "../../header-footer/structs";
import type { LovelaceCardEditor } from "../../types";
import "../header-footer-editor/hui-header-footer-editor";
import "../hui-entities-card-row-editor";
import "../hui-sub-element-editor";
import { processEditorEntities } from "../process-editor-entities";
import { actionConfigStruct } from "../structs/action-struct";
import { entitiesConfigStruct } from "../structs/entities-struct";
import {
EditorTarget,
EditSubElementEvent,
entitiesConfigStruct,
SubElementEditorConfig,
} from "../types";
import { configElementStyle } from "./config-elements-style";
const buttonEntitiesRowConfigStruct = object({
type: literal("button"),
name: string(),
action_name: optional(string()),
tap_action: actionConfigStruct,
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
const castEntitiesRowConfigStruct = object({
type: literal("cast"),
view: union([string(), number()]),
dashboard: optional(string()),
name: optional(string()),
icon: optional(string()),
hide_if_unavailable: optional(boolean()),
});
const callServiceEntitiesRowConfigStruct = object({
type: literal("call-service"),
name: string(),
service: string(),
icon: optional(string()),
action_name: optional(string()),
service_data: optional(any()),
});
const conditionalEntitiesRowConfigStruct = object({
type: literal("conditional"),
row: any(),
conditions: array(
object({
entity: string(),
state: optional(string()),
state_not: optional(string()),
})
),
});
const dividerEntitiesRowConfigStruct = object({
type: literal("divider"),
style: optional(any()),
});
const sectionEntitiesRowConfigStruct = object({
type: literal("section"),
label: optional(string()),
});
const webLinkEntitiesRowConfigStruct = object({
type: literal("weblink"),
url: string(),
name: optional(string()),
icon: optional(string()),
});
const buttonsEntitiesRowConfigStruct = object({
type: literal("buttons"),
entities: array(
union([
object({
entity: string(),
icon: optional(string()),
image: optional(string()),
name: optional(string()),
}),
string(),
])
),
});
const attributeEntitiesRowConfigStruct = object({
type: literal("attribute"),
entity: string(),
attribute: string(),
prefix: optional(string()),
suffix: optional(string()),
name: optional(string()),
});
const textEntitiesRowConfigStruct = object({
type: literal("text"),
name: string(),
text: string(),
icon: optional(string()),
});
const customRowConfigStruct = type({
type: customType(),
});
const entitiesRowConfigStruct = union([
entitiesConfigStruct,
buttonEntitiesRowConfigStruct,
castEntitiesRowConfigStruct,
conditionalEntitiesRowConfigStruct,
dividerEntitiesRowConfigStruct,
sectionEntitiesRowConfigStruct,
webLinkEntitiesRowConfigStruct,
buttonsEntitiesRowConfigStruct,
attributeEntitiesRowConfigStruct,
callServiceEntitiesRowConfigStruct,
textEntitiesRowConfigStruct,
customRowConfigStruct,
]);
const cardConfigStruct = object({
type: string(),
title: optional(union([string(), boolean()])),
@ -47,7 +159,7 @@ const cardConfigStruct = object({
icon: optional(string()),
show_header_toggle: optional(boolean()),
state_color: optional(boolean()),
entities: array(entitiesConfigStruct),
entities: array(entitiesRowConfigStruct),
header: optional(headerFooterConfigStructs),
footer: optional(headerFooterConfigStructs),
});

View File

@ -11,7 +11,7 @@ import { EntityCardConfig } from "../../cards/types";
import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { headerFooterConfigStructs } from "../../header-footer/types";
import { headerFooterConfigStructs } from "../../header-footer/structs";
import { LovelaceCardEditor } from "../../types";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";

View File

@ -14,11 +14,8 @@ import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceRowEditor } from "../../types";
import {
EditorTarget,
entitiesConfigStruct,
EntitiesEditorEvent,
} from "../types";
import { entitiesConfigStruct } from "../structs/entities-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const SecondaryInfoValues: { [key: string]: { domains?: string[] } } = {

View File

@ -26,11 +26,8 @@ import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
import {
EditorTarget,
entitiesConfigStruct,
EntitiesEditorEvent,
} from "../types";
import { entitiesConfigStruct } from "../structs/entities-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -8,10 +8,8 @@ import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-formfield";
import "../../../../components/ha-switch";
import type { HomeAssistant } from "../../../../types";
import {
GraphHeaderFooterConfig,
graphHeaderFooterConfigStruct,
} from "../../header-footer/types";
import { graphHeaderFooterConfigStruct } from "../../header-footer/structs";
import { GraphHeaderFooterConfig } from "../../header-footer/types";
import type { LovelaceCardEditor } from "../../types";
import type { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";

View File

@ -1,34 +1,18 @@
import "@polymer/paper-input/paper-input";
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import {
array,
assert,
number,
object,
optional,
string,
union,
} from "superstruct";
import { array, assert, number, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { entityId } from "../../../../common/structs/is-entity-id";
import { HomeAssistant } from "../../../../types";
import { HistoryGraphCardConfig } from "../../cards/types";
import "../../components/hui-entity-editor";
import { EntityConfig } from "../../entity-rows/types";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
import { entitiesConfigStruct } from "../structs/entities-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const entitiesConfigStruct = union([
object({
entity: entityId(),
name: optional(string()),
}),
entityId(),
]);
const cardConfigStruct = object({
type: string(),
entities: array(entitiesConfigStruct),

View File

@ -12,7 +12,8 @@ import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { actionConfigStruct, EditorTarget } from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -22,11 +22,8 @@ import "../../components/hui-input-list-editor";
import { EntityConfig } from "../../entity-rows/types";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
import {
EditorTarget,
entitiesConfigStruct,
EntitiesEditorEvent,
} from "../types";
import { entitiesConfigStruct } from "../structs/entities-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -9,7 +9,8 @@ import { PictureCardConfig } from "../../cards/types";
import "../../components/hui-action-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { actionConfigStruct, EditorTarget } from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -16,7 +16,8 @@ import "../../components/hui-action-editor";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import { actionConfigStruct, EditorTarget } from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -16,11 +16,9 @@ import "../../components/hui-theme-select-editor";
import { EntityConfig } from "../../entity-rows/types";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
import {
actionConfigStruct,
EditorTarget,
entitiesConfigStruct,
} from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { entitiesConfigStruct } from "../structs/entities-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -11,11 +11,8 @@ import { HomeAssistant } from "../../../../types";
import { WeatherForecastCardConfig } from "../../cards/types";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import {
actionConfigStruct,
EditorTarget,
EntitiesEditorEvent,
} from "../types";
import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = object({

View File

@ -0,0 +1,67 @@
import {
object,
string,
union,
boolean,
optional,
array,
literal,
enums,
} from "superstruct";
const actionConfigStructUser = object({
user: string(),
});
const actionConfigStructConfirmation = union([
boolean(),
object({
text: optional(string()),
excemptions: optional(array(actionConfigStructUser)),
}),
]);
const actionConfigStructUrl = object({
action: literal("url"),
url_path: string(),
confirmation: optional(actionConfigStructConfirmation),
});
const actionConfigStructService = object({
action: literal("call-service"),
service: string(),
service_data: optional(object()),
target: optional(
object({
entity_id: optional(union([string(), array(string())])),
device_id: optional(union([string(), array(string())])),
area_id: optional(union([string(), array(string())])),
})
),
confirmation: optional(actionConfigStructConfirmation),
});
const actionConfigStructNavigate = object({
action: literal("navigate"),
navigation_path: string(),
confirmation: optional(actionConfigStructConfirmation),
});
export const actionConfigStructType = object({
action: enums([
"none",
"toggle",
"more-info",
"call-service",
"url",
"navigate",
]),
confirmation: optional(actionConfigStructConfirmation),
});
export const actionConfigStruct = union([
actionConfigStructType,
actionConfigStructUrl,
actionConfigStructNavigate,
actionConfigStructService,
]);

View File

@ -0,0 +1,18 @@
import { union, object, string, optional, boolean } from "superstruct";
import { actionConfigStruct } from "./action-struct";
export const entitiesConfigStruct = union([
object({
entity: string(),
name: optional(string()),
icon: optional(string()),
image: optional(string()),
secondary_info: optional(string()),
format: optional(string()),
state_color: optional(boolean()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
}),
string(),
]);

View File

@ -1,16 +1,3 @@
import {
any,
array,
boolean,
dynamic,
enums,
literal,
number,
object,
optional,
string,
union,
} from "superstruct";
import {
ActionConfig,
LovelaceCardConfig,
@ -94,175 +81,3 @@ export interface SubElementEditorConfig {
export interface EditSubElementEvent {
subElementConfig: SubElementEditorConfig;
}
export const actionConfigStruct = dynamic((_value, ctx) => {
if (ctx.branch[0][ctx.path[0]]) {
return (
actionConfigMap[ctx.branch[0][ctx.path[0]].action] ||
actionConfigStructType
);
}
return actionConfigStructType;
});
const actionConfigStructUser = object({
user: string(),
});
const actionConfigStructConfirmation = union([
boolean(),
object({
text: optional(string()),
excemptions: optional(array(actionConfigStructUser)),
}),
]);
const actionConfigStructUrl = object({
action: literal("url"),
url_path: string(),
confirmation: optional(actionConfigStructConfirmation),
});
const actionConfigStructService = object({
action: literal("call-service"),
service: string(),
service_data: optional(object()),
target: optional(
object({
entity_id: optional(union([string(), array(string())])),
device_id: optional(union([string(), array(string())])),
area_id: optional(union([string(), array(string())])),
})
),
confirmation: optional(actionConfigStructConfirmation),
});
const actionConfigStructNavigate = object({
action: literal("navigate"),
navigation_path: string(),
confirmation: optional(actionConfigStructConfirmation),
});
const actionConfigMap = {
url: actionConfigStructUrl,
navigate: actionConfigStructNavigate,
"call-service": actionConfigStructService,
};
export const actionConfigStructType = object({
action: enums([
"none",
"toggle",
"more-info",
"call-service",
"url",
"navigate",
]),
confirmation: optional(actionConfigStructConfirmation),
});
const buttonEntitiesRowConfigStruct = object({
type: string(),
name: string(),
action_name: optional(string()),
tap_action: actionConfigStruct,
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
const castEntitiesRowConfigStruct = object({
type: string(),
view: union([string(), number()]),
dashboard: optional(string()),
name: optional(string()),
icon: optional(string()),
hide_if_unavailable: optional(boolean()),
});
const callServiceEntitiesRowConfigStruct = object({
type: string(),
name: string(),
service: string(),
icon: optional(string()),
action_name: optional(string()),
service_data: optional(any()),
});
const conditionalEntitiesRowConfigStruct = object({
type: string(),
row: any(),
conditions: array(
object({
entity: string(),
state: optional(string()),
state_not: optional(string()),
})
),
});
const dividerEntitiesRowConfigStruct = object({
type: string(),
style: optional(any()),
});
const sectionEntitiesRowConfigStruct = object({
type: string(),
label: optional(string()),
});
const webLinkEntitiesRowConfigStruct = object({
type: string(),
url: string(),
name: optional(string()),
icon: optional(string()),
});
const buttonsEntitiesRowConfigStruct = object({
type: string(),
entities: array(
union([
object({
entity: string(),
icon: optional(string()),
image: optional(string()),
name: optional(string()),
}),
string(),
])
),
});
const attributeEntitiesRowConfigStruct = object({
type: string(),
entity: string(),
attribute: string(),
prefix: optional(string()),
suffix: optional(string()),
name: optional(string()),
});
export const entitiesConfigStruct = union([
object({
entity: string(),
name: optional(string()),
icon: optional(string()),
image: optional(string()),
secondary_info: optional(string()),
format: optional(string()),
state_color: optional(boolean()),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
}),
string(),
buttonEntitiesRowConfigStruct,
castEntitiesRowConfigStruct,
conditionalEntitiesRowConfigStruct,
dividerEntitiesRowConfigStruct,
sectionEntitiesRowConfigStruct,
webLinkEntitiesRowConfigStruct,
buttonsEntitiesRowConfigStruct,
attributeEntitiesRowConfigStruct,
callServiceEntitiesRowConfigStruct,
]);

View File

@ -0,0 +1,29 @@
import { object, string, optional, array, number, union } from "superstruct";
import { actionConfigStruct } from "../editor/structs/action-struct";
import { entitiesConfigStruct } from "../editor/structs/entities-struct";
export const pictureHeaderFooterConfigStruct = object({
type: string(),
image: string(),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
export const buttonsHeaderFooterConfigStruct = object({
type: string(),
entities: array(entitiesConfigStruct),
});
export const graphHeaderFooterConfigStruct = object({
type: string(),
entity: string(),
detail: optional(number()),
hours_to_show: optional(number()),
});
export const headerFooterConfigStructs = union([
pictureHeaderFooterConfigStruct,
buttonsHeaderFooterConfigStruct,
graphHeaderFooterConfigStruct,
]);

View File

@ -1,6 +1,4 @@
import { array, number, object, optional, string, union } from "superstruct";
import { ActionConfig } from "../../../data/lovelace";
import { actionConfigStruct, entitiesConfigStruct } from "../editor/types";
import { EntityConfig } from "../entity-rows/types";
export interface LovelaceHeaderFooterConfig {
@ -27,29 +25,3 @@ export interface PictureHeaderFooterConfig extends LovelaceHeaderFooterConfig {
hold_action?: ActionConfig;
double_tap_action?: ActionConfig;
}
export const pictureHeaderFooterConfigStruct = object({
type: string(),
image: string(),
tap_action: optional(actionConfigStruct),
hold_action: optional(actionConfigStruct),
double_tap_action: optional(actionConfigStruct),
});
export const buttonsHeaderFooterConfigStruct = object({
type: string(),
entities: array(entitiesConfigStruct),
});
export const graphHeaderFooterConfigStruct = object({
type: string(),
entity: string(),
detail: optional(number()),
hours_to_show: optional(number()),
});
export const headerFooterConfigStructs = union([
pictureHeaderFooterConfigStruct,
buttonsHeaderFooterConfigStruct,
graphHeaderFooterConfigStruct,
]);