Begins implementation of Related Items list on the item single edition page. #521
This commit is contained in:
parent
476a0021f5
commit
8fbe444f11
|
@ -561,6 +561,33 @@
|
|||
</div>
|
||||
</b-tab-item>
|
||||
|
||||
<!-- Related items -->
|
||||
<b-tab-item v-if="totalRelatedItems">
|
||||
<template slot="header">
|
||||
<span class="icon has-text-gray4">
|
||||
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-processes tainacan-icon-rotate-270"/>
|
||||
</span>
|
||||
<span>
|
||||
{{ $i18n.get('label_related_items') }}
|
||||
<span class="has-text-gray">
|
||||
({{ totalRelatedItems }})
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="attachments-list-heading">
|
||||
<p>
|
||||
{{ $i18n.get("info_related_items") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<related-items-list
|
||||
:related-items="item.related_items"
|
||||
:is-editable="true"
|
||||
:is-loading.sync="isLoading" />
|
||||
|
||||
</b-tab-item>
|
||||
|
||||
</b-tabs>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -800,6 +827,7 @@ import { eventBusItemMetadata } from '../../js/event-bus-item-metadata';
|
|||
import wpMediaFrames from '../../js/wp-media-frames';
|
||||
import FileItem from '../other/file-item.vue';
|
||||
import DocumentItem from '../other/document-item.vue';
|
||||
import RelatedItemsList from '../lists/related-items-list.vue';
|
||||
import CustomDialog from '../other/custom-dialog.vue';
|
||||
import AttachmentsList from '../lists/attachments-list.vue';
|
||||
import { formHooks } from '../../js/mixins';
|
||||
|
@ -811,6 +839,7 @@ export default {
|
|||
FileItem,
|
||||
DocumentItem,
|
||||
AttachmentsList,
|
||||
RelatedItemsList,
|
||||
ItemMetadatumErrorsTooltip
|
||||
},
|
||||
mixins: [ formHooks ],
|
||||
|
@ -873,6 +902,9 @@ export default {
|
|||
totalAttachments() {
|
||||
return this.getTotalAttachments();
|
||||
},
|
||||
totalRelatedItems() {
|
||||
return (this.item && this.item.related_items) ? Object.values(this.item.related_items).reduce((totalItems, aRelatedItemsGroup) => totalItems + parseInt(aRelatedItemsGroup.total_items), 0) : false;
|
||||
},
|
||||
formErrors() {
|
||||
return eventBusItemMetadata && eventBusItemMetadata.errors && eventBusItemMetadata.errors.length ? eventBusItemMetadata.errors : []
|
||||
}
|
||||
|
@ -1501,7 +1533,7 @@ export default {
|
|||
this.fetchItem({
|
||||
itemId: this.itemId,
|
||||
contextEdit: true,
|
||||
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document,comment_status,document_as_html'
|
||||
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document,comment_status,document_as_html,related_items'
|
||||
})
|
||||
.then((resp) => {
|
||||
resp.request.then((res) => {
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="table-container">
|
||||
<b-loading
|
||||
is-full-page="false"
|
||||
:active.sync="isLoading" />
|
||||
<div class="table-wrapper">
|
||||
<div class="related-items-list">
|
||||
<div
|
||||
v-for="(relatedItemGroup, index) of relatedItemsArray"
|
||||
:key="index"
|
||||
class="related-item-group">
|
||||
<div class="columns">
|
||||
<div class="column is-narrow">
|
||||
<div class="section-status">
|
||||
<div class="field has-addons">
|
||||
<span>
|
||||
<span class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-collection"/>
|
||||
</span>
|
||||
{{ relatedItemGroup.collection_name ? relatedItemGroup.collection_name : '' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div class="section-status">
|
||||
<div class="field has-addons">
|
||||
<span>
|
||||
<span class="icon">
|
||||
<i class="tainacan-icon tainacan-icon-metadata"/>
|
||||
</span>
|
||||
{{ relatedItemGroup.metadata_name ? relatedItemGroup.metadata_name : '' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="tainacan-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<!-- Status -->
|
||||
<th>
|
||||
|
||||
</th>
|
||||
|
||||
<!-- Displayed Metadata -->
|
||||
<th
|
||||
v-for="(column, columnIndex) in displayedMetadata"
|
||||
:key="columnIndex"
|
||||
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.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') : false,
|
||||
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' ||
|
||||
column.metadata_type_object.primitive_type == 'compound' ||
|
||||
column.metadata_type_object.related_mapped_prop == 'description') : false,
|
||||
}">
|
||||
<div class="th-wrap">{{ column.name }}</div>
|
||||
</th>
|
||||
<th
|
||||
v-if="isEditable && relatedItemGroup.items.findIndex((relatedItem) => relatedItem.current_user_can_edit || relatedItem.current_user_can_delete) >= 0"
|
||||
class="actions-header">
|
||||
|
||||
<!-- nothing to show on header for actions cell-->
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(relatedItem, itemIndex) of relatedItemGroup.items"
|
||||
:key="itemIndex">
|
||||
<!-- Checking list -->
|
||||
|
||||
<td class="status-cell">
|
||||
<span
|
||||
v-if="$statusHelper.hasIcon(relatedItem.status)"
|
||||
class="icon has-text-gray"
|
||||
v-tooltip="{
|
||||
content: $i18n.get('status_' + relatedItem.status),
|
||||
autoHide: true,
|
||||
placement: 'auto-start'
|
||||
}">
|
||||
<i
|
||||
class="tainacan-icon tainacan-icon-1em"
|
||||
:class="$statusHelper.getIcon(relatedItem.status)"
|
||||
/>
|
||||
</span>
|
||||
</td>
|
||||
<!-- Item Displayed Metadata -->
|
||||
<td
|
||||
:key="columnIndex"
|
||||
v-for="(column, columnIndex) in displayedMetadata"
|
||||
class="column-default-width"
|
||||
: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.metadata_type_object.primitive_type == 'int' ) : false,
|
||||
'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') : false,
|
||||
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' ||
|
||||
column.metadata_type_object.primitive_type == 'compound' ||
|
||||
column.metadata_type_object.related_mapped_prop == 'description') : false,
|
||||
}">
|
||||
|
||||
<p
|
||||
v-tooltip="{
|
||||
delay: {
|
||||
show: 500,
|
||||
hide: 300,
|
||||
},
|
||||
content: relatedItem.title != undefined && relatedItem.title != '' ? relatedItem.title : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`,
|
||||
html: true,
|
||||
autoHide: false,
|
||||
placement: 'auto-start'
|
||||
}"
|
||||
v-if="collectionId == undefined &&
|
||||
column.metadata_type_object != undefined &&
|
||||
column.metadata_type_object.related_mapped_prop == 'title'"
|
||||
v-html="`<span class='sr-only'>` + column.name + ': </span>' + ((relatedItem.title != undefined && relatedItem.title != '') ? relatedItem.title : `<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)"/>
|
||||
|
||||
<span
|
||||
v-if="column.metadatum == 'row_thumbnail'"
|
||||
class="table-thumb">
|
||||
<blur-hash-image
|
||||
:width="$thumbHelper.getWidth(relatedItem['thumbnail'], 'tainacan-small', 40)"
|
||||
:height="$thumbHelper.getHeight(relatedItem['thumbnail'], 'tainacan-small', 40)"
|
||||
:hash="$thumbHelper.getBlurhashString(relatedItem['thumbnail'], 'tainacan-small')"
|
||||
:src="$thumbHelper.getSrc(relatedItem['thumbnail'], 'tainacan-small', relatedItem.document_mimetype)"
|
||||
:alt="relatedItem.thumbnail_alt ? relatedItem.thumbnail_alt : $i18n.get('label_thumbnail')"
|
||||
:transition-duration="500"
|
||||
/>
|
||||
</span>
|
||||
|
||||
</td>
|
||||
|
||||
<!-- Actions -->
|
||||
<td
|
||||
v-if="isEditable && (relatedItem.current_user_can_edit || relatedItem.current_user_can_delete)"
|
||||
class="actions-cell"
|
||||
:label="$i18n.get('label_actions')">
|
||||
<div class="actions-container">
|
||||
<a
|
||||
v-if="!relatedItem.status != 'trash'"
|
||||
id="button-edit"
|
||||
:aria-label="$i18n.getFrom('items','edit_item')">
|
||||
<span
|
||||
v-tooltip="{
|
||||
content: $i18n.get('edit'),
|
||||
autoHide: true,
|
||||
placement: 'auto'
|
||||
}"
|
||||
class="icon">
|
||||
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-edit"/>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RelatedItemsList',
|
||||
props: {
|
||||
relatedItems: Object,
|
||||
isLoading: Boolean,
|
||||
isEditable: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
displayedMetadata: [
|
||||
{
|
||||
name: this.$i18n.get('label_thumbnail'),
|
||||
metadatum: 'row_thumbnail',
|
||||
slug: 'thumbnail',
|
||||
},
|
||||
{
|
||||
name: this.$i18n.get('label_title'),
|
||||
metadatum: 'row_title',
|
||||
metadata_type_object: {core: true, related_mapped_prop: 'title'},
|
||||
slug: 'title',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
relatedItemsArray() {
|
||||
return this.relatedItems ? Object.values(this.relatedItems).filter((aRelatedItemGroup) => aRelatedItemGroup.total_items) : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section-status {
|
||||
padding-bottom: 16px;
|
||||
margin-left: -0.875rem;
|
||||
font-size: 0.875em;
|
||||
|
||||
.field {
|
||||
padding: 10px 0 14px 0px !important;
|
||||
|
||||
.icon {
|
||||
font-size: 1.125em !important;
|
||||
color: var(--tainacan-info-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.related-items-list {
|
||||
.related-item-group {
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--tainacan-info-color);
|
||||
}
|
||||
|
||||
.tainacan-table {
|
||||
margin-top: -2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -253,7 +253,7 @@
|
|||
<b-tabs v-model="activeTab">
|
||||
<b-tab-item>
|
||||
<template slot="header">
|
||||
<span class="icon has-text-gray4">
|
||||
<span class="icon has-text-gray5">
|
||||
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-metadata"/>
|
||||
</span>
|
||||
<span>{{ $i18n.get('metadata') }}</span>
|
||||
|
@ -293,7 +293,7 @@
|
|||
|
||||
<b-tab-item>
|
||||
<template slot="header">
|
||||
<span class="icon has-text-gray4">
|
||||
<span class="icon has-text-gray5">
|
||||
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-attachments"/>
|
||||
</span>
|
||||
<span>
|
||||
|
@ -313,9 +313,36 @@
|
|||
@isLoadingAttachments="(isLoading) => isLoadingAttachments = isLoading" />
|
||||
</b-tab-item>
|
||||
|
||||
<!-- Related items -->
|
||||
<b-tab-item v-if="totalRelatedItems">
|
||||
<template slot="header">
|
||||
<span class="icon has-text-gray5">
|
||||
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-processes tainacan-icon-rotate-270"/>
|
||||
</span>
|
||||
<span>
|
||||
{{ $i18n.get('label_related_items') }}
|
||||
<span class="has-text-gray">
|
||||
({{ totalRelatedItems }})
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="attachments-list-heading">
|
||||
<p>
|
||||
{{ $i18n.get("info_related_items") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<related-items-list
|
||||
:related-items="item.related_items"
|
||||
:is-editable="false"
|
||||
:is-loading.sync="isLoading" />
|
||||
|
||||
</b-tab-item>
|
||||
|
||||
<b-tab-item>
|
||||
<template slot="header">
|
||||
<span class="icon has-text-gray4">
|
||||
<span class="icon has-text-gray5">
|
||||
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-activities"/>
|
||||
</span>
|
||||
<span>{{ $i18n.get('activities') }}</span>
|
||||
|
@ -380,6 +407,7 @@
|
|||
import ActivitiesPage from '../lists/activities-page.vue';
|
||||
import ExposersModal from '../../components/modals/exposers-modal.vue';
|
||||
import AttachmentsList from '../../components/lists/attachments-list.vue';
|
||||
import RelatedItemsList from '../../components/lists/related-items-list.vue';
|
||||
|
||||
export default {
|
||||
name: 'ItemPage',
|
||||
|
@ -387,6 +415,7 @@
|
|||
FileItem,
|
||||
DocumentItem,
|
||||
ActivitiesPage,
|
||||
RelatedItemsList,
|
||||
AttachmentsList
|
||||
},
|
||||
mixins: [formHooks],
|
||||
|
@ -414,6 +443,9 @@
|
|||
metadatumList() {
|
||||
return JSON.parse(JSON.stringify(this.getItemMetadata()));
|
||||
},
|
||||
totalRelatedItems() {
|
||||
return (this.item && this.item.related_items) ? Object.values(this.item.related_items).reduce((totalItems, aRelatedItemsGroup) => totalItems + parseInt(aRelatedItemsGroup.total_items), 0) : false;
|
||||
},
|
||||
totalAttachments() {
|
||||
return this.getTotalAttachments();
|
||||
},
|
||||
|
@ -437,7 +469,7 @@
|
|||
this.fetchItem({
|
||||
itemId: this.itemId,
|
||||
contextEdit: true,
|
||||
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document_mimetype,document,comment_status,document_as_html'
|
||||
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document_mimetype,document,comment_status,document_as_html,related_items'
|
||||
})
|
||||
.then((resp) => {
|
||||
resp.request.then((item) => {
|
||||
|
@ -717,6 +749,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
.attachments-list-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
|
||||
button {
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 18px var(--tainacan-one-column);
|
||||
position: absolute;
|
||||
|
|
|
@ -586,6 +586,7 @@ return apply_filters( 'tainacan-admin-i18n', [
|
|||
'label_pan_selection' => __( 'Pan selection', 'tainacan'),
|
||||
'label_reset_zoom' => __( 'Reset zoom', 'tainacan'),
|
||||
'label_chart_export_options' => __( 'Chart export options', 'tainacan'),
|
||||
'label_related_items' => __( 'Items that are related', 'tainacan'),
|
||||
|
||||
// Instructions. More complex sentences to guide user and placeholders
|
||||
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
|
||||
|
@ -870,7 +871,8 @@ return apply_filters( 'tainacan-admin-i18n', [
|
|||
'info_no_taxonomy_metadata_created' => __( 'No taxonomy metadata created yet', 'tainacan'),
|
||||
'label_amount_of_metadata_of_type' => __( 'Amount of metadata of this type', 'tainacan'),
|
||||
'info_child_terms_chart' => __( 'Click on the term bar on the chart aside to see its child terms (if any) in this panel', 'tainacan' ),
|
||||
|
||||
'info_related_items' => __( 'These are items that are related to this item via their own relationship type metadata. You can edit such relation on their pages.', 'tainacan'),
|
||||
|
||||
/* Activity actions */
|
||||
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),
|
||||
'action_update' => __( 'General Updates', 'tainacan'),
|
||||
|
|
Loading…
Reference in New Issue