Adds pagination to attachments list. Creates separate component for it. #289
This commit is contained in:
parent
d75d30baa8
commit
4bf95048c7
|
@ -496,47 +496,28 @@
|
|||
<span>
|
||||
{{ $i18n.get('label_attachments') }}
|
||||
<span
|
||||
v-if="attachmentsList && attachmentsList.length"
|
||||
v-if="totalAttachments != null && totalAttachments != undefined"
|
||||
class="has-text-gray">
|
||||
({{ attachmentsList.length }})
|
||||
({{ totalAttachments }})
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="section-box section-attachments">
|
||||
<div v-if="item != undefined && item.id != undefined">
|
||||
<br>
|
||||
<button
|
||||
style="margin-left: calc(4.666667% + 12px)"
|
||||
type="button"
|
||||
class="button is-secondary"
|
||||
@click.prevent="attachmentMediaFrame.openFrame($event)">
|
||||
{{ $i18n.get("label_edit_attachments") }}
|
||||
</button>
|
||||
|
||||
<div class="uploaded-files">
|
||||
<div
|
||||
class="file-item-container"
|
||||
v-for="(attachment, index) in attachmentsList"
|
||||
:key="index">
|
||||
<file-item
|
||||
:style="{ margin: 15 + 'px'}"
|
||||
v-if="attachmentsList.length > 0"
|
||||
:modal-on-click="true"
|
||||
:show-name="true"
|
||||
:file="attachment"/>
|
||||
<span class="file-item-control">
|
||||
<a
|
||||
@click="deleteAttachment(attachment)"
|
||||
v-tooltip="{
|
||||
content: $i18n.get('delete'),
|
||||
autoHide: true,
|
||||
placement: 'bottom'
|
||||
}"
|
||||
class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<p v-if="attachmentsList.length <= 0"><br>{{ $i18n.get('info_no_attachments_on_item_yet') }}</p>
|
||||
</div>
|
||||
<attachments-list
|
||||
v-if="item != undefined && item.id != undefined"
|
||||
:item="item"
|
||||
:is-editable="true"
|
||||
@onDeleteAttachment="deleteAttachment($event)"/>
|
||||
</div>
|
||||
</b-tab-item>
|
||||
|
||||
|
@ -729,6 +710,7 @@ import wpMediaFrames from '../../js/wp-media-frames';
|
|||
import FileItem from '../other/file-item.vue';
|
||||
import DocumentItem from '../other/document-item.vue';
|
||||
import CustomDialog from '../other/custom-dialog.vue';
|
||||
import AttachmentsList from '../lists/attachments-list.vue';
|
||||
import { formHooks } from '../../js/mixins';
|
||||
|
||||
export default {
|
||||
|
@ -777,9 +759,6 @@ export default {
|
|||
metadatumList() {
|
||||
return JSON.parse(JSON.stringify(this.getMetadata()));
|
||||
},
|
||||
attachmentsList(){
|
||||
return this.getAttachments().filter((attachment) => attachment.id != this.item.document && attachment.id != this.form.document);
|
||||
},
|
||||
lastUpdated() {
|
||||
return this.getLastUpdated();
|
||||
},
|
||||
|
@ -788,11 +767,15 @@ export default {
|
|||
},
|
||||
itemIdInSequence() {
|
||||
return this.getItemIdInSequence();
|
||||
},
|
||||
totalAttachments() {
|
||||
return this.getTotalAttachments();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FileItem,
|
||||
DocumentItem
|
||||
DocumentItem,
|
||||
AttachmentsList
|
||||
},
|
||||
watch: {
|
||||
'$route.params.itemPosition'(newItemPosition, oldItemPosition) {
|
||||
|
@ -835,15 +818,15 @@ export default {
|
|||
'fetchItem',
|
||||
'cleanMetadata',
|
||||
'sendAttachments',
|
||||
'updateThumbnail',
|
||||
'fetchAttachments',
|
||||
'updateThumbnail',
|
||||
'cleanLastUpdated',
|
||||
'setLastUpdated',
|
||||
'removeAttachmentFromItem'
|
||||
]),
|
||||
...mapGetters('item',[
|
||||
'getMetadata',
|
||||
'getAttachments',
|
||||
'getTotalAttachments',
|
||||
'getLastUpdated'
|
||||
]),
|
||||
...mapActions('collection', [
|
||||
|
@ -945,7 +928,7 @@ export default {
|
|||
this.form.comment_status = this.item.comment_status;
|
||||
|
||||
this.loadMetadata();
|
||||
this.fetchAttachments(this.itemId);
|
||||
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId });
|
||||
|
||||
})
|
||||
.catch(error => this.$console.error(error));
|
||||
|
@ -1045,13 +1028,17 @@ export default {
|
|||
item_id: this.itemId,
|
||||
document: this.form.document,
|
||||
document_type: this.form.document_type
|
||||
}).catch((errors) => {
|
||||
for (let error of errors.errors) {
|
||||
for (let metadatum of Object.keys(error)){
|
||||
eventBus.errors.push({ metadatum_id: metadatum, errors: error[metadatum]});
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document });
|
||||
})
|
||||
.catch((errors) => {
|
||||
for (let error of errors.errors) {
|
||||
for (let metadatum of Object.keys(error)){
|
||||
eventBus.errors.push({ metadatum_id: metadatum, errors: error[metadatum]});
|
||||
}
|
||||
this.formErrorMessage = errors.error_message;
|
||||
}
|
||||
this.formErrorMessage = errors.error_message;
|
||||
});
|
||||
},
|
||||
deleteThumbnail() {
|
||||
|
@ -1064,7 +1051,6 @@ export default {
|
|||
});
|
||||
},
|
||||
deleteAttachment(attachment) {
|
||||
|
||||
this.$modal.open({
|
||||
parent: this,
|
||||
component: CustomDialog,
|
||||
|
@ -1074,7 +1060,9 @@ export default {
|
|||
message: this.$i18n.get('info_warning_attachment_delete'),
|
||||
onConfirm: () => {
|
||||
this.removeAttachmentFromItem(attachment.id)
|
||||
.then(() => { })
|
||||
.then(() => {
|
||||
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document });
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$console.error(error);
|
||||
});
|
||||
|
@ -1144,7 +1132,7 @@ export default {
|
|||
relatedPostId: this.itemId,
|
||||
onSave: () => {
|
||||
// Fetch current existing attachments
|
||||
this.fetchAttachments(this.itemId);
|
||||
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -1232,7 +1220,7 @@ export default {
|
|||
});
|
||||
|
||||
// Fetch current existing attachments
|
||||
this.fetchAttachments(this.itemId);
|
||||
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId, documentId: this.item.document });
|
||||
},
|
||||
onNextInSequence() {
|
||||
this.sequenceRightDirection = true;
|
||||
|
@ -1502,48 +1490,8 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
.section-attachments {
|
||||
margin-top: 0px;
|
||||
p { margin: 4px 15px }
|
||||
}
|
||||
|
||||
.uploaded-files {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
margin-left: -15px;
|
||||
margin-right: -15px;
|
||||
|
||||
.file-item-container {
|
||||
position: relative;
|
||||
|
||||
&:hover .file-item-control {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.file-item-control {
|
||||
position: absolute;
|
||||
background-color: $gray1;
|
||||
width: 112px;
|
||||
margin: 15px;
|
||||
bottom: 0px;
|
||||
padding: 2px 8px 4px 8px;
|
||||
text-align: right;
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity ease 0.2s, visibility ease 0.2s, display ease 0.2s;
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.document-field {
|
||||
|
||||
.document-buttons-row {
|
||||
text-align: right;
|
||||
top: -21px;
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="table-container">
|
||||
<div
|
||||
v-if="attachments.length > 0"
|
||||
class="table-wrapper">
|
||||
<div class="uploaded-files">
|
||||
<div
|
||||
v-for="(attachment, index) in attachments"
|
||||
:key="index"
|
||||
class="file-item-container">
|
||||
<file-item
|
||||
:show-name="true"
|
||||
:modal-on-click="true"
|
||||
:file="attachment"/>
|
||||
<span
|
||||
v-if="isEditable"
|
||||
class="file-item-control">
|
||||
<a
|
||||
@click="onDeleteAttachment(attachment)"
|
||||
v-tooltip="{
|
||||
content: $i18n.get('delete'),
|
||||
autoHide: true,
|
||||
placement: 'bottom'
|
||||
}"
|
||||
class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-delete"/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Empty state image -->
|
||||
<div v-if="(totalAttachments <= 0 || !totalAttachments) && !isLoading">
|
||||
<section class="section">
|
||||
<div class="content has-text-grey has-text-centered">
|
||||
<span class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-attachments"/>
|
||||
</span>
|
||||
<p>{{ $i18n.get('info_no_attachments_on_item_yet') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="pagination-area"
|
||||
v-if="attachments.length > 0">
|
||||
<div class="shown-items">
|
||||
{{
|
||||
$i18n.get('info_showing_attachments') +
|
||||
(attachmentsPerPage * (attachmentsPage - 1) + 1) +
|
||||
$i18n.get('info_to') +
|
||||
getLastAttachmentsNumber() +
|
||||
$i18n.get('info_of') + totalAttachments + '.'
|
||||
}}
|
||||
</div>
|
||||
<!-- <div class="items-per-page">
|
||||
<b-field
|
||||
horizontal
|
||||
:label="$i18n.get('label_attachments_per_page')">
|
||||
<b-select
|
||||
:value="attachmentsPerPage"
|
||||
@input="onChangeAttachmentsPerPage"
|
||||
:disabled="attachments.length <= 0">
|
||||
<option value="12">12</option>
|
||||
<option value="24">24</option>
|
||||
<option value="48">48</option>
|
||||
<option value="96">96</option>
|
||||
</b-select>
|
||||
</b-field>
|
||||
</div> -->
|
||||
<div class="pagination">
|
||||
<b-pagination
|
||||
@change="onPageChange"
|
||||
:total="totalAttachments"
|
||||
:current.sync="attachmentsPage"
|
||||
order="is-centered"
|
||||
size="is-small"
|
||||
:per-page="attachmentsPerPage"
|
||||
:aria-next-label="$i18n.get('label_next_page')"
|
||||
:aria-previous-label="$i18n.get('label_previous_page')"
|
||||
:aria-page-label="$i18n.get('label_page')"
|
||||
:aria-current-label="$i18n.get('label_current_page')"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
import FileItem from '../../components/other/file-item.vue';
|
||||
|
||||
export default {
|
||||
name: 'AttachmentsList',
|
||||
components: {
|
||||
FileItem
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: false,
|
||||
attachmentsPage: 1,
|
||||
attachmentsPerPage: 24
|
||||
}
|
||||
},
|
||||
props: {
|
||||
item: Object,
|
||||
isEditable: Boolean
|
||||
},
|
||||
computed: {
|
||||
attachments() {
|
||||
return this.getAttachments();
|
||||
},
|
||||
totalAttachments() {
|
||||
return this.getTotalAttachments();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('item', [
|
||||
'fetchAttachments',
|
||||
]),
|
||||
...mapGetters('item', [
|
||||
'getAttachments',
|
||||
'getTotalAttachments'
|
||||
]),
|
||||
onChangeAttachmentsPerPage(value) {
|
||||
|
||||
if (value != this.attachmentsPerPage) {
|
||||
this.$userPrefs.set('attachments_per_page', value)
|
||||
.then((newValue) => {
|
||||
this.attachmentsPerPage = newValue;
|
||||
})
|
||||
.catch(() => {
|
||||
this.$console.log("Error settings user prefs for attachments per page")
|
||||
});
|
||||
}
|
||||
this.attachmentsPerPage = value;
|
||||
this.loadAttachments();
|
||||
},
|
||||
onPageChange(page) {
|
||||
this.attachmentsPage = page;
|
||||
this.loadAttachments();
|
||||
},
|
||||
getLastAttachmentsNumber() {
|
||||
let last = (Number(this.attachmentsPerPage * (this.attachmentsPage - 1)) + Number(this.attachmentsPerPage));
|
||||
return last > this.totalAttachments ? this.totalAttachments : last;
|
||||
},
|
||||
loadAttachments() {
|
||||
this.isLoading = true;
|
||||
|
||||
this.fetchAttachments({
|
||||
page: this.attachmentsPage,
|
||||
attachmentsPerPage: this.attachmentsPerPage,
|
||||
itemId: this.item.id,
|
||||
documentId: this.item.document
|
||||
})
|
||||
.then((response) => {
|
||||
this.isLoading = false;
|
||||
this.totalAttachments = response.total;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.isLoading = false;
|
||||
this.$console.error(error);
|
||||
})
|
||||
},
|
||||
onDeleteAttachment(attachment) {
|
||||
this.$emit('onDeleteAttachment', attachment);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// Get attachments
|
||||
this.loadAttachments();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.uploaded-files {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
|
||||
.file-item-container {
|
||||
margin: 15px;
|
||||
position: relative;
|
||||
|
||||
&:hover .file-item-control {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.file-item-control {
|
||||
position: absolute;
|
||||
background-color: #f2f2f2;
|
||||
width: 112px;
|
||||
margin: 6px 0;
|
||||
bottom: 0px;
|
||||
padding: 2px 8px 4px 8px;
|
||||
text-align: right;
|
||||
display: none;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity ease 0.2s, visibility ease 0.2s, display ease 0.2s;
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -233,27 +233,16 @@
|
|||
<span>
|
||||
{{ $i18n.get('label_attachments') }}
|
||||
<span
|
||||
v-if="attachmentsList && attachmentsList.length"
|
||||
v-if="totalAttachments != null && totalAttachments != undefined"
|
||||
class="has-text-gray">
|
||||
({{ attachmentsList.length }})
|
||||
({{ totalAttachments }})
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="section-box section-attachments">
|
||||
<div class="uploaded-files">
|
||||
<file-item
|
||||
:style="{ margin: 15 + 'px'}"
|
||||
v-if="attachmentsList.length > 0"
|
||||
v-for="(attachment, index) in attachmentsList"
|
||||
:key="index"
|
||||
:show-name="true"
|
||||
:modal-on-click="true"
|
||||
:file="attachment"/>
|
||||
<p v-if="attachmentsList.length <= 0"><br>{{
|
||||
$i18n.get('info_no_attachments_on_item_yet') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<attachments-list
|
||||
v-if="item != undefined && item.id != undefined"
|
||||
:item="item" />
|
||||
</b-tab-item>
|
||||
|
||||
<b-tab-item>
|
||||
|
@ -322,6 +311,7 @@
|
|||
import {formHooks} from '../../js/mixins';
|
||||
import ActivitiesPage from '../lists/activities-page.vue';
|
||||
import ExposersModal from '../../components/other/exposers-modal.vue';
|
||||
import AttachmentsList from '../../components/lists/attachments-list.vue';
|
||||
|
||||
export default {
|
||||
name: 'ItemPage',
|
||||
|
@ -330,7 +320,8 @@
|
|||
FileItem,
|
||||
DocumentItem,
|
||||
ActivitiesPage,
|
||||
ExposersModal
|
||||
ExposersModal,
|
||||
AttachmentsList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -355,14 +346,13 @@
|
|||
metadatumList() {
|
||||
return JSON.parse(JSON.stringify(this.getMetadata()));
|
||||
},
|
||||
attachmentsList() {
|
||||
return this.getAttachments().filter((attachment) => attachment.id != this.item.document);
|
||||
},
|
||||
totalAttachments() {
|
||||
return this.getTotalAttachments();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('item', [
|
||||
'fetchItem',
|
||||
'fetchAttachments',
|
||||
'fetchMetadata',
|
||||
]),
|
||||
...mapActions('collection', [
|
||||
|
@ -372,7 +362,7 @@
|
|||
...mapGetters('item', [
|
||||
'getItem',
|
||||
'getMetadata',
|
||||
'getAttachments'
|
||||
'getTotalAttachments'
|
||||
]),
|
||||
loadMetadata() {
|
||||
// Obtains Item Metadatum
|
||||
|
@ -416,15 +406,12 @@
|
|||
this.loadMetadata();
|
||||
});
|
||||
|
||||
// Obtains collection name
|
||||
if (!this.isRepositoryLevel) {
|
||||
this.fetchCollectionName(this.collectionId).then((collectionName) => {
|
||||
this.collectionName = collectionName;
|
||||
});
|
||||
}
|
||||
|
||||
// Get attachments
|
||||
this.fetchAttachments(this.itemId);
|
||||
// Obtains collection name
|
||||
if (!this.isRepositoryLevel) {
|
||||
this.fetchCollectionName(this.collectionId).then((collectionName) => {
|
||||
this.collectionName = collectionName;
|
||||
});
|
||||
}
|
||||
|
||||
// Obtains collection Comment Status
|
||||
this.fetchCollectionAllowComments(this.collectionId).then((collectionAllowComments) => {
|
||||
|
|
|
@ -171,6 +171,7 @@ return apply_filters( 'tainacan-admin-i18n', [
|
|||
'label_taxonomies_per_page' => __( 'Taxonomies per Page:', 'tainacan' ),
|
||||
'label_activities_per_page' => __( 'Activities per Page:', 'tainacan' ),
|
||||
'label_items_per_page' => __( 'Items per Page:', 'tainacan' ),
|
||||
'label_attachments_per_page' => __( 'Attachments per Page:', 'tainacan' ),
|
||||
'label_processes_per_page' => __( 'Processes per Page:', 'tainacan' ),
|
||||
'label_go_to_page' => __( 'Go to Page:', 'tainacan' ),
|
||||
'label_active_metadata' => __( 'Active Metadata', 'tainacan' ),
|
||||
|
@ -551,6 +552,7 @@ return apply_filters( 'tainacan-admin-i18n', [
|
|||
'info_warning_collection_related' => __( 'The metadata Collection related is required', 'tainacan' ),
|
||||
'info_warning_no_metadata_found' => __( 'No metadata found in this collection', 'tainacan' ),
|
||||
'info_showing_items' => __( 'Showing items ', 'tainacan' ),
|
||||
'info_showing_attachments' => __( 'Showing attachments ', 'tainacan' ),
|
||||
'info_showing_collections' => __( 'Showing collections ', 'tainacan' ),
|
||||
'info_showing_taxonomies' => __( 'Showing taxonomies ', 'tainacan' ),
|
||||
'info_showing_activities' => __( 'Showing activities ', 'tainacan' ),
|
||||
|
|
|
@ -202,14 +202,23 @@ export const removeAttachmentFromItem = ( { commit }, attachmentId) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const fetchAttachments = ({ commit }, item_id) => {
|
||||
export const fetchAttachments = ({ commit }, { page, attachmentsPerPage, itemId, documentId }) => {
|
||||
commit('cleanAttachments');
|
||||
commit('setTotalAttachments', null);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.wp.get('/media/?parent=' + item_id + '&per_page=100&paged=1')
|
||||
axios.wp.get('/media/?parent=' + itemId + '&per_page=' + attachmentsPerPage + '&page=' + page)
|
||||
.then(res => {
|
||||
let attachments = res.data;
|
||||
let attachments = res.data.filter((attachment) => attachment.id != documentId);
|
||||
let total = documentId ? res.headers['x-wp-total'] - 1 : res.headers['x-wp-total'];
|
||||
|
||||
commit('setAttachments', attachments);
|
||||
resolve( attachments );
|
||||
commit('setTotalAttachments', total);
|
||||
|
||||
resolve( {
|
||||
attachments: attachments,
|
||||
total: total
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
reject( error );
|
||||
|
|
|
@ -17,3 +17,7 @@ export const getItemTitle = state => {
|
|||
export const getAttachments = state => {
|
||||
return state.attachments;
|
||||
}
|
||||
|
||||
export const getTotalAttachments = state => {
|
||||
return state.totalAttachments;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ const state = {
|
|||
attachment: {},
|
||||
attachments: [],
|
||||
lastUpdated: '',
|
||||
comment_status: ''
|
||||
comment_status: '',
|
||||
totalAttachments: 0
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@ export const cleanAttachments = (state) => {
|
|||
state.attachments = [];
|
||||
}
|
||||
|
||||
export const setTotalAttachments = ( state, total) => {
|
||||
state.totalAttachments = total;
|
||||
}
|
||||
|
||||
export const setItemTitle = ( state, itemTitle ) => {
|
||||
state.itemTitle = itemTitle;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue