Skip to content

Commit

Permalink
Add code tab to Item editor
Browse files Browse the repository at this point in the history
Requested at openhab#1737 (comment), openhab#728 and several times on the community.

Signed-off-by: Florian Hotze <florianh_dev@icloud.com>
  • Loading branch information
florian-h05 committed Mar 30, 2023
1 parent d5d6842 commit 965a91b
Showing 1 changed file with 106 additions and 38 deletions.
144 changes: 106 additions & 38 deletions bundles/org.openhab.ui/web/src/pages/settings/items/item-edit.vue
Expand Up @@ -8,38 +8,47 @@
</f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="block-narrow" v-if="item.name || item.created === false">
<f7-col v-if="item.editable === false">
<div class="padding-left">
Note: this item is not editable because it has been created with textual configuration.
</div>
</f7-col>
<f7-col>
<item-form :item="item" :items="items" :enable-name="createMode" />
</f7-col>
<f7-col>
<f7-block-title>Group Membership</f7-block-title>
<f7-list v-if="ready">
<item-picker title="Parent Group(s)" name="parent-groups" :value="item.groupNames" @input="(value) => item.groupNames = value" :items="items" :multiple="true" filterType="Group" />
</f7-list>
</f7-col>
<f7-col v-if="item && item.type === 'Group'">
<f7-block-title>Group Settings</f7-block-title>
<group-form :item="item" />
</f7-col>
<f7-col class="tags-editor">
<f7-block-title>Non-Semantic Tags</f7-block-title>
<tag-input :item="item" />
</f7-col>
<f7-col>
<!-- <f7-list>
<f7-list-button color="blue" title="Edit Channel Links"></f7-list-button>
</f7-list> -->
<!-- <f7-list>
<f7-list-button color="red" title="Delete this Item"></f7-list-button>
</f7-list> -->
</f7-col>
</f7-block>
<f7-toolbar tabbar position="top">
<f7-link @click="switchTab('design', fromYaml)" :tab-link-active="currentTab === 'design'" class="tab-link">
Design
</f7-link>
<f7-link @click="switchTab('code', toYaml)" :tab-link-active="currentTab === 'code'" class="tab-link">
Code
</f7-link>
</f7-toolbar>
<f7-tabs class="sitemap-editor-tabs">
<f7-tab id="design" @tab:show="() => this.currentTab = 'design'" :tab-active="currentTab === 'design'">
<f7-block class="block-narrow" v-if="item.name || item.created === false">
<f7-col v-if="item.editable === false">
<div class="padding-left">
Note: this item is not editable because it has been created with textual configuration.
</div>
</f7-col>
<f7-col>
<item-form :item="item" :items="items" :enable-name="createMode" />
</f7-col>
<f7-col>
<f7-block-title>Group Membership</f7-block-title>
<f7-list v-if="ready">
<item-picker title="Parent Group(s)" name="parent-groups" :value="item.groupNames" @input="(value) => item.groupNames = value" :items="items" :multiple="true" filterType="Group" />
</f7-list>
</f7-col>
<f7-col v-if="item && item.type === 'Group'">
<f7-block-title>Group Settings</f7-block-title>
<group-form :item="item" />
</f7-col>
<f7-col class="tags-editor">
<f7-block-title>Non-Semantic Tags</f7-block-title>
<tag-input :item="item" />
</f7-col>
</f7-block>
</f7-tab>
<f7-tab id="code" @tab:show="() => { this.currentTab = 'code'; toYaml() }" :tab-active="currentTab === 'code'">
<f7-icon v-if="ready && !isEditable" f7="lock" class="float-right margin" style="opacity:0.5; z-index: 4000; user-select: none;" size="50" color="gray"
tooltip="This Item is not editable because it has been provisioned from a file" />
<editor v-if="currentTab === 'code'" class="rule-code-editor" mode="application/vnd.openhab.item+yaml" :value="itemYaml" @input="onEditorInput" :read-only="!isEditable" />
</f7-tab>
</f7-tabs>

<div v-if="ready && createMode" class="if-aurora display-flex justify-content-center margin padding">
<div class="flex-shrink-0">
Expand All @@ -51,9 +60,23 @@
</f7-page>
</template>

<style lang="stylus">
.rule-code-editor.vue-codemirror
display block
top calc(var(--f7-navbar-height) + var(--f7-tabbar-height))
height calc(100% - 2*var(--f7-navbar-height))
width 100%
.yaml-message
display block
position absolute
top 80%
white-space pre-wrap
</style>

<script>
import * as Types from '@/assets/item-types.js'
import * as SemanticClasses from '@/assets/semantics.js'
import YAML from 'yaml'
import ItemForm from '@/components/item/item-form.vue'
import GroupForm from '@/components/item/group-form.vue'
Expand All @@ -68,21 +91,27 @@ export default {
ItemPicker,
ItemForm,
GroupForm,
TagInput
TagInput,
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue')
},
data () {
return {
ready: false,
item: {},
itemYaml: '',
items: [],
types: Types,
semanticClasses: SemanticClasses,
semanticClass: '',
semanticProperty: '',
pendingTag: ''
pendingTag: '',
currentTab: 'design'
}
},
created () {
computed: {
isEditable () {
return this.item && this.item.editable !== false
}
},
watch: {
item: {
Expand Down Expand Up @@ -112,7 +141,7 @@ export default {
this.ready = true
})
} else {
const loadItem = this.$oh.api.get('/rest/items/' + this.itemName + '?metadata=semantics')
const loadItem = this.$oh.api.get('/rest/items/' + this.itemName + '?metadata=.*')
loadItem.then((data) => {
if (!data.groupType) data.groupType = 'None'
this.item = data
Expand All @@ -138,10 +167,14 @@ export default {
}
},
save () {
// TODO properly validate item
if (!this.item.name) return
if (this.currentTab === 'code') {
if (!this.fromYaml()) return Promise.reject()
}
if (!this.item.name) return // user cannot change name
if (!this.item.type || !this.types.ItemTypes.includes(this.item.type.split(':')[0])) return this.$f7.dialog.alert('Please give Item a valid type').open()
if (this.item.groupType === 'None') delete this.item.groupType
// TODO: Add support for saving metadata
this.$oh.api.put('/rest/items/' + this.item.name, this.item).then((data) => {
if (this.createMode) {
this.$f7.toast.create({
Expand All @@ -167,6 +200,41 @@ export default {
closeTimeout: 2000
}).open()
})
},
onEditorInput (value) {
this.itemYaml = value
this.dirty = true
},
toYaml () {
this.itemYaml = YAML.stringify({
label: this.item.label,
type: this.item.type,
category: this.item.category,
groupNames: this.item.groupNames,
groupType: this.item.groupType,
function: this.item.function,
tags: this.item.tags
// metadata: this.item.metadata
})
},
fromYaml () {
if (!this.item.editable) return false
try {
const updatedItem = YAML.parse(this.itemYaml)
if (updatedItem === null) return false
this.$set(this.item, 'label', updatedItem.label)
this.$set(this.item, 'type', updatedItem.type)
this.$set(this.item, 'category', updatedItem.category)
this.$set(this.item, 'groupNames', updatedItem.groupNames)
this.$set(this.item, 'groupType', updatedItem.groupType)
this.$set(this.item, 'function', updatedItem.function)
this.$set(this.item, 'tags', updatedItem.tags)
// this.$set(this.item, 'metadata', updatedItem.metadata)
return true
} catch (e) {
this.$f7.dialog.alert(e).open()
return false
}
}
}
}
Expand Down

0 comments on commit 965a91b

Please sign in to comment.