diff --git a/src/hat-graph/make-graph.ts b/src/hat-graph/make-graph.ts
index 16dcfb8..70c04f6 100644
--- a/src/hat-graph/make-graph.ts
+++ b/src/hat-graph/make-graph.ts
@@ -1,3 +1,5 @@
+import "./hat-graph";
+import "./hat-graph-node";
import { HatGraphNode } from "./hat-graph-node";
import {
diff --git a/src/main.js b/src/main.js
index 8c3da13..56bc87b 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,61 +1,8 @@
import { demoConfig2 } from "./demo-config";
import "@vanillawc/wc-codemirror";
-import "./script-graph";
-// import "./script-graph3";
-import "./hat-graph/hat-graph-node";
-import "./hat-graph/hat-graph";
import { makeGraph } from "./hat-graph/make-graph";
-import { ActionHandler } from "./script-to-graph";
-
-import { mdiAsterisk, mdiArrowUp, mdiArrowDown } from "@mdi/js";
-
-let index_counter = 0;
-let nodes = [];
-
-window.onload = () => {
- return;
- //const graph2 = document.createElement("script-graph3");
- //document.querySelector("#graph2").appendChild(graph2);
-
- let src = demoConfig;
-
- const fullcode = document.querySelector("#fullcode");
- fullcode.mode = "yaml";
- window.setTimeout(() => (fullcode.value = jsyaml.safeDump(src)), 100);
-
- const updateButton = document.querySelector("#updateButton");
- updateButton.addEventListener("click", () => {
- src = jsyaml.safeLoad(fullcode.value);
- index_counter = 0;
- nodes = [];
- tr.actions = src;
- graph.tree = tr.graph;
- });
-
- const graph = document.createElement("script-graph");
- const tr = new ActionHandler();
- window.tr = tr;
- tr.actions = src;
- tr.updateCallback = (actions) => {
- graph.tree = tr.graph;
- fullcode.value = jsyaml.safeDump(tr.actions);
- };
- tr.selectCallback = (idx, action, update) => {
- graph.tree = tr.graph;
- const code = document.querySelector("#snippet");
- code.value = jsyaml.safeDump(action);
- document.querySelector("#saveSnippet").onclick = () =>
- update(jsyaml.safeLoad(code.value));
- document.querySelector("#deleteSnippet").onclick = () =>
- update(jsyaml.safeLoad(null));
- };
-
- graph.tree = tr.graph;
- document.querySelector("#graph").appendChild(graph);
-};
-
function nodeSelected(ev) {
const code = document.querySelector("#snippet");
code.value = jsyaml.safeDump(ev.detail.config);
diff --git a/src/script-graph.ts b/src/script-graph.ts
deleted file mode 100644
index 6f2095f..0000000
--- a/src/script-graph.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-import {
- LitElement,
- html,
- css,
- svg,
- property
-} from "lit-element";
-
-import { mdiPlus } from "@mdi/js";
-
-const SIZE = 35;
-const DIST = 20;
-
-export interface TreeNode {
- icon: String;
- styles?: String;
- end?: Boolean;
- children?: (TreeNode | TreeNode[])[];
- clickCallback?: any;
- addCallback?: any;
-}
-
-class ScriptGraph2 extends LitElement {
- @property() selected = null;
- @property() tree: [TreeNode];
- @property() nodeSize = SIZE;
- @property() nodeSeparation = DIST;
-
- private _draw_node(x, y, node) {
- return svg`
-
-
-
-
- `;
- }
-
- private _draw_new_node(x, y, node) {
- return svg`
-
- `;
- }
-
-
- private _draw_connector(x1, y1, x2, y2) {
- return svg`
-
- `;
- }
-
- private _draw_tree(tree: TreeNode | TreeNode[]) {
- if(!tree) return {svg: `Hello`, width: 0, height: 0};
- if(!Array.isArray(tree)) {
- let height = this.nodeSize;
- let width = this.nodeSize;
- let pieces = [];
-
- if(tree.children) {
- const childTrees = tree.children.map((c) =>this._draw_tree(c));
- height += childTrees.reduce((a,i) => Math.max(a, i.height), 0);
- width = childTrees.reduce((a,i) => a+i.width, 0) + this.nodeSeparation*(tree.children.length - 1);
- const offsets = childTrees.map((sum => value => sum += value.width + this.nodeSeparation)(0));
-
- let bottomConnectors = false;
-
- for (const [idx, child] of childTrees.entries()) {
- const x = -width/2 + (idx? offsets[idx-1] : 0) + child.width/2;
- // Draw top connectors
- pieces.push(this._draw_connector(
- 0,
- this.nodeSize/2,
- x,
- this.nodeSize + this.nodeSeparation
- ));
-
-
- let endNode = tree.children[idx];
- if(Array.isArray(endNode)) endNode = endNode[endNode.length -1];
- if(endNode.end !== false) {
- // Draw bottom fill
- pieces.push(this._draw_connector(
- x,
- this.nodeSeparation + child.height,
- x,
- this.nodeSeparation + height
- ));
-
- // Draw bottom connectors
- pieces.push(this._draw_connector(
- x,
- this.nodeSeparation + height,
- 0,
- this.nodeSeparation + height + this.nodeSize/2 + this.nodeSeparation
- ));
- bottomConnectors = true;
- }
-
- // Draw child tree
- pieces.push(svg`
-
- ${child.svg}
-
- `);
- }
- if(bottomConnectors)
- height += this.nodeSize + this.nodeSeparation;
-
- }
- if(tree.addCallback) {
- pieces.push(this._draw_connector(
- 0,
- height,
- 0,
- height + this.nodeSeparation
- ));
- pieces.push(this._draw_new_node(
- 0, height + this.nodeSeparation,
- tree
- ));
- height += this.nodeSeparation + this.nodeSize/2;
- }
- if(tree.end !== false) {
- // Draw bottom connector
- pieces.push(this._draw_connector(
- 0,
- height,
- 0,
- height + this.nodeSeparation
- ));
- height += this.nodeSeparation;
- }
-
- // Draw the node itself
- pieces.push(this._draw_node(0, 0, tree));
-
- return {svg: pieces, width, height};
- }
-
- // Array of trees
- let pieces = [];
- let height = 0;
- const children = tree.map((n) => this._draw_tree(n));
- const width = children.reduce((a,i) => Math.max(a, i.width), 0);
- for (const [_, node] of children.entries()) {
- pieces.push(svg`
-
- ${node.svg}
-
- `);
- height += node.height;
- }
-
- return {svg: pieces, width, height};
-
- }
-
-
- render() {
- let tree = this._draw_tree(this.tree);
- return html`
-
-
- `;
- }
-
-}
-
-customElements.define("script-graph", ScriptGraph2);
-
diff --git a/src/script-graph3.ts b/src/script-graph3.ts
deleted file mode 100644
index a8417db..0000000
--- a/src/script-graph3.ts
+++ /dev/null
@@ -1,298 +0,0 @@
-import {
- LitElement,
- html,
- css,
- svg,
- property,
- TemplateResult,
-} from "lit-element";
-
-import {
- mdiCallSplit,
- mdiAbTesting,
- mdiCheck,
- mdiClose,
- mdiChevronRight,
- mdiExclamation,
- mdiTimerOutline,
- mdiTrafficLight,
- mdiRefresh,
- mdiArrowUp,
- mdiCodeJson,
- mdiCheckBoxOutline,
- mdiCheckboxBlankOutline,
- mdiAsterisk,
- mdiCircleOutline,
-} from "@mdi/js";
-
-const ICONS = {
- "call-split": mdiCallSplit,
- "ab-testing": mdiAbTesting,
- check: mdiCheck,
- close: mdiClose,
- "chevron-right": mdiChevronRight,
- exclamation: mdiExclamation,
- asterisk: mdiAsterisk,
-};
-
-const SIZE = 24;
-
-interface GraphNode extends LitElement {
- render_svg(): TemplateResult;
- width: number;
- height: number;
-}
-
-class ScriptGraphNode extends LitElement {
- @property() icon = "chevron-right";
-
- connectedCallback() {
- super.connectedCallback();
- if (!this.hasAttribute("tabindex")) this.setAttribute("tabindex", "0");
- }
-
- get width() {
- return SIZE + 5;
- }
- get height() {
- return SIZE + 5;
- }
- render() {
- return svg`
-
- `;
- }
-
- static get styles() {
- return css`
- :host {
- display: flex;
- --stroke-clr: var(--stroke-color, rgb(3, 169, 244));
- --hover-clr: var(--hover-color, rgb(255, 152, 0));
- }
- circle {
- stroke: var(--stroke-clr);
- stroke-width: 2;
- fill: white;
- }
- :host(:hover) {
- --stroke-clr: var(--hover-clr);
- }
- :host(:focus) {
- --stroke-clr: green;
- outline: none;
- }
- `;
- }
-}
-
-class ScriptGraphBranch extends LitElement {
- @property() _num_items = 0;
- @property() _branch_height = 30;
- @property() _branch_curve = 25;
-
- get width() {
- let w = 0;
- for (const c of this.children) {
- w += (c as any).width ?? 0;
- }
- return w;
- }
- get height() {
- let h = 0;
- for (const c of this.children) {
- h = Math.max(h, (c as any).height ?? 0);
- }
- return h + 2 * this._branch_height;
- }
-
- async updateChildren() {
- this._num_items = this.children.length;
- }
-
- render() {
- let branch_x = [];
- let total = 0;
- for (const c of Array.from(this.children)) {
- const rect = c.getBoundingClientRect();
- branch_x.push(rect.width / 2 + total);
- total += rect.width;
- }
-
- const line_end = this.height - this._branch_height;
-
- return html`
-
-
-
-
-
- `;
- }
-
- static get styles() {
- return css`
- :host {
- position: relative;
- display: flex;
- --stroke-clr: var(--stroke-color, rgb(3, 169, 244));
- --hover-clr: var(--hover-color, rgb(255, 152, 0));
- }
- #branches {
- position: absolute;
- top: 20px;
- left: 0;
- display: flex;
- flex-direction: row;
- align-items: center;
- }
- path.line {
- stroke: var(--stroke-clr);
- stroke-width: 2;
- fill: white;
- }
- #head {
- position: Absolute;
- top: 5px;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- :host(:focus-within) #head {
- --stroke-color: green;
- }
- `;
- }
-}
-
-class ScriptGraph3 extends LitElement {
- @property() content = [];
- @property() _width = 0;
- @property() _height = 0;
- @property() _distance = 20;
-
- async updateChildren() {
- return;
- }
-
- childrenChangedCallback() {
- console.log("Children changed");
- }
-
- get height() {
- let h = 0;
- for (const c of this.children) {
- h += (c as any).height ?? 0;
- h += this._distance;
- }
- return h + this._distance;
- }
-
- get width() {
- let w = 0;
- for (const c of this.children) {
- w = Math.max(w, (c as any).width ?? 0);
- }
- return w;
- }
-
- render() {
- return html`
-
-
-
-
- `;
- }
-
- static get styles() {
- return css`
- :host {
- position: relative;
- display: flex;
- --stroke-clr: var(--stroke-color, rgb(3, 169, 244));
- --hover-clr: var(--hover-color, rgb(255, 152, 0));
- }
- #nodes {
- position: absolute;
- top: var(--distance, 10px);
- left: 0;
- display: flex;
- flex-direction: column;
- align-items: center;
- }
- ::slotted(*) {
- padding-bottom: var(--distance, 10px);
- }
- path.line {
- stroke: var(--stroke-clr);
- stroke-width: 2;
- fill: white;
- }
- `;
- }
-}
-customElements.define("script-graph3", ScriptGraph3);
-customElements.define("script-graph-node", ScriptGraphNode);
-customElements.define("script-graph-branch", ScriptGraphBranch);
diff --git a/src/script-to-graph.ts b/src/script-to-graph.ts
deleted file mode 100644
index 200c0f3..0000000
--- a/src/script-to-graph.ts
+++ /dev/null
@@ -1,262 +0,0 @@
-import {
- mdiCallSplit,
- mdiAbTesting,
- mdiCheck,
- mdiClose,
- mdiChevronRight,
- mdiExclamation,
- mdiTimerOutline,
- mdiTrafficLight,
- mdiRefresh,
- mdiArrowUp,
- mdiCodeJson,
- mdiCheckBoxOutline,
- mdiCheckboxBlankOutline,
- mdiAsterisk,
-} from "@mdi/js";
-
-const ICONS = {
- new: mdiAsterisk,
- service: mdiChevronRight,
- condition: mdiAbTesting,
- TRUE: mdiCheck,
- FALSE: mdiClose,
- delay: mdiTimerOutline,
- wait_template: mdiTrafficLight,
- event: mdiExclamation,
- repeat: mdiRefresh,
- repeatReturn: mdiArrowUp,
- choose: mdiCallSplit,
- chooseChoice: mdiCheckBoxOutline,
- chooseDefault: mdiCheckboxBlankOutline,
- YAML: mdiCodeJson,
-};
-
-import { TreeNode} from "./script-graph";
-import { Action } from "./types";
-
-const OPTIONS = [
- "condition",
- "delay",
- "device_id",
- "event",
- "scene",
- "service",
- "wait_template",
- "repeat",
- "choose",
-];
-
-interface NodeHandler {
- (action, selected: any[], select, update): TreeNode;
-}
-
-const SPECIAL = {
- condition: (action, selected, select, update) => {
- return {
- icon: ICONS["condition"],
- clickCallback: () => select([1], action, update),
- children: [
- {
- icon: ICONS["TRUE"],
- clickCallback: () => select([2], action, update),
- styles: selected[0]
- ? "stroke: orange;"
- : undefined,
- },
- {
- icon: ICONS["FALSE"],
- end: false,
- clickCallback: () => select([3], action, update),
- styles: selected[0]
- ? "stroke: orange;"
- : undefined,
- },
- ],
- }
- },
-
- repeat: (action, selected, select, update) => {
- let seq = action.repeat.sequence;
- if(!seq || !seq.length) seq = [{}];
- const seqHandler = new ActionHandler(seq);
- if(selected[0] !== undefined && selected[0] !== -1)
- seqHandler.selected = selected;
- seqHandler.selectCallback = select;
- seqHandler.updateCallback = (a) => {
- action.repeat["sequence"] = a;
- update(action);
- }
-
- return {
- icon: ICONS["repeat"],
- clickCallback: () => select([-1], action, update),
- children: [
- {
- icon: ICONS["repeatReturn"],
- clickCallback: () => select([-1], action, update),
- styles: selected[0] === -1
- ? "stroke: orange;"
- : undefined,
- },
- seqHandler.graph,
- ],
- };
- },
-
- choose: (action, selected, select, update) => {
-
- let def = action.default || [{}];
- const defaultHandler = new ActionHandler(def);
- if(selected[0] === -2)
- defaultHandler.selected = selected.slice(1);
- defaultHandler.selectCallback = (i, a, u) => {
- select( [-2].concat(i), a, u);
- };
- defaultHandler.updateCallback = (a) => {
- action.default = defaultHandler.actions;
- update(action);
- };
-
-
- return {
- icon: ICONS["choose"],
- clickCallback: () => select([-1], action, update),
- children: [
- ...action.choose.map((b,idx) => {
- const handler = new ActionHandler(b.sequence || [{}]);
- if(selected[0] === idx)
- handler.selected = selected.slice(1);
- handler.selectCallback = (i, a, u) => {
- select([idx].concat(i), a, u);
- };
- handler.updateCallback = (a) => {
- b.sequence = handler.actions;
- action.choose[idx] = b;
- update(action);
- };
-
- return [
- {
- icon: ICONS["chooseChoice"],
- clickCallback: () => select([idx], b, (a) => {
- action.choose[idx] = a;
- update(action);
- }),
- styles: selected[0] === idx
- ? "stroke: orange;"
- : undefined,
- },
- handler.graph,
- ];
-
- }),
-
- [
- {
- icon: ICONS["chooseDefault"],
- clickCallback: () => select([-2], def, (a) => {
- action.default = a;
- update(action);
- }),
- styles: selected[0] === -2
- ? "stroke: orange;"
- : undefined,
- },
- defaultHandler.graph,
- ]
- ],
- };
- },
-
-};
-
-interface NoAction {
-}
-
-export class ActionHandler {
- _actions: (Action | NoAction)[] = [];
- updateCallback = null;
- selectCallback = null;
- selected: number[] = [];
-
- constructor(actions: (Action | NoAction)[] = []) {
- this._actions = actions;
- }
-
- set actions(actions) {
- this._actions = actions;
- }
-
- get actions() {
- if(!this._actions.length) this._actions = [{}];
- return this._actions;
- }
-
- get graph() {
- return this.actions.map((action, idx) => this._make_graph_node(idx, action));
- }
-
- _update_action(idx: number, action) {
- if(action === null)
- this.actions.splice(idx, 1);
- else
- this.actions[idx] = action;
- if (this.updateCallback)
- this.updateCallback(this.actions);
- }
-
- _add_action(idx: number) {
- this.actions.splice(idx, 0, {});
- if (this.updateCallback)
- this.updateCallback(this.actions);
- this._select_node([idx], {}, (a) =>this._update_action(idx, a));
- }
-
- _select_node(path: number[], action, update=null) {
- this.selected = path;
- if (this.selectCallback)
- this.selectCallback(path, action, update);
- }
-
- _make_graph_node(idx: number, action): TreeNode {
- let _type = "yaml";
- if (Object.keys(action).length === 0)
- _type = "new";
- else
- _type = OPTIONS.find((option) => option in action) || "YAML";
-
- const selected = this.selected.length >= 1 && this.selected[0] == idx;
- let node: TreeNode = {icon: ""};
-
- if (_type in SPECIAL) {
- node = SPECIAL[_type](
- action,
- selected ? this.selected.slice(1): [],
- (i, a, u) => this._select_node([idx].concat(i), a, u),
- (a) => this._update_action(idx, a),
- );
- } else {
- node = {
- icon: ICONS[_type],
- clickCallback: () => {
- this._select_node(
- [idx],
- action,
- (a) => this._update_action(idx, a)
- )
- }
- }
- }
- return {
- ...node,
- addCallback: () => this._add_action(idx+1),
- styles: selected
- ? "stroke: orange"
- : _type === "new"
- ? "stroke: lightgreen;"
- : undefined,
- }
- }
-
-}
diff --git a/src/types.ts b/src/types.ts
deleted file mode 100644
index 2881f17..0000000
--- a/src/types.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-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;