Implement copy functionality for Things, Items, scenes & scripts (#2855)
Also improve the rule copy code. Signed-off-by: Florian Hotze <dev@florianhotze.com>pull/2857/head
parent
3022654195
commit
c74af2dad3
|
@ -190,6 +190,11 @@ export default [
|
|||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(ItemEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(ItemEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: 'add-from-textual-definition',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
|
@ -266,10 +271,6 @@ export default [
|
|||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(AddThingChooseBindingPage),
|
||||
routes: [
|
||||
// {
|
||||
// path: 'install-binding',
|
||||
// async: loadAsync(AddonsAddPage, { addonType: 'binding' })
|
||||
// },
|
||||
{
|
||||
path: ':bindingId',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
|
@ -284,6 +285,12 @@ export default [
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(AddThingPage)
|
||||
},
|
||||
{
|
||||
path: 'inbox',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
|
@ -321,14 +328,23 @@ export default [
|
|||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(RulesListPage),
|
||||
routes: [
|
||||
{
|
||||
path: 'add',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(RuleEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(RuleEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: ':ruleId',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(RuleEditPage, (routeTo) =>
|
||||
routeTo.params.ruleId === 'add' ? { createMode: true }
|
||||
: routeTo.params.ruleId === 'copy' ? { copyMode: true }
|
||||
: {}),
|
||||
async: loadAsync(RuleEditPage),
|
||||
routes: [
|
||||
{
|
||||
path: 'script/:moduleId',
|
||||
|
@ -345,11 +361,23 @@ export default [
|
|||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(RulesListPage, { showScenes: true }),
|
||||
routes: [
|
||||
{
|
||||
path: 'add',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(SceneEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(SceneEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: ':ruleId',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(SceneEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {})
|
||||
async: loadAsync(SceneEditPage)
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -358,11 +386,23 @@ export default [
|
|||
beforeEnter: [enforceAdminForRoute],
|
||||
async: loadAsync(RulesListPage, { showScripts: true }),
|
||||
routes: [
|
||||
{
|
||||
path: 'add',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(ScriptEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: 'copy',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(ScriptEditPage, { createMode: true })
|
||||
},
|
||||
{
|
||||
path: ':ruleId',
|
||||
beforeEnter: [enforceAdminForRoute],
|
||||
beforeLeave: [checkDirtyBeforeLeave],
|
||||
async: loadAsync(ScriptEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {})
|
||||
async: loadAsync(ScriptEditPage)
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -87,6 +87,9 @@
|
|||
<f7-row>
|
||||
<f7-col>
|
||||
<f7-list>
|
||||
<f7-list-button color="blue" @click="copyItem">
|
||||
Copy Item
|
||||
</f7-list-button>
|
||||
<f7-list-button v-if="item.editable" color="red" @click="deleteItem">
|
||||
Remove Item
|
||||
</f7-list-button>
|
||||
|
@ -153,6 +156,8 @@
|
|||
</style>
|
||||
|
||||
<script>
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
import ItemStatePreview from '@/components/item/item-state-preview.vue'
|
||||
import LinkDetails from '@/components/model/link-details.vue'
|
||||
import GroupMembers from '@/components/item/group-members.vue'
|
||||
|
@ -202,6 +207,16 @@ export default {
|
|||
this.iconUrl = '/icon/' + this.item.category + '?format=svg'
|
||||
})
|
||||
},
|
||||
copyItem () {
|
||||
let itemClone = cloneDeep(this.item)
|
||||
this.$f7router.navigate({
|
||||
url: '/settings/items/copy'
|
||||
}, {
|
||||
props: {
|
||||
itemCopy: itemClone
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteItem () {
|
||||
this.$f7.dialog.confirm(
|
||||
`Are you sure you want to delete ${this.item.label || this.item.name}?`,
|
||||
|
|
|
@ -73,7 +73,7 @@ import ItemMixin from '@/components/item/item-mixin'
|
|||
|
||||
export default {
|
||||
mixins: [DirtyMixin, ItemMixin],
|
||||
props: ['itemName', 'createMode'],
|
||||
props: ['itemName', 'createMode', 'itemCopy'],
|
||||
components: {
|
||||
ItemForm,
|
||||
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue')
|
||||
|
@ -144,7 +144,7 @@ export default {
|
|||
if (this.loading) return
|
||||
this.loading = true
|
||||
if (this.createMode) {
|
||||
const newItem = {
|
||||
const newItem = this.itemCopy || {
|
||||
name: '',
|
||||
label: '',
|
||||
category: '',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<f7-page @page:afterin="onPageAfterIn" @page:afterout="onPageAfterOut">
|
||||
<f7-navbar :title="(isNewRule ? 'Create rule' : rule.name) + dirtyIndicator" back-link="Back" no-hairline>
|
||||
<f7-navbar :title="(createMode ? 'Create rule' : rule.name) + dirtyIndicator" back-link="Back" no-hairline>
|
||||
<f7-nav-right>
|
||||
<developer-dock-icon />
|
||||
<template v-if="isEditable">
|
||||
|
@ -21,8 +21,8 @@
|
|||
</f7-toolbar>
|
||||
<f7-tabs class="sitemap-editor-tabs">
|
||||
<f7-tab id="design" @tab:show="() => this.currentTab = 'design'" :tab-active="currentTab === 'design'">
|
||||
<f7-block v-if="ready && rule.status && (!isNewRule)" class="block-narrow padding-left padding-right" strong>
|
||||
<f7-col v-if="!isNewRule">
|
||||
<f7-block v-if="ready && rule.status && (!createMode)" class="block-narrow padding-left padding-right" strong>
|
||||
<f7-col v-if="!createMode">
|
||||
<div class="float-right align-items-flex-start align-items-center">
|
||||
<!-- <f7-toggle class="enable-toggle"></f7-toggle> -->
|
||||
<f7-link :icon-color="(rule.status.statusDetail === 'DISABLED') ? 'orange' : 'gray'" :tooltip="((rule.status.statusDetail === 'DISABLED') ? 'Enable' : 'Disable') + (($device.desktop) ? ' (Ctrl-D)' : '')" icon-ios="f7:pause_circle" icon-md="f7:pause_circle" icon-aurora="f7:pause_circle" icon-size="32" color="orange" @click="toggleDisabled" />
|
||||
|
@ -42,7 +42,7 @@
|
|||
</f7-col>
|
||||
</f7-block>
|
||||
<!-- skeletons for not ready -->
|
||||
<f7-block v-else-if="!isNewRule" class="block-narrow padding-left padding-right skeleton-text skeleton-effect-blink" strong>
|
||||
<f7-block v-else-if="!createMode" class="block-narrow padding-left padding-right skeleton-text skeleton-effect-blink" strong>
|
||||
<f7-col>
|
||||
______:
|
||||
<f7-chip class="margin-left" text="________" />
|
||||
|
@ -53,7 +53,7 @@
|
|||
</f7-col>
|
||||
</f7-block>
|
||||
|
||||
<rule-general-settings :rule="rule" :ready="ready" :createMode="isNewRule" :hasTemplate="hasTemplate" />
|
||||
<rule-general-settings :rule="rule" :ready="ready" :createMode="createMode" :hasTemplate="hasTemplate" />
|
||||
|
||||
<f7-block v-if="ready" class="block-narrow">
|
||||
<f7-block-footer v-if="!isEditable" class="no-margin padding-left">
|
||||
|
@ -125,7 +125,7 @@
|
|||
</f7-list>
|
||||
</div>
|
||||
</f7-col>
|
||||
<f7-col v-if="isEditable && (!isNewRule)">
|
||||
<f7-col v-if="isEditable && (!createMode)">
|
||||
<f7-list>
|
||||
<f7-list-button color="blue" @click="copyRule">
|
||||
Copy Rule
|
||||
|
@ -198,7 +198,7 @@ export default {
|
|||
ConfigSheet,
|
||||
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue')
|
||||
},
|
||||
props: ['ruleId', 'createMode', 'copyMode', 'ruleCopy', 'schedule'],
|
||||
props: ['ruleId', 'createMode', 'ruleCopy', 'schedule'],
|
||||
data () {
|
||||
return {
|
||||
SECTION_LABELS: {
|
||||
|
@ -270,7 +270,7 @@ export default {
|
|||
this.moduleTypes.conditions = data[1]
|
||||
this.moduleTypes.triggers = data[2]
|
||||
if (this.createMode) {
|
||||
this.$set(this, 'rule', {
|
||||
const newRule = this.ruleCopy || {
|
||||
uid: this.$f7.utils.id(),
|
||||
name: '',
|
||||
triggers: [],
|
||||
|
@ -283,28 +283,14 @@ export default {
|
|||
status: {
|
||||
status: 'NEW'
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.ruleCopy) newRule.uid = this.$f7.utils.id()
|
||||
this.$set(this, 'rule', newRule)
|
||||
this.$oh.api.get('/rest/templates').then((data2) => {
|
||||
this.$set(this, 'templates', data2)
|
||||
loadingFinished()
|
||||
})
|
||||
// no need for an event source, the rule doesn't exist yet
|
||||
} else if (this.copyMode) {
|
||||
this.$set(this, 'rule', {
|
||||
uid: this.$f7.utils.id(),
|
||||
name: this.ruleCopy.name + ' Copy',
|
||||
triggers: this.ruleCopy.triggers,
|
||||
actions: this.ruleCopy.actions,
|
||||
conditions: this.ruleCopy.conditions,
|
||||
tags: this.ruleCopy.tags,
|
||||
configuration: this.ruleCopy.configuration,
|
||||
visibility: 'VISIBLE',
|
||||
status: {
|
||||
status: 'NEW'
|
||||
}
|
||||
})
|
||||
loadingFinished()
|
||||
// no need for an event source, the rule doesn't exist yet
|
||||
} else {
|
||||
this.$oh.api.get('/rest/rules/' + this.ruleId).then((data2) => {
|
||||
this.$set(this, 'rule', data2)
|
||||
|
@ -329,12 +315,12 @@ export default {
|
|||
this.$f7.dialog.alert('Please give a name to the rule')
|
||||
return Promise.reject()
|
||||
}
|
||||
const promise = (this.isNewRule)
|
||||
const promise = (this.createMode)
|
||||
? this.$oh.api.postPlain('/rest/rules', JSON.stringify(this.rule), 'text/plain', 'application/json')
|
||||
: this.$oh.api.put('/rest/rules/' + this.rule.uid, this.rule)
|
||||
return promise.then((data) => {
|
||||
this.dirty = false
|
||||
if (this.isNewRule) {
|
||||
if (this.createMode) {
|
||||
this.$f7.toast.create({
|
||||
text: 'Rule created',
|
||||
destroyOnClose: true,
|
||||
|
@ -375,7 +361,7 @@ export default {
|
|||
})
|
||||
},
|
||||
runNow () {
|
||||
if (this.isNewRule) return
|
||||
if (this.createMode) return
|
||||
if (this.rule.status.status === 'RUNNING' || this.rule.status.status === 'UNINITIALIZED') {
|
||||
return this.$f7.toast.create({
|
||||
text: `Rule cannot be run ${(this.rule.status.status === 'RUNNING') ? 'while already running, please wait' : 'if it is uninitialized'}!`,
|
||||
|
@ -562,7 +548,7 @@ export default {
|
|||
this.currentModuleType = mod.type
|
||||
this.scriptCode = mod.configuration.script
|
||||
|
||||
const updatePromise = (this.rule.editable || this.isNewRule) && this.dirty ? this.save() : Promise.resolve()
|
||||
const updatePromise = (this.rule.editable || this.createMode) && this.dirty ? this.save() : Promise.resolve()
|
||||
updatePromise.then(() => {
|
||||
this.$f7router.navigate('/settings/rules/' + this.rule.uid + '/script/' + mod.id, { transition: this.$theme.aurora ? 'f7-cover-v' : '' })
|
||||
})
|
||||
|
@ -594,9 +580,6 @@ export default {
|
|||
hasTemplate () {
|
||||
return this.rule && this.currentTemplate !== null
|
||||
},
|
||||
isNewRule () {
|
||||
return this.createMode || this.copyMode
|
||||
},
|
||||
templateTopicLink () {
|
||||
if (!this.currentTemplate) return null
|
||||
if (!this.currentTemplate.tags) return null
|
||||
|
|
|
@ -115,6 +115,9 @@
|
|||
</f7-col>
|
||||
<f7-col v-if="isEditable && !createMode">
|
||||
<f7-list>
|
||||
<f7-list-button color="blue" @click="copyRule">
|
||||
Copy Scene
|
||||
</f7-list-button>
|
||||
<f7-list-button color="red" @click="deleteRule">
|
||||
Remove Scene
|
||||
</f7-list-button>
|
||||
|
@ -206,7 +209,7 @@ export default {
|
|||
ItemPicker,
|
||||
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue')
|
||||
},
|
||||
props: ['ruleId', 'createMode'],
|
||||
props: ['ruleId', 'createMode', 'ruleCopy'],
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
|
@ -262,7 +265,7 @@ export default {
|
|||
Promise.all([loadModules1]).then((data) => {
|
||||
this.moduleTypes.actions = data[0]
|
||||
if (this.createMode) {
|
||||
this.$set(this, 'rule', {
|
||||
const newRule = this.ruleCopy || {
|
||||
uid: this.$f7.utils.id(),
|
||||
name: '',
|
||||
triggers: [],
|
||||
|
@ -275,7 +278,9 @@ export default {
|
|||
status: {
|
||||
status: 'NEW'
|
||||
}
|
||||
})
|
||||
}
|
||||
if (this.ruleCopy) newRule.uid = this.$f7.utils.id()
|
||||
this.$set(this, 'rule', newRule)
|
||||
loadingFinished()
|
||||
} else {
|
||||
this.$oh.api.get('/rest/rules/' + this.ruleId).then((data2) => {
|
||||
|
@ -367,6 +372,16 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
copyRule () {
|
||||
let ruleClone = cloneDeep(this.rule)
|
||||
this.$f7router.navigate({
|
||||
url: '/settings/scenes/copy'
|
||||
}, {
|
||||
props: {
|
||||
ruleCopy: ruleClone
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteRule () {
|
||||
this.$f7.dialog.confirm(
|
||||
`Are you sure you want to delete ${this.rule.name}?`,
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<editor v-if="!createMode && (!isBlockly || blocklyCodePreview)" class="rule-script-editor" :mode="mode" :value="script" @input="onEditorInput" :read-only="isBlockly || !editable" :tern-autocompletion-hook="true" />
|
||||
<blockly-editor ref="blocklyEditor" v-else-if="!createMode && isBlockly" :blocks="currentModule.configuration.blockSource" @change="scriptDirty = true" @mounted="onBlocklyMounted" @ready="onBlocklyReady" />
|
||||
<script-general-settings v-else-if="createMode" :createMode="true" :rule="rule" />
|
||||
<f7-block class="block-narrow" v-if="createMode">
|
||||
<f7-block class="block-narrow" v-if="createMode && !ruleCopy">
|
||||
<f7-col>
|
||||
<f7-block-title medium class="margin-left margin-bottom">
|
||||
Scripting Method
|
||||
|
@ -131,6 +131,9 @@
|
|||
<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>
|
||||
<f7-list-button color="red" @click="deleteRule">
|
||||
Remove Script
|
||||
</f7-list-button>
|
||||
|
@ -168,7 +171,7 @@ export default {
|
|||
'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue'),
|
||||
'blockly-editor': () => import(/* webpackChunkName: "blockly-editor" */ '@/components/config/controls/blockly-editor.vue')
|
||||
},
|
||||
props: ['ruleId', 'moduleId', 'createMode'],
|
||||
props: ['ruleId', 'moduleId', 'createMode', 'ruleCopy'],
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
|
@ -336,7 +339,7 @@ export default {
|
|||
}
|
||||
},
|
||||
initializeNewScript () {
|
||||
this.rule = {
|
||||
this.rule = this.ruleCopy || {
|
||||
uid: this.$f7.utils.id(),
|
||||
name: '',
|
||||
description: '',
|
||||
|
@ -345,6 +348,7 @@ export default {
|
|||
actions: [],
|
||||
tags: ['Script']
|
||||
}
|
||||
if (this.ruleCopy) this.rule.uid = this.$f7.utils.id()
|
||||
this.savedRule = cloneDeep(this.rule)
|
||||
this.savedMode = this.mode = 'application/javascript+blockly'
|
||||
this.loadScriptModuleTypes().then(() => {
|
||||
|
@ -361,19 +365,21 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
const actionModule = {
|
||||
id: 'script',
|
||||
type: 'script.ScriptAction',
|
||||
configuration: {
|
||||
type: this.mode,
|
||||
script: ''
|
||||
if (!this.ruleCopy) {
|
||||
const actionModule = {
|
||||
id: 'script',
|
||||
type: 'script.ScriptAction',
|
||||
configuration: {
|
||||
type: this.mode,
|
||||
script: ''
|
||||
}
|
||||
}
|
||||
if (this.mode === 'application/javascript+blockly') {
|
||||
actionModule.configuration.type = this.GRAALJS_MIME_TYPE
|
||||
actionModule.configuration.blockSource = '<xml xmlns="https://developers.google.com/blockly/xml"></xml>'
|
||||
}
|
||||
this.rule.actions.push(actionModule)
|
||||
}
|
||||
if (this.mode === 'application/javascript+blockly') {
|
||||
actionModule.configuration.type = this.GRAALJS_MIME_TYPE
|
||||
actionModule.configuration.blockSource = '<xml xmlns="https://developers.google.com/blockly/xml"></xml>'
|
||||
}
|
||||
this.rule.actions.push(actionModule)
|
||||
|
||||
this.$oh.api.postPlain('/rest/rules', JSON.stringify(this.rule), 'text/plain', 'application/json').then(() => {
|
||||
this.resetDirty()
|
||||
|
@ -382,7 +388,7 @@ export default {
|
|||
destroyOnClose: true,
|
||||
closeTimeout: 2000
|
||||
}).open()
|
||||
this.$f7router.navigate(this.$f7route.url.replace('/add', '/' + this.rule.uid), { reloadCurrent: true })
|
||||
this.$f7router.navigate(this.$f7route.url.replace(/(\/add)|(\/copy)/, '/' + this.rule.uid), { reloadCurrent: true })
|
||||
})
|
||||
},
|
||||
isMimeTypeAvailable (mimeType) {
|
||||
|
@ -573,6 +579,16 @@ export default {
|
|||
run(false)
|
||||
}
|
||||
},
|
||||
copyRule () {
|
||||
let ruleClone = cloneDeep(this.rule)
|
||||
this.$f7router.navigate({
|
||||
url: '/settings/scripts/copy'
|
||||
}, {
|
||||
props: {
|
||||
ruleCopy: ruleClone
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteRule () {
|
||||
this.$f7.dialog.confirm(
|
||||
`Are you sure you want to delete ${this.rule.name}?`,
|
||||
|
|
|
@ -67,12 +67,17 @@ export default {
|
|||
ConfigSheet,
|
||||
ThingGeneralSettings
|
||||
},
|
||||
props: ['thingTypeId'],
|
||||
props: ['thingTypeId', 'thingCopy'],
|
||||
data () {
|
||||
if (this.thingCopy) {
|
||||
delete this.thingCopy.editable
|
||||
delete this.thingCopy.properties
|
||||
delete this.thingCopy.statusInfo
|
||||
}
|
||||
return {
|
||||
ready: false,
|
||||
currentTab: 'info',
|
||||
thing: {
|
||||
thing: this.thingCopy || {
|
||||
UID: '',
|
||||
label: '',
|
||||
configuration: {},
|
||||
|
@ -83,6 +88,12 @@ export default {
|
|||
codePopupOpened: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isExtensible () {
|
||||
if (!this.thingType || !this.thingType.extensibleChannelTypeIds) return false
|
||||
return this.thingType.extensibleChannelTypeIds.length > 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn () {
|
||||
if (this.ready) return
|
||||
|
@ -95,6 +106,18 @@ export default {
|
|||
console.log('Cannot generate ID: ' + e)
|
||||
}
|
||||
this.thing.label = this.thingType.label
|
||||
|
||||
if (this.thingCopy) {
|
||||
if (this.thing.bridgeUID) this.thing.UID = [this.thing.thingTypeUID, this.thing.bridgeUID.substring(this.thing.bridgeUID.lastIndexOf(':') + 1), this.thing.ID].join(':')
|
||||
if (this.isExtensible) {
|
||||
this.thing.channels.forEach((ch) => {
|
||||
ch.uid = this.thing.UID + ':' + ch.id
|
||||
})
|
||||
} else {
|
||||
this.thing.channels = []
|
||||
}
|
||||
}
|
||||
|
||||
this.ready = true
|
||||
})
|
||||
},
|
||||
|
|
|
@ -135,10 +135,11 @@
|
|||
</f7-block>
|
||||
</div>
|
||||
|
||||
<f7-block class="block-narrow" v-if="ready && editable">
|
||||
<f7-block class="block-narrow" v-if="ready">
|
||||
<f7-col>
|
||||
<f7-list>
|
||||
<f7-list-button color="red" title="Delete Thing" @click="deleteThing" />
|
||||
<f7-list-button color="blue" title="Copy Thing" @click="copyThing" />
|
||||
<f7-list-button v-if="editable" color="red" title="Delete Thing" @click="deleteThing" />
|
||||
</f7-list>
|
||||
</f7-col>
|
||||
</f7-block>
|
||||
|
@ -610,6 +611,17 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
copyThing () {
|
||||
let thingClone = cloneDeep(this.thing)
|
||||
this.$f7router.navigate({
|
||||
url: '/settings/things/copy'
|
||||
}, {
|
||||
props: {
|
||||
thingTypeId: this.thing.thingTypeUID,
|
||||
thingCopy: thingClone
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteThing () {
|
||||
let url, message
|
||||
if (this.thing.statusInfo.status === 'REMOVING') {
|
||||
|
|
Loading…
Reference in New Issue