diff --git a/bundles/org.openhab.ui/doc/components/index.md b/bundles/org.openhab.ui/doc/components/index.md index bf2a52892a..ac84314c61 100644 --- a/bundles/org.openhab.ui/doc/components/index.md +++ b/bundles/org.openhab.ui/doc/components/index.md @@ -14,6 +14,7 @@ source: https://github.com/openhab/openhab-webui/edit/main/bundles/org.openhab.u | [`oh-chart`](./oh-chart.html) | [Chart](./oh-chart.html) | Visualize series of data | | [`oh-clock`](./oh-clock.html) | [Digital Clock](./oh-clock.html) | Display a digital clock | | [`oh-colorpicker`](./oh-colorpicker.html) | [Colorpicker](./oh-colorpicker.html) | Control to pick a color | +| [`oh-context`](./oh-context.html) | [Context](./oh-context.html) | Non-rendered component with functions, constants, and scoped variables for widgets | | [`oh-gauge`](./oh-gauge.html) | [Gauge](./oh-gauge.html) | Circular or semi-circular read-only gauge | | [`oh-icon`](./oh-icon.html) | [Icon](./oh-icon.html) | Display an openHAB icon | | [`oh-image`](./oh-image.html) | [Image](./oh-image.html) | Displays an image from a URL or an item | diff --git a/bundles/org.openhab.ui/doc/components/oh-context.md b/bundles/org.openhab.ui/doc/components/oh-context.md new file mode 100644 index 0000000000..bdcffcc2bf --- /dev/null +++ b/bundles/org.openhab.ui/doc/components/oh-context.md @@ -0,0 +1,101 @@ +--- +title: oh-context - Widget Context +component: oh-context +label: Widget Context +description: Non-rendered component with functions, constants, and local variables for widgets +source: https://github.com/openhab/openhab-webui/edit/main/bundles/org.openhab.ui/doc/components/oh-context.md +prev: /docs/ui/components/ +--- + +# oh-context - Widget Context + + + +[[toc]] + + + + +Non-rendered component with functions, constants, and scoped variables for widgets + + +## Configuration + + + +### General +
+ + + + Object with key:arrow-function pairs. Functions are available to expressions in all child components via the fn object. + + + + + Object with key:constant pairs. Constants are available to expressions in all child components via the const object. + + + + + Object with key:variable default value pairs. Variables are available to expressions in all child components via the vars object and take precedence over variables with the same name from higher contexts. + + + +
+ + + + + + + + + + + diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/context.js b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/context.js new file mode 100644 index 0000000000..2522d37231 --- /dev/null +++ b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/context.js @@ -0,0 +1,7 @@ +import { pt, pb, pi, pn } from '../helpers.js' + +export default () => [ + pt('functions', 'Widget Functions', 'Object with key:arrow-function pairs. Functions are available to expressions in all child components via the fn object.'), + pt('constants', 'Widget Constants', 'Object with key:constant pairs. Constants are available to expressions in all child components via the const object.'), + pt('variables', 'Widget Variables', 'Object with key:variable default value pairs. Variables are available to expressions in all child components via the vars object and take precedence over variables with the same name from higher contexts.') +] diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/index.js b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/index.js index c41fdb64e2..d53d953e61 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/index.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/widgets/system/index.js @@ -20,6 +20,10 @@ import ColorpickerParameters from './colorpicker.js' export const OhColorpickerDefinition = () => new WidgetDefinition('oh-colorpicker', 'Colorpicker', 'Control to pick a color') .params(ColorpickerParameters()) +import ContextParameters from './context.js' +export const OhContextDefinition = () => new WidgetDefinition('oh-context', 'Context', 'Non-rendered component with functions, constants, and scoped variables for widgets') + .params(ContextParameters()) + import GaugeParameters from './gauge.js' export const OhGaugeDefinition = () => new WidgetDefinition('oh-gauge', 'Gauge', 'Circular or semi-circular read-only gauge') .params(GaugeParameters()) diff --git a/bundles/org.openhab.ui/web/src/components/config/editor/hint-components.js b/bundles/org.openhab.ui/web/src/components/config/editor/hint-components.js index 3a7ec25757..df78ef7799 100644 --- a/bundles/org.openhab.ui/web/src/components/config/editor/hint-components.js +++ b/bundles/org.openhab.ui/web/src/components/config/editor/hint-components.js @@ -107,6 +107,8 @@ function hintExpression (cm, line) { { text: 'props.', displayText: 'props', description: 'Access to the props of the parent root component' }, { text: 'config.', displayText: 'config', description: 'Access to the configuration of the current component' }, { text: 'vars.', displayText: 'vars', description: 'Access to context vars' }, + { text: 'fn.', displayText: 'fn', description: 'Access to oh-context functions' }, + { text: 'const.', displayText: 'const', description: 'Access to oh-context constants' }, { text: 'loop.', displayText: 'loop', description: 'Access to oh-repeater loop variables' }, { text: 'JSON.', displayText: 'JSON', description: 'Access to the JSON object functions' }, { text: 'Math.', displayText: 'Math', description: 'Access to the Math object functions' }, diff --git a/bundles/org.openhab.ui/web/src/components/widgets/modals/modal-mixin.js b/bundles/org.openhab.ui/web/src/components/widgets/modals/modal-mixin.js index 912e6e246e..d80f705df4 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/modals/modal-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/modals/modal-mixin.js @@ -12,6 +12,7 @@ export default { return { currentTab: 0, vars: {}, + ctxVars: {}, tabVars: {} } }, @@ -24,6 +25,7 @@ export default { store: this.$store.getters.trackedItems, props: this.modalConfig, vars: this.vars, + ctxVars: this.ctxVars, modalConfig: this.modalConfig // For configuration of oh- components } }, @@ -67,6 +69,7 @@ export default { onTabChange (idx) { this.currentTab = idx this.$set(this, 'vars', {}) + this.$set(this, 'ctxVars', {}) }, tabContext (tab) { const page = this.$store.getters.page(tab.config.page.replace('page:', '')) diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/index.js b/bundles/org.openhab.ui/web/src/components/widgets/system/index.js index 10145440f5..6e60f5d461 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/index.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/index.js @@ -22,3 +22,4 @@ export { default as OhRepeater } from './oh-repeater.vue' export { default as OhChart } from './oh-chart.vue' export { default as OhClock } from './oh-clock.vue' export { default as OhSipclient } from './oh-sipclient.vue' +export { default as OhContext } from './oh-context.vue' diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-button.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-button.vue index fa633349cf..ffa8543063 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-button.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-button.vue @@ -22,19 +22,29 @@ export default { } if (this.config.clearVariable && !this.config.clearVariableKey) { if (Array.isArray(this.config.clearVariable)) { - this.config.clearVariable.forEach((v) => this.$set(this.context.vars, v, undefined)) + this.config.clearVariable.forEach((v) => { + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, v) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + this.$set(clearVariableLocation, v, undefined) + }) } else if (typeof this.config.clearVariable === 'string') { - this.$set(this.context.vars, this.config.clearVariable, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + this.$set(clearVariableLocation, this.config.clearVariable, undefined) } } if (this.config.clearVariable && this.config.clearVariableKey) { let value = this.context.vars[this.config.clearVariable] if (Array.isArray(this.config.clearVariableKey)) { this.config.clearVariableKey.forEach((key) => { - value = this.setVariableKeyValues(value, key, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + value = this.setVariableKeyValues(clearVariableLocation, key, undefined) }) } else if (typeof this.config.clearVariableKey === 'string') { - value = this.setVariableKeyValues(value, this.config.clearVariableKey, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + value = this.setVariableKeyValues(clearVariableLocation, this.config.clearVariableKey, undefined) } this.$set(this.context.vars, this.config.clearVariable, value) } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-context.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-context.vue new file mode 100644 index 0000000000..80631ebb4c --- /dev/null +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-context.vue @@ -0,0 +1,89 @@ + + + diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-gauge.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-gauge.vue index c8ce3ea1a2..dff0ee6e1c 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-gauge.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-gauge.vue @@ -11,7 +11,11 @@ export default { widget: OhGaugeDefinition, computed: { value () { - if (this.config.variable) return this.context.vars[this.config.variable] + if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars + return variableLocation[this.config.variable] + } let value = (this.config.item) ? this.context.store[this.config.item].state : this.config.value // use as a brightness indicator for HSB values if (value.split && value.split(',').length === 3) value = value.split(',')[2] diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-input.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-input.vue index 274e3f589f..cc044769ca 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-input.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-input.vue @@ -37,13 +37,18 @@ export default { }, computed: { value () { + let variableLocation = this.context.vars + if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + if (variableScope) variableLocation = this.context.ctxVars[variableScope] + } if (this.config.variable && this.config.variableKey) { - const keyValue = this.getLastVariableKeyValue(this.context.vars[this.config.variable], this.config.variableKey) + const keyValue = this.getLastVariableKeyValue(variableLocation[this.config.variable], this.config.variableKey) if (keyValue) { return keyValue } - } else if (this.config.variable && this.context.vars[this.config.variable] !== undefined) { - return this.context.vars[this.config.variable] + } else if (this.config.variable && variableLocation[this.config.variable] !== undefined) { + return variableLocation[this.config.variable] } else if (this.config.sendButton && this.pendingUpdate !== null) { return this.pendingUpdate } else if (this.config.item && this.context.store[this.config.item].state !== 'NULL' && this.context.store[this.config.item].state !== 'UNDEF' && this.context.store[this.config.item].state !== 'Invalid Date') { @@ -107,10 +112,12 @@ export default { this.$set(this, 'pendingUpdate', value) } if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - value = this.setVariableKeyValues(this.context.vars[this.config.variable], this.config.variableKey, value) + value = this.setVariableKeyValues(variableLocation[this.config.variable], this.config.variableKey, value) } - this.$set(this.context.vars, this.config.variable, value) + this.$set(variableLocation, this.config.variable, value) } }, sendButtonClicked () { diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-link.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-link.vue index f32e1362b5..0fef857546 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-link.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-link.vue @@ -22,19 +22,29 @@ export default { } if (this.config.clearVariable && !this.config.clearVariableKey) { if (Array.isArray(this.config.clearVariable)) { - this.config.clearVariable.forEach((v) => this.$set(this.context.vars, v, undefined)) + this.config.clearVariable.forEach((v) => { + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, v) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + this.$set(clearVariableLocation, v, undefined) + }) } else if (typeof this.config.clearVariable === 'string') { - this.$set(this.context.vars, this.config.clearVariable, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + this.$set(clearVariableLocation, this.config.clearVariable, undefined) } } if (this.config.clearVariable && this.config.clearVariableKey) { let value = this.context.vars[this.config.clearVariable] if (Array.isArray(this.config.clearVariableKey)) { this.config.clearVariableKey.forEach((key) => { - value = this.setVariableKeyValues(value, key, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + value = this.setVariableKeyValues(clearVariableLocation, key, undefined) }) } else if (typeof this.config.clearVariableKey === 'string') { - value = this.setVariableKeyValues(value, this.config.clearVariableKey, undefined) + const clearVariableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.clearVariable) + const clearVariableLocation = (clearVariableScope) ? this.context.ctxVars[clearVariableScope] : this.context.vars + value = this.setVariableKeyValues(clearVariableLocation, this.config.clearVariableKey, undefined) } this.$set(this.context.vars, this.config.clearVariable, value) } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-stepper.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-stepper.vue index 33515bc879..b412c01775 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-stepper.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-stepper.vue @@ -24,10 +24,12 @@ export default { value () { const applyOffset = (num) => (!isNaN(this.config.offset)) ? Number(this.toStepFixed(num + Number(this.config.offset))) : num if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - return applyOffset(this.getLastVariableKeyValue(this.context.vars[this.config.variable], this.config.variableKey)) + return applyOffset(this.getLastVariableKeyValue(variableLocation[this.config.variable], this.config.variableKey)) } - return applyOffset(this.context.vars[this.config.variable]) + return applyOffset(variableLocation[this.config.variable]) } let value = applyOffset(parseFloat(this.context.store[this.config.item].state)) if (this.config.min !== undefined) value = Math.max(value, this.config.min) @@ -71,10 +73,12 @@ export default { if (isNaN(newValue)) newValue = this.config.min || this.config.max || 0 if (newValue === this.value) return if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - newValue = applyOffset(this.setVariableKeyValues(this.context.vars[this.config.variable], this.config.variableKey, value)) + newValue = applyOffset(this.setVariableKeyValues(variableLocation[this.config.variable], this.config.variableKey, value)) } - this.$set(this.context.vars, this.config.variable, newValue) + this.$set(variableLocation, this.config.variable, newValue) } else if (this.config.item) { this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: newValue.toString() }) } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-toggle.vue b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-toggle.vue index fa00083dac..30c59ccf1f 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/oh-toggle.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/oh-toggle.vue @@ -16,10 +16,12 @@ export default { computed: { value () { if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - return this.getLastVariableKeyValue(this.context.vars[this.config.variable], this.config.variableKey) + return this.getLastVariableKeyValue(variableLocation[this.config.variable], this.config.variableKey) } - return this.context.vars[this.config.variable] + return variableLocation[this.config.variable] } if (!this.context.store[this.config.item]) return const value = this.context.store[this.config.item].state @@ -33,10 +35,12 @@ export default { onChange (value) { if (value === this.value) return if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - value = this.setVariableKeyValues(this.context.vars[this.config.variable], this.config.variableKey, value) + value = this.setVariableKeyValues(variableLocation[this.config.variable], this.config.variableKey, value) } - this.$set(this.context.vars, this.config.variable, value) + this.$set(variableLocation, this.config.variable, value) } else if (this.config.item) { this.$store.dispatch('sendCommand', { itemName: this.config.item, cmd: (value) ? 'ON' : 'OFF' }) } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/system/slide-mixin.js b/bundles/org.openhab.ui/web/src/components/widgets/system/slide-mixin.js index cca43202fc..35b43def12 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/system/slide-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/system/slide-mixin.js @@ -16,10 +16,12 @@ export default { computed: { value () { if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - return this.getLastVariableKeyValue(this.context.vars[this.config.variable], this.config.variableKey) + return this.getLastVariableKeyValue(variableLocation[this.config.variable], this.config.variableKey) } else { - return this.context.vars[this.config.variable] + return variableLocation[this.config.variable] } } if (this.pendingCommand !== null) return this.pendingCommand // to keep the control reactive when operating @@ -40,10 +42,12 @@ export default { if ((value === this.value && !stop) || value === this.lastValueSent) return if (this.config.variable) { + const variableScope = this.getVariableScope(this.context.ctxVars, this.context.varScope, this.config.variable) + const variableLocation = (variableScope) ? this.context.ctxVars[variableScope] : this.context.vars if (this.config.variableKey) { - value = this.setVariableKeyValues(this.context.vars[this.config.variable], this.config.variableKey, value) + value = this.setVariableKeyValues(variableLocation[this.config.variable], this.config.variableKey, value) } - this.$set(this.context.vars, this.config.variable, value) + this.$set(variableLocation, this.config.variable, value) return } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/variable-mixin.js b/bundles/org.openhab.ui/web/src/components/widgets/variable-mixin.js index fba8529c6d..93b45bbc2d 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/variable-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/variable-mixin.js @@ -90,6 +90,30 @@ export default { } } return obj + }, + /** + * Get the oh-context variables scope for a given variable key. + * + * If no variable with the given key is found in the given scope, the parent context/scope is checked, and so on. + * If the variable is not found in any scope, null is returned. + * + * oh-context variables are local in scope to the oh-context and it's children and take precedence over other variables + * of the same name from higher contexts/scopes, including normal variables. + * Changes to oh-context variables done by children are always propagated to the parent, which is not the case with normal variables used inside widgets. + * + * @param {object} varObj the object containing the variables for each context/scope + * @param {string} scopeObj the key of the given variable context/scope + * @param {string} key the key of the variable + * @returns {string|null} the key of the variable context/scope to be used + */ + getVariableScope (varObj, scopeObj, key) { + if (!scopeObj) return null + const scopeIDs = scopeObj.split('-') + for (let scope_idx = scopeIDs.length; scope_idx > 1; scope_idx--) { + const scopeKey = scopeIDs.slice(0, scope_idx).join('-') + if (Object.keys(varObj[scopeKey]).includes(key)) return scopeKey + } + return null } } } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/widget-actions.js b/bundles/org.openhab.ui/web/src/components/widgets/widget-actions.js index 1baa8a6278..b281d61405 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/widget-actions.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/widget-actions.js @@ -271,10 +271,12 @@ export const actionsMixin = { const actionVariable = actionConfig[prefix + 'actionVariable'] let actionVariableValue = actionConfig[prefix + 'actionVariableValue'] const actionVariableKey = actionConfig[prefix + 'actionVariableKey'] + const actionVariableScope = this.getVariableScope(context.ctxVars, context.varScope, actionVariable) + const actionVariableLocation = (actionVariableScope) ? context.ctxVars[actionVariableScope] : context.vars if (actionVariableKey) { - actionVariableValue = this.setVariableKeyValues(context.vars[actionVariable], actionVariableKey, actionVariableValue) + actionVariableValue = this.setVariableKeyValues(actionVariableLocation[actionVariable], actionVariableKey, actionVariableValue) } - this.$set(context.vars, actionVariable, actionVariableValue) + this.$set(actionVariableLocation, actionVariable, actionVariableValue) break default: console.log('Invalid action: ' + action) diff --git a/bundles/org.openhab.ui/web/src/components/widgets/widget-expression-mixin.js b/bundles/org.openhab.ui/web/src/components/widgets/widget-expression-mixin.js index 273a3664a0..7dd513ba05 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/widget-expression-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/widget-expression-mixin.js @@ -68,7 +68,9 @@ export default { items: ctx.store, props: props || this.props, config: ctx.component.config, - vars: ctx.vars, + fn: ctx.fn, + const: ctx.const, + vars: this.getAllVars(ctx), loop: ctx.loop, Math: Math, Number: Number, @@ -114,6 +116,24 @@ export default { viewAreaWidth: pageContent.clientWidth - parseFloat(pageContentStyle.paddingLeft) - parseFloat(pageContentStyle.paddingRight), viewAreaHeight: pageContent.clientHeight - parseFloat(pageContentStyle.paddingTop) - parseFloat(pageContentStyle.paddingBottom) } + }, + getAllVars (context) { + const vars = {} + if (context.vars) { + for (const varKey in context.vars) { + vars[varKey] = context.vars[varKey] + } + } + if (context.varScope) { + const scopeIDs = context.varScope.split('-') + for (let scope_idx = 1; scope_idx < scopeIDs.length; scope_idx++) { + let scopeKey = scopeIDs.slice(0, scope_idx + 1).join('-') + for (const varKey in context.ctxVars[scopeKey]) { + vars[varKey] = context.ctxVars[scopeKey][varKey] + } + } + } + return vars } } } diff --git a/bundles/org.openhab.ui/web/src/components/widgets/widget-mixin.js b/bundles/org.openhab.ui/web/src/components/widgets/widget-mixin.js index b42cfd76cd..b40c9b38dc 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/widget-mixin.js +++ b/bundles/org.openhab.ui/web/src/components/widgets/widget-mixin.js @@ -9,6 +9,7 @@ export default { data () { return { vars: (this.context) ? this.context.vars : {}, + ctxVars: (this.context) ? this.context.ctxVars : {}, widgetVars: {} } }, @@ -32,7 +33,7 @@ export default { if (sourceConfig) { if (typeof sourceConfig !== 'object') return {} for (const key in sourceConfig) { - if (key === 'visible' || key === 'visibleTo' || key === 'stylesheet') continue + if (key === 'visible' || key === 'visibleTo' || key === 'stylesheet' || key === 'constants') continue this.$set(evalConfig, key, this.evaluateExpression(key, sourceConfig[key])) } } @@ -69,7 +70,7 @@ export default { } }, mounted () { - if (this.context && this.context.component.config && this.context.component.config.stylesheet) { + if (this.context && this.context.component && this.context.component.config && this.context.component.config.stylesheet) { this.cssUid = 'scoped-' + this.$f7.utils.id() this.$el.classList.add(this.cssUid) @@ -92,7 +93,11 @@ export default { component: component, rootcomponent: this.context.root || this.context.component, props: this.props, + fn: this.context.fn, + const: this.context.const, vars: this.context.vars, + varScope: this.varScope || this.context.varScope, + ctxVars: this.context.ctxVars, loop: this.context.loop, store: this.context.store, config: this.context.config, @@ -117,7 +122,11 @@ export default { component: widget, root: widget, props: this.config, + fn: this.context.fn, + const: this.context.const, vars: this.widgetVars, + varScope: this.varScope || this.context.varScope, + ctxVars: this.context.ctxVars, store: this.context.store, config: this.context.config, editmode: this.context.editmode, diff --git a/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue b/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue index 5cd1de0f4f..18a6d8d6bc 100644 --- a/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue +++ b/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue @@ -124,6 +124,7 @@ export default { split: 'vertical', props: {}, vars: {}, + ctxVars: {}, blockKey: this.$f7.utils.id(), widgetKey: this.$f7.utils.id(), widgetPropsOpened: false, @@ -146,7 +147,8 @@ export default { : this.widget, store: this.$store.getters.trackedItems, props: this.props, - vars: this.vars + vars: this.vars, + ctxVars: this.ctxVars } }, widget () { @@ -301,6 +303,7 @@ export default { this.$store.dispatch('sendCommand', { itemName, cmd }) }, redrawWidget () { + this.ctxVars = {} this.widgetKey = this.$f7.utils.id() // const wd = this.widgetDefinition // this.widgetDefinition = 'component: Label\nnconfig: { text: "Redrawing..."}'