Comitt of all things done before I forgot about it. beginnings of a restructuring, I think...
This commit is contained in:
parent
14ec3e37da
commit
65d391e050
@ -35,6 +35,11 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="card" id="graph">
|
<div class="card" id="graph">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card" id="graph2">
|
||||||
|
<script-graph3>
|
||||||
|
<script-graph-node></script-graph-node>
|
||||||
|
</script-graph3>
|
||||||
|
</div>
|
||||||
<div class="card code">
|
<div class="card code">
|
||||||
<h1> Selected node code </h1>
|
<h1> Selected node code </h1>
|
||||||
<wc-codemirror mode="json" id="snippet">
|
<wc-codemirror mode="json" id="snippet">
|
||||||
|
@ -2,6 +2,7 @@ import {demoConfig} from "./demo-config";
|
|||||||
import "@vanillawc/wc-codemirror";
|
import "@vanillawc/wc-codemirror";
|
||||||
|
|
||||||
import "./script-graph";
|
import "./script-graph";
|
||||||
|
import "./script-graph3";
|
||||||
|
|
||||||
import { ActionHandler } from "./script-to-graph";
|
import { ActionHandler } from "./script-to-graph";
|
||||||
|
|
||||||
@ -12,6 +13,9 @@ let nodes = [];
|
|||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
|
|
||||||
|
const graph2 = document.createElement("script-graph3");
|
||||||
|
document.querySelector("#graph2").appendChild(graph2);
|
||||||
|
|
||||||
let src = demoConfig;
|
let src = demoConfig;
|
||||||
|
|
||||||
const fullcode = document.querySelector("#fullcode");
|
const fullcode = document.querySelector("#fullcode");
|
||||||
|
@ -11,9 +11,9 @@ import { mdiPlus } from "@mdi/js";
|
|||||||
const SIZE = 35;
|
const SIZE = 35;
|
||||||
const DIST = 20;
|
const DIST = 20;
|
||||||
|
|
||||||
interface TreeNode {
|
export interface TreeNode {
|
||||||
icon: String;
|
icon: String;
|
||||||
styles: String;
|
styles?: String;
|
||||||
end?: Boolean;
|
end?: Boolean;
|
||||||
children?: (TreeNode | TreeNode[])[];
|
children?: (TreeNode | TreeNode[])[];
|
||||||
clickCallback?: any;
|
clickCallback?: any;
|
||||||
|
110
src/script-graph3.ts
Normal file
110
src/script-graph3.ts
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import {
|
||||||
|
LitElement,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
svg,
|
||||||
|
property,
|
||||||
|
TemplateResult
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
import { mdiAsterisk } from "@mdi/js";
|
||||||
|
|
||||||
|
const SIZE = 35;
|
||||||
|
const DIST = 20;
|
||||||
|
|
||||||
|
interface GraphNode extends LitElement{
|
||||||
|
render_svg(): TemplateResult;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScriptGraphNode extends LitElement {
|
||||||
|
|
||||||
|
@property() icon = mdiAsterisk;
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
return SIZE;
|
||||||
|
}
|
||||||
|
get height() {
|
||||||
|
return SIZE + DIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_svg() {
|
||||||
|
return svg`
|
||||||
|
<circle
|
||||||
|
cx="0"
|
||||||
|
cy="${this.width/2}"
|
||||||
|
r="${SIZE/2}"
|
||||||
|
/>
|
||||||
|
<g style="pointer-events: none" transform="translate(-12, ${this.width/2-12})">
|
||||||
|
</g>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScriptGraph3 extends LitElement {
|
||||||
|
|
||||||
|
@property() content = [];
|
||||||
|
@property() _width = 0;
|
||||||
|
@property() _height = 0;
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
console.log(this.querySelectorAll('*'))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateChildren() {
|
||||||
|
this.content = [];
|
||||||
|
let y = 0;
|
||||||
|
let w = 0;
|
||||||
|
for (const e of this.querySelectorAll('*') as NodeListOf<GraphNode>) {
|
||||||
|
this.content.push({
|
||||||
|
svg: e.render_svg(),
|
||||||
|
offset_y: y,
|
||||||
|
});
|
||||||
|
y += e.height;
|
||||||
|
w = Math.max(w, e.width);
|
||||||
|
}
|
||||||
|
this._width = w;
|
||||||
|
this._height = y;
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
childrenChangedCallback() {
|
||||||
|
console.log("Children changed");
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
|
||||||
|
let y = 0;
|
||||||
|
let nodes = [];
|
||||||
|
for (const e of this.content) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<svg width=500 height=500>
|
||||||
|
${this.content.map(e =>
|
||||||
|
svg`
|
||||||
|
<g transform="translate(${this._width/2} ${e.offset_y})">
|
||||||
|
${e.svg}
|
||||||
|
</g>
|
||||||
|
`)}
|
||||||
|
</svg>
|
||||||
|
<slot
|
||||||
|
@slotchange=${this.updateChildren}
|
||||||
|
></slot>
|
||||||
|
<style>
|
||||||
|
slot {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
customElements.define("script-graph3", ScriptGraph3);
|
||||||
|
customElements.define("script-graph-node", ScriptGraphNode);
|
@ -32,6 +32,9 @@ const ICONS = {
|
|||||||
YAML: mdiCodeJson,
|
YAML: mdiCodeJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
import { TreeNode} from "./script-graph";
|
||||||
|
import { Action } from "./types";
|
||||||
|
|
||||||
const OPTIONS = [
|
const OPTIONS = [
|
||||||
"condition",
|
"condition",
|
||||||
"delay",
|
"delay",
|
||||||
@ -44,10 +47,14 @@ const OPTIONS = [
|
|||||||
"choose",
|
"choose",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
interface NodeHandler {
|
||||||
|
(action, selected: any[], select, update): TreeNode;
|
||||||
|
}
|
||||||
|
|
||||||
const SPECIAL = {
|
const SPECIAL = {
|
||||||
condition: (action, selected, select, update) => {
|
condition: (action, selected, select, update) => {
|
||||||
return {
|
return {
|
||||||
icon: ICONS["choose"],
|
icon: ICONS["condition"],
|
||||||
clickCallback: () => select([1], action, update),
|
clickCallback: () => select([1], action, update),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -164,13 +171,16 @@ const SPECIAL = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface NoAction {
|
||||||
|
}
|
||||||
|
|
||||||
export class ActionHandler {
|
export class ActionHandler {
|
||||||
_actions = [];
|
_actions: (Action | NoAction)[] = [];
|
||||||
updateCallback = null;
|
updateCallback = null;
|
||||||
selectCallback = null;
|
selectCallback = null;
|
||||||
selected = [];
|
selected: number[] = [];
|
||||||
|
|
||||||
constructor(actions = []) {
|
constructor(actions: (Action | NoAction)[] = []) {
|
||||||
this._actions = actions;
|
this._actions = actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +194,10 @@ export class ActionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get graph() {
|
get graph() {
|
||||||
return this.actions.map((_, idx) => this._make_graph_node(idx));
|
return this.actions.map((action, idx) => this._make_graph_node(idx, action));
|
||||||
}
|
}
|
||||||
|
|
||||||
_update_action(idx, action) {
|
_update_action(idx: number, action) {
|
||||||
if(action === null)
|
if(action === null)
|
||||||
this.actions.splice(idx, 1);
|
this.actions.splice(idx, 1);
|
||||||
else
|
else
|
||||||
@ -196,21 +206,20 @@ export class ActionHandler {
|
|||||||
this.updateCallback(this.actions);
|
this.updateCallback(this.actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
_add_action(idx) {
|
_add_action(idx: number) {
|
||||||
this.actions.splice(idx, 0, {});
|
this.actions.splice(idx, 0, {});
|
||||||
if (this.updateCallback)
|
if (this.updateCallback)
|
||||||
this.updateCallback(this.actions);
|
this.updateCallback(this.actions);
|
||||||
this._select_node([idx], {}, (a) =>this._update_action(idx, a));
|
this._select_node([idx], {}, (a) =>this._update_action(idx, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
_select_node(idx, action, update=null) {
|
_select_node(path: number[], action, update=null) {
|
||||||
this.selected = idx;
|
this.selected = path;
|
||||||
if (this.selectCallback)
|
if (this.selectCallback)
|
||||||
this.selectCallback(idx, action, update);
|
this.selectCallback(path, action, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
_make_graph_node(idx) {
|
_make_graph_node(idx: number, action): TreeNode {
|
||||||
const action = this.actions[idx] || {};
|
|
||||||
let _type = "yaml";
|
let _type = "yaml";
|
||||||
if (Object.keys(action).length === 0)
|
if (Object.keys(action).length === 0)
|
||||||
_type = "new";
|
_type = "new";
|
||||||
@ -218,7 +227,7 @@ export class ActionHandler {
|
|||||||
_type = OPTIONS.find((option) => option in action) || "YAML";
|
_type = OPTIONS.find((option) => option in action) || "YAML";
|
||||||
|
|
||||||
const selected = this.selected.length >= 1 && this.selected[0] == idx;
|
const selected = this.selected.length >= 1 && this.selected[0] == idx;
|
||||||
let node = {};
|
let node: TreeNode = {icon: ""};
|
||||||
|
|
||||||
if (_type in SPECIAL) {
|
if (_type in SPECIAL) {
|
||||||
node = SPECIAL[_type](
|
node = SPECIAL[_type](
|
||||||
|
70
src/types.ts
Normal file
70
src/types.ts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
export interface Condition {
|
||||||
|
condition: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventAction {
|
||||||
|
event: string;
|
||||||
|
event_data?: { [key: string]: any };
|
||||||
|
event_data_template?: { [key: string]: any };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceAction {
|
||||||
|
service: string;
|
||||||
|
entity_id?: string;
|
||||||
|
data?: { [key: string]: any };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DeviceAction {
|
||||||
|
device_id: string;
|
||||||
|
domain: string;
|
||||||
|
entity_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DelayAction {
|
||||||
|
delay: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SceneAction {
|
||||||
|
scene: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WaitAction {
|
||||||
|
wait_template: string;
|
||||||
|
timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RepeatAction {
|
||||||
|
repeat: CountRepeat | WhileRepeat | UntilRepeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseRepeat {
|
||||||
|
sequence: Action[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CountRepeat extends BaseRepeat {
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WhileRepeat extends BaseRepeat {
|
||||||
|
while: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UntilRepeat extends BaseRepeat {
|
||||||
|
until: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChooseAction {
|
||||||
|
choose: [{ conditions: Condition[]; sequence: Action[] }];
|
||||||
|
default?: Action[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Action =
|
||||||
|
| EventAction
|
||||||
|
| DeviceAction
|
||||||
|
| ServiceAction
|
||||||
|
| Condition
|
||||||
|
| DelayAction
|
||||||
|
| SceneAction
|
||||||
|
| WaitAction
|
||||||
|
| RepeatAction
|
||||||
|
| ChooseAction;
|
Loading…
x
Reference in New Issue
Block a user