[blockly] Switch between Item name or label display (#1868)

This PR allows to show either the name or the label of the item.

Since the beginning the Item picker would show the label during
selection but the item block itself then would show the name (hence the
"id" that is used internally). This always confused me because I rather
remember the labels rather the "internal" names of the item. From the
implementation perspective it is now clear to me why this was done (it
was much easier to generate the code) and also it is consistent with
what is used for code generation.

This new way allows the user of the blockly editor to switch between showing
the label or the name while the code generation always uses the name.

Note that this requires both the name and the label stored in the
blockly code. Because the current code does not store the label, it
needs to repicked once, via the item picker, to retrieve that label and
then store it. I may add automatic retrieval for the label in the future
but due to some internal limitations it doesn't seem that easy to
provide clear code separation for that.

Also-by: Florian Hotze <florianh_dev@icloud.com>
Signed-off-by: Stefan Höhn <mail@stefanhoehn.com>
pull/1900/head
stefan-hoehn 2023-05-14 15:32:30 +02:00 committed by GitHub
parent ca306c7a6d
commit c631470fd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 5 deletions

View File

@ -7,24 +7,58 @@ import Blockly from 'blockly'
import { javascriptGenerator } from 'blockly/javascript'
import { FieldItemModelPicker } from './fields/item-field'
import { FieldThingPicker } from './fields/thing-field'
import api from '@/js/openhab/api'
export default function (f7, isGraalJs) {
/* Helper block to allow selecting an item */
Blockly.Blocks['oh_item'] = {
fieldPicker: null,
init: function () {
this.fieldPicker = new FieldItemModelPicker('MyItem', null, { f7 })
this.appendDummyInput()
.appendField('item')
.appendField(new FieldItemModelPicker('MyItem', null, { f7 }), 'itemName')
.appendField(this.fieldPicker, 'itemName')
this.setColour(160)
this.setInputsInline(true)
this.setTooltip('Pick an item from the Model')
this.setTooltip(() => {
let tooltip = 'Pick an Item from the Model'
const itemData = this.fieldPicker.data
if (itemData[0] !== itemData[1]) {
tooltip = itemData[0]
}
return tooltip
})
this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-items-things.html#item')
this.setOutput(true, 'oh_item')
},
_updateFieldPicker: function (name, label) {
this.fieldPicker.data = [name, label]
},
mutationToDom: function () {
const container = Blockly.utils.xml.createElement('mutation')
if (!this.fieldPicker.data) { // "migrate" old storage
this.fieldPicker.data = [this.fieldPicker.value_, this.fieldPicker.value_]
if (this.fieldPicker.value_ && this.fieldPicker.value_ !== 'MyItem') {
api.get(`/rest/items/${this.fieldPicker.value_}?metadata=^$`).then((data) => {
this.fieldPicker.data = [this.fieldPicker.value_, data.label]
}).catch()
}
}
this.fieldPicker.value_ = (this.workspace.showLabels) ? this.fieldPicker.data[1] : this.fieldPicker.data[0]
container.setAttribute('itemName', this.fieldPicker.data[0])
container.setAttribute('itemLabel', this.fieldPicker.data[1])
return container
},
domToMutation: function (xmlElement) {
this._updateFieldPicker(xmlElement.getAttribute('itemName'), xmlElement.getAttribute('itemLabel'))
}
}
javascriptGenerator['oh_item'] = function (block) {
const itemName = block.getFieldValue('itemName')
const itemName = block.fieldPicker.data[0]
return [`'${itemName}'`, 0]
}

View File

@ -18,6 +18,7 @@ export class FieldItemModelPicker extends Blockly.FieldTextInput {
showEditor_ (options) {
if (this.f7) {
const itemsPicked = (value) => {
this.data = [value.name, value.label]
this.setEditorValue_(value.name)
}
const popup = {

View File

@ -1157,7 +1157,8 @@ export default {
scaleSpeed: 1.2,
pinch: true
},
trashcan: false
trashcan: false,
showLabels: false
})
this.workspace.addChangeListener(shadowBlockConversionChangeListener)
const workspaceSearch = new WorkspaceSearch(this.workspace)
@ -1191,6 +1192,12 @@ export default {
this.workspace.registerButtonCallback('ohBlocklyHelp', function (button) {
window.open(button.info.helpurl, '_blank')
})
Blockly.Workspace.prototype.refresh = function () {
const xml = Blockly.Xml.workspaceToDom(this)
this.clear()
Blockly.Xml.domToWorkspace(xml, this)
this.refreshToolboxSelection()
}
},
addLibraryToToolbox (definitions) {
const library = this.$refs.libraryCategory
@ -1206,6 +1213,10 @@ export default {
this.workspace.registerToolboxCategoryCallback('LIBRARY_' + definition.uid, defineLibraryToolboxCategory(definition, this.$f7))
})
},
showHideLabels (showLabels) {
this.workspace.showLabels = showLabels
this.workspace.refresh()
},
getBlocks () {
const xml = Blockly.Xml.workspaceToDom(this.workspace)
return Blockly.Xml.domToText(xml)

View File

@ -25,6 +25,7 @@
:tooltip="rule.status.description" />
</span>
<span class="display-flex flex-direction-row align-items-center">
<f7-button v-if="!newScript && isBlockly && !blocklyCodePreview" outline small :active="blocklyShowLabels" icon-f7="square_on_circle" :icon-size="($theme.aurora) ? 20 : 22" class="no-ripple" style="margin-right: 5px" @click="toggleBlocklyItemLabelId" :tooltip="'Toggle to show either Item labels or IDs'" />
<f7-segmented v-if="!newScript && isBlockly" class="margin-right">
<f7-button outline small :active="!blocklyCodePreview" icon-f7="ticket" :icon-size="($theme.aurora) ? 20 : 22" class="no-ripple" @click="blocklyCodePreview = false" />
<f7-button outline small :active="blocklyCodePreview" icon-f7="doc_text" :icon-size="($theme.aurora) ? 20 : 22" class="no-ripple" @click="showBlocklyCode" />
@ -144,7 +145,8 @@ export default {
eventSource: null,
keyHandler: null,
detailsOpened: false,
blocklyCodePreview: false
blocklyCodePreview: false,
blocklyShowLabels: false
}
},
computed: {
@ -393,6 +395,10 @@ export default {
}
)
},
toggleBlocklyItemLabelId () {
this.blocklyShowLabels = !this.blocklyShowLabels
this.$refs.blocklyEditor.showHideLabels(this.blocklyShowLabels)
},
showBlocklyCode () {
try {
this.currentModule.configuration.blockSource = this.$refs.blocklyEditor.getBlocks()