Commit f4867688 authored by anton's avatar anton

Add functionality for duplicating timelines

parent be9be223
......@@ -10,6 +10,10 @@ and this project adheres to
## [Unreleased]
### Added
- Duplicate a Timeline on its `edit` page
### Fixed
- Swimlane breaks when loading improperly formatted Annotations
......
<template lang="pug">
q-modal(v-model="showModal", minimized)
.bg-dark.q-pa-md.text-center
.q-py-md {{ $t('labels.duplicate_timeline_title') }}
q-input(v-model="title", dark)
.q-mt-md
q-btn.q-mx-xs(color="primary", @click="confirm") {{ $t('buttons.duplicate_timeline') }}
q-btn.q-mx-xs(color="faded", @click="clear") {{ $t('buttons.cancel') }}
</template>
<script>
export default {
name: 'DuplicateTimelineModal',
data () {
return {
showModal: false,
title: undefined
}
},
methods: {
show (title) {
this.showModal = true
this.title = title
},
clear () {
this.showModal = false
this.title = undefined
},
confirm () {
this.$emit('confirm', this.title)
this.clear()
}
}
}
</script>
<style scoped lanhg="stylus">
</style>
......@@ -31,6 +31,7 @@ export default {
download_package: 'Download Package',
download: 'Download',
done: 'Done',
duplicate_timeline: 'Duplicate Timeline',
edit: 'Edit',
export_grid: 'Export Grid',
export_timeline: 'Export Timeline',
......@@ -129,7 +130,8 @@ export default {
editing_forbidden: 'You are not allowed to edit this item.',
annotate_timeline_forbidden: 'You are not allowed to annotate this Timeline.',
media_could_not_be_accessed: 'The supplied media URL could not be accessed.',
access_to_media_denied: 'Access to the media URL was denied.'
access_to_media_denied: 'Access to the media URL was denied.',
duplicate_timeline_failed: 'Duplicate Timeline failed: {error}'
},
labels: {
rejected: 'Rejected.',
......@@ -152,6 +154,7 @@ export default {
author: 'Author',
creator: 'Creator',
duration_seconds: 'Duration (s)',
duplicate_timeline_title: 'Duplicate Timeline title',
biovision_hierarchy: 'Biovision Hierarchy',
anonymous_creator: 'Anonymous',
unknown_creator: 'Unknown',
......@@ -249,6 +252,7 @@ export default {
submit_success: 'Submission successful',
timeline_imported: 'Timeline imported successfully',
timeline_deleted: 'Timeline deleted',
timeline_duplicated: 'Timeline duplicated successfully',
grid_imported: 'Grid imported successfully',
grid_deleted: 'Grid deleted',
confirm_delete: 'Delete this item?',
......
<template lang="pug">
full-screen
duplicate-timeline-modal(ref="duplicateModal", @confirm="duplicateTimeline")
// --------------------------------------------------------------------------------------------------- edit timeline
content-block(:position="'first'")
......@@ -9,6 +11,9 @@
form-main(v-if="acl.put", v-model="payload", :schema="schema")
//
div(slot="form-buttons-add", :class="{'full-width row q-mb-sm': isMobile}")
q-btn.col(v-if="$route.params.uuid", slot="form-buttons-add",
:label="$t('buttons.duplicate_timeline')", @click="showDuplicateModal",
color="grey", :class="[!isMobile ? 'q-mr-sm' : '']")
q-btn.col(v-if="$route.params.uuid", slot="form-buttons-add",
:label="exportLabel", @click="exportTimeline",
color="grey", :class="[!isMobile ? 'q-mr-sm' : '']")
......@@ -39,6 +44,7 @@
import { openURL } from 'quasar'
import { mapGetters } from 'vuex'
import PageSubNav from '../../../components/shared/navigation/PageSubNav'
import DuplicateTimelineModal from '../../../components/piecemaker/modals/DuplicateTimelineModal'
export default {
components: {
......@@ -49,7 +55,8 @@
Tags,
ContentBlock,
ContentParagraph,
Permissions
Permissions,
DuplicateTimelineModal
},
data () {
const _this = this
......@@ -108,6 +115,75 @@
})
},
methods: {
showDuplicateModal () {
this.$refs.duplicateModal.show(this.timeline.title + ' Copy')
},
async duplicateTimeline (title) {
console.log('duplicate as', title, this.timeline)
if (!title || !this.timeline) return
this.$q.loading.show()
try {
const timeline = await this.$store.dispatch('maps/post', {
title,
type: this.timeline.type
})
if (timeline) {
let result = await this.$store.dispatch('annotations/find', { 'target.id': this.timeline.id })
const annotations = result.items
for (let annotation of annotations) {
annotation = annotation.toObject()
let created, payload, title
if (annotation.body) {
if (annotation.body && annotation.body.type === 'Video') {
const { items } = (await this.$store.dispatch('annotations/find', { 'target.id': annotation.id }))
title = items.shift()
payload = {
body: annotation.body,
target: {
id: timeline.id,
type: annotation.target.type,
selector: annotation.target.selector
}
}
}
else {
payload = {
body: annotation.body,
target: {
id: timeline.id,
type: annotation.target.type,
selector: annotation.target.selector
}
}
}
}
if (payload) {
created = await this.$store.dispatch('annotations/post', payload)
}
if (title) {
title = title.toObject()
await this.$store.dispatch('annotations/post', {
body: title.body,
target: {
id: created.id,
type: title.target.type
}
})
}
}
}
}
catch (err) {
this.$handleError(this, err, 'errors.duplicate_timeline_failed')
}
this.$q.loading.hide()
this.$store.commit('notifications/addMessage', {
body: 'messages.timeline_duplicated',
mode: 'alert',
type: 'success'
})
return this.$router.push({ name: 'piecemaker.timelines.list' })
},
async exportTimeline () {
if (this.downloadURL) return openURL(this.downloadURL)
this.$q.loading.show()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment