3
0

Add option to save page layout as copy with or without references

This commit is contained in:
Jože Fortun 2023-09-18 13:16:00 +02:00
parent c89df1c846
commit d64ed2b456
5 changed files with 88 additions and 24 deletions

View File

@ -47,6 +47,8 @@
>
{{ $t('label.delete') }}
</c-input-confirm>
<slot name="saveAsCopy" />
<b-button
v-if="!hideClone"
data-test-id="button-clone"
@ -59,6 +61,7 @@
>
{{ $t('label.saveAsCopy') }}
</b-button>
<b-button
v-if="!hideSave"
data-test-id="button-save-and-close"
@ -70,6 +73,7 @@
>
{{ $t('label.saveAndClose') }}
</b-button>
<b-button
v-if="!hideSave"
data-test-id="button-save"

View File

@ -152,12 +152,9 @@ export default {
if (this.record.valueErrors.set) {
this.toastWarning(this.$t('notification:record.validationWarnings'))
} else {
if (isNew) {
this.inCreating = false
this.inEditing = false
} else {
this.record = record
}
this.inCreating = false
this.inEditing = false
this.record = record
if (this.showRecordModal) {
this.$emit('handle-record-redirect', { recordID: record.recordID, recordPageID: this.page.pageID })

View File

@ -256,10 +256,10 @@
<editor-toolbar
:hide-save="!page.canUpdatePage"
:processing="processing"
hide-clone
@save="handleSaveLayout()"
@delete="handleDeleteLayout()"
@saveAndClose="handleSaveLayout({ closeOnSuccess: true })"
@clone="handleCloneLayout()"
@back="$router.push(previousPage || { name: 'admin.pages' })"
>
<b-button
@ -272,6 +272,31 @@
>
+ {{ $t('build.addBlock') }}
</b-button>
<template #saveAsCopy>
<b-dropdown
v-if="page.canUpdatePage"
data-test-id="dropdown-saveAsCopy"
:text="$t('general:label.saveAsCopy')"
:disabled="processing"
size="lg"
variant="light"
class="ml-2"
>
<b-dropdown-item
data-test-id="dropdown-item-saveAsCopy-ref"
@click="handleCloneLayout({ ref: true })"
>
{{ $t('build.saveAsCopy.ref') }}
</b-dropdown-item>
<b-dropdown-item
data-test-id="dropdown-item-saveAsCopy-noRef"
@click="handleCloneLayout({ ref: false })"
>
{{ $t('build.saveAsCopy.noRef') }}
</b-dropdown-item>
</b-dropdown>
</template>
</editor-toolbar>
</portal>
@ -676,7 +701,7 @@ export default {
appendBlock (block, msg) {
this.calculateNewBlockPosition(block)
this.editor = { index: undefined, block: compose.PageBlockMaker(block) }
this.editor = { index: undefined, block }
this.updateBlocks()
if (!this.editor) {
@ -735,7 +760,7 @@ export default {
return !req.size
},
async handleSaveLayout ({ closeOnSuccess = false, previewOnSuccess = false } = {}) {
async handleSaveLayout ({ closeOnSuccess = false, previewOnSuccess = false, alert = true } = {}) {
const { namespaceID } = this.namespace
// Record blocks
@ -788,26 +813,27 @@ export default {
layout = await this.updatePageLayout({ ...layout, blocks })
return { page, layout }
})
}).then(({ page, layout }) => {
this.page = new compose.Page(page)
this.layout = new compose.PageLayout(layout)
this.unsavedBlocks.clear()
this.toastSuccess(this.$t('notification:page.page-layout.save.success'))
}).then(async ({ page, layout }) => {
if (closeOnSuccess) {
this.$router.push(this.previousPage || { name: 'admin.pages' })
return
}
return this.fetchPageLayouts()
if (alert) {
this.toastSuccess(this.$t('notification:page.page-layout.save.success'))
}
this.page = new compose.Page(page)
await this.fetchPageLayouts()
this.setLayout(layout.pageLayoutID)
}).finally(() => {
this.processing = false
}).catch(this.toastErrorHandler(this.$t('notification:page.page-layout.save.failed')))
},
handleCloneLayout () {
async handleCloneLayout ({ ref = false }) {
this.processing = true
this.processingLayout = true
const layout = {
...this.layout.clone(),
@ -817,13 +843,46 @@ export default {
layout.meta.title = `${this.$t('copyOf')}${layout.meta.title}`
this.createPageLayout(layout).then(({ pageLayoutID }) => {
return this.fetchPageLayouts().then(() => {
this.setLayout(pageLayoutID)
this.toastSuccess(this.$t('notification:page.page-layout.clone.success'))
// If we are cloning a layout with references, we need to clone the blocks
if (!ref) {
const oldBlockIDs = {}
layout.blocks = []
// Sort based on if tab or not
this.blocks = this.blocks.toSorted((a, b) => {
if (a.kind === 'Tabs' && b.kind !== 'Tabs') {
return 1 // Move 'Tabs' to the end
} else if (a.kind !== 'Tabs' && b.kind === 'Tabs') {
return -1 // Keep 'Tabs' before other elements
} else {
return 0 // No change in order
}
}).map(block => {
const oldBlockID = block.blockID
if (block.kind === 'Tabs') {
block.options.tabs = block.options.tabs.map(tab => {
tab.blockID = oldBlockIDs[tab.blockID]
return tab
})
}
block = block.clone()
oldBlockIDs[oldBlockID] = block.meta.tempID
return block
})
}
this.createPageLayout(layout).then(layout => {
this.layout = layout
this.layouts.push({ ...layout, label: layout.meta.title || layout.handle || layout.pageLayoutID })
return this.handleSaveLayout({ alert: false })
}).then(() => {
this.toastSuccess(this.$t('notification:page.page-layout.clone.success'))
}).finally(() => {
this.processing = false
this.processingLayout = false
}).catch(this.toastErrorHandler(this.$t('notification:page.page-layout.clone.failed')))
},
@ -884,7 +943,7 @@ export default {
const paste = (event.clipboardData || window.clipboardData).getData('text')
// Doing this to handle JSON parse error
try {
const block = JSON.parse(paste)
const block = compose.pageBlockMaker(JSON.parse(paste))
const valid = this.isValid(block)
if (valid) {

View File

@ -1,6 +1,7 @@
import { merge } from 'lodash'
import { Apply, NoID } from '../../../cast'
import { generateUID } from '../../helpers/idgen'
import { PageBlockMaker } from '.'
interface PageBlockStyleVariants {
[_: string]: string;
@ -105,7 +106,7 @@ export class PageBlock {
}
clone (): PageBlockInput {
return { ...JSON.parse(JSON.stringify(this)), blockID: NoID, meta: { tempID: '' } }
return PageBlockMaker({ ...JSON.parse(JSON.stringify(this)), blockID: NoID, meta: { tempID: generateUID() } })
}
}

View File

@ -61,6 +61,9 @@ build:
addBlock: Add block
selectBlockTitle: Select type of the new block
unsavedChanges: Unsaved changes will be lost. Do you wish to leave the page?
saveAsCopy:
ref: With references
noRef: Without references
createLabel: Create page
edit:
create: Create page