Skip to content
Permalink
Browse files

WIP Rules editor

  • Loading branch information...
robin-dekkers committed Apr 8, 2019
1 parent cbd5206 commit 1f2c914623933dc3c50c5118d6ab93528e397d12
@@ -1,5 +1,7 @@
import {html, LitElement, property} from 'lit-element';


import {orInputStyle} from './style';
class OrInput extends LitElement {

@property({type: String})
@@ -11,6 +13,13 @@ class OrInput extends LitElement {
@property({type: String})
value: string = '';


static get styles() {
return [
orInputStyle
];
}

protected render() {

return html`
@@ -21,16 +30,17 @@ class OrInput extends LitElement {

onChange() {
if(this.shadowRoot){
const value = (<HTMLInputElement>this.shadowRoot.getElementById('or-input')).value;
const input = (<HTMLInputElement>this.shadowRoot.getElementById('or-input'));
const value = input.value;
const name = input.name;

// Launch event for all parent elements
let event = new CustomEvent('or-input:changed', {
detail: { value: value },
detail: { value: value, name: name },
bubbles: true,
composed: true });

this.dispatchEvent(event);

}
}

@@ -0,0 +1,15 @@
import {css} from "lit-element";

// TODO this is temp work, should be replaced with material design components / styling
// language=CSS
export const orInputStyle = css`
input {
position: relative;
font-family: inherit;
background-color: transparent;
padding: 10px;
border-radius: 0;
border: none;
font-size: 14px;
}
`;
@@ -2,7 +2,14 @@ import {customElement, html, LitElement, property, TemplateResult} from "lit-ele

import "@openremote/or-select";
import "@openremote/or-icon";
import {Rule, RuleActionWriteAttribute, RulesetLang, TenantRuleset} from "@openremote/model";
import {
AttributeDescriptor,
Rule,
RuleActionWriteAttribute,
RulesetLang,
TenantRuleset,
ValueType
} from "@openremote/model";
import openremote from "@openremote/core";
import rest from "@openremote/rest";

@@ -29,6 +36,32 @@ const rulesetModel: TenantRuleset = {
rules: JSON.stringify({rules: [ruleModel]})
};


const attributeDescriptors: AttributeDescriptor[] = [
{name: "profiles", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}},
{name: "airportIata", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}},
{name: "airlineIata", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}},
{name: "originRegion", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}},
{name: "languageCodes", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}},
{name: "passengerCapacity", valueDescriptor: {name: "NUMBER", valueType: ValueType.NUMBER}},
{name: "countryCode", valueDescriptor: {name: "STRING", valueType: ValueType.STRING}}
];

const rulesEditorConfig = {
languageCodes: {
options: [
"Dutch",
"English",
]
},
countryCode: {
options: [
"NL",
"GB",
]
},
};

class InputHandlers {
public handlers: Array<(condition: RuleActionWriteAttribute) => TemplateResult | undefined> = [];

@@ -74,13 +107,17 @@ class OrRulesEditor extends LitElement {
super();
this.readRules();
this.addEventListener("rules:set-active-rule", this.setActiveRule);
this.addEventListener("rules:write-rule", this.writeRule);
this.addEventListener("rules:create-rule", this.createRule);
this.addEventListener("rules:update-rule", this.updateRule);
this.addEventListener("rules:delete-rule", this.deleteRule);
}

public readRules() {
rest.api.RulesResource.getTenantRulesets(openremote.config.realm, { language: RulesetLang.JSON, fullyPopulate: true }).then((response: any) => {
rest.api.RulesResource.getTenantRulesets(openremote.config.realm, {
language: RulesetLang.JSON,
fullyPopulate: true
}).then((response: any) => {
if (response && response.data) {
this.rulesets = response.data;
if (this.ruleset && this.rulesets) {
@@ -112,7 +149,15 @@ class OrRulesEditor extends LitElement {
this.ruleset = newRule;
this.computeRuleset();

rest.api.RulesResource.createTenantRuleset(newRule).then((response: any) => {

}
}

public writeRule() {
if (this.ruleset && this.rule) {
this.rule.name = this.ruleset.name;
this.ruleset.rules = JSON.stringify({rules: [this.rule]});
rest.api.RulesResource.createTenantRuleset(this.ruleset).then((response: any) => {
this.readRules();
});
}
@@ -128,11 +173,11 @@ class OrRulesEditor extends LitElement {

// Parse rule to string of array of rules
this.rule.name = this.ruleset.name;
this.ruleset.rules = JSON.stringify({rules: [this.rule] });
this.ruleset.rules = JSON.stringify({rules: [this.rule]});

// this.ruleset.rules = JSON.stringify(this.rules);
rest.api.RulesResource.updateTenantRuleset(this.ruleset.id, this.ruleset).then((response: any) => {
this.readRules();
this.readRules();
});
}

@@ -162,7 +207,6 @@ class OrRulesEditor extends LitElement {
this.rule = ruleModel;
this.rule.name = this.ruleset.name;
}

this.requestUpdate();
}

@@ -177,20 +221,20 @@ class OrRulesEditor extends LitElement {
return html`
<div class="rule-editor-container">
<side-menu class="bg-white shadow">
<or-rule-list .rulesets="${this.rulesets}" .ruleset="${this.ruleset}"></or-rule-list>
<or-rule-list .rulesets="${this.rulesets}" .ruleset="${this.ruleset}" ></or-rule-list>
<div class="bottom-toolbar">
<icon class="small-icon" @click="${this.deleteRule}"><or-icon icon="delete"></or-icon></icon>
<icon class="small-icon" @click="${this.createRule}"><or-icon icon="plus"></or-icon></icon>
</div>
</side-menu>
${this.ruleset ? html`
<or-body>
<or-rule-header class="bg-white shadow" .ruleset="${this.ruleset}"></or-rule-header>
<or-rule-header class="bg-white shadow" .ruleset="${this.ruleset}" .rule="${this.rule}"></or-rule-header>
${this.rule ? html`
<div class="content">
<or-rule-when .rule="${this.rule}"></or-rule-when>
<or-rule-then .rule="${this.rule}"></or-rule-then>
<or-rule-when .rule="${this.rule}" .attributeDescriptors="${attributeDescriptors}"></or-rule-when>
<or-rule-then .rule="${this.rule}" .attributeDescriptors="${attributeDescriptors}"></or-rule-then>
</div>
` : ``}
@@ -38,7 +38,12 @@ class OrRuleHeader extends LitElement {
<span @click="${this.toggleEditmode}"><or-icon style="margin:10px;" icon="pencil-outline"></or-icon></span>
<span class="rule-status ${this.ruleset && this.ruleset.enabled ? 'bg-green' : 'bg-red'}"></span>
<or-toggle @click="${this.toggleEnabled}">toggle</or-toggle>
<button @click="${this.updateRule}">opslaan</button>
${this.ruleset && this.ruleset.id ? html`
<button @click="${this.updateRule}">opslaan</button>
` : html`
<button @click="${this.createRule}">toevoegen</button>
`}
</div>
</div>
`;
@@ -57,6 +62,15 @@ class OrRuleHeader extends LitElement {
}
}

createRule() {
let event = new CustomEvent('rules:write-rule', {
detail: {ruleset: this.ruleset},
bubbles: true,
composed: true
});
this.dispatchEvent(event);
}

updateRule() {
let event = new CustomEvent('rules:update-rule', {
detail: {ruleset: this.ruleset},
@@ -7,8 +7,9 @@ import "@openremote/or-select";
import "@openremote/or-icon";
import handler from "../index";
import {style} from "./style";
import set from 'lodash/set';

import {RuleActionUnion, RuleActionWriteAttribute} from "@openremote/model";
import {RuleActionUnion, RuleActionWriteAttribute, AttributeDescriptor} from "@openremote/model";

// TODO use create select option to
@customElement("or-rule-then-condition")
@@ -26,6 +27,9 @@ class OrRuleThenCondition extends LitElement {
@property({type: Number})
private value: number = 0;

@property({type: Array})
public attributeDescriptors?: AttributeDescriptor[];

constructor() {
super();

@@ -34,9 +38,9 @@ class OrRuleThenCondition extends LitElement {

public setValue(e: any) {
const value = e.detail.value;

const name = e.detail.name;
if (this.condition && this.condition.value) {
this.condition.value = value;
this.condition.value = set(this.condition.value, name, value);
this.requestUpdate();
}
}
@@ -46,7 +50,7 @@ class OrRuleThenCondition extends LitElement {
return html`
<div class="rule-container">
${this.condition ? html`
<or-select-asset-attribute disabled type="${this.condition}" value="${this.condition.attributeName}"></or-select-asset-attribute>
<or-select-asset-attribute disabled type="${this.condition}" value="${this.condition.attributeName}" .attributeDescriptors="${this.attributeDescriptors}"></or-select-asset-attribute>
<or-select-operator disabled type="${this.condition}" value="EQUAL"></or-select-operator>
${this.createInputControl(this.condition!)}
` : ``}
@@ -59,7 +63,8 @@ class OrRuleThenCondition extends LitElement {

const result = h(this.condition!);
if (result) {
return html`${result}`;
let response = html`${result}`;
return response;
}
}

@@ -9,7 +9,7 @@ export const style = css`
.rule-container {
display: flex;
margin-bottom: 10px;
padding: 15px 20px;
padding: 5px 20px;
border-radius: 5px;
border: 1px solid var(--app-lightgrey-color, #F5F5F5);
@@ -1,7 +1,8 @@
import {html, LitElement, property, customElement, PropertyValues} from 'lit-element';

import {style} from './style';
import {Rule, RuleTrigger, RuleActionUnion, NewAssetQuery, BaseAssetQueryMatch} from "@openremote/model";
import {Rule, RuleTrigger, RuleActionUnion, NewAssetQuery, BaseAssetQueryMatch, RuleActionUpdateAttributeUpdateAction,
AttributeDescriptor} from "@openremote/model";

import '../or-rule-then-condition';

@@ -15,9 +16,14 @@ const defaultAssetType:NewAssetQuery = {
};

let defaultThenCondition:RuleActionUnion = {
action: "write-attribute",
attributeName: 'profileColor',
value: {"%RULESET_ID%": {"profileName":"%RULESET_NAME%", "profileColor": "red"}},
action: "update-attribute",
updateAction: RuleActionUpdateAttributeUpdateAction.ADD_OR_REPLACE,
attributeName: "profiles",
key: "%RULESET_ID%",
value: {
profileName: "%RULESET_NAME%",
profileColor: "orange"
},
target: { "useAssetsFromWhen": true}
};

@@ -40,7 +46,7 @@ class OrRuleThen extends LitElement {
<div class="rule-then-container bg-white shadow">
${this.rule && this.rule.then ? this.rule.then.map((then:RuleActionUnion) => {
return html`
<or-rule-then-condition .condition="${then}"></or-rule-then-condition>
<or-rule-then-condition .condition="${then}" .attributeDescriptors="${this.attributeDescriptors}"></or-rule-then-condition>
<span class="rule-additional">&</span>
`
}) : ``}
@@ -53,6 +59,10 @@ class OrRuleThen extends LitElement {
@property({type: Object})
rule?: Rule;

@property({type: Array})
public attributeDescriptors?: AttributeDescriptor[];


constructor() {
super();
}
@@ -7,7 +7,8 @@ import '@openremote/or-select';
import '@openremote/or-icon';

import {style} from './style';
import {AttributePredicate} from "@openremote/model";
import {AttributePredicate, AttributeDescriptor, ValueType} from "@openremote/model";
import find from 'lodash/find';

@customElement('or-rule-when-condition')
class OrRuleWhenCondition extends LitElement {
@@ -29,15 +30,19 @@ class OrRuleWhenCondition extends LitElement {
</or-select-asset-type>
${this.predicate.name ? html`
<or-select-asset-attribute icon="${this.predicate}" value="${this.predicate.name.value}"></or-select-asset-attribute>
<or-select-asset-attribute icon="${this.predicate}" value="${this.predicate.name.value}" .attributeDescriptors="${this.attributeDescriptors}"></or-select-asset-attribute>
${this.predicate.value && this.predicate.value.predicateType === 'string' ? html`
${this.predicate.name.value ? html`
<or-select-operator type="${this.predicate.value.predicateType}" value="${this.predicate.value.match}"></or-select-operator>
<or-select-operator type="${this.getAttributeDescriptors(this.predicate.name.value)!.valueDescriptor!.valueType}" value="${this.predicate.value.match}"></or-select-operator>
` : ``}
${this.predicate.value.match ? html`
<or-input type="text" value="${this.predicate.value.value ? this.predicate.value.value : ''}"></or-input>
${this.predicate.name.value && this.predicate.value.match ? html`
${this.getAttributeDescriptors(this.predicate.name.value)!.valueDescriptor!.valueType === ValueType.ARRAY ? html`
<or-select .options="${this.getAttributeDescriptors(this.predicate.name.value)!.initialValue}" value="${this.predicate.value.value ? this.predicate.value.value : ''}"></or-select>
`: html`
<or-input type="text" value="${this.predicate.value.value ? this.predicate.value.value : ''}"></or-input>
`}
` : ``}
${this.predicate.value.value ? html`
@@ -61,6 +66,8 @@ class OrRuleWhenCondition extends LitElement {
@property({type: Number})
index?: number;

@property({type: Array})
public attributeDescriptors?: AttributeDescriptor[];

// setAssetType(value:string) {
// const assetType = {
@@ -75,13 +82,17 @@ class OrRuleWhenCondition extends LitElement {
// }
// }

getAttributeDescriptors(name: string) {
return find(this.attributeDescriptors, ['name', name]);
}

setAssetAttribute(e:any) {
const value = e.detail.value;

if(this.predicate && this.predicate.name) {
this.predicate.name.value = value;

this.setOperator(e)
this.setOperator(e);
this.requestUpdate();
}
}
Oops, something went wrong.

0 comments on commit 1f2c914

Please sign in to comment.
You can’t perform that action at this time.