Merge branch 'feature/200' into develop

This commit is contained in:
Mateus Machado Luna 2019-12-17 18:05:11 -03:00
commit e4ef756f90
25 changed files with 3225 additions and 1779 deletions

View File

@ -279,9 +279,6 @@ class Admin {
$settings['wp_post_types'] = $wp_post_types;
// add an alternative to enable select all items in all pages while we temporarly disable bulk edit for all (see #199)
$settings['enable_select_all_items_pages'] = defined('TAINACAN_ENABLE_SELECT_ALL_ITEMS_PAGES') ? TAINACAN_ENABLE_SELECT_ALL_ITEMS_PAGES : false;
return $settings;
}

View File

@ -80,20 +80,17 @@
type="text"
disabled />
<!-- Replace or Redefine in case of multiple -->
<!-- Replace -->
<template
v-if="bulkEditionProcedures[criterion] &&
bulkEditionProcedures[criterion].metadatumID &&
(bulkEditionProcedures[criterion].action == editionActionsForMultiple.replace ||
(bulkEditionProcedures[criterion].action == editionActionsForMultiple.redefine &&
getMetadataByID(bulkEditionProcedures[criterion].metadatumID).multiple == 'yes'))">
bulkEditionProcedures[criterion].metadatumID &&
bulkEditionProcedures[criterion].action == editionActionsForMultiple.replace">
<component
:forced-component-type="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:allow-new="false"
:allow-select-to-create="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_options.allow_new_terms === 'yes'"
:allow-select-to-create="false"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
@ -109,11 +106,18 @@
</small>
</div>
<b-input
<component
:forced-component-type="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:allow-new="false"
:allow-select-to-create="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
:is="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).metadata_type_object.component"
:metadatum="{metadatum: getMetadataByID(bulkEditionProcedures[criterion].metadatumID)}"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
type="text"
@input="addToBulkEditionProcedures($event, 'newValue', criterion)"
/>
</template>
@ -157,15 +161,6 @@
/>
</template>
<!-- DISABLED FIELD -->
<!--<template v-else>-->
<!--<input-->
<!--style="border: none !important; background-color: white !important;"-->
<!--class="tainacan-bulk-edition-field tainacan-bulk-edition-field-last"-->
<!--type="text"-->
<!--disabled >-->
<!--</template>-->
<div
:style="{
marginRight: !bulkEditionProcedures[criterion].isDone && !bulkEditionProcedures[criterion].isExecuting ? '-7.4px': 0
@ -188,7 +183,7 @@
</button>
<div
v-if="bulkEditionProcedures[criterion].isDone && bulkEditionProcedures[criterion].actionResult >= totalItems"
v-if="bulkEditionProcedures[criterion].isDone"
@mouseover="$set(bulkEditionProcedures[criterion], 'tooltipShow', !bulkEditionProcedures[criterion].tooltipShow)"
class="is-pulled-right">
<b-tooltip
@ -198,62 +193,18 @@
size="is-small"
position="is-left"
animated
multilined
:label="bulkEditionProcedures[criterion].actionResult.constructor.name !== 'Object' && bulkEditionProcedures[criterion].actionResult === 1 ? `${bulkEditionProcedures[criterion].actionResult} ${$i18n.get('info_item_affected')}` : `${bulkEditionProcedures[criterion].actionResult} ${$i18n.get('info_items_affected')}`">
:label="$i18n.get('info_bulk_edition_process_added')">
<span class="icon">
<i class="has-text-success tainacan-icon tainacan-icon-20px tainacan-icon-approvedcircle"/>
</span>
</b-tooltip>
</div>
<div
v-if="bulkEditionProcedures[criterion].isDone && bulkEditionProcedures[criterion].actionResult < totalItems"
@mouseover="$set(bulkEditionProcedures[criterion], 'tooltipShow', !bulkEditionProcedures[criterion].tooltipShow)"
class="is-pulled-right">
<b-tooltip
:active="bulkEditionProcedures[criterion].tooltipShow"
always
class="is-yellow2"
size="is-small"
position="is-left"
animated
multilined
:label="bulkEditionProcedures[criterion].actionResult.constructor.name !== 'Object' && bulkEditionProcedures[criterion].actionResult === 1 ? `${bulkEditionProcedures[criterion].actionResult} ${$i18n.get('info_item_affected')}` : `${bulkEditionProcedures[criterion].actionResult} ${$i18n.get('info_items_affected')}`">
<span class="icon">
<i class="has-text-yello2 tainacan-icon tainacan-icon-20px tainacan-icon-alertcircle"/>
</span>
</b-tooltip>
</div>
<button
:disabled="!groupID"
v-if="bulkEditionProcedures[criterion].isDoneWithError &&
!bulkEditionProcedures[criterion].isExecuting"
@click="executeBulkEditionProcedure(criterion)"
@mousedown="$set(bulkEditionProcedures[criterion], 'tooltipShow', !bulkEditionProcedures[criterion].tooltipShow)"
@mouseup="$set(bulkEditionProcedures[criterion], 'tooltipShow', !bulkEditionProcedures[criterion].tooltipShow)"
class="button is-white is-pulled-right">
<b-tooltip
:active="bulkEditionProcedures[criterion].tooltipShow"
always
class="is-red2"
size="is-small"
position="is-bottom"
animated
multilined
:label="bulkEditionProcedures[criterion].actionResult.constructor.name === 'Object' ? (bulkEditionProcedures[criterion].actionResult.error_message ? bulkEditionProcedures[criterion].actionResult.error_message : bulkEditionProcedures[criterion].actionResult.message) : ''">
<span class="icon">
<i class="has-text-danger tainacan-icon tainacan-icon-20px tainacan-icon-processerror"/>
</span>
</b-tooltip>
</button>
<button
:disabled="!groupID"
v-if="!bulkEditionProcedures[criterion].isDoneWithError &&
!bulkEditionProcedures[criterion].isDone &&
!bulkEditionProcedures[criterion].isExecuting &&
bulkEditionProcedures[criterion].metadatumID &&
v-if="!bulkEditionProcedures[criterion].isDone &&
!bulkEditionProcedures[criterion].isExecuting &&
bulkEditionProcedures[criterion].metadatumID &&
bulkEditionProcedures[criterion].action"
@click="executeBulkEditionProcedure(criterion)"
class="button is-white is-pulled-right">
@ -276,6 +227,15 @@
</div>
</div>
</div>
<a
:disabled="dones.every((item) => item === true) === false"
@click="addEditionCriterion()"
class="has-text-right is-block add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('new_action') }}
</a>
</div>
<!--<pre>{{ bulkEditionProcedures }}</pre>-->
@ -291,17 +251,11 @@
</button>
</p>
<p class="control">
<button
class="button is-turquoise5"
:disabled="dones.every((item) => item === true) === false"
@click="addEditionCriterion()">
{{ $i18n.get('new_action') }}
</button>
<button
:disabled="dones.every((item) => item === true) === false"
class="button is-success"
type="button"
@click="$eventBusSearch.loadItems(); $parent.close();">
@click="$root.$emit('openProcessesPopup'); $eventBusSearch.loadItems(); $parent.close();">
{{ $i18n.get('finish') }}
</button>
</p>
@ -320,7 +274,7 @@
totalItems: Array,
objectType: String,
selectedForBulk: Object,
collectionID: Number,
collectionID: Number
},
created(){
if (this.collectionID){
@ -385,9 +339,7 @@
bulkEditionProcedures: {
1: {
isDone: false,
isDoneWithError: false,
isExecuting: false,
actionResult: '',
totalItemsEditedWithSuccess: 0,
tooltipShow: true,
}
@ -400,8 +352,7 @@
},
methods: {
...mapGetters('bulkedition', [
'getGroupID',
'getActionResult'
'getGroupID'
]),
...mapActions('bulkedition', [
'createEditGroup',
@ -419,22 +370,10 @@
'getMetadata'
]),
finalizeProcedure(criterion){
this.$set(this.bulkEditionProcedures[criterion], 'actionResult', this.getActionResult());
let withError = false;
if(this.bulkEditionProcedures[criterion].actionResult.constructor.name === 'Object' &&
(this.bulkEditionProcedures[criterion].actionResult.data &&
this.bulkEditionProcedures[criterion].actionResult.data.status.toString().split('')[0] != 2) ||
this.bulkEditionProcedures[criterion].actionResult.error_message) {
withError = true;
} else {
this.$set(this.bulkEditionProcedures[criterion], 'totalItemsEditedWithSuccess', this.actionResult);
}
this.$set(this.bulkEditionProcedures[criterion], 'isDone', !withError);
this.$set(this.bulkEditionProcedures[criterion], 'isDoneWithError', withError);
this.$set(this.bulkEditionProcedures[criterion], 'isDone', true);
let index = this.editionCriteria.indexOf(criterion);
@ -523,9 +462,7 @@
this.bulkEditionProcedures = Object.assign({}, this.bulkEditionProcedures, {
[`${aleatoryKey}`]: {
isDone: false,
isDoneWithError: false,
isExecuting: false,
actionResult: '',
totalItemsEditedWithSuccess: 0,
tooltipShow: true,
}
@ -603,7 +540,7 @@
}
.this-tainacan-modal-content .form-submit {
padding: 160px 0 0.4em 0 !important;
padding: 42px 0 0.4em 0 !important;
}
.no-overflow-modal-card-body {
@ -698,6 +635,7 @@
border: none !important;
background-color: white !important;
min-height: auto !important;
line-height: 1.5rem;
}
.select {

View File

@ -153,7 +153,7 @@
style="margin-left: auto;"
class="control">
<button
:disabled="!(uploadedItems.length > 0 && uploadedItems.length == amountFinished) || isCreatingBulkEditGroup"
:disabled="!(uploadedItems.length > 0 && uploadedItems.length == amountFinished)"
class="button is-secondary"
:class="{'is-loading': isCreatingSequenceEditGroup }"
@click.prevent="sequenceEditGroup()"
@ -161,10 +161,9 @@
</div>
<div class="control">
<button
:disabled="!(uploadedItems.length > 0 && uploadedItems.length == amountFinished) || isCreatingSequenceEditGroup"
:disabled="!(uploadedItems.length > 0 && uploadedItems.length == amountFinished)"
class="button is-secondary"
:class="{'is-loading': isCreatingBulkEditGroup }"
@click.prevent="createBulkEditGroup()"
@click.prevent="openBulkEditionModal()"
type="submit">{{ $i18n.get('label_bulk_edit_items') }}</button>
</div>
</div>
@ -188,6 +187,7 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
import BulkEditionModal from '../bulk-edition/bulk-edition-modal.vue';
export default {
name: 'ItemBulkEditionForm',
@ -195,7 +195,6 @@ export default {
return {
collectionId: '',
isLoading: false,
isCreatingBulkEditGroup: false,
isCreatingSequenceEditGroup: false,
submitedFileList: [],
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
@ -227,8 +226,8 @@ export default {
]),
...mapActions('bulkedition', [
'createEditGroup',
'setStatusInBulk',
'setBulkAddItems'
'createSequenceEditGroup',
'setStatusInBulk'
]),
uploadFiles() {
@ -237,7 +236,7 @@ export default {
// Creates draft Item
let data = {
collection_id: this.collectionId,
status: 'auto-draft',
status: 'draft',
title: file.name
};
this.sendItem(data)
@ -273,12 +272,11 @@ export default {
});
})
.catch((error) => {
let index = this.uploadedItems.findIndex(existingItem => existingItem.id === item.id);
if ( index >= 0)
this.uploadedItems.splice(index, 1);
item.errorMessage = error.data.message;
item.errorMessage = error.data && error.data.message ? error.data.message : this.$i18n.get('info_error_upload');
this.$buefy.toast.open({
message: item.errorMessage + ": " + file.name,
type: 'is-danger',
@ -299,42 +297,32 @@ export default {
sequenceEditGroup() {
let onlyItemIds = this.uploadedItems.map(item => item.id);
this.isCreatingSequenceEditGroup = true;
this.createEditGroup({
this.createSequenceEditGroup({
object: onlyItemIds,
collectionID: this.collectionId
}).then((group) => {
let sequenceId = group.id;
this.setStatusInBulk({
groupID: sequenceId,
collectionID: this.collectionId,
bodyParams: { value: 'draft' }
}).then(() => {
this.isCreatingSequenceEditGroup = true;
this.$router.push(this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, sequenceId, 1));
});
this.isCreatingSequenceEditGroup = false;
this.$router.push(this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, sequenceId, 1));
});
},
createBulkEditGroup() {
// Sends to store, so we can retrieve in next page.
this.setBulkAddItems(this.uploadedItems);
openBulkEditionModal() {
let onlyItemIds = this.uploadedItems.map(item => item.id);
this.isCreatingBulkEditGroup = true;
this.createEditGroup({
object: onlyItemIds,
collectionID: this.collectionId
}).then((group) => {
let groupId = group.id;
this.setStatusInBulk({
groupID: groupId,
collectionID: this.collectionId,
bodyParams: { value: 'draft' }
}).then(() => {
this.isCreatingBulkEditGroup = false;
this.$router.push(this.$routerHelper.getItemMetadataBulkAddPath(this.collectionId, groupId));
});
});
this.$buefy.modal.open({
parent: this,
component: BulkEditionModal,
props: {
modalTitle: this.$i18n.get('info_editing_items_in_bulk'),
totalItems: onlyItemIds.length,
selectedForBulk: onlyItemIds,
objectType: this.$i18n.get('items'),
collectionID: this.collectionId
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
},
deleteOneItem(itemId, index) {
this.$buefy.modal.open({
@ -363,7 +351,6 @@ export default {
this.collectionId = this.$route.params.collectionId;
this.cleanFiles();
this.setBulkAddItems([]);
// Updates Collection BreadCrumb
this.$root.$emit('onCollectionBreadCrumbUpdate', [

View File

@ -7,27 +7,27 @@
<div class="tainacan-page-title">
<h1 v-if="isCreatingNewItem">
<span
<span
v-if="(item != null && item != undefined && item.status != undefined && !isLoading)"
class="status-tag">{{ $i18n.get('status_' + item.status) }}</span>
{{ $i18n.get('title_create_item_collection') + ' ' }}
<span style="font-weight: 600;">{{ collection && collection.name ? collection.name : '' }}</span>
</h1>
<h1 v-else>
<span
<span
v-if="(item != null && item != undefined && item.status != undefined && !isLoading)"
class="status-tag">{{ $i18n.get('status_' + item.status) }}</span>
{{ $i18n.get('title_edit_item') + ' ' }}
<span style="font-weight: 600;">{{ (item != null && item != undefined) ? item.title : '' }}</span>
</h1>
<a
<a
@click="$router.go(-1)"
class="back-link has-text-secondary">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<transition
<transition
mode="out-in"
:name="(isOnSequenceEdit && sequenceRightDirection != undefined) ? (sequenceRightDirection ? 'page-right' : 'page-left') : ''">
<form
@ -38,11 +38,11 @@
<div class="column is-5">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['begin-left'] != undefined">
<form
formHooks['item']['begin-left'] != undefined">
<form
id="form-item-begin-left"
class="form-hook-region"
v-html="formHooks['item']['begin-left'].join('')"/>
@ -71,7 +71,7 @@
id="button-edit-document"
:aria-label="$i18n.get('label_button_edit_document')"
@click.prevent="setFileDocument($event)">
<span
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
@ -87,7 +87,7 @@
id="button-delete-document"
:aria-label="$i18n.get('label_button_delete_document')"
@click.prevent="removeDocument()">
<span
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
@ -107,7 +107,7 @@
:aria-label="$i18n.get('label_button_edit_document')"
id="button-edit-document"
@click.prevent="setTextDocument()">
<span
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
@ -123,7 +123,7 @@
:aria-label="$i18n.get('label_button_delete_document')"
id="button-delete-document"
@click.prevent="removeDocument()">
<span
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
@ -144,7 +144,7 @@
:aria-label="$i18n.get('label_button_edit_document')"
id="button-edit-document"
@click.prevent="setURLDocument()">
<span
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
@ -175,7 +175,7 @@
</div>
<ul v-else>
<li>
<button
<button
type="button"
@click.prevent="setFileDocument($event)">
<span class="icon">
@ -185,7 +185,7 @@
<p>{{ $i18n.get('label_file') }}</p>
</li>
<li>
<button
<button
type="button"
@click.prevent="setTextDocument()">
<span class="icon">
@ -195,7 +195,7 @@
<p>{{ $i18n.get('label_text') }}</p>
</li>
<li>
<button
<button
type="button"
@click.prevent="setURLDocument()">
<span class="icon">
@ -252,7 +252,7 @@
:active.sync="isURLModalActive"
:width="640"
scroll="keep"
trap-focus
trap-focus
role="dialog"
tabindex="-1"
aria-modal
@ -291,7 +291,7 @@
:title="$i18n.getHelperTitle('items', '_thumbnail_id')"
:message="$i18n.getHelperMessage('items', '_thumbnail_id')"/>
</div>
</div>
<div class="section-box section-thumbnail">
<div class="thumbnail-field">
<file-item
@ -299,12 +299,12 @@
:show-name="false"
:modal-on-click="false"
:size="178"
:file="{
media_type: 'image',
:file="{
media_type: 'image',
guid: { rendered: item.thumbnail['tainacan-medium'] ? item.thumbnail['tainacan-medium'][0] : item.thumbnail.medium[0] },
title: { rendered: $i18n.get('label_thumbnail')},
description: { rendered: `<img alt='` + $i18n.get('label_thumbnail') + `' src='` + item.thumbnail.full[0] + `'/>` }}"/>
<figure
<figure
v-if="item.thumbnail == undefined || ((item.thumbnail.medium == undefined || item.thumbnail.medium == false) && (item.thumbnail['tainacan-medium'] == undefined || item.thumbnail['tainacan-medium'] == false))"
class="image">
<span class="image-placeholder">{{ $i18n.get('label_empty_thumbnail') }}</span>
@ -318,7 +318,7 @@
id="button-edit-thumbnail"
:aria-label="$i18n.get('label_button_edit_thumb')"
@click.prevent="thumbnailMediaFrame.openFrame($event)">
<span
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
@ -334,7 +334,7 @@
class="button is-rounded is-secondary"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteThumbnail()">
<span
<span
v-tooltip="{
content: $i18n.get('delete'),
autoHide: true,
@ -349,25 +349,25 @@
</div>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['end-left'] != undefined">
<form
formHooks['item']['end-left'] != undefined">
<form
id="form-item-end-left"
class="form-hook-region"
v-html="formHooks['item']['end-left'].join('')"/>
</template>
</div>
</div>
<div class="column is-7">
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['begin-right'] != undefined">
<form
formHooks['item']['begin-right'] != undefined">
<form
id="form-item-begin-right"
class="form-hook-region"
v-html="formHooks['item']['begin-right'].join('')"/>
@ -429,22 +429,22 @@
</div>
</div>
<!-- Comment Status ------------------------ -->
<div
<!-- Comment Status ------------------------ -->
<div
class="column is-narrow"
v-if="collection && collection.allow_comments && collection.allow_comments == 'open'">
<div class="section-label">
<label>{{ $i18n.get('label_comments') }}</label>
<help-button
:title="$i18n.getHelperTitle('items', 'comment_status')"
<help-button
:title="$i18n.getHelperTitle('items', 'comment_status')"
:message="$i18n.getHelperMessage('items', 'comment_status')"/>
</div>
<div class="section-status">
<div class="field has-addons">
<b-switch
id="tainacan-checkbox-comment-status"
id="tainacan-checkbox-comment-status"
size="is-small"
true-value="open"
true-value="open"
false-value="closed"
v-model="form.comment_status">
{{ $i18n.get('label_allow_comments') }}
@ -454,7 +454,7 @@
</div>
</div>
<b-tabs v-model="activeTab">
<!-- Metadata from Collection-------------------------------- -->
@ -465,13 +465,13 @@
</span>
<span>{{ $i18n.get('metadata') }}</span>
</template>
<a
class="collapse-all"
@click="toggleCollapseAll()">
{{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }}
<span class="icon">
<i
<i
:class="{ 'tainacan-icon-arrowdown' : collapseAll, 'tainacan-icon-arrowright' : !collapseAll }"
class="tainacan-icon tainacan-icon-20px"/>
</span>
@ -484,11 +484,11 @@
@changeCollapse="onChangeCollapse($event, index)"/>
<!-- Hook for extra Form options -->
<template
v-if="formHooks != undefined &&
<template
v-if="formHooks != undefined &&
formHooks['item'] != undefined &&
formHooks['item']['end-right'] != undefined">
<form
formHooks['item']['end-right'] != undefined">
<form
id="form-item-end-right"
class="form-hook-region"
v-html="formHooks['item']['end-right'].join('')"/>
@ -510,7 +510,7 @@
</span>
</span>
</template>
<div v-if="item != undefined && item.id != undefined">
<br>
<button
@ -527,14 +527,14 @@
:is-editable="true"
:is-loading.sync="isLoadingAttachments"
@isLoadingAttachments="(isLoading) => isLoadingAttachments = isLoading"
@onDeleteAttachment="deleteAttachment($event)"/>
@onDeleteAttachment="deleteAttachment($event)"/>
</div>
</b-tab-item>
</b-tabs>
</div>
</div>
</form>
<!-- In case user enters this page whithout having permission -->
@ -554,26 +554,26 @@
</transition>
<footer class="footer">
<!-- Sequence Progress -->
<div
<div
v-if="isOnSequenceEdit"
class="sequence-progress-background"/>
<div
<div
v-if="isOnSequenceEdit && itemPosition != undefined && group != null && group.items_count != undefined"
:style="{ width: (itemPosition/group.items_count)*100 + '%' }"
class="sequence-progress"/>
<!-- Last Updated Info -->
<!-- Last Updated Info -->
<div class="update-info-section">
<p
<p
class="has-text-gray5"
v-if="isOnSequenceEdit">
{{ $i18n.get('label_sequence_editing_item') + " " + itemPosition + " " + $i18n.get('info_of') + " " + ((group != null && group.items_count != undefined) ? group.items_count : '') + "." }}
</p>
</p>
<p v-if="!isUpdatingValues">
{{ ($i18n.get('info_updated_at') + ' ' + lastUpdated) }}
<span class="help is-danger">{{ formErrorMessage }}</span>
</p>
<p
</p>
<p
class="update-warning"
v-if="isUpdatingValues">
<span class="icon">
@ -581,9 +581,9 @@
</span>
{{ $i18n.get('info_updating_metadata_values') }}
<span class="help is-danger">{{ formErrorMessage }}</span>
</p>
</div>
<div
</p>
</div>
<div
class="form-submission-footer"
v-if="form.status == 'trash'">
<button
@ -591,7 +591,7 @@
@click="onDeletePermanently()"
type="button"
class="button is-outlined">{{ $i18n.get('label_delete_permanently') }}</button>
<button
<button
@click="onSubmit('draft')"
type="button"
class="button is-secondary">{{ $i18n.get('label_save_as_draft') }}</button>
@ -601,14 +601,14 @@
type="button"
class="button is-success">{{ $i18n.get('label_publish') }}</button>
</div>
<div
<div
class="form-submission-footer"
v-if="form.status == 'auto-draft' || form.status == 'draft' || form.status == undefined">
<button
<button
v-if="isOnSequenceEdit && itemPosition > 1"
@click="onPrevInSequence()"
type="button"
class="button sequence-button">
class="button sequence-button">
<span class="icon is-large">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-previous"/>
</span>
@ -619,17 +619,17 @@
@click="onSubmit('trash')"
type="button"
class="button is-outlined">{{ $i18n.get('label_send_to_trash') }}</button>
<button
<button
v-if="form.status == 'auto-draft'"
@click="onDiscard()"
type="button"
class="button is-outlined">{{ $i18n.get('label_discard') }}</button>
<button
<button
v-if="!isOnSequenceEdit || (group != null && group.items_count != undefined && group.items_count == itemPosition)"
@click="onSubmit('draft')"
type="button"
class="button is-secondary">{{ form.status == 'draft' ? $i18n.get('label_update') : $i18n.get('label_save_as_draft') }}</button>
<button
<button
v-else
@click="onSubmit('draft'); onNextInSequence();"
type="button"
@ -679,10 +679,10 @@
<span>{{ $i18n.get('finish') }}</span>
</button>
</div>
<div
<div
class="form-submission-footer"
v-if="form.status == 'publish' || form.status == 'private'">
<button
<button
v-if="isOnSequenceEdit && itemPosition > 1"
@click="onPrevInSequence()"
type="button"
@ -697,12 +697,12 @@
@click="onSubmit('trash')"
type="button"
class="button is-outlined">{{ $i18n.get('label_send_to_trash') }}</button>
<button
<button
v-if="!isOnSequenceEdit || (group != null && group.items_count != undefined && group.items_count == itemPosition)"
@click="onSubmit('draft')"
type="button"
class="button is-secondary">{{ isOnSequenceEdit ? $i18n.get('label_save_as_draft') : $i18n.get('label_return_to_draft') }}</button>
<button
<button
v-else
@click="onSubmit('draft', 'next')"
type="button"
@ -838,8 +838,8 @@ export default {
watch: {
'$route.params.itemPosition'(newItemPosition, oldItemPosition) {
if (oldItemPosition == undefined || oldItemPosition == newItemPosition)
this.sequenceRightDirection = undefined;
this.sequenceRightDirection = undefined;
this.itemPosition = Number(newItemPosition);
// Saves current itemPosition to user prefs
@ -849,7 +849,7 @@ export default {
this.cleanMetadata();
eventBus.clearAllErrors();
this.formErrorMessage = '';
this.isLoading = true;
// Obtains current Item ID from Sequence
@ -861,9 +861,9 @@ export default {
.catch(() => {
this.isLoading = false;
});
// Obtains current Sequence Group Info
this.fetchGroup({ collectionId: this.collectionId, groupId: this.sequenceId });
this.fetchSequenceGroup({ collectionId: this.collectionId, groupId: this.sequenceId });
}
},
methods: {
@ -896,7 +896,8 @@ export default {
]),
...mapActions('bulkedition', [
'fetchItemIdInSequence',
'fetchGroup'
'fetchGroup',
'fetchSequenceGroup'
]),
...mapGetters('bulkedition', [
'getItemIdInSequence',
@ -905,7 +906,7 @@ export default {
onSubmit(status, sequenceDirection) {
// Puts loading on Item edition
this.isLoading = true;
this.sequenceRightDirection = undefined;
this.sequenceRightDirection = undefined;
let previousStatus = this.form.status;
this.form.status = status;
@ -920,12 +921,12 @@ export default {
promise = this.deleteItem({ itemId: this.itemId, isPermanently: false });
else
promise = this.updateItem(data);
promise.then(updatedItem => {
this.item = updatedItem;
// Fills hook forms with it's real values
// Fills hook forms with it's real values
this.updateExtraFormData(this.item);
// Fill this.form data with current data.
@ -936,7 +937,7 @@ export default {
this.isLoading = false;
if (!this.isOnSequenceEdit) {
if (!this.isOnSequenceEdit) {
if (this.form.status != 'trash') {
if (previousStatus == 'auto-draft')
this.$router.push({ path: this.$routerHelper.getItemPath(this.form.collectionId, this.itemId), query: { recent: true } });
@ -1102,10 +1103,10 @@ export default {
this.urlLink = '';
this.form.document_type = 'empty';
this.form.document = '';
this.updateItemDocument({
item_id: this.itemId,
document: this.form.document,
document_type: this.form.document_type
this.updateItemDocument({
item_id: this.itemId,
document: this.form.document,
document_type: this.form.document_type
})
.then(() => {
this.isLoadingAttachments = true;
@ -1141,9 +1142,9 @@ export default {
message: this.$i18n.get('info_warning_attachment_delete'),
onConfirm: () => {
this.deletePermanentlyAttachment(attachment.id)
.then(() => {
.then(() => {
this.isLoadingAttachments = true;
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document })
.then(() => this.isLoadingAttachments = false)
.catch(() => this.isLoadingAttachments = false);
@ -1153,7 +1154,7 @@ export default {
});
}
},
trapFocus: true
trapFocus: true
});
},
@ -1257,10 +1258,10 @@ export default {
// Initializes Media Frames now that itemId exists
this.initializeMediaFrames();
this.fetchItem({
itemId: this.itemId,
contextEdit: true,
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document,comment_status,document_as_html'
this.fetchItem({
itemId: this.itemId,
contextEdit: true,
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document,comment_status,document_as_html'
})
.then(res => {
this.item = res;
@ -1274,7 +1275,7 @@ export default {
this.$root.$emit('onCollectionBreadCrumbUpdate', [
{ path: this.$routerHelper.getCollectionPath(this.collectionId), label: this.$i18n.get('items') },
{ path: '', label: this.$i18n.get('sequence') },
{ path: '', label: this.item.title },
{ path: '', label: this.item.title },
{ path: '', label: this.$i18n.get('edit') }
]);
} else {
@ -1285,18 +1286,18 @@ export default {
]);
}
// Fills hook forms with it's real values
// Fills hook forms with it's real values
this.$nextTick()
.then(() => {
this.updateExtraFormData(this.item);
});
// Fill this.form data with current data.
this.form.status = this.item.status;
this.form.document = this.item.document;
this.form.document_type = this.item.document_type;
this.form.comment_status = this.item.comment_status;
if (this.form.document_type != undefined && this.form.document_type == 'url')
this.urlLink = this.form.document;
if (this.form.document_type != undefined && this.form.document_type == 'text')
@ -1313,14 +1314,14 @@ export default {
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document });
},
onNextInSequence() {
this.sequenceRightDirection = true;
this.$router.push({
path: this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, this.sequenceId, this.itemPosition + 1),
this.sequenceRightDirection = true;
this.$router.push({
path: this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, this.sequenceId, this.itemPosition + 1),
query: { collapses: this.metadataCollapses }
});
},
onPrevInSequence() {
this.sequenceRightDirection = false;
this.sequenceRightDirection = false;
this.$router.push({
path: this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, this.sequenceId, this.itemPosition - 1),
query: { collapses: this.metadataCollapses }
@ -1353,7 +1354,7 @@ export default {
this.isLoading = true;
this.sequenceId = this.$route.params.sequenceId;
let savedItemPosition = (this.$userPrefs.get('sequence_' + this.sequenceId + '_position') != undefined ? Number(this.$userPrefs.get('sequence_' + this.sequenceId + '_position')) : 1);
let savedItemPosition = (this.$userPrefs.get('sequence_' + this.sequenceId + '_position') != undefined ? Number(this.$userPrefs.get('sequence_' + this.sequenceId + '_position')) : 1);
this.itemPosition = this.$route.params.itemPosition != undefined ? Number(this.$route.params.itemPosition) : savedItemPosition;
this.isOnSequenceEdit = true;
@ -1370,9 +1371,9 @@ export default {
.catch(() => {
this.isLoading = false;
});
// Obtains current Sequence Group Info
this.fetchGroup({ collectionId: this.collectionId, groupId: this.sequenceId });
this.fetchSequenceGroup({ collectionId: this.collectionId, groupId: this.sequenceId });
}
// Sets feedback variables
@ -1382,7 +1383,7 @@ export default {
eventBus.$on('hasErrorsOnForm', (hasErrors) => {
if (hasErrors)
this.formErrorMessage = this.$i18n.get('info_errors_in_form');
else
else
this.formErrorMessage = '';
});
this.cleanLastUpdated();
@ -1405,10 +1406,10 @@ export default {
},
},
trapFocus: true
});
});
} else {
next()
}
}
}
}
</script>
@ -1465,7 +1466,7 @@ export default {
margin-top: 5px;
}
hr{
margin: 3px 0px 4px 0px;
margin: 3px 0px 4px 0px;
height: 1px;
background-color: $secondary;
width: 100%;
@ -1524,8 +1525,8 @@ export default {
.collapse-all {
font-size: 12px;
.icon {
vertical-align: bottom;
.icon {
vertical-align: bottom;
}
}
@ -1558,9 +1559,9 @@ export default {
}
}
.section-status {
padding-bottom: 16px;
font-size: 0.75rem;
padding-bottom: 16px;
font-size: 0.75rem;
.field {
padding: 10px 0 14px 0px !important;
@ -1569,13 +1570,13 @@ export default {
margin-left: 0;
}
.icon {
font-size: 18px !important;
font-size: 18px !important;
color: $gray3;
}
}
}
.document-field {
.document-field {
.document-buttons-row {
text-align: right;
top: -21px;
@ -1583,9 +1584,9 @@ export default {
}
}
#button-edit-thumbnail,
#button-edit-thumbnail,
#button-edit-document,
#button-delete-thumbnail,
#button-delete-thumbnail,
#button-delete-document {
border-radius: 100px !important;
@ -1596,7 +1597,7 @@ export default {
padding: 0 !important;
z-index: 99;
margin-left: 12px !important;
.icon {
display: inherit;
padding: 0;
@ -1628,7 +1629,7 @@ export default {
top: 70px;
max-width: 90px;
}
.thumbnail-buttons-row {
position: relative;
left: 90px;
@ -1648,7 +1649,7 @@ export default {
justify-content: flex-end;
align-items: center;
.form-submission-footer {
.form-submission-footer {
.button {
margin-left: 16px;
margin-right: 6px;

View File

@ -1,690 +0,0 @@
<template>
<div>
<b-loading
:is-full-page="false"
:active.sync="showLoading"
:can-cancel="false"/>
<div class="tainacan-page-title">
<h1><span class="status-tag">{{ $i18n.get('status_' + status) }}</span>{{ $i18n.get('label_bulk_edit_items') }}</h1>
<a
@click="$router.go(-1)"
class="back-link has-text-secondary">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<form
v-if="collection && collection.current_user_can_bulk_edit"
class="tainacan-form"
label-width="120px">
<div class="columns">
<div class="column is-half document-list">
<div class="section-label">
<label>{{ $i18n.get('label_added_items') }}
<span
v-if="!isLoadingGroupInfo && bulkEditGroup.items_count != undefined"
class="has-text-gray has-text-weight-normal">{{ ' (' + bulkEditGroup.items_count + ')' }}</span>
</label>
</div>
<br>
<p v-if="items.length <= 0 && !isLoadingGroupInfo && bulkEditGroup.items_count == 1">
{{ $i18n.get('info_there_is_one_item_being_edited') }}
</p>
<p v-if="items.length <= 0 && !isLoadingGroupInfo && bulkEditGroup.items_count > 1">
{{ $i18n.getWithVariables('info_there_are_%s_items_being_edited', [bulkEditGroup.items_count]) }}
</p>
<p v-if="items.length <= 0 && !isLoadingGroupInfo">
{{ $i18n.get('info_no_preview_found') }}
</p>
<transition-group name="item-appear">
<div
class="document-item"
v-for="(item) of items"
:key="item.id">
<img
v-if="item.document!= undefined && item.document != '' && item.document_type != 'empty'"
class="document-thumb"
:alt="$i18n.get('label_thumbnail') + ': ' + item.title"
:src="item.thumbnail['tainacan-small'] ? item.thumbnail['tainacan-small'][0] : (item.thumbnail.thumbnail ? item.thumbnail.thumbnail[0] : thumbPlaceholderPath)" >
<span
class="document-name"
v-html="item.title" />
<span
v-if="item.errorMessage != undefined"
class="help is-danger">
{{ item.errorMessage }}
</span>
</div>
</transition-group>
</div>
<div class="column is-half">
<!-- Visibility (status public or private) -------------------------------- -->
<div class="section-label">
<label>{{ $i18n.get('label_status') }}</label>
<span class="required-metadatum-asterisk">*</span>
<help-button
:title="$i18n.get('label_status')"
:message="$i18n.get('info_visibility_helper')"/>
</div>
<div class="section-status">
<div class="field has-addons">
<b-radio
v-for="(statusOption, index) of $statusHelper.getStatuses().filter(option => { return option.value != 'trash' })"
:key="index"
v-model="status"
@input="changeStatus($event)"
:value="statusOption.slug"
:native-value="statusOption.slug">
<span class="icon">
<i
class="tainacan-icon"
:class="$statusHelper.getIcon(statusOption.slug)"/>
</span> {{ statusOption.name }}
</b-radio>
</div>
</div>
<!-- Metadata from Collection-------------------------------- -->
<span class="section-label">
<label>{{ $i18n.get('metadata') }}</label>
</span>
<br>
<a
class="collapse-all"
@click="toggleCollapseAll()">
{{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }}
<b-icon :icon=" collapseAll ? 'menu-down' : 'menu-right'" />
</a>
<template
v-if="!showLoading"
v-for="(metadatum, index) of metadata">
<b-field
:key="index"
:addons="false"
:message="getErrorMessage(formErrors[metadatum.id])"
:type="getErrorMessage(formErrors[metadatum.id]) != '' ? 'is-danger' : ''">
<span
class="collapse-handle"
@click="changeCollapse(!metadatumCollapses[index], index)">
<b-icon
type="is-secondary"
:icon="metadatumCollapses[index] ? 'menu-down' : 'menu-right'" />
<label class="label">{{ metadatum.name }}</label>
<span
v-if="metadatum.required == 'yes'"
class="required-metadatum-asterisk">*</span>
<span class="metadata-type">({{ metadatum.metadata_type_object.metadata }})</span>
<help-button
:title="metadatum.name"
:message="metadatum.description"/>
</span>
<transition name="filter-item">
<div v-show="metadatumCollapses[index]">
<component
:forced-component-type="false"
:allow-new="false"
:allow-select-to-create="metadatum.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:id="metadatum.metadata_type_object.component + '-' + metadatum.slug"
:is="metadatum.metadata_type_object.component"
:metadatum="{ metadatum: metadatum }"
:value="itemMetadata[index].value"
@input="clearErrorMessage(metadatum.id); bulkEdit($event, metadatum)"/>
</div>
</transition>
</b-field>
</template>
</div>
</div>
<footer class="footer">
<!-- Last Updated Info -->
<div class="update-info-section">
<p v-if="!isExecutingBulkEdit && lastUpdated != ''">
{{ ($i18n.get('info_updated_at') + ' ' + lastUpdated) }}
<span class="help is-danger">{{ formErrorMessage }}</span>
</p>
<p v-if="!isExecutingBulkEdit && lastUpdated == ''">
<span class="help is-danger">{{ formErrorMessage }}</span>
</p>
<p
class="update-warning"
v-if="isExecutingBulkEdit">
<b-icon icon="autorenew" />{{ $i18n.get('info_updating_metadata_values') }}
<span class="help is-danger">{{ formErrorMessage }}</span>
</p>
</div>
<div class="form-submission-footer">
<button
v-if="status != 'trash'"
@click="onSubmit('trash')"
type="button"
:class="{ 'is-loading': isTrashingItems }"
class="button is-outlined">{{ $i18n.get('label_send_to_trash') }}</button>
<button
v-if="status == 'trash'"
class="button is-secondary"
:class="{'is-loading': isCreatingSequenceEditGroup || isTrashingItems }"
@click.prevent="status = previousStatus; changeStatus(previousStatus)"
type="submit">{{ $i18n.get('label_recover_from_trash') }}</button>
<button
:disabled="status == 'trash'"
class="button is-secondary"
:class="{'is-loading': isCreatingSequenceEditGroup }"
@click.prevent="sequenceEditGroup()"
type="submit">{{ $i18n.get('label_sequence_edit_items') }}</button>
<button
:disabled="formErrorMessage != undefined && formErrorMessage != ''"
@click="onSubmit(status)"
type="button"
:class="{ 'is-loading': isPublishingItems }"
class="button is-success">{{ $i18n.get('finish') }}</button>
</div>
</footer>
</form>
<template v-if="collection && !collection.current_user_can_bulk_edit">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>
<span class="icon">
<i class="tainacan-icon tainacan-icon-30px tainacan-icon-collection"/>
</span>
</p>
<p>{{ $i18n.get('info_can_not_bulk_edit_items_collection') }}</p>
</div>
</section>
</template>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'ItemMetadataBulkEditionForm',
data(){
return {
collectionId: '',
isLoadingItems: false,
isLoadingMetadata: false,
isLoadingItemMetadata: false,
isLoadingGroupInfo: false,
isExecutingBulkEdit: false,
isCreatingSequenceEditGroup: false,
isUpdatingItems: false,
isTrashingItems: false,
isPublishingItems: false,
collapseAll: true,
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
metadatumCollapses: [],
itemMetadata: [],
formErrors: {},
status: 'draft',
previousStatus: 'draft',
groupID: null,
formErrorMessage: '',
copyItemId: null
}
},
computed: {
metadata() {
return this.getMetadata();
},
lastUpdated() {
return this.getLastUpdated();
},
items() {
return this.getBulkAddItems();
},
bulkEditGroup() {
return this.getGroup();
},
showLoading() {
return this.isLoadingMetadata || this.isLoadingItemMetadata;
},
collection() {
return this.getCollection()
}
},
methods: {
...mapActions('item', {
'updateItem': 'updateItem',
'fetchItemMetadata':'fetchMetadata'
}),
...mapActions('metadata', [
'fetchMetadata',
]),
...mapGetters('metadata', [
'getMetadata',
]),
...mapGetters('collection', [
'getCollection',
]),
...mapActions('bulkedition', [
'setValueInBulk',
'addValueInBulk',
'replaceValueInBulk',
'redefineValueInBulk',
'setStatusInBulk',
'removeValueInBulk',
'createEditGroup',
'deleteItemsInBulk',
'trashItemsInBulk',
'fetchItemIdInSequence',
'fetchGroup'
]),
...mapGetters('bulkedition', [
'getItemIdInSequence',
'getGroup',
'getLastUpdated',
'getBulkAddItems'
]),
toggleCollapseAll() {
this.collapseAll = !this.collapseAll;
for (let i = 0; i < this.metadatumCollapses.length; i++)
this.metadatumCollapses[i] = this.collapseAll;
},
changeCollapse(event, index) {
this.metadatumCollapses.splice(index, 1, event);
},
bulkEdit: _.debounce(function(newValue, metadatum) {
this.isExecutingBulkEdit = true;
this.setValueInBulk({
collectionID: this.collectionId,
groupID: this.groupID,
bodyParams: {
metadatum_id: metadatum.id,
value: newValue,
}
}).then(() => {
this.isExecutingBulkEdit = false;
}).catch(() => this.isExecutingBulkEdit = false);
}, 1000),
onSubmit(status) {
this.isExecutingBulkEdit = true;
this.previousStatus = status;
if (status != 'trash') {
this.status = status;
this.isPublishingItems = false;
this.isExecutingBulkEdit = false;
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_leaving_bulk_edition' ),
onConfirm: () => {
this.$router.push(this.$routerHelper.getCollectionItemsPath(this.collectionId));
}
},
trapFocus: true
});
} else if (status == 'trash') {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_selected_items_trash'),
onConfirm: () => {
this.isTrashingItems = true;
this.trashItemsInBulk({
groupID: this.groupID,
collectionID: this.collectionId
}).then(() => {
this.status = status;
this.isTrashingItems = false;
this.isExecutingBulkEdit = false;
this.$router.push(this.$routerHelper.getCollectionItemsPath(this.collectionId));
}).catch(() => {
this.isExecutingBulkEdit = false;
this.isTrashingItems = false;
});
}
},
trapFocus: true
});
}
},
sequenceEditGroup() {
this.isCreatingSequenceEditGroup = true;
this.$router.push(this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, this.groupID, 1));
},
changeStatus(status) {
this.isPublishingItems = true;
if (!this.copyItemId){
// Gets an item from the bulk group
this.fetchItemIdInSequence({ collectionId: this.collectionId, sequenceId: this.groupID, itemPosition: 1 })
.then((itemId) => {
this.copyItemId = itemId;
this.updateItemStatus(status);
})
.catch(() => {
this.isPublishingItems = false;
this.isExecutingBulkEdit = false;
});
} else {
this.updateItemStatus(status);
}
},
updateItemStatus(status) {
// Test if this item can be set to this status
this.updateItem({ id: this.copyItemId, status: status })
.then(() => {
// The status can be applied to everyone.
this.setStatusInBulk({
groupID: this.groupID,
collectionID: this.collectionId,
bodyParams: { value: status }
}).then(() => {
this.status = status;
this.isPublishingItems = false;
this.isExecutingBulkEdit = false;
}).catch(() => {
this.isPublishingItems = false;
this.isExecutingBulkEdit = false;
});
})
.catch((errors) => {
// The status can not be applied.
this.isPublishingItems = false;
this.isExecutingBulkEdit = false;
for (let error of errors.errors) {
for (let metadatum of Object.keys(error)){
this.formErrors[metadatum] = error[metadatum];
}
}
this.formErrorMessage = errors.error_message;
});
},
clearErrorMessage(metadatumId) {
this.formErrors[metadatumId] = false;
let amountClean = 0;
for (let formError in this.formErrors) {
if (formError == false || formError == undefined)
amountClean++;
}
if (amountClean == 0)
this.formErrorMessage = '';
},
getErrorMessage(errors) {
let msg = '';
if ( errors != undefined && errors != false) {
for (let error of errors) {
for (let index of Object.keys(error)) {
msg += error[index] + '\n';
}
}
}
return msg;
},
loadItemMetadata() {
this.isLoadingItemMetadata = true;
// Gets an item from the bulk group
this.fetchItemIdInSequence({ collectionId: this.collectionId, sequenceId: this.groupID, itemPosition: 1 })
.then((itemId) => {
this.copyItemId = itemId;
this.fetchItemMetadata(this.copyItemId)
.then((metadata) => {
this.itemMetadata = metadata;
this.isLoadingItemMetadata = false;
});
})
.catch(() => this.isLoadingItemMetadata = false);
}
},
created() {
// Obtains collection ID
this.collectionId = this.$route.params.collectionId;
this.groupID = this.$route.params.groupId;
// Updates Collection BreadCrumb
this.$root.$emit('onCollectionBreadCrumbUpdate', [
{ path: this.$routerHelper.getCollectionPath(this.collectionId), label: this.$i18n.get('items') },
{ path: '', label: this.$i18n.get('add_items_bulk') }
]);
this.isLoadingMetadata = true;
this.fetchMetadata({
collectionId: this.collectionId,
isRepositoryLevel: false,
isContextEdit: true,
includeDisabled: false,
}).then(() => {
this.isLoadingMetadata = false;
for (let i = 0; i < this.metadata.length; i++) {
this.metadatumCollapses.push(false);
this.metadatumCollapses[i] = true;
}
this.loadItemMetadata();
})
.catch(() => this.isLoadingMetadata = false);
this.isLoadingGroupInfo = true;
this.fetchGroup({ collectionId: this.collectionId, groupId: this.groupID })
.then(() => this.isLoadingGroupInfo = false)
.then(() => this.isLoadingGroupInfo = false)
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.page-container {
&>.tainacan-form {
padding: 0 $page-side-padding;
margin-bottom: 110px;
}
.tainacan-page-title {
margin-bottom: 35px;
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
h1, h2 {
font-size: 20px;
font-weight: 500;
color: $gray5;
display: inline-block;
flex-shrink: 1;
flex-grow: 1;
}
.status-tag {
color: white;
background: $turquoise5;
padding: 0.15rem 0.5rem;
font-size: 0.75rem;
margin: 0 1rem 0 0;
font-weight: 600;
position: relative;
top: -2px;
}
a.back-link{
font-weight: 500;
float: right;
margin-top: 5px;
}
hr{
margin: 0px 0px 4px 0px;
height: 1px;
background-color: $secondary;
width: 100%;
}
}
.document-list {
display: inline-block;
.document-item {
display: flex;
flex-wrap: nowrap;
width: 100%;
justify-content: flex-start;
align-items: center;
padding: 0.5rem 0.75rem;
position: relative;
cursor: default;
.document-thumb {
max-height: 42px;
max-width: 42px;
margin-right: 1rem;
}
.document-name {
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
white-space: nowrap;
}
}
}
.column {
.section-status{
padding: 16px 0;
.field {
border-bottom: none;
.b-radio {
margin-right: 24px;
.icon {
font-size: 18px !important;
color: $gray3;
}
}
}
}
.section-label {
cursor: default;
position: relative;
label {
font-size: 16px !important;
font-weight: 500 !important;
color: $gray5 !important;
line-height: 1.2em;
}
}
.collapse-all {
font-size: 12px;
.icon {
vertical-align: bottom;
}
}
.multiple-inputs {
display: flex;
align-items: center;
justify-content: space-between;
}
.field {
border-bottom: 1px solid $gray2;
padding: 10px 0px 10px 60px;
.label {
font-size: 0.875rem;
font-weight: 500;
margin-left: 15px;
margin-bottom: 0.5em;
}
.metadata-type {
font-size: 0.8125rem;
font-weight: 400;
color: $gray3;
top: -0.2em;
position: relative;
}
.help-wrapper {
top: -0.2em;
}
.collapse-handle {
cursor: pointer;
position: relative;
margin-left: -42px;
}
}
}
.footer {
padding: 18px $page-side-padding;
position: absolute;
bottom: 0;
z-index: 999999;
background-color: $gray1;
width: 100%;
height: 65px;
display: flex;
justify-content: flex-end;
align-items: center;
left: 0;
.form-submission-footer {
.button {
margin-left: 16px;
margin-right: 6px;
}
}
@keyframes blink {
from { color: $blue5; }
to { color: $gray4; }
}
.update-warning {
color: $blue5;
animation-name: blink;
animation-duration: 0.5s;
animation-delay: 0.5s;
align-items: center;
display: flex;
}
.update-info-section {
color: $gray4;
margin-right: auto;
}
.help {
display: inline-block;
font-size: 1.0em;
margin-top: 0;
margin-left: 24px;
}
}
}
</style>

View File

@ -12,11 +12,11 @@
:value="allItemsOnPageSelected">
{{ $i18n.get('label_select_all_items_page') }}
</b-checkbox>
</span>
</span>
<span
style="margin-left: 10px"
v-if="enableSelectAllItemsPages == true && allItemsOnPageSelected && items.length > 1">
v-if="allItemsOnPageSelected && items.length > 1">
<b-checkbox
v-model="isAllItemsSelected">
{{ $i18n.getWithVariables('label_select_all_%s_items', [totalItems]) }}
@ -74,22 +74,22 @@
<div class="table-wrapper">
<!-- Context menu for right click selection -->
<div
<div
v-if="cursorPosY > 0 && cursorPosX > 0 && !$route.query.readmode"
class="context-menu">
<!-- Backdrop for escaping context menu -->
<div
<div
@click.left="clearContextMenu()"
@click.right="clearContextMenu()"
class="context-menu-backdrop" />
<b-dropdown
class="context-menu-backdrop" />
<b-dropdown
inline
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }"
trap-focus>
<b-dropdown-item
@click="openItem()"
@click="openItem()"
v-if="!isOnTrash && !$route.query.iframemode">
{{ $i18n.getFrom('items','view_item') }}
</b-dropdown-item>
@ -98,7 +98,7 @@
v-if="!isOnTrash && !$route.query.iframemode">
{{ $i18n.get('label_open_item_new_tab') }}
</b-dropdown-item>
<b-dropdown-item
<b-dropdown-item
@click="selectItem()"
v-if="contextMenuItem != null">
{{ getSelectedItemChecked(contextMenuItem.id) == true ? $i18n.get('label_unselect_item') : $i18n.get('label_select_item') }}
@ -120,36 +120,36 @@
</b-dropdown-item>
</b-dropdown>
</div>
<!-- GRID (THUMBNAILS) VIEW MODE -->
<div
role="list"
class="tainacan-grid-container"
v-if="viewMode == 'grid'">
<div
<div
role="listitem"
:key="index"
v-for="(item, index) of items"
:class="{ 'selected-grid-item': getSelectedItemChecked(item.id) == true }"
class="tainacan-grid-item">
<!-- Checkbox -->
<!-- TODO: Remove v-if="collectionId" from this element when the bulk edit in repository is done -->
<div
v-if="collectionId && !$route.query.readmode && ($route.query.iframemode || collection && collection.current_user_can_bulk_edit)"
:class="{ 'is-selecting': isSelectingItems }"
class="grid-item-checkbox">
<b-checkbox
<b-checkbox
size="is-small"
:value="getSelectedItemChecked(item.id)"
@input="setSelectedItemChecked(item.id)"/>
@input="setSelectedItemChecked(item.id)"/>
</div>
<!-- Title -->
<div
:style="{ 'padding-left': !collectionId || !($route.query.iframemode || collection && collection.current_user_can_bulk_edit) || $route.query.readmode ? '0.5rem !important' : '2.75rem' }"
class="metadata-title">
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -159,13 +159,13 @@
html: true,
autoHide: false,
placement: 'auto-start'
}"
@click.left="onClickItem($event, item)"
}"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)">
{{ item.title != undefined ? item.title : '' }}
</p>
</p>
</div>
<!-- Thumbnail -->
<a
v-if="item.thumbnail != undefined"
@ -173,22 +173,22 @@
@click.right="onRightClickItem($event, item)"
class="grid-item-thumbnail"
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)) + ')' }">
<img
<img
:alt="$i18n.get('label_thumbnail')"
:src="item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)">
</a>
<!-- Actions -->
<div
<div
v-if="item.current_user_can_edit && !$route.query.iframemode"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
v-if="!isOnTrash"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
@ -202,7 +202,7 @@
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash">
<span
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
@ -224,18 +224,18 @@
placement: 'auto'
}"
class="icon">
<i
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
</span>
</a>
</div>
</div>
</div>
<!-- MASONRY VIEW MODE -->
<masonry
<masonry
role="list"
v-if="viewMode == 'masonry'"
:cols="{default: 7, 1919: 6, 1407: 5, 1215: 4, 1023: 3, 767: 2, 343: 1}"
@ -246,7 +246,7 @@
:key="index"
v-for="(item, index) of items"
:class="{
'selected-masonry-item': getSelectedItemChecked(item.id) == true,
'selected-masonry-item': getSelectedItemChecked(item.id) == true,
}"
class="tainacan-masonry-item">
@ -256,14 +256,14 @@
v-if="collectionId && !$route.query.readmode && ($route.query.iframemode || collection && collection.current_user_can_bulk_edit)"
:class="{ 'is-selecting': isSelectingItems }"
class="masonry-item-checkbox">
<label
tabindex="0"
<label
tabindex="0"
class="b-checkbox checkbox is-small">
<input
<input
type="checkbox"
:checked="getSelectedItemChecked(item.id)"
@input="setSelectedItemChecked(item.id)">
<span class="check" />
@input="setSelectedItemChecked(item.id)">
<span class="check" />
<span class="control-label" />
</label>
</div>
@ -276,30 +276,30 @@
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
class="metadata-title">
<p>{{ item.title != undefined ? item.title : '' }}</p>
<p>{{ item.title != undefined ? item.title : '' }}</p>
</div>
<!-- Thumbnail -->
<div
<!-- Thumbnail -->
<div
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-if="item.thumbnail != undefined"
class="tainacan-masonry-item-thumbnail"
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][0] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[0] : thumbPlaceholderPath)) + ')' }">
<img
<img
:alt="$i18n.get('label_thumbnail')"
:src="item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][0] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[0] : thumbPlaceholderPath)">
</div>
<!-- Actions -->
<div
<div
v-if="item.current_user_can_edit && !$route.query.iframemode"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
v-if="!isOnTrash"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
@ -337,7 +337,7 @@
placement: 'auto'
}"
class="icon">
<i
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
</span>
@ -351,25 +351,25 @@
role="list"
class="tainacan-cards-container"
v-if="viewMode == 'cards'">
<div
<div
role="listitem"
:key="index"
v-for="(item, index) of items"
:class="{ 'selected-card': getSelectedItemChecked(item.id) == true }"
class="tainacan-card">
<!-- Checkbox -->
<!-- TODO: Remove v-if="collectionId" from this element when the bulk edit in repository is done -->
<div
v-if="collectionId && !$route.query.readmode && ($route.query.iframemode || collection && collection.current_user_can_bulk_edit)"
:class="{ 'is-selecting': isSelectingItems }"
class="card-checkbox">
<b-checkbox
<b-checkbox
size="is-small"
:value="getSelectedItemChecked(item.id)"
@input="setSelectedItemChecked(item.id)"/>
@input="setSelectedItemChecked(item.id)"/>
</div>
<!-- Title -->
<div
:style="{
@ -377,7 +377,7 @@
'margin-bottom': item.current_user_can_edit && !$route.query.iframemode ? '-26px' : '0px'
}"
class="metadata-title">
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -387,21 +387,21 @@
html: true,
autoHide: false,
placement: 'auto-start'
}"
}"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)">
{{ item.title != undefined ? item.title : '' }}
</p>
</p>
</div>
<!-- Actions -->
<div
<div
v-if="item.current_user_can_edit && !$route.query.iframemode"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
v-if="!isOnTrash"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
@ -439,22 +439,22 @@
placement: 'auto'
}"
class="icon">
<i
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
</span>
</a>
</div>
<!-- Remaining metadata -->
<div
<!-- Remaining metadata -->
<div
class="media"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)">
<div
<div
:style="{ backgroundImage: 'url(' + (item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)) + ')' }"
class="card-thumbnail">
<img
<img
:alt="$i18n.get('label_thumbnail')"
v-if="item.thumbnail != undefined"
:src="item['thumbnail']['tainacan-medium'] ? item['thumbnail']['tainacan-medium'][0] : (item['thumbnail'].medium ? item['thumbnail'].medium[0] : thumbPlaceholderPath)">
@ -462,7 +462,7 @@
<div class="list-metadata media-body">
<!-- Description -->
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -472,11 +472,11 @@
html: true,
autoHide: false,
placement: 'auto-start'
}"
}"
class="metadata-description"
v-html="item.description != undefined && item.description != '' ? getLimitedDescription(item.description) : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_description_not_informed') + `</span>`" />
<!-- Author-->
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -486,12 +486,12 @@
html: false,
autoHide: false,
placement: 'auto-start'
}"
class="metadata-author-creation">
}"
class="metadata-author-creation">
{{ $i18n.get('info_created_by') + ' ' + (item.author_name != undefined ? item.author_name : '') }}
</p>
</p>
<!-- Creation Date-->
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -501,13 +501,13 @@
html: false,
autoHide: false,
placement: 'auto-start'
}"
class="metadata-author-creation">
}"
class="metadata-author-creation">
{{ $i18n.get('info_date') + ' ' + (item.creation_date != undefined ? parseDateToNavigatorLanguage(item.creation_date) : '') }}
</p>
</p>
</div>
</div>
</div>
</div>
@ -515,16 +515,16 @@
<masonry
role="list"
:cols="{default: 4, 1919: 3, 1407: 2, 1215: 2, 1023: 1, 767: 1, 343: 1}"
:gutter="30"
:gutter="30"
class="tainacan-records-container"
v-if="viewMode == 'records'">
<div
<div
role="listitem"
:key="index"
v-for="(item, index) of items"
:class="{ 'selected-record': getSelectedItemChecked(item.id) == true }"
class="tainacan-record">
<!-- Checkbox -->
<!-- TODO: Remove v-if="collectionId" from this element when the bulk edit in repository is done -->
<div
@ -542,7 +542,7 @@
<span class="control-label" />
</label>
</div>
<!-- Title -->
<div
class="metadata-title"
@ -566,8 +566,8 @@
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-tooltip="{
delay: {
show: 500,
@ -583,17 +583,17 @@
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-html="item.title != undefined ? item.title : ''" />
v-html="item.title != undefined ? item.title : ''" />
</div>
<!-- Actions -->
<div
<div
v-if="item.current_user_can_edit && !$route.query.iframemode"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
v-if="!isOnTrash"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
@ -631,62 +631,62 @@
placement: 'auto'
}"
class="icon">
<i
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
</span>
</a>
</div>
<!-- Remaining metadata -->
<div
<!-- Remaining metadata -->
<div
class="media"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)">
<div class="list-metadata media-body">
<div class="tainacan-record-thumbnail">
<img
<img
:alt="$i18n.get('label_thumbnail')"
v-if="item.thumbnail != undefined"
:src="item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][0] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[0] : thumbPlaceholderPath)">
:src="item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][0] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[0] : thumbPlaceholderPath)">
</div>
<span
<span
v-for="(column, index) in tableMetadata"
:key="index"
:class="{ 'metadata-type-textarea': column.metadata_type_object != undefined && column.metadata_type_object.component == 'tainacan-textarea' }"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'description')">
<h3 class="metadata-label">{{ $i18n.get('label_description') }}</h3>
<p
<p
v-html="item.description != undefined ? item.description : ''"
class="metadata-value"/>
</span>
<span
<span
v-for="(column, index) in tableMetadata"
:key="index"
:class="{ 'metadata-type-textarea': column.metadata_type_object != undefined && column.metadata_type_object.component == 'tainacan-textarea' }"
v-if="renderMetadata(item.metadata, column) != '' && column.display && column.slug != 'thumbnail' && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop != 'title')">
<h3 class="metadata-label">{{ column.name }}</h3>
<p
<p
v-html="renderMetadata(item.metadata, column)"
class="metadata-value"/>
</span>
<span
<span
v-for="(column, index) in tableMetadata"
:key="index"
v-if="(column.metadatum == 'row_creation' || column.metadatum == 'row_author') && item[column.slug] != undefined">
<h3 class="metadata-label">{{ column.name }}</h3>
<p
<p
v-html="column.metadatum == 'row_creation' ? parseDateToNavigatorLanguage(item[column.slug]) : item[column.slug]"
class="metadata-value"/>
</span>
</div>
</div>
</div>
</masonry>
<!-- TABLE VIEW MODE -->
<table
<table
v-if="viewMode == 'table'"
class="tainacan-table">
<thead>
@ -698,18 +698,18 @@
<!-- nothing to show on header for checkboxes -->
</th>
<!-- Displayed Metadata -->
<th
<th
v-for="(column, index) in tableMetadata"
:key="index"
v-if="column.display"
class="column-default-width"
:class="{
'thumbnail-cell': column.metadatum == 'row_thumbnail',
'column-small-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'date' ||
'column-small-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'date' ||
column.metadata_type_object.primitive_type == 'float' ||
column.metadata_type_object.primitive_type == 'int') : false,
'column-medium-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'term' ||
column.metadata_type_object.primitive_type == 'item' ||
'column-medium-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'term' ||
column.metadata_type_object.primitive_type == 'item' ||
column.metadata_type_object.primitive_type == 'compound') : false,
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' || column.metadata_type_object.related_mapped_prop == 'description') : false,
}">
@ -724,10 +724,10 @@
</tr>
</thead>
<tbody>
<tr
:class="{
'selected-row': getSelectedItemChecked(item.id) == true,
'highlighted-item': highlightedItem == item.id
<tr
:class="{
'selected-row': getSelectedItemChecked(item.id) == true,
'highlighted-item': highlightedItem == item.id
}"
:key="index"
v-for="(item, index) of items">
@ -737,14 +737,14 @@
v-if="collectionId && !$route.query.readmode && ($route.query.iframemode || collection && collection.current_user_can_bulk_edit)"
:class="{ 'is-selecting': isSelectingItems }"
class="checkbox-cell">
<b-checkbox
<b-checkbox
size="is-small"
:value="getSelectedItemChecked(item.id)"
@input="setSelectedItemChecked(item.id)"/>
</td>
<!-- Item Displayed Metadata -->
<td
<td
:key="columnIndex"
v-for="(column, columnIndex) in tableMetadata"
v-if="column.display"
@ -752,13 +752,13 @@
:class="{ 'metadata-type-textarea': column.metadata_type_object != undefined && column.metadata_type_object.component == 'tainacan-textarea',
'thumbnail-cell': column.metadatum == 'row_thumbnail',
'column-main-content' : column.metadata_type_object != undefined ? (column.metadata_type_object.related_mapped_prop == 'title') : false,
'column-needed-width column-align-right' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'float' ||
'column-needed-width column-align-right' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'float' ||
column.metadata_type_object.primitive_type == 'int' ) : false,
'column-small-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'date' ||
'column-small-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'date' ||
column.metadata_type_object.primitive_type == 'int' ||
column.metadata_type_object.primitive_type == 'float') : false,
'column-medium-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'item' ||
column.metadata_type_object.primitive_type == 'term' ||
'column-medium-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'item' ||
column.metadata_type_object.primitive_type == 'term' ||
column.metadata_type_object.primitive_type == 'compound') : false,
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' || column.metadata_type_object.related_mapped_prop == 'description') : false,
}"
@ -777,7 +777,7 @@
placement: 'auto-start'
}"
v-if="collectionId == undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object.related_mapped_prop == 'title'"
v-html="`<span class='sr-only'>` + column.name + ': </span>' + ((item.title != undefined && item.title != '') ? item.title : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`)"/>
<p
@ -792,7 +792,7 @@
placement: 'auto-start'
}"
v-if="collectionId == undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object != undefined &&
column.metadata_type_object.related_mapped_prop == 'description'"
v-html="`<span class='sr-only'>` + column.name + ': </span>' + ((item.description != undefined && item.description) != '' ? item.description : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`)"/>
<p
@ -817,12 +817,12 @@
v-html="renderMetadata(item.metadata, column) != '' ? renderMetadata(item.metadata, column) : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_informed') + `</span>`"/>
<span v-if="column.metadatum == 'row_thumbnail'">
<img
<img
:alt="$i18n.get('label_thumbnail')"
class="table-thumb"
class="table-thumb"
:src="item['thumbnail']['tainacan-small'] ? item['thumbnail']['tainacan-small'][0] : (item['thumbnail'].thumbnail ? item['thumbnail'].thumbnail[0] : thumbPlaceholderPath)">
</span>
<p
</span>
<p
v-tooltip="{
delay: {
show: 500,
@ -836,7 +836,7 @@
v-if="column.metadatum == 'row_author'">
{{ item[column.slug] }}
</p>
<p
<p
v-tooltip="{
delay: {
show: 500,
@ -861,8 +861,8 @@
<div class="actions-container">
<a
v-if="!isOnTrash"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
@ -900,7 +900,7 @@
placement: 'auto'
}"
class="icon">
<i
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-20px"/>
</span>
@ -910,7 +910,7 @@
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
@ -930,8 +930,7 @@ export default {
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
cursorPosX: -1,
cursorPosY: -1,
contextMenuItem: null,
enableSelectAllItemsPages: tainacan_plugin.enable_select_all_items_pages
contextMenuItem: null
}
},
mixins: [ dateInter ],
@ -963,7 +962,7 @@ export default {
selectedItems () {
if (this.$route.query.iframemode)
this.$eventBusSearch.setSelectedItemsForIframe(this.getSelectedItems());
return this.getSelectedItems();
},
isSelectingItems () {
@ -1003,6 +1002,7 @@ export default {
]),
...mapActions('bulkedition', [
'createEditGroup',
'createSequenceEditGroup',
'trashItemsInBulk',
'deleteItemsInBulk',
'untrashItemsInBulk'
@ -1050,11 +1050,9 @@ export default {
});
},
sequenceEditSelectedItems() {
this.createEditGroup({
this.createSequenceEditGroup({
object: Object.keys(this.queryAllItemsSelected).length ? this.queryAllItemsSelected : this.selectedItems,
collectionID: this.collectionId,
order: this.getOrder(),
orderBy: this.getOrderBy()
collectionID: this.collectionId
}).then(() => {
let sequenceId = this.getGroupID();
this.$router.push(this.$routerHelper.getCollectionSequenceEditPath(this.collectionId, sequenceId, 1));
@ -1071,7 +1069,7 @@ export default {
}
},
makeCopiesOfOneItem(itemId) {
this.$buefy.modal.open({
parent: this,
component: ItemCopyDialog,
@ -1297,7 +1295,7 @@ export default {
@import "../../scss/_view-mode-records.scss";
.selection-control {
padding: 6px 0px 0px 12px;
background: white;
height: 40px;

View File

@ -174,6 +174,9 @@
this.$root.$on('closeAdvancedSearchShortcut', () => {
this.$refs.advancedSearchShortcut.toggle();
});
this.$root.$on('openProcessesPopup', () => {
this.showProcesses = true;
});
},
beforeDestroy() {
this.$root.$off('closeAdvancedSearchShortcut');

View File

@ -81,9 +81,8 @@
</button>
<button
v-if="copyCount > 1 && hasCopied && newItems.length > 1"
class="button is-secondary"
:class="{'is-loading': isCreatingBulkEditGroup }"
@click.prevent="createBulkEditGroup()"
class="button is-secondary"
@click.prevent="openBulkEditionModal()"
type="submit">
{{ $i18n.get('label_bulk_edit_items') }}
</button>
@ -94,6 +93,8 @@
<script>
import { mapActions } from 'vuex';
import BulkEditionModal from '../bulk-edition/bulk-edition-modal.vue';
export default {
name: 'ItemCopyDialog',
props: {
@ -112,7 +113,6 @@
newItems: Array,
copyCount: Number,
hasCopied: Boolean,
isCreatingBulkEditGroup: Boolean,
isCreatingSequenceEditGroup: Boolean,
}
},
@ -123,8 +123,8 @@
]),
...mapActions('bulkedition', [
'createEditGroup',
'setStatusInBulk',
'setBulkAddItems'
'createSequenceEditGroup',
'setStatusInBulk'
]),
generateCopies() {
this.isLoading = true;
@ -151,7 +151,7 @@
let onlyItemIds = this.newItems.map(item => item.id);
this.isCreatingSequenceEditGroup = true;
this.createEditGroup({
this.createSequenceEditGroup({
object: onlyItemIds,
collectionID: this.collectionId
}).then((group) => {
@ -161,29 +161,31 @@
this.$parent.close();
});
},
createBulkEditGroup() {
// Sends to store, so we can retrieve in next page.
this.setBulkAddItems(this.newItems);
openBulkEditionModal() {
let onlyItemIds = this.newItems.map(item => item.id);
this.isCreatingBulkEditGroup = true;
this.createEditGroup({
object: onlyItemIds,
collectionID: this.collectionId
}).then((group) => {
let groupId = group.id;
this.isCreatingBulkEditGroup = false;
this.$router.push({ path: this.$routerHelper.getItemMetadataBulkAddPath(this.collectionId, groupId), query: { loadCopy: true }});
this.$parent.close();
this.$buefy.modal.open({
parent: this,
component: BulkEditionModal,
props: {
modalTitle: this.$i18n.get('info_editing_items_in_bulk'),
totalItems: onlyItemIds.length,
selectedForBulk: onlyItemIds,
objectType: this.$i18n.get('items'),
collectionID: this.collectionId
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
this.$parent.close();
},
},
created() {
this.message = this.$i18n.get('instruction_select_the_amount_of_copies');
this.isLoading = false;
this.hasCopied = false;
this.isCreatingBulkEditGroup = false;
this.isCreatingSequenceEditGroup = false;
this.copyCount = 1;
},

View File

@ -22,7 +22,6 @@ import ImporterEditionForm from '../components/edition/importer-edition-form.vue
import ImporterMappingForm from '../components/edition/importer-mapping-form.vue'
import ItemEditionForm from '../components/edition/item-edition-form.vue'
import ItemBulkEditionForm from '../components/edition/item-bulk-edition-form.vue'
import ItemMetadataBulkEditionForm from '../components/edition/item-metadata-bulk-edition-form.vue'
import TaxonomyEditionForm from '../components/edition/taxonomy-edition-form.vue'
import ExporterEditionForm from '../components/edition/exporter-edition-form.vue'
@ -53,7 +52,6 @@ const routes = [
{ path: 'items/new', name: 'CollectionItemCreatePage', component: ItemEditionForm, meta: {title: i18nGet('title_create_item_collection') } },
{ path: 'items/:itemId', name: 'ItemPage', component: ItemPage, meta: {title: i18nGet('title_item_page') } },
{ path: 'bulk-add', name: 'CollectionItemBulkAddPage', component: ItemBulkEditionForm, meta: {title: i18nGet('title_item_bulk_add') } },
{ path: 'bulk-add/:groupId', name: 'CollectionItemBulkAddMetadataPage', component: ItemMetadataBulkEditionForm, meta: {title: i18nGet('title_item_bulk_add') } },
{ path: 'settings', component: CollectionEditionForm, name: 'CollectionEditionForm', meta: {title: i18nGet('title_collection_settings') } },
{ path: 'metadata', component: MetadataList, name: 'MetadataList', meta: {title: i18nGet('title_collection_metadata_edition') } },
{ path: 'filters', component: FiltersList, name: 'FiltersList', meta: {title: i18nGet('title_collection_filters_edition') } },

View File

@ -139,6 +139,7 @@
}
.tags {
margin: 0.17rem 0.25rem 0.08rem 0.25rem !important;
display: inline-flex;
}
.tag {
background: white;

View File

@ -557,6 +557,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_error_deleting_taxonomy' => __( 'Error on deleting taxonomy', 'tainacan' ),
'info_error_first_value_greater' => __( 'First value should be lower than second value', 'tainacan' ),
'info_error_value_must_be_number' => __( 'Value should be a number', 'tainacan' ),
'info_error_upload' => __( 'Error while uploading files.', 'tainacan' ),
'info_collection_deleted' => __( 'Collection deleted.', 'tainacan' ),
'info_item_deleted' => __( 'Item deleted.', 'tainacan' ),
'info_taxonomy_deleted' => __( 'Taxonomy deleted', 'tainacan' ),
@ -648,9 +649,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_bulk_add_items' => __( 'Bulk add documents from your computer as items.', 'tainacan' ),
'info_editing_items_in_bulk' => __( 'Bulk edit items', 'tainacan' ),
'info_by_inner' => __( 'by', 'tainacan' ),
'info_items_selected' => __( 'items selected', 'tainacan' ),
'info_items_affected' => __( 'items affected', 'tainacan' ),
'info_item_affected' => __( 'item affected', 'tainacan' ),
'info_bulk_edition_process_added' => __( 'Bulk edition added to process queue.', 'tainacan' ),
'info_no_parent_term_found' => __( 'No valid parent term was found with this name.', 'tainacan' ),
'info_warning_changing_parent_term' => __( 'Warning! Changing parent term will reload the terms list, thus uncheking any selection.', 'tainacan' ),
'info_warning_selected_items_remove_from_trash' => __( 'Do you really want to remove from trash the selected items?', 'tainacan' ),

View File

@ -11,15 +11,14 @@ class REST_Bulkedit_Controller extends REST_Controller {
public function __construct() {
$this->rest_base = 'bulk-edit';
parent::__construct();
add_action('init', array(&$this, 'init_objects'), 11);
}
public function init_objects() {
$this->metadatum_repository = Repositories\Metadata::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
parent::__construct();
add_action('init', array(&$this, 'init_objects'), 11);
}
public function init_objects() {
$this->metadatum_repository = Repositories\Metadata::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
}
/**
*
@ -36,7 +35,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
'args' => $this->get_create_params()
),
)
);
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)',
array(
array(
@ -45,27 +44,27 @@ class REST_Bulkedit_Controller extends REST_Controller {
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/add',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/add',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'add_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/trash',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/trash',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -73,8 +72,8 @@ class REST_Bulkedit_Controller extends REST_Controller {
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/untrash',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/untrash',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -82,8 +81,8 @@ class REST_Bulkedit_Controller extends REST_Controller {
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/delete_items',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/delete_items',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -91,7 +90,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set_status',
array(
array(
@ -99,75 +98,75 @@ class REST_Bulkedit_Controller extends REST_Controller {
'callback' => array($this, 'set_status'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'value' => [
'type' => 'string',
'description' => __( 'The new status value', 'tainacan' ),
],
],
'value' => [
'type' => 'string',
'description' => __( 'The new status value', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'set_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer/array',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer/array',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/remove',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/remove',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'remove_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/replace',
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/replace',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'replace_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'old_value' => [
'type' => 'string/integer',
'description' => __( 'The value to search for', 'tainacan' ),
],
'new_value' => [
'type' => 'string/integer',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
'metadatum_id' => [
'type' => 'integer',
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'old_value' => [
'type' => 'string/integer',
'description' => __( 'The value to search for', 'tainacan' ),
],
'new_value' => [
'type' => 'string/integer',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
),
)
);
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/sequence/(?P<sequence_index>[\d]+)',
array(
array(
@ -176,10 +175,8 @@ class REST_Bulkedit_Controller extends REST_Controller {
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
}
);
}
public function bulk_edit_permissions_check($request) {
$collection = $this->collections_repository->fetch($request['collection_id']);
@ -192,13 +189,16 @@ class REST_Bulkedit_Controller extends REST_Controller {
return false;
}
public function create_item($request) {
$body = json_decode($request->get_body(), true);
$args = [];
if (isset($body['items_ids']) && is_array($body['items_ids']) && !empty($body['items_ids'])) {
$args['items_ids'] = $body['items_ids'];
$collection_id = $request['collection_id'];
$args = [
'items_ids' => $body['items_ids'],
'collection_id' => $collection_id
];
if (isset($body['options'])) {
$args['options'] = $body['options'];
}
@ -220,17 +220,32 @@ class REST_Bulkedit_Controller extends REST_Controller {
], 400);
}
$bulk = new \Tainacan\Bulk_Edit($args);
global $Tainacan_Generic_Process_Handler;
$process = $Tainacan_Generic_Process_Handler->initialize_generic_process('bulk_edit', $bulk->get_id());
$Tainacan_Generic_Process_Handler->save_process_instance($process);
$bulk = $Tainacan_Generic_Process_Handler->initialize_generic_process('bulk_edit');
$bulk->create_bulk_edit($args);
$Tainacan_Generic_Process_Handler->save_process_instance($bulk);
$response = $this->prepare_item_for_response($bulk, $request);
$rest_response = new \WP_REST_Response($response, 200);
return $rest_response;
}
public function set_status($request) {
return $this->generic_action('set_status', $request);
}
public function trash_items($request) {
return $this->generic_action('trash_items', $request);
}
public function untrash_items($request) {
return $this->generic_action('untrash_items', $request);
}
public function delete_items($request) {
return $this->generic_action('delete_items', $request);
}
public function add_value($request) {
return $this->generic_action('add_value', $request);
}
@ -247,146 +262,71 @@ class REST_Bulkedit_Controller extends REST_Controller {
return $this->generic_action('replace_value', $request, ['old_value', 'new_value']);
}
public function set_status($request) {
$body = json_decode($request->get_body(), true);
if( !isset($body['value']) ) {
return new \WP_REST_Response([
'error_message' => __('Value must be provided', 'tainacan'),
], 400);
}
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->set_status($body['value']);
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
public function get_item($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$return = $this->prepare_item_for_response($bulk, $request);
if (0 === $return['items_count']) {
global $Tainacan_Generic_Process_Handler;
$bulk = $Tainacan_Generic_Process_Handler->get_process_instance_by_session_id($group_id);
if ($bulk == false) {
return new \WP_REST_Response([
'error_message' => __('Group not found', 'tainacan'),
], 404);
}
$return = $this->prepare_item_for_response($bulk, $request);
return new \WP_REST_Response($return, 200);
}
function prepare_item_for_response($bulk_object, $request) {
$count = $bulk_object->count_posts();
$options = $bulk_object->get_options();
$return = [
'id' => $bulk_object->get_id(),
'items_count' => $count,
'options' => $options
];
return $return;
}
public function trash_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->trash_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
public function untrash_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->untrash_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
public function delete_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->delete_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
private function generic_action($method, $request, $keys = ['value']) {
$body = json_decode($request->get_body(), true);
if (empty($body)) {
return new \WP_REST_Response([
'error_message' => __('Body can not be empty.', 'tainacan'),
], 400);
}
if (!isset($body['metadatum_id'])) {
return new \WP_REST_Response([
'error_message' => __('You must specify a Metadatum ID.', 'tainacan'),
], 400);
}
foreach ($keys as $key) {
if (!isset($body[$key])) {
if ( !in_array($method, ['trash_items', 'untrash_items', 'delete_items']) ) {
if (empty($body)) {
return new \WP_REST_Response([
'error_message' => sprintf(__('%s must be provided', 'tainacan'), $key),
'error_message' => __('Body can not be empty.', 'tainacan'),
], 400);
}
if ($method != 'set_status' && !isset($body['metadatum_id'])) {
return new \WP_REST_Response([
'error_message' => __('You must specify a Metadatum ID.', 'tainacan'),
], 400);
}
foreach ($keys as $key) {
if (!isset($body[$key])) {
return new \WP_REST_Response([
'error_message' => sprintf(__('%s must be provided', 'tainacan'), $key),
], 400);
}
}
}
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$bulk_id = $request['group_id'];
$metadatum = $this->metadatum_repository->fetch($body['metadatum_id']);
if ( $metadatum instanceof Entities\Metadatum ) {
$value = isset($body['new_value']) ? $body['new_value'] : $body['value'];
$old_value = isset($body['old_value']) ? $body['old_value'] : null;
$action = $bulk->$method($metadatum, $value, $old_value);
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
} else {
return new \WP_REST_Response([
'error_message' => __('Metadatum not found.', 'tainacan'),
], 400);
global $Tainacan_Generic_Process_Handler;
$process = $Tainacan_Generic_Process_Handler->get_process_instance_by_session_id($bulk_id);
if ($process !== false) {
$bulk_edit_data = [
"value" => isset($body['new_value']) ? $body['new_value'] : $body['value'],
"method" => $method,
"old_value" => isset($body['old_value']) ? $body['old_value'] : null,
"metadatum_id" => isset($body['metadatum_id']) ? $body['metadatum_id'] : null,
];
$process->set_bulk_edit_data($bulk_edit_data);
$bg_bulk = $Tainacan_Generic_Process_Handler->add_to_queue($process);
//$Tainacan_Generic_Process_Handler->delete_process_instance($process);
}
return new \WP_REST_Response(["bg_process_id"=>$bulk_id, "method" => $method], 200);
}
public function get_item_in_sequence($request) {

View File

@ -0,0 +1,203 @@
<?php
namespace Tainacan\API\EndPoints;
use \Tainacan\API\REST_Controller;
use Tainacan\Entities;
use Tainacan\Repositories;
use Tainacan\Entities\Entity;
class REST_Sequence_Edit_Controller extends REST_Controller {
public function __construct() {
$this->rest_base = 'sequence-edit';
parent::__construct();
add_action('init', array(&$this, 'init_objects'), 11);
}
public function init_objects() {
$this->items_repository = Repositories\Items::get_instance();
$this->collections_repository = Repositories\Collections::get_instance();
}
/**
*
*
* @throws \Exception
*/
public function register_routes() {
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base,
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_item'),
'permission_callback' => array($this, 'sequence_edit_permissions_check'),
'args' => $this->get_create_params()
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'sequence_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/(?P<sequence_index>[\d]+)',
array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_item_in_sequence'),
'permission_callback' => array($this, 'sequence_edit_permissions_check'),
),
)
);
}
public function prepare_item_for_response($item, $request) {
}
public function sequence_edit_permissions_check($request) {
$collection = $this->collections_repository->fetch($request['collection_id']);
if ($collection instanceof Entities\Collection) {
return current_user_can($collection->get_items_capabilities()->edit_others_posts);
}
return false;
}
public function create_item($request) {
$body = json_decode($request->get_body(), true);
$args = [];
if (isset($body['items_ids']) && is_array($body['items_ids']) && !empty($body['items_ids'])) {
$args['items_ids'] = $body['items_ids'];
$count = sizeof($args['items_ids']);
$args['items_count'] = $count;
} elseif ( isset($body['use_query']) && $body['use_query'] ) {
unset($body['use_query']['paged']);
unset($body['use_query']['offset']);
unset($body['use_query']['perpage']);
$query_args = $this->prepare_filters($body['use_query']);
$collection_id = $request['collection_id'];
$args = [
'query' => $query_args,
'collection_id' => $collection_id
];
// calculate size
$query_args['posts_per_page'] = 1;
$items_q = $this->items_repository->fetch( $query_args, $collection_id );
$count = $items_q->found_posts;
$args['items_count'] = $count;
} else {
return new \WP_REST_Response([
'error_message' => __('You mus specify items_ids OR use_query', 'tainacan'),
], 400);
}
$new_group_id = uniqid();
update_option('tnc_transient_' . $new_group_id, $args);
$response = [
'id' => $new_group_id,
'items_count' => $count
];
$rest_response = new \WP_REST_Response($response, 200);
return $rest_response;
}
public function get_item($request) {
$group_id = $request['group_id'];
$group = get_option('tnc_transient_' . $group_id);
if ( is_array($group) ) {
return new \WP_REST_Response( $group, 200 );
}
return new \WP_REST_Response([
'error_message' => __('Item not found.', 'tainacan'),
], 404);
}
public function get_item_in_sequence($request) {
$group_id = $request['group_id'];
$index = (int) $request['sequence_index'];
$group = get_option('tnc_transient_' . $group_id);
if ( is_array($group) ) {
if ( isset($group['items_ids']) && is_array($group['items_ids']) ) {
$index = $index - 1;
if ( isset( $group['items_ids'][$index] ) ) {
return new \WP_REST_Response( $group['items_ids'][$index], 200 );
}
} elseif (
is_array($group) &&
isset($group['collection_id']) &&
isset($group['query']) &&
is_array($group['query'])
) {
$group['query']['paged'] = $index;
$group['query']['posts_per_page'] = 1;
$items = $this->items_repository->fetch_ids( $group['query'], $group['collection_id'] );
if ( is_array($items) && !empty($items) ) {
return new \WP_REST_Response( $items[0], 200 );
}
}
}
return new \WP_REST_Response([
'error_message' => __('Item not found.', 'tainacan'),
], 404);
}
/**
* @param null $object_name
*
* @return array|void
*/
public function get_create_params($object_name = null) {
$query_params['items_ids'] = [
'type' => 'array',
'items' => ['type' => 'integer'],
'description' => __( 'Array of items IDs', 'tainacan' ),
];
$query_params['use_query'] = [
'description' => __( 'The query used to define the items in the group', 'tainacan' ),
];
return $query_params;
}
}
?>

View File

@ -22,6 +22,7 @@ $rest_roles_controller = new \Tainacan\API\EndPoints\REST_Roles_Controller();
new \Tainacan\API\EndPoints\REST_Metadatum_Mappers_Controller();
$rest_facets_controller = new \Tainacan\API\EndPoints\REST_Facets_Controller();
$rest_oaipmh_expose_controller = new \Tainacan\API\EndPoints\REST_Oaipmh_Expose_Controller();
$rest_sequence_edit_controller = new \Tainacan\API\EndPoints\REST_Sequence_Edit_Controller();
// Add here other endpoints imports
?>

View File

@ -1,4 +1,11 @@
<?php
/**
* This is the old Bulk Edit approach that performs SQL queries directly into the database
* It was disabled in favor of Bulk edit BG process approach
*
* Its is still here because there is an idea to use it via WP CLI command
* If we do this someday, there are also tests written in __test-bulk-edit.php file
*/
namespace Tainacan;
use Tainacan\Repositories;
@ -9,10 +16,10 @@ defined( 'ABSPATH' ) || exit;
/**
* Bulk_Edit class handles bulk item edition
*/
class Bulk_Edit {
class __Bulk_Edit {
private $meta_key = '_tnc_bulk';
/**
* The ID of the current bulk edition group.
* @var string
@ -49,82 +56,84 @@ class Bulk_Edit {
* @throws \Exception
*/
public function __construct($params) {
throw new \Exception('This Class is currently disabled');
if (isset($params['id']) && !empty($params['id'])) {
$this->id = $params['id'];
return;
}
global $wpdb;
$id = uniqid();
$this->id = $id;
if (isset($params['query']) && is_array($params['query'])) {
if (!isset($params['collection_id']) || !is_numeric($params['collection_id'])) {
throw new \Exception('Collection ID must be informed when creating a group via query');
}
/**
* Here we use the fetch method to parse the parameter and use WP_Query
*
* However, we add a filter so the query is not executed. We just want WP_Query to build it for us
* and then we can use it to INSERT the postmeta with the bulk group ID
*/
// this avoids wp_query to run the query. We just want to build the query
add_filter('posts_pre_query', '__return_empty_array');
// this adds the meta key and meta value to the SELECT query so it can be used directly in the INSERT below
add_filter('posts_fields_request', [$this, 'add_fields_to_query'], 10, 2);
$itemsRepo = Repositories\Items::get_instance();
$params['query']['fields'] = 'ids';
$items_query = $itemsRepo->fetch($params['query'], $params['collection_id']);
remove_filter('posts_pre_query', '__return_empty_array');
remove_filter('posts_fields_request', [$this, 'add_fields_to_query']);
$wpdb->query( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) {$items_query->request}" );
$bulk_params = [
'orderby' => isset($params['query']['orderby']) ? $params['query']['orderby'] : 'post_date',
'order' => isset($params['query']['order']) ? $params['query']['order'] : 'DESC'
];
} elseif (isset($params['items_ids']) && is_array($params['items_ids'])) {
$items_ids = array_filter($params['items_ids'], 'is_integer');
$insert_q = '';
foreach ($items_ids as $item_id) {
$insert_q .= $wpdb->prepare( "(%d, %s, %s),", $item_id, $this->meta_key, $this->get_id() );
}
$insert_q = rtrim($insert_q, ',');
$wpdb->query( "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) VALUES $insert_q" );
$bulk_params = [
'orderby' => isset($params['options']['orderby']) ? $params['options']['orderby'] : 'post_date',
'order' => isset($params['options']['order']) ? $params['options']['order'] : 'DESC'
];
}
/**
* This is stored to be used by the get_sequence_item_by_index() method, which is used
* This is stored to be used by the get_sequence_item_by_index() method, which is used
* by the sequence edit routine.
*
* For everything else, the order does not matter...
*/
$this->save_options($bulk_params);
return;
}
/**
* Internally used to filter WP_Query and build the INSERT statement.
* Internally used to filter WP_Query and build the INSERT statement.
* Must be public because it is registered as a filter callback
*/
public function add_fields_to_query($fields, $wp_query) {
@ -134,7 +143,7 @@ class Bulk_Edit {
}
return $fields;
}
/**
* Get the current group ID
* @return string the group ID
@ -142,7 +151,7 @@ class Bulk_Edit {
public function get_id() {
return $this->id;
}
/**
* return the number of items selected in the current bulk group
* @return int number of items in the group
@ -155,19 +164,19 @@ class Bulk_Edit {
}
return 0;
}
/**
* Gets the id of the item in a given position inside the group
*
* @param int $index THe position of the index to search for. From 1 to the length of the group
* Gets the id of the item in a given position inside the group
*
* @param int $index THe position of the index to search for. From 1 to the length of the group
* @return int|bool Returns the ID of the item or false if the index is out of range
*/
public function get_item_id_by_index($index) {
if (!is_int($index)) {
throw new InvalidArgumentException('get_item_id_by_index function only accepts integers. Input was: '.$index);
}
$options = $this->get_options();
$query = [
'meta_query' => [
@ -184,20 +193,20 @@ class Bulk_Edit {
'order' => $options['order'],
'post_status' => 'any'
];
$object = new \WP_Query($query);
if ( $object->have_posts() && isset($object->posts) && is_array($object->posts) && isset($object->posts[0]) && is_integer($object->posts[0]) ) {
return $object->posts[0];
}
return false;
}
public function save_options($value) {
update_option('tainacan_bulk_' . $this->get_id(), $value);
}
public function get_options() {
return get_option('tainacan_bulk_' . $this->get_id());
}
@ -208,17 +217,17 @@ class Bulk_Edit {
return $wpdb->prepare( "SELECT $fields FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $this->meta_key, $this->get_id() );
}
/**
* Sets the status to all items in the current group
*
*
*/
public function set_status($value) {
if (!$this->get_id()) {
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
$possible_values = ['trash', 'draft', 'publish', 'private'];
// Specific validation
@ -229,15 +238,15 @@ class Bulk_Edit {
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
$query = $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s WHERE ID IN ($select_q)", $value);
$run = $wpdb->query($query);
if ($run) {
do_action('tainacan-bulk-edit-set-status', $value, $this->get_id(), $select_q, $query);
}
return $run;
}
@ -245,7 +254,7 @@ class Bulk_Edit {
/**
* Adds a value to a metadatum to all items in the current group
* Must be used with a multiple metadatum
*
*
*/
public function add_value(Entities\Metadatum $metadatum, $value) {
@ -277,7 +286,7 @@ class Bulk_Edit {
/**
* Sets a value to a metadatum to all items in the current group.
*
*
* If metadatum is multiple, it will delete all values item may have for this metadatum and then add
* this value
*/
@ -288,7 +297,7 @@ class Bulk_Edit {
}
// Specific validation
if ($metadatum->is_collection_key()) {
return new \WP_Error( 'invalid_action', __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
}
@ -313,9 +322,9 @@ class Bulk_Edit {
/**
* Removes one value from a metadatum of all items in current group
*
*
* Must be used with multiple metadatum that are not set as required
*
*
*/
public function remove_value(Entities\Metadatum $metadatum, $value) {
@ -324,7 +333,7 @@ class Bulk_Edit {
}
// Specific validation
if ($metadatum->is_required()) {
return new \WP_Error( 'invalid_action', __( 'Unable to remove a value from a required metadatum', 'tainacan' ) );
}
@ -347,11 +356,11 @@ class Bulk_Edit {
}
// Specific validation
if ($metadatum->is_collection_key()) {
return new \WP_Error( 'invalid_action', __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
}
if ($new_value == $old_value) {
return new \WP_Error( 'invalid_action', __( 'Old value and new value can not be the same', 'tainacan' ) );
}
@ -378,7 +387,7 @@ class Bulk_Edit {
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
$select_insert = "SELECT ID, '_wp_trash_meta_status', post_status FROM $wpdb->posts WHERE ID IN ($select_q)";
$select_insert_time = $wpdb->prepare("SELECT ID, '_wp_trash_meta_time', %s FROM $wpdb->posts WHERE ID IN ($select_q)", time());
@ -388,7 +397,7 @@ class Bulk_Edit {
$wpdb->query($query_original_status);
$wpdb->query($query_trash_time);
$query = "UPDATE $wpdb->posts SET post_status = 'trash' WHERE ID IN ($select_q)";
// TODO trash comments?
@ -442,7 +451,7 @@ class Bulk_Edit {
/**
* Adds a value to the current group of items
*
*
* This method adds value to the database directly, any check or validation must be done beforehand
*/
private function _add_value(Entities\Metadatum $metadatum, $value) {
@ -461,9 +470,9 @@ class Bulk_Edit {
if ( !is_array($value) ) {
$value = [$value];
}
foreach ($value as $v) {
$term = $taxRepo->term_exists($tax, $v, 0, true);
$term_id = false;
@ -477,19 +486,19 @@ class Bulk_Edit {
$term_id = $term->term_taxonomy_id;
}
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $term_id) );
$query = "INSERT IGNORE INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q";
$return = $wpdb->query($query);
}
return $return;
//TODO update term count
@ -499,13 +508,13 @@ class Bulk_Edit {
} else {
global $wpdb;
if ( !is_array($value) ) {
$value = [$value];
}
foreach ($value as $v) {
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %s, %s", $metadatum->get_id(), $v) );
$query = "INSERT IGNORE INTO $wpdb->postmeta (post_id, meta_key, meta_value) $insert_q";
@ -526,11 +535,11 @@ class Bulk_Edit {
}
$return = $affected;
}
return $return; // return last value
}
@ -538,7 +547,7 @@ class Bulk_Edit {
/**
* Removes a value from the current group of items
*
*
* This method removes value from the database directly, any check or validation must be done beforehand
*/
private function _remove_value(Entities\Metadatum $metadatum, $value) {
@ -587,24 +596,24 @@ class Bulk_Edit {
}
}
/**
* Replaces a value in the current group of items
*
*
* This method replaces a value from the database directly, and adds a new value to all itemsm that had the previous value
*
* TODO: Possible refactor: This method is almost identical to the _add_value method and calls the _remove_value at the end. So it is almost
* TODO: Possible refactor: This method is almost identical to the _add_value method and calls the _remove_value at the end. So it is almost
* the same thing as calling _add_value() and _remove_value() one after another. The only difference is that it does both checks before doing anything to the DB
* and a small change to the insert queries (marked below)
*
*
*/
private function _replace_value(Entities\Metadatum $metadatum, $newvalue, $value) {
global $wpdb;
if ($value == $newvalue) {
return new \WP_Error( 'error', __( 'New value and old value can not be the same', 'tainacan' ) );
}
$taxRepo = Repositories\Taxonomies::get_instance();
$type = $metadatum->get_metadata_type_object();
@ -626,10 +635,10 @@ class Bulk_Edit {
if (is_WP_Error($term) || !isset($term->term_taxonomy_id)) {
return new \WP_Error( 'error', __( 'Term not found', 'tainacan' ) );
}
// check new term
$newterm = $taxRepo->term_exists($tax, $newvalue, 0, true);
if (false === $newterm) {
$newterm = wp_insert_term($newvalue, $tax->get_db_identifier());
@ -641,21 +650,21 @@ class Bulk_Edit {
$newtermid = $newterm->term_taxonomy_id;
}
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $newtermid) );
// only where old_value is present (this is what this method have different from the _add_value())
$insert_q .= $wpdb->prepare( " AND post_id IN(SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = %d)", $term->term_taxonomy_id );
$query = "INSERT IGNORE INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q ";
// Add
$wpdb->query($query);
// Remove
return $this->_remove_value($metadatum, $value);
//TODO update term count
}
@ -665,7 +674,7 @@ class Bulk_Edit {
global $wpdb;
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %s, %s", $metadatum->get_id(), $newvalue) );
// only where old_value is present (this is what this method have different from the _add_value())
$insert_q .= $wpdb->prepare( " AND post_id IN (SELECT post_ID FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s)", $metadatum->get_id(), $value );
@ -680,7 +689,7 @@ class Bulk_Edit {
'description' => 'post_content'
];
$column = $map_field[$field];
$update_q = $this->_build_select( "post_id" );
$update_q = $this->_build_select( "post_id" );
// only where old_value is present (this is what this method have different from the _add_value())
$update_q .= $wpdb->prepare( " AND post_id IN (SELECT post_ID FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s)", $metadatum->get_id(), $value );
@ -697,7 +706,7 @@ class Bulk_Edit {
/**
* Removes all values of a metadatum from the current group of items
*
*
* This method removes value from the database directly, any check or validation must be done beforehand
*/
private function _remove_values(Entities\Metadatum $metadatum) {
@ -737,7 +746,7 @@ class Bulk_Edit {
}
}
}
}

View File

@ -5,14 +5,405 @@ use Tainacan\Entities;
class Bulk_Edit_Process extends Generic_Process {
public function __construct($id) {
parent::__construct();
$this->id = $id;
private $meta_key = '_tnc_bulk';
private $group_id = false;
public function __construct($attributes = array()) {
$this->array_attributes = array_merge($this->array_attributes, [
'group_id',
'bulk_edit_data'
]);
parent::__construct($attributes);
$this->init_objects();
}
public function main_process() {
$this->add_log("log");
public function init_objects() {
$this->items_repository = \Tainacan\Repositories\Items::get_instance();
$this->metadatum_repository = \Tainacan\Repositories\Metadata::get_instance();
$this->item_metadata_repository = \Tainacan\Repositories\Item_Metadata::get_instance();
$this->steps = [
[
'name' => __('Bulk edit control metadada', 'tainacan'),
'progress_label' => __('Creating bulk edit control metadada', 'tainacan'),
'callback' => 'add_control_metadata'
],[
'name' => __('Bulk edit', 'tainacan'),
'progress_label' => __('Running bulk edit', 'tainacan'),
'callback' => 'main_process',
'total' => $this->get_total_items()
]
];
}
public function create_bulk_edit($params) {
if ( isset($params['group_id']) && !empty($params['group_id']) ) {
$this->set_group_id($params['group_id']);
return;
}
if (!isset($params['collection_id']) || !is_numeric($params['collection_id'])) {
throw new \Exception('Collection ID must be informed when creating a group.');
}
$this->set_group_id(uniqid());
if (isset($params['query']) && is_array($params['query'])) {
$bulk_params = [
'collection_id' => $params['collection_id'],
'query' => $params['query'],
'order' => isset($params['query']['order']) ? $params['query']['order'] : 'DESC',
'orderby' => isset($params['query']['orderby']) ? $params['query']['orderby'] : 'post_date'
];
} elseif (isset($params['items_ids']) && is_array($params['items_ids'])) {
$items_ids = array_filter($params['items_ids'], 'is_integer');
$bulk_params = [
'collection_id' => $params['collection_id'],
'items_ids' => $items_ids,
'order' => isset($params['options']['order']) ? $params['options']['order'] : 'DESC',
'orderby' => isset($params['options']['orderby']) ? $params['options']['orderby'] : 'post_date'
];
}
$this->save_options($bulk_params);
return;
}
public function save_options($value) {
update_option('tainacan_bulk_' . $this->get_group_id(), $value);
}
public function get_options() {
return get_option('tainacan_bulk_' . $this->get_group_id());
}
public function set_group_id($group_id) {
$this->group_id = $group_id;
}
public function get_group_id( ) {
return $this->group_id;
}
public function get_output() {
$message = __('Bulk edit finished', 'tainacan');
return $message;
}
public function set_bulk_edit_data($bulk_edit_data = false) {
$this->bulk_edit_data = $bulk_edit_data;
}
public function get_bulk_edit_data() {
return $this->bulk_edit_data;
}
private function bulk_list_remove_item($item) {
return delete_post_meta( $item->get_id(), $this->meta_key, $this->get_group_id());
}
public function add_control_metadata() {
$params = $this->get_options();
if( !isset($params['control_metadata']) ) {
$params['control_metadata'] = $this->get_id();
$this->save_options($params);
} elseif ($params['control_metadata'] === true) {
$this->add_log( __('bulk edit control metadata has already been created', 'tainacan') );
return false;
} elseif( is_numeric($params['control_metadata']) && $params['control_metadata'] != $this->get_id() ) {
$this->add_log( sprintf( __( 'waiting creating bulk edit control metadata by process ID: "%d"', 'tainacan' ), $params['control_metadata'] ) );
return true;
}
if (isset($params['query']) && is_array($params['query'])) {
$itemsRepo = \Tainacan\Repositories\Items::get_instance();
$count = $this->get_in_step_count();
$post_per_page = 1;
if ( isset($params['query']['posts_per_page']) && $params['query']['posts_per_page'] != -1 ) {
$post_per_page = $params['query']['posts_per_page'] - $count;
$params['query']['posts_per_page'] = $post_per_page;
}
if($post_per_page <= 0) {
return false;
}
$query = $params['query'];
$query['fields'] = 'ids';
$query['posts_per_page'] = $post_per_page;
$query['offset'] = $count++;
$query['nopaging'] = false;
$item_query = $itemsRepo->fetch($query, $params['collection_id']);
if(!$item_query->have_posts() ) {
$params['control_metadata'] = true;
$this->save_options($params);
$this->add_log( __('bulk edit control metadata created', 'tainacan') );
return false;
}
$item_id = $item_query->get_posts()[0];
$this->add_log( sprintf( __( 'creating bulk edit control metadata for item: "%d"', 'tainacan' ), $item_id ) );
add_post_meta($item_id, $this->meta_key, $this->get_group_id());
return $count;
} elseif (isset($params['items_ids']) && is_array($params['items_ids'])) {
$items_ids = array_filter($params['items_ids'], 'is_integer');
$count = $this->get_in_step_count();
if( isset($items_ids[$count]) ) {
$this->add_log( sprintf( __( 'creating bulk edit control metadata for item: "%d"', 'tainacan' ), $items_ids[$count] ) );
add_post_meta($items_ids[$count++], $this->meta_key, $this->get_group_id());
return $count;
} else {
$params['control_metadata'] = true;
$this->save_options($params);
$this->add_log( __('bulk edit control metadata created', 'tainacan') );
return false;
}
}
$this->add_error_log(__('wrong parameter on add bulk edit control metadata', 'tainacan'));
$this->abort();
return false;
}
}
private function get_total_items() {
if (!$this->get_group_id()) return 0;
$args = [
'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash'),
'meta_query' => array(
array(
'key' => $this->meta_key,
'value' => $this->get_group_id(),
'compare' => '=',
)
)
];
$item = $this->items_repository->fetch($args, [], 'WP_Query');
return intval($item->found_posts);
}
private function bulk_list_get_item($count) {
$args = [
'perpage' => 1,
'offset' => $count,
'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash'),
'meta_query' => array(
array(
'key' => $this->meta_key,
'value' => $this->get_group_id(),
'compare' => '=',
)
)
];
$item = $this->items_repository->fetch($args, [], 'WP_Query');
$this->set_current_step_total($item->found_posts);
if ($item->have_posts()) {
$item->the_post();
$item = new \Tainacan\Entities\Item($item->post);
return $item;
}
return false;
}
public function main_process() {
$method = $this->bulk_edit_data['method'];
if ( !method_exists($this, $method) ) {
$this->add_error_log(__('method not exists', 'tainacan'));
$this->abort();
return false;
}
$count = $this->get_in_step_count();
$item = $this->bulk_list_get_item($count++);
if($item == false) {
return false;
}
$this->add_log( sprintf( __('bulk edit has process the item ID: "%d"', 'tainacan'), $item->get_id() ) );
$add_steps = $this->$method($item);
if ( is_int($add_steps) ) {
$count = $count + $add_steps;
}
return $count;
}
private function save_item_metadata(\Tainacan\Entities\Item_Metadata_Entity $item_metadata, \Tainacan\Entities\Item $item) {
if ( $item_metadata->validate() ) {
if( $item->can_edit() ) {
$updated_item_metadata = $this->item_metadata_repository->update( $item_metadata );
} else {
$this->add_error_log( sprintf( __('do not have permission to edit item ID: "%d"', 'tainacan'), $item->get_id() ) );
return false;
}
} else {
$this->add_error_log( sprintf( __( 'Please verify, invalid value(s) to edit item ID: "%d"', 'tainacan' ), $item->get_id() ) );
$serealize_erro = (object) array('err' => array());
$erro = $item_metadata->get_errors();
array_walk_recursive($erro, function($v, $k, &$t) {$t->err[] = $v;}, $serealize_erro);
$this->add_error_log( __('errors: ', 'tainacan') . implode(", ", $serealize_erro->err) );
return false;
}
return true;
}
private function set_value(\Tainacan\Entities\Item $item) {
$metadatum = $this->metadatum_repository->fetch($this->bulk_edit_data['metadatum_id']);
$value = $this->bulk_edit_data['value'];
$item_metadata = new Entities\Item_Metadata_Entity( $item, $metadatum );
if($item_metadata->is_multiple()) {
$value = is_array( $value ) ? $value : [$value];
$item_metadata->set_value( $value );
} else {
$item_metadata->set_value($value);
}
return $this->save_item_metadata($item_metadata, $item);
}
private function add_value(\Tainacan\Entities\Item $item) {
$metadatum_id = $this->bulk_edit_data['metadatum_id'];
$metadatum = $this->metadatum_repository->fetch($metadatum_id);
$value = $this->bulk_edit_data['value'];
if (!$metadatum->is_multiple()) {
$this->add_error_log( __( 'Unable to add a value to a metadata if it does not accept multiple values', 'tainacan' ) );
return false;
}
if ($metadatum->is_collection_key()) {
$this->add_error_log( __( 'Unable to add a value to a metadata set to be a collection key', 'tainacan' ) );
return false;
}
$items_metadata = $item->get_metadata();
foreach ($items_metadata as $item_metadata) {
$metadatum = $item_metadata->get_metadatum();
if($metadatum->get_id() == $metadatum_id) {
$values = is_array($item_metadata->get_value()) ? $item_metadata->get_value() : [$item_metadata->get_value()];
$values = array_merge($values, [$value]);
$item_metadata->set_value( $values );
return $this->save_item_metadata($item_metadata, $item);
}
}
return false;
}
private function remove_value(\Tainacan\Entities\Item $item) {
$metadatum_id = $this->bulk_edit_data['metadatum_id'];
$metadatum = $this->metadatum_repository->fetch($metadatum_id);
$value = $this->bulk_edit_data['value'];
if ($metadatum->is_required()) {
$this->add_error_log( __( 'Unable to remove a value from a required metadatum', 'tainacan' ) );
return false;
}
if (!$metadatum->is_multiple()) {
$this->add_error_log( __( 'Unable to remove a value from a metadata if it does not accept multiple values', 'tainacan' ) );
return false;
}
$items_metadata = $item->get_metadata();
foreach ($items_metadata as $item_metadata) {
$metadatum = $item_metadata->get_metadatum();
if($metadatum->get_id() == $metadatum_id) {
$values = is_array($item_metadata->get_value()) ? $item_metadata->get_value() : [$item_metadata->get_value()];
$pos = array_search($value, $values);
unset($values[$pos]);
$item_metadata->set_value( $values );
return $this->save_item_metadata($item_metadata, $item);
}
}
return false;
}
private function replace_value(\Tainacan\Entities\Item $item) {
$metadatum_id = $this->bulk_edit_data['metadatum_id'];
$metadatum = $this->metadatum_repository->fetch($metadatum_id);
$old_value = $this->bulk_edit_data['old_value'];
$new_value = $this->bulk_edit_data['value'];
if ($metadatum->is_collection_key()) {
$this->add_error_log( __( 'Unable to set a value to a metadata set to be a collection key', 'tainacan' ) );
return false;
}
if ($new_value == $old_value) {
$this->add_error_log( __( 'Old value and new value can not be the same', 'tainacan' ) );
return false;
}
$items_metadata = $item->get_metadata();
foreach ($items_metadata as $item_metadata) {
$metadatum = $item_metadata->get_metadatum();
if($metadatum->get_id() == $metadatum_id) {
$values = is_array($item_metadata->get_value()) ? $item_metadata->get_value() : [$item_metadata->get_value()];
$pos = array_search($old_value, $values);
if ($pos !== false) {
$values[$pos] = $new_value;
$item_metadata->set_value( $metadatum->is_multiple() ? $values : $values[$pos] );
return $this->save_item_metadata($item_metadata, $item);
}
return false;
}
}
return false;
}
private function trash_items(\Tainacan\Entities\Item $item) {
if ( !$this->items_repository->trash($item) ) {
$this->add_error_log( sprintf( __('error on send to trash, item ID: "%d"', 'tainacan'), $item->get_id() ) );
return false;
}
return true;
}
private function untrash_items(\Tainacan\Entities\Item $item) {
if ( !wp_untrash_post( $item->get_id() ) ) {
$this->add_error_log( sprintf( __('error on untrash, item ID: "%d"', 'tainacan'), $item->get_id() ) );
return false;
}
return true;
}
private function delete_items(\Tainacan\Entities\Item $item) {
if ('trash' != $item->get_status() ) {
$this->add_error_log( sprintf( __('Items must be on trash to be deleted, item ID: "%d"', 'tainacan'), $item->get_id() ) );
return false;
}
if ( !$this->items_repository->delete($item) ) {
$this->add_error_log( sprintf( __('error on send to trash, item ID: "%d"', 'tainacan'), $item->get_id() ) );
return false;
}
return -1;
}
private function set_status(\Tainacan\Entities\Item $item) {
$value = $this->bulk_edit_data['value'];
$possible_values = ['trash', 'draft', 'publish', 'private'];
if (!in_array($value, $possible_values)) {
$this->add_error_log( __( 'Invalid status', 'tainacan' ) );
return false;
}
$item->set("status", $value);
if($item->validate()) {
$this->items_repository->update($item);
return true;
}
$this->add_error_log( sprintf( __( 'Please verify, invalid value(s) to edit item ID: "%d"', 'tainacan' ), $item->get_id() ) );
$serealize_erro = (object) array('err' => array());
array_walk_recursive($item->get_errors(), create_function('&$v, $k, &$t', '$t->err[] = $v;'), $serealize_erro);
$this->add_error_log( __('errors: ', 'tainacan') . implode(", ", $serealize_erro->err) );
return false;
}
}

View File

@ -34,12 +34,12 @@ class Generic_Process_Handler {
return true;
}
function add_to_queue(\Tainacan\process\process $process_object) {
function add_to_queue(\Tainacan\GenericBackgroundProcess\Generic_Process $process_object) {
$data = $process_object->_to_Array(true);
$process = $this->get_process_by_object($process_object);
$process = $this->get_generic_process_by_object($process_object);
$process_name = sprintf( __('%s process', 'tainacan'), $process['name'] );
$bg_process = $this->bg_process->data($data)->set_name($process_name)->save();
if ( is_wp_error($bg_process->dispatch()) ) {
return false;
@ -63,13 +63,22 @@ class Generic_Process_Handler {
return null;
}
public function initialize_generic_process($slug, $id = null) {
public function get_generic_process_by_object(\Tainacan\GenericBackgroundProcess\Generic_Process $process_object) {
$class_name = get_class($process_object);
$class_name = '\\' . $class_name;
$generic_process = $this->get_registered_generic_process();
foreach ($generic_process as $process) {
if ($process['class_name'] == $class_name)
return $process;
}
return null;
}
public function initialize_generic_process($slug) {
$process = $this->get_generic_process($slug);
if ( is_array($process) && isset($process['class_name']) && class_exists($process['class_name']) ) {
if ($id == null)
return new $process['class_name']();
else
return new $process['class_name']($id);
$prc = new $process['class_name']();
return $prc;
}
return false;
}

View File

@ -5,12 +5,20 @@ use Tainacan\Entities;
abstract class Generic_Process {
public function __construct( ) {
public function __construct( $attributess = array() ) {
$this->id = uniqid();
$author = get_current_user_id();
if($author) {
$this->add_transient('author', $author);
}
if (!empty($attributess)) {
foreach ($attributess as $attr => $value) {
$method = 'set_' . $attr;
if (method_exists($this, $method)) {
$this->$method($value);
}
}
}
}
/**
@ -66,7 +74,7 @@ abstract class Generic_Process {
/**
* List of attributes that are saved in DB and that are used to
* reconstruct the object, this property need be overwrite in custom import/export.
* reconstruct the object, this property need be overwrite.
* @var array
*/
protected $array_attributes = [
@ -271,8 +279,8 @@ abstract class Generic_Process {
$current_step = $this->get_current_step();
$steps = $this->get_steps();
$current_step ++;
$this->set_current_step($current_step);
if (isset($steps[$current_step])) {
$this->set_current_step($current_step);
return $current_step;
}
return false;
@ -295,6 +303,10 @@ abstract class Generic_Process {
return $return;
}
public function finished() {
$this->add_log('finished');
}
/**
* runs one iteration
*/
@ -319,7 +331,7 @@ abstract class Generic_Process {
//Move on to the next step
$this->set_in_step_count(0);
$return = $this->next_step();
} else if(is_numeric($result) && $result > 0) {
} else if(is_numeric($result) && $result >= 0) {
$this->set_in_step_count($result);
$return = $result;
}

View File

@ -50,6 +50,21 @@ export const fetchGroup = ({commit}, { collectionId, groupId }) => {
});
};
export const fetchSequenceGroup = ({commit}, { collectionId, groupId }) => {
return new Promise ((resolve, reject) => {
axios.tainacan.get(`/collection/${collectionId}/sequence-edit/${groupId}`)
.then(response => {
commit('setGroup', response.data);
resolve(response.data);
})
.catch(error => {
console.log(error);
reject(error);
});
});
};
export const setValueInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
@ -61,13 +76,11 @@ export const setValueInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/set`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
commit('setLastUpdated');
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
@ -82,12 +95,10 @@ export const addValueInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/add`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
@ -101,12 +112,8 @@ export const removeValueInBulk = ({commit}, parameters) => {
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/remove`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
@ -121,12 +128,10 @@ export const replaceValueInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/replace`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
@ -142,13 +147,11 @@ export const setStatusInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/set_status`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
commit('setLastUpdated');
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
@ -158,13 +161,11 @@ export const trashItemsInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/trash`)
.then(response => {
commit('setActionResult', response.data);
commit('setLastUpdated');
return response;
})
.catch(error => {
console.log(error);
commit('setActionResult', error.response.data);
});
};
@ -174,12 +175,10 @@ export const untrashItemsInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/untrash`)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.log(error);
commit('setActionResult', error.response.data)
});
};
@ -189,13 +188,11 @@ export const deleteItemsInBulk = ({commit}, parameters) => {
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/delete_items`)
.then(response => {
commit('setActionResult', response.data);
commit('setLastUpdated');
return response;
})
.catch(error => {
console.log(error);
commit('setActionResult', error.response.data);
});
};
@ -203,7 +200,7 @@ export const deleteItemsInBulk = ({commit}, parameters) => {
export const fetchItemIdInSequence = ({commit}, { collectionId, sequenceId, itemPosition }) => {
return new Promise ((resolve, reject) => {
axios.tainacan.get(`/collection/${collectionId}/bulk-edit/${sequenceId}/sequence/${itemPosition}`)
axios.tainacan.get(`/collection/${collectionId}/sequence-edit/${sequenceId}/${itemPosition}`)
.then(response => {
commit('setItemIdInSequence', response.data);
resolve(response.data);
@ -215,7 +212,32 @@ export const fetchItemIdInSequence = ({commit}, { collectionId, sequenceId, item
});
};
// BULK ADD SPECIFIC
export const setBulkAddItems = ({commit}, items) => {
commit('setBulkAddItems', items);
};
export const createSequenceEditGroup = ({commit}, parameters) => {
let object = parameters.object;
let collectionID = parameters.collectionID;
let sequenceEditParams = null;
if(object.constructor.name === 'Array'){
sequenceEditParams = {
items_ids: object,
};
} else if(object.constructor.name === 'Object'){
sequenceEditParams = {
use_query: object,
};
}
return new Promise ((resolve, reject) => {
axios.tainacan.post(`/collection/${collectionID}/sequence-edit`, sequenceEditParams)
.then(response => {
commit('setGroup', response.data);
resolve(response.data);
})
.catch(error => {
console.error(error);
reject(error);
});
});
};

View File

@ -6,18 +6,10 @@ export const getGroup = state => {
return state.group;
};
export const getActionResult = state => {
return state.actionResult;
};
export const getItemIdInSequence = state => {
return state.itemIdInSequence;
};
export const getLastUpdated = state => {
return state.lastUpdated;
}
export const getBulkAddItems = state => {
return state.bulkAddItems;
}

View File

@ -4,10 +4,8 @@ import * as getters from './getters.js'
const state = {
group: null,
actionResult: null,
itemIdInSequence: null,
lastUpdated: '',
bulkAddItems: []
lastUpdated: ''
};
export default {

View File

@ -2,10 +2,6 @@ export const setGroup = (state, group) => {
state.group = group;
};
export const setActionResult = (state, actionResult) => {
state.actionResult = actionResult;
};
export const setItemIdInSequence = (state, itemIdInSequence) => {
state.itemIdInSequence = itemIdInSequence;
};
@ -17,8 +13,4 @@ export const setLastUpdated = (state, value) => {
let now = new Date();
state.lastUpdated = now.toLocaleString();
}
}
export const setBulkAddItems = (state, items) => {
return state.bulkAddItems = items;
}

View File

@ -3,7 +3,10 @@
namespace Tainacan\Tests;
/**
* Class TestCollections
* Class BulkEdit
*
* These are the tests for the old Bulk edit class that has been disabled
* More info in src/classes/class-tainacan-bulk-edit.php
*
* @package Test_Tainacan
*/
@ -28,7 +31,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
true
);
$this->collection = $collection;
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
@ -39,7 +42,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
),
true
);
$this->metadatum = $metadatum;
$multiple_meta = $this->tainacan_entity_factory->create_entity(
@ -54,7 +57,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
),
true
);
$this->multiple_meta = $multiple_meta;
$taxonomy = $this->tainacan_entity_factory->create_entity(
@ -67,7 +70,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
),
true
);
$this->taxonomy = $taxonomy;
$category = $this->tainacan_entity_factory->create_entity(
@ -85,13 +88,13 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
),
true
);
$this->category = $category;
for ($i = 1; $i<=40; $i++) {
$title = 'testeItem ' . str_pad($i, 2, "0", STR_PAD_LEFT);
$title = 'testeItem ' . str_pad($i, 2, "0", STR_PAD_LEFT);
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
@ -101,26 +104,26 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
),
true
);
$this->items_ids[] = $item->get_id();
$this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum, $i % 2 == 0 ? 'even' : 'odd');
$this->tainacan_item_metadata_factory->create_item_metadata($item, $category, ['good', 'bad']);
$this->tainacan_item_metadata_factory->create_item_metadata($item, $collection->get_core_title_metadatum(), $title);
}
$this->api_baseroute = $this->namespace . '/collection/' . $collection->get_id() . '/bulk-edit';
}
function test_setup() {
$this->assertEquals(40, sizeof($this->items_ids));
}
function test_init_by_query() {
$query = [
'meta_query' => [
[
@ -130,45 +133,45 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$this->assertEquals(20, $bulk->count_posts());
}
function test_init_by_ids() {
$ids = array_slice($this->items_ids, 2, 7);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$this->assertEquals(7, $bulk->count_posts());
}
function test_init_by_bulk_id() {
$ids = array_slice($this->items_ids, 4, 11);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$id = $bulk->get_id();
$newBulk = new \Tainacan\Bulk_Edit([
'id' => $id,
]);
$this->assertEquals(11, $newBulk->count_posts());
}
function test_add() {
@ -184,7 +187,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -193,7 +196,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$bulk->add_value($this->category, 'test');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
@ -282,14 +285,14 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$bulk->remove_value($this->category, 'good');
@ -331,7 +334,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
'items_ids' => $this->items_ids,
]);
$bulk->add_value($this->multiple_meta, 'test'); // for everyone
@ -344,7 +347,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -381,7 +384,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -390,7 +393,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$bulk->replace_value($this->category, 'awesome', 'good');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
@ -444,7 +447,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => 5
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -480,13 +483,13 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(15, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_only_when_search_is_present_tax() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$query = [
'meta_query' => [
[
@ -496,19 +499,19 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
// add test to 20 items
$bulk->add_value($this->category, 'test');
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->replace_value($this->category, 'super', 'test');
// should add super only to the 20 items that had test
@ -538,20 +541,20 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
]);
$this->assertEquals(0, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_only_when_search_is_present() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
// all items
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->replace_value($this->metadatum, 'super', 'even');
// should add super only to the 20 items that had even
@ -581,23 +584,23 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(0, $items->found_posts);
}
/**
* @group replace
*/
function test_replace_core_metadatum() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
// all items
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$core_title = $this->collection->get_core_title_metadatum();
// all items selected, search and replace the value of one
$bulk->replace_value($core_title, 'super_test', 'testeItem 22');
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
@ -609,11 +612,11 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
]);
$this->assertEquals(1, $items->found_posts);
$items = $Tainacan_Items->fetch(['title' => 'super_test']);
$this->assertEquals(1, $items->found_posts);
}
function test_set_tax_meta() {
@ -628,7 +631,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => 5
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -697,7 +700,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => 5
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -744,16 +747,16 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(20, $items->found_posts);
}
function test_set_status() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 4, 11);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$id = $bulk->get_id();
$bulk->set_status('draft');
@ -782,18 +785,18 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
'items_ids' => $this->items_ids,
]);
$bulk->add_value($this->multiple_meta, 'test'); // for everyone
$bulk->add_value($this->multiple_meta, 'super'); // for everyone
$ids = array_slice($this->items_ids, 2, 7);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$bulk->set_value($this->multiple_meta, 'ultra');
@ -844,7 +847,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$core_description = $this->collection->get_core_description_metadatum();
$ids = array_slice($this->items_ids, 2, 7);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
@ -892,158 +895,6 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(7, $count);
}
/**
* @group api
*/
function test_api_create_by_items_ids() {
$ids = array_slice($this->items_ids, 2, 17);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
$request->set_body( json_encode(['items_ids' => $ids]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertTrue(is_string($data['id']));
$this->assertEquals(17, $data['items_count']);
}
/**
* @group api
*/
function test_api_create_by_query() {
$query = [
'metaquery' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'odd'
]
],
'taxquery' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'good'
]
],
'perpage' => 4,
'paged' => 2
];
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
//$request->set_query_params($query);
$request->set_body( json_encode(['use_query' => $query]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertTrue(is_string($data['id']));
$this->assertEquals(20, $data['items_count']);
}
/**
* @group api
*/
public function test_api_add_action() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 14);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$body = json_encode([
'metadatum_id' => $this->multiple_meta->get_id(),
'value' => 'superduper'
]);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute . '/' . $bulk->get_id() . '/add'
);
$request->set_body( $body );
$response = $this->server->dispatch($request);
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
'key' => $this->multiple_meta->get_id(),
'value' => 'superduper'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(14, $items->found_posts);
}
/**
* @group api
*/
public function test_api_set_status() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 14);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$body = json_encode([
'value' => 'private'
]);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute . '/' . $bulk->get_id() . '/set_status'
);
$request->set_body( $body );
$response = $this->server->dispatch($request);
$items = $Tainacan_Items->fetch([
'status' => 'private',
'posts_per_page' => -1
]);
$this->assertEquals(14, $items->found_posts);
}
/**
@ -1052,12 +903,12 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
function test_trash() {
$ids = array_slice($this->items_ids, 2, 17);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$this->assertEquals( 17, $bulk->trash_items() );
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
@ -1065,10 +916,10 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$rest = $Tainacan_Items->fetch_ids(['posts_per_page' => -1]);
$this->assertEquals(17, sizeof($trashed));
$this->assertEquals(40 - 17, sizeof($rest));
}
@ -1084,21 +935,21 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
// Lets set 17 as private
$i = 1;
foreach ($items as $item) {
If ($i > 17) break;
$item->set_status('private');
$item->validate();
$Tainacan_Items->update($item);
$i++;
}
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$this->assertEquals( 40, $bulk->trash_items() ); // trash all items
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
@ -1108,7 +959,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(0, sizeof($rest));
$this->assertEquals( 40, $bulk->untrash_items() ); // untrash all items
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$private = $Tainacan_Items->fetch_ids(['post_status' => 'private', 'posts_per_page' => -1]);
$public = $Tainacan_Items->fetch_ids(['post_status' => 'publish', 'posts_per_page' => -1]);
@ -1116,7 +967,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(0, sizeof($trashed));
$this->assertEquals(17, sizeof($private));
$this->assertEquals(40 - 17, sizeof($public));
}
@ -1126,7 +977,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
function test_delete_items() {
$ids = array_slice($this->items_ids, 2, 17);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
@ -1142,10 +993,10 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$rest = $Tainacan_Items->fetch_ids(['posts_per_page' => -1]);
$this->assertEquals(0, sizeof($trashed));
$this->assertEquals(40 - 17, sizeof($rest));
}
@ -1162,7 +1013,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -1171,7 +1022,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$bulk->add_value($this->category, 'test');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
@ -1191,7 +1042,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$bulk->add_value($this->category, 'test');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
@ -1209,7 +1060,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
function test_allow_new_terms() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$taxonomy2 = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
@ -1245,7 +1096,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $taxonomy2->get_db_identifier(),
@ -1263,7 +1114,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$bulk->set_value($category2, 'test_new_value');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $taxonomy2->get_db_identifier(),
@ -1285,7 +1136,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 7);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
@ -1296,7 +1147,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
'status' => 'trash',
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -1306,131 +1157,59 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
}
/**
* @group sequence
*/
function test_get_item_in_sequence() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$query = [
'posts_per_page' => 22,
'orderby' => 'title'
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$item_id = $bulk->get_item_id_by_index(7);
$item = $Tainacan_Items->fetch($item_id);
$this->assertEquals('testeItem 34', $item->get_title());
$item_id = $bulk->get_item_id_by_index(15);
$item = $Tainacan_Items->fetch($item_id);
$this->assertEquals('testeItem 26', $item->get_title());
$query = [
'posts_per_page' => 22,
'orderby' => 'title',
'order' => 'ASC'
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$item_id = $bulk->get_item_id_by_index(19);
$item = $Tainacan_Items->fetch($item_id);
$this->assertEquals('testeItem 19', $item->get_title());
$item_id = $bulk->get_item_id_by_index(30);
$this->assertFalse($item_id);
}
/**
* @group sequence
*/
function test_api_get_item_in_sequence() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$query = [
'posts_per_page' => 22,
'orderby' => 'title',
'order' => 'ASC'
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $bulk->get_id() . '/sequence/7'
);
$response = $this->server->dispatch($request);
$id = $response->get_data();
$item = $Tainacan_Items->fetch($id);
$this->assertEquals('testeItem 07', $item->get_title());
}
function test_api_get_group() {
$query = [
'posts_per_page' => 22,
'orderby' => 'title',
'order' => 'ASC'
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $bulk->get_id()
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals($bulk->get_id(), $data['id']);
$this->assertEquals($bulk->get_options()['order'], $data['options']['order']);
$this->assertEquals($bulk->get_options()['orderby'], $data['options']['orderby']);
$this->assertEquals($bulk->count_posts(), $data['items_count']);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/fefefe23232'
);
$response = $this->server->dispatch($request);
$this->assertEquals(404, $response->get_status());
}
function test_set_multiple_tax_meta() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
@ -1443,7 +1222,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => 5
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -1495,7 +1274,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
]);
$this->assertEquals(5, $items->found_posts);
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
@ -1525,7 +1304,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
],
'posts_per_page' => 5
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
@ -1534,7 +1313,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
// single valued metadatum dont accept array
$error = $bulk->set_value($this->metadatum, ['super', 'dooper']);
$this->assertTrue(is_wp_error($error));
$bulk->set_value($this->multiple_meta, ['super', 'dooper']);
@ -1549,7 +1328,7 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
]);
$this->assertEquals(5, $items->found_posts);
$items = $Tainacan_Items->fetch([
'meta_query' => [
[
@ -1565,4 +1344,4 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
}
}
}

View File

@ -0,0 +1,206 @@
<?php
namespace Tainacan\Tests;
use Tainacan\Entities;
/**
* Sample test case.
*/
class SequenceEdit extends TAINACAN_UnitApiTestCase {
public $items_ids = [];
function setUp() {
parent::setUp();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test_col',
'status' => 'publish'
),
true
);
$this->collection = $collection;
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'metadado',
'status' => 'publish',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Text',
),
true
);
$this->metadatum = $metadatum;
for ($i = 1; $i<=40; $i++) {
$title = 'testeItem ' . str_pad($i, 2, "0", STR_PAD_LEFT);
$item = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => $title,
'collection' => $collection,
'status' => 'publish'
),
true
);
$this->items_ids[] = $item->get_id();
$this->tainacan_item_metadata_factory->create_item_metadata($item, $metadatum, $i % 2 == 0 ? 'even' : 'odd');
$this->tainacan_item_metadata_factory->create_item_metadata($item, $collection->get_core_title_metadatum(), $title);
}
$this->api_baseroute = $this->namespace . '/collection/' . $collection->get_id() . '/sequence-edit';
}
function test_setup() {
$this->assertEquals(40, sizeof($this->items_ids));
}
function test_init_by_query() {
$query = [
'metaquery' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'even'
]
],
'orderby' => 'title'
];
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
$request->set_body( json_encode(['use_query' => $query]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals(20, $data['items_count']);
$group_id = $data['id'];
$items = \Tainacan\Repositories\Items::get_instance()->fetch( [
'meta_query' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'even'
]
],
'nopaging' => 1,
'orderby' => 'post_title'
], $this->collection->get_id(), 'OBJECT');
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/1'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($items[0]->get_id(), $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/7'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($items[6]->get_id(), $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/20'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($items[19]->get_id(), $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/30'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(404, $response->get_status());
}
function test_init_by_ids() {
$ids = array_slice($this->items_ids, 2, 7);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute
);
$request->set_body( json_encode(['items_ids' => $ids]) );
$response = $this->server->dispatch($request);
$this->assertEquals(200, $response->get_status());
$data = $response->get_data();
$this->assertEquals(7, $data['items_count']);
$group_id = $data['id'];
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/1'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($ids[0], $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/3'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($ids[2], $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/6'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($ids[5], $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/7'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(200, $response->get_status());
$this->assertEquals($ids[6], $data);
$request = new \WP_REST_Request(
'GET', $this->api_baseroute . '/' . $group_id . '/8'
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(404, $response->get_status());
}
}

File diff suppressed because it is too large Load Diff