Skip to content

Commit

Permalink
Thing Details: Add Copy DSL Definition button (#3086)
Browse files Browse the repository at this point in the history
Based on openhab/openhab-core#4569.
Resolve openhab/openhab-core#4509.

Also cleaned up / removed the previous attempt (from 5 years ago) to
create a textual definition. It was commented out and wasn't actually used.

---------

Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng authored Mar 11, 2025
1 parent d651945 commit a229c3d
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
<tag-input :item="page" />
</f7-list>
<f7-list v-if="!createMode" inline-labels no-hairline-md>
<f7-list-button color="blue" @click="copyPage">
Copy Page
<f7-list-button color="blue" @click="duplicatePage">
Duplicate Page
</f7-list-button>
<f7-list-button color="red" @click="deletePage">
Remove Page
Expand Down Expand Up @@ -77,7 +77,7 @@ export default {
}).open()
}
},
copyPage () {
duplicatePage () {
const pageClone = cloneDeep(this.page)
const pageType = pageClone.component.replace(/^oh-|-page$/g, '')
pageClone.uid = pageClone.uid + '_copy'
Expand Down
10 changes: 5 additions & 5 deletions bundles/org.openhab.ui/web/src/components/thing/channel-link.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<f7-icon slot="media" color="green" aurora="f7:plus_circle_fill" ios="f7:plus_circle_fill" md="material:control_point" />
</f7-list-item>
<f7-list-button class="searchbar-ignore" color="blue" :title="thing.editable && (channelType.parameterGroups.length || channelType.parameters.length) ? 'Configure Channel' : 'Channel Details'" @click="configureChannel()" />
<f7-list-button class="searchbar-ignore" v-if="extensible && thing.editable" color="blue" title="Copy Channel" @click="copyChannel()" />
<f7-list-button class="searchbar-ignore" v-if="extensible && thing.editable" color="blue" title="Duplicate Channel" @click="duplicateChannel()" />
<f7-list-button class="searchbar-ignore" v-if="extensible && thing.editable" color="red" title="Remove Channel" @click="removeChannel()" />
</f7-list>
</template>
Expand All @@ -62,7 +62,7 @@
import AddLinkPage from '@/pages/settings/things/link/link-add.vue'
import ConfigureLinkPage from '@/pages/settings/things/link/link-edit.vue'
import ConfigureChannelPage from '@/pages/settings/things/channel/channel-edit.vue'
import CopyChannelPage from '@/pages/settings/things/channel/channel-copy.vue'
import DuplicateChannelPage from '@/pages/settings/things/channel/channel-duplicate.vue'
import ItemMixin from '@/components/item/item-mixin'
Expand Down Expand Up @@ -177,16 +177,16 @@ export default {
}
})
},
copyChannel () {
duplicateChannel () {
const self = this
const path = 'channels/' + this.channelId + '/edit'
this.$f7router.navigate({
url: path,
route: {
component: CopyChannelPage,
component: DuplicateChannelPage,
path,
context: {
operation: 'copy-channel'
operation: 'duplicate-channel'
},
on: {
pageAfterOut (event, page) {
Expand Down
10 changes: 5 additions & 5 deletions bundles/org.openhab.ui/web/src/js/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export default [
async: loadAsync(ItemEditPage, { createMode: true })
},
{
path: 'copy',
path: 'duplicate',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(ItemEditPage, { createMode: true })
},
Expand Down Expand Up @@ -287,7 +287,7 @@ export default [
]
},
{
path: 'copy',
path: 'duplicate',
beforeEnter: [enforceAdminForRoute],
beforeLeave: [checkDirtyBeforeLeave],
async: loadAsync(AddThingPage)
Expand Down Expand Up @@ -336,7 +336,7 @@ export default [
async: loadAsync(RuleEditPage, { createMode: true })
},
{
path: 'copy',
path: 'duplicate',
beforeEnter: [enforceAdminForRoute],
beforeLeave: [checkDirtyBeforeLeave],
async: loadAsync(RuleEditPage, { createMode: true })
Expand Down Expand Up @@ -369,7 +369,7 @@ export default [
async: loadAsync(SceneEditPage, { createMode: true })
},
{
path: 'copy',
path: 'duplicate',
beforeEnter: [enforceAdminForRoute],
beforeLeave: [checkDirtyBeforeLeave],
async: loadAsync(SceneEditPage, { createMode: true })
Expand All @@ -394,7 +394,7 @@ export default [
async: loadAsync(ScriptEditPage, { createMode: true })
},
{
path: 'copy',
path: 'duplicate',
beforeEnter: [enforceAdminForRoute],
beforeLeave: [checkDirtyBeforeLeave],
async: loadAsync(ScriptEditPage, { createMode: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
<f7-row>
<f7-col>
<f7-list>
<f7-list-button color="blue" @click="copyItem">
Copy Item
<f7-list-button color="blue" @click="duplicateItem">
Duplicate Item
</f7-list-button>
<f7-list-button v-if="item.editable" color="red" @click="deleteItem">
Remove Item
Expand Down Expand Up @@ -207,10 +207,10 @@ export default {
this.iconUrl = '/icon/' + this.item.category + '?format=svg'
})
},
copyItem () {
duplicateItem () {
let itemClone = cloneDeep(this.item)
this.$f7router.navigate({
url: '/settings/items/copy'
url: '/settings/items/duplicate'
}, {
props: {
itemCopy: itemClone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@
</f7-col>
<f7-col v-if="isEditable && (!createMode)">
<f7-list>
<f7-list-button color="blue" @click="copyRule">
Copy Rule
<f7-list-button color="blue" @click="duplicateRule">
Duplicate Rule
</f7-list-button>
<f7-list-button color="red" @click="deleteRule">
Remove Rule
Expand Down Expand Up @@ -333,7 +333,7 @@ export default {
}).open()
this.$f7router.navigate(this.$f7route.url
.replace('/add', '/' + this.rule.uid)
.replace('/copy', '/' + this.rule.uid)
.replace('/duplicate', '/' + this.rule.uid)
.replace('/schedule/', '/rules/'), { reloadCurrent: true })
this.load()
} else {
Expand All @@ -355,10 +355,10 @@ export default {
}).open()
})
},
copyRule () {
duplicateRule () {
let ruleClone = cloneDeep(this.rule)
this.$f7router.navigate({
url: '/settings/rules/copy'
url: '/settings/rules/duplicate'
}, {
props: {
ruleCopy: ruleClone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@
</f7-col>
<f7-col v-if="isEditable && !createMode">
<f7-list>
<f7-list-button color="blue" @click="copyRule">
Copy Scene
<f7-list-button color="blue" @click="duplicateRule">
Duplicate Scene
</f7-list-button>
<f7-list-button color="red" @click="deleteRule">
Remove Scene
Expand Down Expand Up @@ -372,10 +372,10 @@ export default {
})
})
},
copyRule () {
duplicateRule () {
let ruleClone = cloneDeep(this.rule)
this.$f7router.navigate({
url: '/settings/scenes/copy'
url: '/settings/scenes/duplicate'
}, {
props: {
ruleCopy: ruleClone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@
<f7-block class="block-narrow" v-if="editable && isScriptRule">
<f7-col>
<f7-list>
<f7-list-button color="blue" @click="copyRule">
Copy Script
<f7-list-button color="blue" @click="duplicateRule">
Duplicate Script
</f7-list-button>
<f7-list-button color="red" @click="deleteRule">
Remove Script
Expand Down Expand Up @@ -388,7 +388,7 @@ export default {
destroyOnClose: true,
closeTimeout: 2000
}).open()
this.$f7router.navigate(this.$f7route.url.replace(/(\/add)|(\/copy)/, '/' + this.rule.uid), { reloadCurrent: true })
this.$f7router.navigate(this.$f7route.url.replace(/(\/add)|(\/duplicate)/, '/' + this.rule.uid), { reloadCurrent: true })
})
},
isMimeTypeAvailable (mimeType) {
Expand Down Expand Up @@ -603,10 +603,10 @@ export default {
run(false)
}
},
copyRule () {
duplicateRule () {
let ruleClone = cloneDeep(this.rule)
this.$f7router.navigate({
url: '/settings/scripts/copy'
url: '/settings/scripts/duplicate'
}, {
props: {
ruleCopy: ruleClone
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<f7-page @page:afterin="onPageAfterIn" name="channel-copy">
<f7-navbar title="Copy channel" :subtitle="thing.label" back-link="Cancel">
<f7-page @page:afterin="onPageAfterIn" name="channel-duplicate">
<f7-navbar title="Duplicate channel" :subtitle="thing.label" back-link="Cancel">
<f7-nav-right>
<f7-link @click="save()" v-if="$theme.md" icon-md="material:save" icon-only />
<f7-link @click="save()" v-if="!$theme.md">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,15 @@
<f7-col>
<f7-list>
<f7-list-button v-if="thing.statusInfo.statusDetail === 'HANDLER_MISSING_ERROR'" color="blue" title="Install Binding" @click="installBinding" />
<f7-list-button v-if="!error" color="blue" title="Copy Thing" @click="copyThing" />
<f7-list-button v-if="editable" color="red" title="Delete Thing" @click="deleteThing" />
<f7-list-button v-if="!error" color="blue" @click="duplicateThing">
Duplicate Thing
</f7-list-button>
<f7-list-button v-if="!error" color="blue" @click="copyThingDsl">
Copy DSL Definition
</f7-list-button>
<f7-list-button v-if="editable" color="red" @click="deleteThing">
Remove Thing
</f7-list-button>
</f7-list>
</f7-col>
</f7-block>
Expand Down Expand Up @@ -166,44 +173,10 @@
<!-- <pre class="yaml-message padding-horizontal" :class="[yamlError === 'OK' ? 'text-color-green' : 'text-color-red']">{{yamlError}}</pre> -->
</f7-tab>
</f7-tabs>

<!-- <f7-fab position="right-bottom" color="blue" slot="fixed" @click="codePopupOpened = true">
<f7-icon ios="f7:document_text" md="material:assignment" aurora="f7:document_text"></f7-icon>
<f7-icon ios="f7:close" md="material:close"></f7-icon>
</f7-fab>
<f7-popup tablet-fullscreen :opened="codePopupOpened" close-on-escape @popup:closed="codePopupOpened = false">
<f7-page>
<f7-toolbar>
<div class="left">
<f7-link @click="copyTextualDefinition">Copy</f7-link>
</div>
<div class="right">
<f7-link popup-close>Close</f7-link>
</div>
</f7-toolbar>
<textarea class="textual-definition" id="textual-definition" :value="textualDefinition"></textarea>
</f7-page>
</f7-popup> -->
</f7-page>
</template>

<style lang="stylus">
code.textual-definition pre
overflow-x auto
white-space normal
pre.textual-definition
padding 5px
textarea.textual-definition
position absolute
top var(--f7-toolbar-height)
left 5px
right 5px
bottom 0
width calc(100% - 10px)
font-family monospace
.md .code-popup
margin-bottom 0 !important
Expand Down Expand Up @@ -272,13 +245,16 @@ import ZWaveNetworkPopup from '@/pages/settings/things/zwave/zwave-network-popup
import AddChannelPage from '@/pages/settings/things/channel/channel-add.vue'
import AddFromThingPage from '@/pages/settings/model/add-from-thing.vue'
import buildTextualDefinition from './thing-textual-definition'
import ThingStatus from '@/components/thing/thing-status-mixin'
import DirtyMixin from '../dirty-mixin'
import ThingActionPopup from '@/pages/settings/things/thing-action-popup.vue'
import Vue from 'vue'
import Clipboard from 'v-clipboard'
Vue.use(Clipboard)
let copyToast = null
export default {
Expand Down Expand Up @@ -310,18 +286,11 @@ export default {
*/
configActionsByGroup: [],
thingEnabled: true,
codePopupOpened: false,
eventSource: null,
thingYaml: null,
notEditableMsg: 'This Thing is not editable because it has been provisioned from a file.'
}
},
created () {
copyToast = this.$f7.toast.create({
text: 'Textual definition copied to clipboard',
closeTimeout: 2000
})
},
computed: {
editable () {
return this.thing && this.thing.editable
Expand All @@ -334,10 +303,6 @@ export default {
if (!this.thingType || !this.thingType.extensibleChannelTypeIds) return false
return this.thingType.extensibleChannelTypeIds.length > 0
},
textualDefinition () {
if (!this.thingType || !this.thing) return
return buildTextualDefinition(this.thing, this.thingType)
},
context () {
return {
store: this.$store.getters.trackedItems
Expand Down Expand Up @@ -619,17 +584,31 @@ export default {
}
})
},
copyThing () {
duplicateThing () {
let thingClone = cloneDeep(this.thing)
this.$f7router.navigate({
url: '/settings/things/copy'
url: '/settings/things/duplicate'
}, {
props: {
thingTypeId: this.thing.thingTypeUID,
thingCopy: thingClone
}
})
},
copyThingDsl () {
this.$oh.api.getPlain({
url: '/rest/file-format/things/' + this.thingId,
headers: { accept: 'text/vnd.openhab.dsl.thing' }
}).then((definition) => {
if (this.$clipboard(definition)) {
this.$f7.toast.create({
text: 'Thing DSL definition copied to clipboard',
destroyOnClose: true,
closeTimeout: 2000
}).open()
}
})
},
deleteThing () {
let url, message
if (this.thing.statusInfo.status === 'REMOVING') {
Expand Down Expand Up @@ -830,12 +809,6 @@ export default {
this.$oh.sse.close(this.eventSource)
this.eventSource = null
},
copyTextualDefinition () {
let el = document.getElementById('textual-definition')
el.select()
document.execCommand('copy')
copyToast.open()
},
toYaml () {
const editableThing = {
UID: this.thing.UID,
Expand Down
Loading

0 comments on commit a229c3d

Please sign in to comment.