Add missing sitemap attributes (#1487)
Closes #324. Signed-off-by: Mark Herwege <mark.herwege@telenet.be>pull/1512/head
parent
09adec507b
commit
72fe51ea1d
|
@ -11,11 +11,15 @@
|
|||
label: 'label=',
|
||||
item: 'item=',
|
||||
icon: 'icon=',
|
||||
widgetattr: ['url=', 'refresh=', 'service=', 'refresh=', 'period=', 'legend=', 'height=', 'frequency=', 'sendFrequency=',
|
||||
'switchEnabled=', 'mappings=', 'minValue=', 'maxValue=', 'step=', 'separator=', 'encoding='],
|
||||
widgetattr: ['url=', 'refresh=', 'service=', 'period=', 'legend=', 'height=', 'mappings=', 'minValue=', 'maxValue=', 'step=', 'separator=', 'encoding=', 'yAxisDecimalPattern='],
|
||||
widgetfreqattr: 'sendFrequency=',
|
||||
widgetfrcitmattr: 'forceasitem=',
|
||||
widgetvisiattr: 'visibility=',
|
||||
widgetcolorattr: ['labelcolor=', 'valuecolor=', 'iconcolor='],
|
||||
widgetswitchattr: 'switchSupport',
|
||||
nlwidget: ['Switch ', 'Selection ', 'Slider ', 'List ', 'Setpoint ', 'Video ', 'Chart ', 'Webview ', 'Colorpicker ', 'Mapview ', 'Default '],
|
||||
lwidget: ['Text ', 'Group ', 'Image ', 'Frame '],
|
||||
identifier: /[A-Za-z0-9_]+/,
|
||||
identifier: /[A-Za-z][A-Za-z0-9_]*/,
|
||||
lparen: '(',
|
||||
rparen: ')',
|
||||
colon: ':',
|
||||
|
@ -23,6 +27,10 @@
|
|||
rbrace: '}',
|
||||
lbracket: '[',
|
||||
rbracket: ']',
|
||||
eq: '==',
|
||||
noteq: '!=',
|
||||
lteq: '<=',
|
||||
gteq: '>=',
|
||||
lt: '<',
|
||||
gt: '>',
|
||||
equals: '=',
|
||||
|
@ -64,7 +72,6 @@
|
|||
|
||||
@lexer lexer
|
||||
|
||||
|
||||
Main -> _ Sitemap _ {% (d) => d[1] %}
|
||||
Sitemap -> %sitemap _ SitemapName __ SitemapLabel __ %lbrace _ Widgets _ %rbrace {% getSitemap %}
|
||||
|
||||
|
@ -77,23 +84,49 @@ Widgets -> Widget
|
|||
|
||||
Widget -> %nlwidget _ WidgetAttrs:* {% getWidget %}
|
||||
| %lwidget _ WidgetAttrs:* {% getWidget %}
|
||||
| %lwidget _ WidgetAttrs:* __ %lbrace __ Widgets __ %rbrace {% getWidget %}
|
||||
| %lwidget _ WidgetAttrs:* _ %lbrace _ Widgets _ %rbrace {% getWidget %}
|
||||
|
||||
WidgetAttrs -> WidgetAttr {% (d) => [d[0]] %}
|
||||
| WidgetAttrs _ WidgetAttr {% (d) => d[0].concat([d[2]]) %}
|
||||
WidgetAttr -> WidgetAttrName WidgetAttrValue {% (d) => [d[0][0].value, d[1]] %}
|
||||
WidgetAttr -> %widgetswitchattr {% (d) => ['switchEnabled', true] %}
|
||||
| %widgetfreqattr {% (d) => ['frequency', d[1]] %}
|
||||
| %widgetfrcitmattr {% (d) => ['forceAsItem', d[1]] %}
|
||||
| WidgetAttrName WidgetAttrValue {% (d) => [d[0][0].value, d[1]] %}
|
||||
| WidgetVisibilityAttrName WidgetVisibilityAttrValue {% (d) => [d[0][0].value, d[1]] %}
|
||||
| WidgetColorAttrName WidgetColorAttrValue {% (d) => [d[0][0].value, d[1]] %}
|
||||
WidgetAttrName -> %item | %label | %icon | %widgetattr
|
||||
WidgetAttrValue -> %string {% (d) => d[0].value %}
|
||||
| %identifier {% (d) => d[0].value %}
|
||||
| %number {% (d) => { return parseFloat(d[0].value) } %}
|
||||
| %lbracket _ Mappings _ %rbracket {% (d) => d[2] %}
|
||||
WidgetVisibilityAttrName -> %widgetvisiattr
|
||||
WidgetVisibilityAttrValue -> %lbracket _ Visibilities _ %rbracket {% (d) => d[2] %}
|
||||
WidgetColorAttrName -> %widgetcolorattr
|
||||
WidgetColorAttrValue -> %lbracket _ Colors _ %rbracket {% (d) => d[2] %}
|
||||
|
||||
Mappings -> Mapping {% (d) => [d[0]] %}
|
||||
| Mappings _ %comma _ Mapping {% (d) => d[0].concat([d[4]]) %}
|
||||
Mapping -> MappingCommand %equals MappingLabel {% (d) => d[0][0].value.toString() + '=' + d[2][0].value.toString() %}
|
||||
Mapping -> MappingCommand _ %equals _ MappingLabel {% (d) => d[0][0].value.toString() + '=' + d[4][0].value.toString() %}
|
||||
MappingCommand -> %number | %identifier | %string
|
||||
MappingLabel -> %number | %identifier | %string
|
||||
|
||||
Visibilities -> Visibility {% (d) => [d[0]] %}
|
||||
| Visibilities _ %comma _ Visibility {% (d) => d[0].concat([d[4]]) %}
|
||||
Visibility -> VisibilityCommand _ VisibilityComparator _ VisibilityValue {% (d) => d[0][0].value.toString() + d[2][0].value.toString() + d[4][0].value.toString() %}
|
||||
VisibilityCommand -> %identifier | %string
|
||||
VisibilityComparator -> %eq | %noteq | %lteq | %gteq | %lt | %gt
|
||||
VisibilityValue -> %number | %identifier | %string
|
||||
|
||||
Colors -> Color {% (d) => [d[0]] %}
|
||||
| Colors _ %comma _ Color {% (d) => d[0].concat([d[4]]) %}
|
||||
Color -> ColorCommand _ ColorComparator _ ColorValue _ %equals _ ColorName {% (d) => d[0][0].value.toString() + d[2][0].value.toString() + d[4][0].value.toString() + '=' + d[8][0].value.toString() %}
|
||||
| ColorComparator _ ColorValue _ %equals _ ColorName {% (d) => d[0][0].value.toString() + d[2][0].value.toString() + '=' + d[6][0].value.toString() %}
|
||||
| ColorValue _ %equals _ ColorName {% (d) => "==" + d[0][0].value.toString() + '=' + d[4][0].value.toString() %}
|
||||
| ColorName {% (d) => d[0][0].value.toString() %}
|
||||
ColorCommand -> %identifier | %string
|
||||
ColorComparator -> %eq | %noteq | %lteq | %gteq | %lt | %gt
|
||||
ColorValue -> %number | %identifier | %string
|
||||
ColorName -> %identifier | %string
|
||||
|
||||
_ -> null {% () => null %}
|
||||
| _ %WS {% () => null %}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<f7-card v-if="widget">
|
||||
<f7-card-content v-if="attributes.length">
|
||||
<f7-list inline-labels sortable sortable-opposite sortable-enabled @sortable:sort="onSort">
|
||||
<f7-list-input v-for="(attr, idx) in attributes" :key="attr.key"
|
||||
type="text" :placeholder="placeholder" :value="attr.value" @change="updateAttribute(idx, $event)" clear-button />
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
<f7-card-footer key="item-card-buttons-edit-mode" v-if="widget.component !== 'Sitemap'">
|
||||
<f7-button color="blue" @click="addAttribute">
|
||||
Add
|
||||
</f7-button>
|
||||
</f7-card-footer>
|
||||
</f7-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['widget', 'attribute', 'placeholder'],
|
||||
computed: {
|
||||
attributes () {
|
||||
if (this.widget && this.widget.config && this.widget.config[this.attribute]) {
|
||||
return this.widget.config[this.attribute].map((attr, idx) => ({ key: idx + ': ' + attr, value: attr }))
|
||||
}
|
||||
return []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateAttribute (idx, $event) {
|
||||
const value = $event.target.value
|
||||
if (!value) {
|
||||
this.widget.config[this.attribute].splice(idx, 1)
|
||||
} else {
|
||||
this.$set(this.widget.config[this.attribute], idx, value)
|
||||
}
|
||||
},
|
||||
addAttribute () {
|
||||
if (this.widget && this.widget.config && this.widget.config[this.attribute]) {
|
||||
this.widget.config[this.attribute].push('')
|
||||
} else {
|
||||
this.$set(this.widget.config, this.attribute, [''])
|
||||
}
|
||||
},
|
||||
onSort (ev) {
|
||||
const element = this.widget.config[this.attribute][ev.from]
|
||||
this.widget.config[this.attribute].splice(ev.from, 1)
|
||||
this.widget.config[this.attribute].splice(ev.to, 0, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -4,21 +4,34 @@ function writeWidget (widget, indent) {
|
|||
if (widget.config) {
|
||||
for (let key in widget.config) {
|
||||
if (!widget.config[key]) continue
|
||||
if ((Array.isArray(widget.config[key]) && widget.config[key].filter(Boolean).length <= 0)) continue
|
||||
if (key === 'switchEnabled') {
|
||||
dsl += ' switchSupport'
|
||||
} else if (key === 'frequency') {
|
||||
dsl += ' sendFrequency=' + widget.config[key]
|
||||
} else if (key === 'forceAsItem') {
|
||||
dsl += ' forceasitem=' + widget.config[key]
|
||||
} else {
|
||||
dsl += ` ${key}=`
|
||||
if (key === 'item' || Number.isFinite(widget.config[key])) {
|
||||
dsl += widget.config[key]
|
||||
} else if (key === 'mappings') {
|
||||
} else if (['mappings', 'visibility', 'valuecolor', 'labelcolor', 'iconcolor'].includes(key)) {
|
||||
dsl += '['
|
||||
const mappingsDsl = widget.config.mappings.map((m) =>
|
||||
`${m.split('=')[0]}="${m.substring(m.indexOf('=') + 1)}"`
|
||||
)
|
||||
dsl += mappingsDsl.join(',')
|
||||
const arrayDsl = widget.config[key].map((v) => {
|
||||
// Anything after the first comparator that is a string should be in quotes.
|
||||
// Also quote string if no comparator (i.e. fixed labelcolor or valuecolor).
|
||||
let value = v.substring(0, v.search(/[=<>]/))
|
||||
value += v.substring(v.search(/[=<>]/)).replace(/"/g, '').replace(/[A-Za-z][A-Za-z0-9 _-]*/g, function (x) { return '"' + x.trim() + '"' })
|
||||
return value.trim()
|
||||
})
|
||||
dsl += arrayDsl.filter(Boolean).join(',')
|
||||
dsl += ']'
|
||||
} else {
|
||||
dsl += '"' + widget.config[key] + '"'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (widget.slots) {
|
||||
dsl += ' {\n'
|
||||
widget.slots.widgets.forEach((w) => {
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
<template>
|
||||
<f7-card v-if="widget">
|
||||
<f7-card-content v-if="mappings.length">
|
||||
<f7-list inline-labels sortable @sortable:sort="onSort">
|
||||
<f7-list-input v-for="(mapping, idx) in mappings" :key="idx"
|
||||
:label="`#${idx+1}`" type="text" placeholder="command=Label" :value="mapping" @input="updateMapping(idx, $event)" clear-button />
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
<f7-card-footer key="item-card-buttons-edit-mode" v-if="widget.component !== 'Sitemap'">
|
||||
<f7-button color="blue" @click="addMapping">
|
||||
Add
|
||||
</f7-button>
|
||||
</f7-card-footer>
|
||||
</f7-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['widget'],
|
||||
computed: {
|
||||
mappings () {
|
||||
if (this.widget && this.widget.config && this.widget.config.mappings) {
|
||||
return this.widget.config.mappings
|
||||
}
|
||||
return []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateMapping (idx, $event) {
|
||||
const value = $event.target.value
|
||||
if (!value) {
|
||||
this.widget.config.mappings.splice(idx, 1)
|
||||
} else {
|
||||
this.$set(this.widget.config.mappings, idx, value)
|
||||
}
|
||||
},
|
||||
addMapping () {
|
||||
if (this.widget && this.widget.config && this.widget.config.mappings) {
|
||||
this.widget.config.mappings.push('')
|
||||
} else {
|
||||
this.$set(this.widget.config, 'mappings', [''])
|
||||
}
|
||||
},
|
||||
onSort (ev) {
|
||||
const element = this.widget.config.mappings[ev.from]
|
||||
this.widget.config.mappings.splice(ev.from, 1)
|
||||
this.widget.config.mappings.splice(ev.to, 0, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -5,7 +5,7 @@
|
|||
<f7-list-input v-if="widget.component === 'Sitemap'" label="ID" type="text" placeholder="ID" :value="widget.uid" @input="widget.uid = $event.target.value"
|
||||
required validate pattern="[A-Za-z0-9_]+" error-message="Required. Alphanumeric & underscores only" :disabled="!createMode" />
|
||||
<f7-list-input label="Label" type="text" placeholder="Label" :value="widget.config.label" @input="updateParameter('label', $event)" clear-button />
|
||||
<item-picker v-if="widget.component !== 'Sitemap'" title="Item" :value="widget.config.item" @input="(value) => widget.config.item = value" />
|
||||
<item-picker v-if="widget.component !== 'Sitemap' && widget.component !== 'Frame'" title="Item" :value="widget.config.item" @input="(value) => widget.config.item = value" />
|
||||
<ul v-if="widget.component !== 'Sitemap'">
|
||||
<f7-list-input ref="icon" label="Icon" autocomplete="off" type="text" placeholder="temperature, firstfloor..." :value="widget.config.icon"
|
||||
@input="updateParameter('icon', $event)" clear-button>
|
||||
|
@ -23,14 +23,17 @@
|
|||
<f7-list-input v-if="supports('period')" label="Period" type="text" :value="widget.config.period" @input="updateParameter('period', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('height')" label="Height" type="number" :value="widget.config.height" @input="updateParameter('height', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('sendFrequency')" label="Frequency" type="text" :value="widget.config.sendFrequency" @input="updateParameter('sendFrequency', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('frequency')" label="Frequency" type="text" :value="widget.config.frequency" @input="updateParameter('frequency', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('minValue')" label="Minimum" type="number" :value="widget.config.minValue" @input="updateParameter('minValue', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('maxValue')" label="Maximum" type="number" :value="widget.config.maxValue" @input="updateParameter('maxValue', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('step')" label="Step" type="number" :value="widget.config.step" @input="updateParameter('step', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('separator')" label="Separator" type="text" :value="widget.config.separator" @input="updateParameter('separator', $event)" clear-button />
|
||||
<f7-list-input v-if="supports('yAxisDecimalPattern')" label="Y-axis decimal pattern" type="text" :value="widget.config.separator" @input="updateParameter('yAxisDecimalPattern', $event)" clear-button />
|
||||
<f7-list-item v-if="supports('switchEnabled')" title="Switch enabled">
|
||||
<f7-toggle slot="after" :checked="widget.config.switchEnabled" @toggle:change="widget.config.switchEnabled = $event" />
|
||||
</f7-list-item>
|
||||
<f7-list-item v-if="supports('forceAsItem')" title="Force as item">
|
||||
<f7-toggle slot="after" :checked="widget.config.forceAsItem" @toggle:change="widget.config.forceAsItem = $event" />
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
|
@ -67,13 +70,13 @@ export default {
|
|||
additionalControls: {
|
||||
Image: ['url', 'refresh'],
|
||||
Video: ['url', 'encoding'],
|
||||
Chart: ['service', 'period', 'refresh', 'legend'],
|
||||
Chart: ['service', 'period', 'refresh', 'legend', 'forceAsItem', 'yAxisDecimalPattern'],
|
||||
Webview: ['url', 'height'],
|
||||
Mapview: ['height'],
|
||||
Slider: ['sendFrequency', 'switchEnabled', 'minValue', 'maxValue', 'step'],
|
||||
List: ['separator'],
|
||||
Setpoint: ['minValue', 'maxValue', 'step'],
|
||||
Colorpicker: ['frequency'],
|
||||
Colorpicker: ['sendFrequency'],
|
||||
Default: ['height']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,25 @@
|
|||
Nothing selected
|
||||
</div>
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && selectedWidget.component !== 'Sitemap'">
|
||||
<div><f7-block-title>Visibility</f7-block-title></div>
|
||||
<attribute-details :widget="selectedWidget" attribute="visibility" placeholder="item_name operator value" />
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && selectedWidget.component !== 'Sitemap'">
|
||||
<div><f7-block-title>Label Color</f7-block-title></div>
|
||||
<attribute-details :widget="selectedWidget" attribute="labelcolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && selectedWidget.component !== 'Sitemap'">
|
||||
<div><f7-block-title>Value Color</f7-block-title></div>
|
||||
<attribute-details :widget="selectedWidget" attribute="valuecolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && selectedWidget.component === 'Image'">
|
||||
<div><f7-block-title>Icon Color</f7-block-title></div>
|
||||
<attribute-details :widget="selectedWidget" attribute="iconcolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && ['Switch', 'Selection'].indexOf(selectedWidget.component) >= 0">
|
||||
<div><f7-block-title>Mappings</f7-block-title></div>
|
||||
<mapping-details :widget="selectedWidget" />
|
||||
<attribute-details :widget="selectedWidget" attribute="mappings" placeholder="command = label" />
|
||||
</f7-block>
|
||||
<f7-block v-if="selectedWidget && canAddChildren">
|
||||
<div><f7-block-title>Add Child Widget</f7-block-title></div>
|
||||
|
@ -101,8 +117,20 @@
|
|||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'widget'">
|
||||
<widget-details :widget="selectedWidget" :createMode="createMode" @remove="removeWidget" @movedown="moveWidgetDown" @moveup="moveWidgetUp" />
|
||||
</f7-block>
|
||||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'visibility' && selectedWidget.component !== 'Sitemap'">
|
||||
<attribute-details :widget="selectedWidget" attribute="visibility" placeholder="item_name operator value" />
|
||||
</f7-block>
|
||||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'labelcolor' && selectedWidget.component !== 'Sitemap'">
|
||||
<attribute-details :widget="selectedWidget" attribute="labelcolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'valuecolor' && selectedWidget.component !== 'Sitemap'">
|
||||
<attribute-details :widget="selectedWidget" attribute="valuecolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'iconcolor' && selectedWidget.component === 'Image'">
|
||||
<attribute-details :widget="selectedWidget" attribute="iconcolor" placeholder="item_name operator value = color" />
|
||||
</f7-block>
|
||||
<f7-block style="margin-bottom: 6rem" v-if="selectedWidget && detailsTab === 'mappings' && ['Switch', 'Selection'].indexOf(selectedWidget.component) >= 0">
|
||||
<mapping-details :widget="selectedWidget" />
|
||||
<attribute-details :widget="selectedWidget" attribute="mappings" placeholder="command = label" />
|
||||
</f7-block>
|
||||
</f7-page>
|
||||
</f7-sheet>
|
||||
|
@ -176,7 +204,7 @@
|
|||
<script>
|
||||
import SitemapCode from '@/components/pagedesigner/sitemap/sitemap-code.vue'
|
||||
import WidgetDetails from '@/components/pagedesigner/sitemap/widget-details.vue'
|
||||
import MappingDetails from '@/components/pagedesigner/sitemap/mapping-details.vue'
|
||||
import AttributeDetails from '@/components/pagedesigner/sitemap/attribute-details.vue'
|
||||
import DirtyMixin from '../../dirty-mixin'
|
||||
|
||||
export default {
|
||||
|
@ -184,7 +212,7 @@ export default {
|
|||
components: {
|
||||
SitemapCode,
|
||||
WidgetDetails,
|
||||
MappingDetails
|
||||
AttributeDetails
|
||||
},
|
||||
props: ['createMode', 'uid'],
|
||||
data () {
|
||||
|
@ -285,6 +313,7 @@ export default {
|
|||
}
|
||||
},
|
||||
save (stay) {
|
||||
this.cleanConfig(this.sitemap)
|
||||
if (!this.sitemap.uid) {
|
||||
this.$f7.dialog.alert('Please give an ID to the sitemap')
|
||||
return
|
||||
|
@ -331,6 +360,9 @@ export default {
|
|||
cleanConfig (widget) {
|
||||
if (widget.config) {
|
||||
for (let key in widget.config) {
|
||||
if (widget.config[key] && Array.isArray(widget.config[key])) {
|
||||
widget.config[key] = widget.config[key].filter(Boolean)
|
||||
}
|
||||
if (!widget.config[key]) {
|
||||
delete widget.config[key]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue