Skip to content

Commit

Permalink
#2044|#1818: Improve repeater cloning.
Browse files Browse the repository at this point in the history
  • Loading branch information
haringsrob committed Feb 24, 2023
1 parent 748467b commit c3224c6
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 71 deletions.
152 changes: 83 additions & 69 deletions frontend/js/components/Repeater.vue
Original file line number Diff line number Diff line change
@@ -1,78 +1,80 @@
<template>
<div class="content">
<draggable class="content__content" v-model="blocks" :options="dragOptions">
<transition-group name="draggable_list" tag='div'>
<div class="content__item" v-for="(block, index) in blocks" :key="block.id">
<a17-blockeditor-item
ref="blockList"
:block="block"
:index="index"
:withHandle="draggable"
:size="blockSize"
:opened="opened"
>
<a17-button slot="block-actions" variant="icon" data-action @click="duplicateBlock(index)" v-if="hasRemainingBlocks">
<span v-svg symbol="add"></span>
<div class="content">
<draggable class="content__content" v-model="blocks" :options="dragOptions">
<transition-group name="draggable_list" tag='div'>
<div class="content__item" v-for="(block, index) in blocks" :key="block.id">
<a17-blockeditor-item
ref="blockList"
:block="block"
:index="index"
:withHandle="draggable"
:size="blockSize"
:opened="opened"
>
<a17-button slot="block-actions" variant="icon" data-action @click="duplicateBlock(index)"
v-if="hasRemainingBlocks">
<span v-svg symbol="add"></span>
</a17-button>
<div slot="dropdown-action">
<button type="button" @click="collapseAllBlocks()" v-if="opened">
{{ $trans('fields.block-editor.collapse-all', 'Collapse all') }}
</button>
<button v-else type="button" @click="expandAllBlocks()">
{{ $trans('fields.block-editor.expand-all', 'Expand all') }}
</button>
<button type="button" @click="duplicateBlock(index)" v-if="hasRemainingBlocks">
{{ $trans('fields.block-editor.clone-block', 'Clone block') }}
</button>
<button type="button" @click="deleteBlock(index)">
{{ $trans('fields.block-editor.delete', 'Delete') }}
</button>
</div>
</a17-blockeditor-item>
</div>
</transition-group>
</draggable>
<div class="content__trigger">
<a17-button
v-if="hasRemainingBlocks && blockType.trigger && allowCreate"
:class="triggerClass"
:variant="triggerVariant"
@click="addBlock()"
>
{{ blockType.trigger }}
</a17-button>
<div slot="dropdown-action">
<button type="button" @click="collapseAllBlocks()" v-if="opened">
{{ $trans('fields.block-editor.collapse-all', 'Collapse all') }}
</button>
<button v-else type="button" @click="expandAllBlocks()">
{{ $trans('fields.block-editor.expand-all', 'Expand all') }}
</button>
<button type="button" @click="duplicateBlock(index)" v-if="hasRemainingBlocks">
{{ $trans('fields.block-editor.clone-block', 'Clone block') }}
</button>
<button type="button" @click="deleteBlock(index)">
{{ $trans('fields.block-editor.delete', 'Delete') }}
</button>
<a17-button
v-if="hasRemainingBlocks && browser"
:class="triggerClass"
:variant="triggerVariant"
@click="openBrowser()"
>
{{ blockType.selectTrigger }}
</a17-button>
<div class="content__note f--note f--small">
<slot></slot>
</div>
</a17-blockeditor-item>
</div>
</transition-group>
</draggable>
<div class="content__trigger">
<a17-button
v-if="hasRemainingBlocks && blockType.trigger && allowCreate"
:class="triggerClass"
:variant="triggerVariant"
@click="addBlock()"
>
{{ blockType.trigger }}
</a17-button>
<a17-button
v-if="hasRemainingBlocks && browser"
:class="triggerClass"
:variant="triggerVariant"
@click="openBrowser()"
>
{{ blockType.selectTrigger }}
</a17-button>
<div class="content__note f--note f--small">
<slot></slot>
</div>
<a17-standalone-browser
v-if="browserIsOpen"
:endpoint="browser"
:for-repeater="true"
@selected="addRepeatersFromSelection"
ref="localbrowser"
@close="browserIsOpen = false"
:max="max"
/>
</div>
<a17-standalone-browser
v-if="browserIsOpen"
:endpoint="browser"
:for-repeater="true"
@selected="addRepeatersFromSelection"
ref="localbrowser"
@close="browserIsOpen = false"
:max="max"
/>
</div>
</template>

<script>
import draggable from 'vuedraggable'
import { mapState } from 'vuex'
import {mapState} from 'vuex'
import BlockEditorItem from '@/components/blocks/BlockEditorItem.vue'
import A17StandaloneBrowser from "@/components/StandaloneBrowser.vue"
import draggableMixin from '@/mixins/draggable'
import { FORM } from '@/store/mutations'
import {FORM} from '@/store/mutations'
import ACTIONS from "@/store/actions";
export default {
name: 'A17Repeater',
Expand Down Expand Up @@ -178,21 +180,33 @@
}
},
addBlock: function () {
this.$store.commit(FORM.ADD_FORM_BLOCK, { type: this.type, name: this.name })
this.$store.commit(FORM.ADD_FORM_BLOCK, {type: this.type, name: this.name})
this.$nextTick(() => {
this.checkExpandBlocks()
})
},
addRepeatersFromSelection(selected) {
this.$store.commit(FORM.ADD_REPEATER_FROM_SELECTION, { type: this.type, name: this.name, selection: selected, relation: this.relation })
},
duplicateBlock: function (index) {
this.$store.commit(FORM.DUPLICATE_FORM_BLOCK, {
addRepeatersFromSelection (selected) {
this.$store.commit(FORM.ADD_REPEATER_FROM_SELECTION, {
type: this.type,
name: this.name,
index
selection: selected,
relation: this.relation
})
},
duplicateBlock: function (index) {
this.$store.dispatch(ACTIONS.DUPLICATE_REPEATER, {
editorName: this.name,
index,
futureIndex: index + 1,
block: this.blocks[index],
id: Date.now() + Math.floor(Math.random() * 1000)
})
// this.$store.commit(FORM.DUPLICATE_FORM_BLOCK, {
// type: this.type,
// name: this.name,
// index
// })
this.$nextTick(() => {
this.checkExpandBlocks()
Expand Down
6 changes: 5 additions & 1 deletion frontend/js/store/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
export const MOVE_BLOCK_TO_EDITOR = 'moveBlockToEditor'
export const DUPLICATE_BLOCK = 'duplicateBlock'

/* Repeaters */
export const DUPLICATE_REPEATER = 'duplicateRepeater'

/* Buckets */
export const GET_BUCKETS = 'getBucketsData'
export const SAVE_BUCKETS = 'saveBuckets'
Expand Down Expand Up @@ -70,5 +73,6 @@ export default {
GET_REVISION,
GET_CURRENT,
MOVE_BLOCK_TO_EDITOR,
DUPLICATE_BLOCK
DUPLICATE_BLOCK,
DUPLICATE_REPEATER
}
39 changes: 38 additions & 1 deletion frontend/js/store/modules/repeaters.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,17 @@ const mutations = {
clone.twillUi.isNew = true

state.repeaters[blockInfos.name].splice(blockInfos.index + 1, 0, clone)

// Clone the fields as well.
const fields = [...getters.fieldsByBlockId(blockInfos.id)]
const fieldCopies = []
fields.forEach(field => {
fieldCopies.push({
name: field.name.replace(blockInfos.id, clone.id),
value: field.value
})
})
this.commit(FORM.ADD_FORM_FIELDS, fieldCopies)
},
[FORM.REORDER_FORM_BLOCKS] (state, newValues) {
const newBlocks = {}
Expand All @@ -127,6 +138,32 @@ const mutations = {
}

const actions = {
async [ACTIONS.DUPLICATE_REPEATER] ({ state, commit, getters }, { editorName, block, index, id }) {
const clone = Object.assign({}, state.repeaters[editorName][index])
clone.id = id

// Metadata for rendering
clone.twillUi = {}
clone.twillUi.isNew = true

const duplicates = {}
duplicates[editorName] = [...state.repeaters[editorName]];
duplicates[editorName].splice(index + 1, 0, clone)


// Clone the fields as well.
const fields = [...getters.fieldsByBlockId(block.id)]
const fieldCopies = []
fields.forEach(field => {
fieldCopies.push({
name: field.name.replace(block.id, clone.id),
value: Object.assign({}, field.value)
})
})

commit(FORM.ADD_FORM_FIELDS, fieldCopies)
commit(FORM.ADD_REPEATERS, { repeaters: duplicates })
},
async [ACTIONS.DUPLICATE_BLOCK] ({ commit, getters }, { block, id }) {
// copy repeaters and update with the provided id
const repeaters = { ...getters.repeatersByBlockId(block.id) }
Expand All @@ -145,7 +182,7 @@ const actions = {
fields.forEach(field => {
fieldCopies.push({
name: field.name.replace(block.id, id),
value: field.value
value: Object.assign({}, field.value)
})
})
})
Expand Down

0 comments on commit c3224c6

Please sign in to comment.