Adds duplication dialog and routine.

This commit is contained in:
Mateus Machado Luna 2019-07-18 14:50:30 -03:00
parent 61e597c6c8
commit 72388ecd14
10 changed files with 195 additions and 28 deletions

View File

@ -107,11 +107,11 @@
v-if="contextMenuItem != null && contextMenuItem.current_user_can_edit && !$route.query.iframemode">
{{ $i18n.getFrom('items','edit_item') }}
</b-dropdown-item>
<!-- <b-dropdown-item
<b-dropdown-item
@click="duplicateOneItem(contextMenuItem.id)"
v-if="contextMenuItem != null && contextMenuItem.current_user_can_edit && !$route.query.iframemode">
{{ $i18n.get('label_duplicate_item') }}
</b-dropdown-item> -->
</b-dropdown-item>
<b-dropdown-item
@click="deleteOneItem(contextMenuItem.id)"
v-if="contextMenuItem != null && contextMenuItem.current_user_can_edit && !$route.query.iframemode">
@ -673,7 +673,7 @@
</div>
</masonry>
<!-- TABLE VIEW MODE -->
<table
v-if="viewMode == 'table'"
@ -712,7 +712,10 @@
</thead>
<tbody>
<tr
:class="{ 'selected-row': selectedItems[index] }"
:class="{
'selected-row': selectedItems[index],
'highlighted-item': highlightedItem == item.id
}"
:key="index"
v-for="(item, index) of items">
<!-- Checking list -->
@ -900,6 +903,7 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
import DuplicationDialog from '../other/duplication-dialog.vue';
import BulkEditionModal from '../bulk-edition/bulk-edition-modal.vue';
import { dateInter } from "../../../admin/js/mixins";
@ -939,6 +943,14 @@ export default {
this.selectedItemsIDs.push(false);
this.selectedItems.push(false);
}
if (this.highlightsItem)
setTimeout(() => this.$eventBusSearch.highlightsItem(null), 3000);
},
computed: {
highlightedItem () {
return this.getHighlightedItem();
}
},
watch: {
selectedItems() {
@ -972,18 +984,18 @@ export default {
'createEditGroup',
'trashItemsInBulk',
'deleteItemsInBulk',
'untrashItemsInBulk',
'untrashItemsInBulk'
]),
...mapGetters('bulkedition', [
'getGroupID'
]),
...mapActions('item', [
'fetchItem',
'duplicateItem'
'fetchItem'
]),
...mapGetters('search', [
'getOrder',
'getOrderBy'
'getOrderBy',
'getHighlightedItem'
]),
openBulkEditionModal(){
this.$modal.open({
@ -1026,15 +1038,24 @@ export default {
}
},
duplicateOneItem(itemId) {
this.fetchItem({ itemId: itemId, contextEdit: true })
.then((item) => {
this.duplicateItem({ item: item })
.then((duplicatedItem) => {
this.$console.log(duplicatedItem);
})
.catch((error) => this.$console.error(error));
})
.catch(error => this.$console.error("Error fetching item for duplicate: " + error));
this.$modal.open({
parent: this,
component: DuplicationDialog,
canCancel: false,
props: {
icon: 'items',
collectionId: this.collectionId,
itemId: itemId,
onConfirm: (duplicatedItemId) => {
if (duplicatedItemId != null && duplicatedItemId != undefined)
this.$eventBusSearch.highlightsItem(duplicatedItemId);
this.$eventBusSearch.loadItems();
}
}
});
this.clearContextMenu();
},
untrashOneItem(itemId) {
@ -1278,6 +1299,23 @@ export default {
}
}
@keyframes highlight {
from {
background-color: $blue1;
}
to {
background-color: initial;
}
}
.highlighted-item {
transition: background-color 0.5s;
animation-name: highlight;
animation-duration: 1s;
animation-iteration-count: 2;
}
</style>

View File

@ -525,7 +525,7 @@
.highlighted-process {
&>.process-handler {
transition: background-color 0.5s;
transition: background-color 0.8s;
animation-name: highlight;
animation-duration: 1s;
animation-iteration-count: 2;

View File

@ -0,0 +1,113 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal="true"
role="alertdialog"
class="tainacan-form dialog">
<div
class="modal-card"
style="width: auto">
<div
v-if="icon != undefined && icon != ''"
class="modal-custom-icon">
<span class="icon is-large">
<i
:class="'tainacan-icon-' + icon"
class="tainacan-icon"/>
</span>
</div>
<section
tabindex="1"
class="modal-card-body">
<header
class="modal-card-head">
<h1
id="alert-dialog-title"
class="modal-card-title">
{{ $i18n.get('label_duplicating_item') }}
</h1>
</header>
{{ message }}
</section>
<footer class="modal-card-foot form-submit">
<button
type="submit"
class="button is-outlined"
:disabled="isLoading"
@click="onConfirm(duplicatedItemId); $parent.close();">
{{ $i18n.get('label_items_list') }}
</button>
<button
type="submit"
class="button is-success"
:disabled="isLoading"
@click="$router.push($routerHelper.getItemEditPath(collectionId, duplicatedItemId)); $parent.close();">
{{ $i18n.getFrom('items','edit_item') }}
</button>
</footer>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'DuplicationDialog',
props: {
icon: String,
onConfirm: {
type: Function,
default: () => {}
},
collectionId: String,
itemId: String
},
data() {
return {
isLoading: Boolean,
message: String,
duplicatedItemId: String
}
},
methods: {
...mapActions('item', [
'fetchItem',
'duplicateItem'
]),
},
created() {
this.isLoading = true;
this.message = this.$i18n.get('info_await_while_item_duplication');
this.duplicateItem({ collectionId: this.collectionId, itemId: this.itemId })
.then((duplicatedItem) => {
this.isLoading = false;
this.message = this.$i18n.get('label_item_duplication_success');
this.duplicatedItemId = duplicatedItem.id;
})
.catch((error) => {
this.$console.error('Error fetching item for duplicate ' + error);
this.isLoading = false;
this.message = this.$i18n.get('label_item_duplication_failure');
});
}
}
</script>
<style scoped>
i.tainacan-icon,
i.tainacan-icon::before {
font-size: 42px;
}
button.is-success {
margin-left: auto;
}
.modal-card-foot {
margin-top: 12px;
}
</style>

View File

@ -415,6 +415,9 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_duplicate_item' => __( 'Duplicate item', 'tainacan' ),
'label_create_another_item' => __( 'Create another item', 'tainacan' ),
'label_recent_collections' => __( 'Recent Collections', 'tainacan' ),
'label_duplicating_item' => __( 'Duplicating item', 'tainacan' ),
'label_item_duplication_success' => __( 'The item was duplicated with success!', 'tainacan' ),
'label_item_duplication_failure' => __( 'Something wrong happened... Item duplication failed!', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -625,8 +628,9 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_send_email' => __('The exporter may take a while. Check this option to receive an e-mail when the process is done. You can also check the process status visiting the', 'tainacan'),
'info_tainacan_api' => __('Tainacan API on JSON format.', 'tainacan'),
'info_items_hidden_due_sorting' => __('When ordering by metadata value, items that have no value for the chosen metadata will not be listed. This list may have less elements than the total existing for current search criteria.', 'tainacan'),
'info_sorting_by_metadata_value_%s' => __('Showing only items that have value for metadata %s.'),
'info_sorting_by_metadata_value_%s_empty_list' => __('No item found, but only items with values for metadata %s are shown. Try sorting by other metatada.'),
'info_sorting_by_metadata_value_%s' => __('Showing only items that have value for metadata %s.', 'tainacan'),
'info_sorting_by_metadata_value_%s_empty_list' => __('No item found, but only items with values for metadata %s are shown. Try sorting by other metatada.', 'tainacan'),
'info_await_while_item_duplication' => __('Please wait while item is being duplicated...', 'tainacan'),
// Tainacan Metadatum Types
'tainacan-text' => __( 'Text', 'tainacan' ),

View File

@ -303,6 +303,9 @@ export default {
this.$store.dispatch('search/setAdminViewMode', adminViewMode);
this.updateURLQueries();
},
highlightsItem(itemId) {
this.$store.dispatch('search/highlightsItem', itemId);
},
updateURLQueries() {
this.$router.replace({ query: {} });
this.$router.replace({ query: this.$store.getters['search/getPostQuery'] });

View File

@ -134,14 +134,10 @@ export const updateItem = ({ commit }, item) => {
});
};
export const duplicateItem = ({ commit }, { item, attachment }) => {
delete item['id'];
if (item['terms'] == null)
item['terms'] = [];
export const duplicateItem = ({ commit }, { collectionId, itemId }) => {
return new Promise((resolve, reject) => {
axios.tainacan.post('/collection/' + item.collection_id + '/items/', item)
axios.tainacan.post('/collection/' + collectionId + '/items/' + itemId + '/duplicate')
.then( res => {
resolve( res.data );
}).catch( error => {

View File

@ -165,4 +165,8 @@ export const cleanTaxQueries = ({ commit }) => {
export const cleanFetchOnly = ({ commit }) => {
commit('cleanFetchOnly');
};
export const highlightsItem = ({ commit }, itemId ) => {
commit('setHighlightedItem', itemId);
};

View File

@ -83,3 +83,7 @@ export const getFilterTags = state => {
export const getFacets = state => {
return state.facets;
};
export const getHighlightedItem = state => {
return state.highlightedItem;
};

View File

@ -23,7 +23,8 @@ const state = {
totalPages: 0,
itemsPerPage: 12, // Not the same as postquery.perpage as API may have limited it's value
facets: {},
orderByName: ''
orderByName: '',
highlightedItem: null
};
export default {

View File

@ -187,4 +187,8 @@ export const cleanFetchOnly = (state) => {
export const setFacets = (state, facets) => {
state.facets = facets;
}
}
export const setHighlightedItem = (state, itemId) => {
state.highlightedItem = itemId;
}