Improvements to importer and mappers mapping screens

This commit is contained in:
mateuswetah 2021-10-18 17:04:07 -03:00
parent 8e01486b8a
commit 2050339db4
4 changed files with 316 additions and 158 deletions

View File

@ -47,37 +47,40 @@
v-if="importerSourceInfo != undefined &&
importerSourceInfo != null &&
!isLoading">
<a
v-if="importerSourceInfo.source_metadata && importerSourceInfo.source_metadata.length > 0"
style="margin-left: 2rem; font-size: 0.875em;"
class="is-inline is-pulled-right add-link has-text-secondary"
@click="createAllMetadata()">
<span class="icon">
<i class="tainacan-icon tainacan-icon-approvedcircle"/>
</span>
{{ $i18n.get('label_set_all_create_metadada') }}
</a>
<a
v-if="collectionId != null && collectionId != undefined && importerSourceInfo.source_metadata &&importerSourceInfo.source_metadata.length > 0 && collection && collection.current_user_can_edit_metadata"
style="font-size: 0.875em;"
class="is-inline is-pulled-right add-link has-text-secondary"
@click="createNewMetadatum()">
<span class="icon">
<i class="tainacan-icon tainacan-icon-add"/>
</span>
{{ $i18n.get('label_add_more_metadata') }}
</a>
<div class="mapping-control">
<a
v-if="importerSourceInfo.source_metadata && importerSourceInfo.source_metadata.length > 0"
style="margin-left: 2rem; font-size: 0.875em;"
class="is-inline is-pulled-right add-link has-text-secondary"
@click="createAllMetadata()">
<span class="icon">
<i class="tainacan-icon tainacan-icon-approvedcircle"/>
</span>
{{ $i18n.get('label_set_all_create_metadada') }}
</a>
<a
v-if="collectionId != null && collectionId != undefined && importerSourceInfo.source_metadata &&importerSourceInfo.source_metadata.length > 0 && collection && collection.current_user_can_edit_metadata"
style="font-size: 0.875em;"
class="is-inline is-pulled-right add-link has-text-secondary"
@click="createNewMetadatum()">
<span class="icon">
<i class="tainacan-icon tainacan-icon-add"/>
</span>
{{ $i18n.get('label_add_more_metadata') }}
</a>
</div>
<div
class="mapping-header"
v-if="importerSourceInfo.source_metadata.length > 0 || (importerSourceInfo.source_special_fields && importerSourceInfo.source_special_fields.length > 0)">
<p>{{ $i18n.get('label_from_source_collection') }}</p>
<hr>
<span class="icon">
<i class="tainacan-icon tainacan-icon-pointer" />
<i class="tainacan-icon tainacan-icon-pointer tainacan-icon-1-25em" />
</span>
<hr>
<p>{{ $i18n.get('label_to_target_collection') }}</p>
</div>
<div
class="source-metadatum"
v-for="(sourceMetadatum, index) of importerSourceInfo.source_metadata"
@ -195,8 +198,11 @@
<p style="font-style: italic">{{ specialField }}</p>
<p>{{ $i18n.get('info_special_fields_mapped_default') }}</p>
</div>
<p v-if="importerSourceInfo.source_metadata.length <= 0">{{ $i18n.get('info_no_metadata_source_file') }}<br></p>
<p v-if="(!importerSourceInfo.source_special_fields || importerSourceInfo.source_special_fields.length <= 0)">{{ $i18n.get('info_no_special_fields_available') }}<br></p>
<b-modal
@close="onMetadatumEditionCanceled()"
:active.sync="isNewMetadatumModalActive"
@ -837,6 +843,10 @@ export default {
}
}
.page-container {
padding-bottom: 0;
}
.field {
position: relative;
}
@ -850,6 +860,13 @@ export default {
.form-submit {
margin-top: 24px;
position: sticky !important;
bottom: 0;
background: var(--tainacan-background-color, white);
z-index: 9;
padding: 12px;
border-top: 1px solid var(--tainacan-gray3);
box-shadow: 0 -5px 12px -14px var(--tainacan-gray5);
}
.section-label {
@ -860,22 +877,40 @@ export default {
}
.source-metadatum {
padding: 2px 0 2px 8px;
padding: 2px 0;
min-height: 35px;
border-bottom: 1px solid var(--tainacan-gray2);
width: 100%;
margin-bottom: 6px;
width: calc(100% - 32px);
margin: 3px 16px 6px 16px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
position: relative;
&::before {
display: block;
content: '';
position: absolute;
height: 1px;
width: 100%;
background-color: var(--tainacan-gray2);
z-index: -1;
}
&>p {
font-weight: normal;
transition: font-weight 0.1s ease;
padding-right: 6px;
overflow: hidden;
word-wrap: break-word;
background-color: var(--tainacan-background-color, white);
}
.control {
max-width: 60%;
}
&:hover {
--tainacan-input-border-color: var(--tainacan-gray4);
&::before {
background-color: var(--tainacan-gray4);
}
&>p {
font-weight: bold;
}
@ -907,11 +942,23 @@ export default {
.is-inline .control{
display: inline;
}
.drop-inner{
.drop-inner {
padding: 1em 3em;
}
.mapping-control {
background-color: var(--tainacan-background-color, white);
position: sticky;
top: -34px;
z-index: 9;
height: 2.5rem;
padding-top: 12px;
}
.mapping-header {
background-color: var(--tainacan-background-color, white);
position: sticky;
top: 0;
z-index: 9;
width: 100%;
display: flex;
justify-content: space-between;
@ -919,7 +966,9 @@ export default {
color: var(--tainacan-info-color);
font-size: 0.875em;
font-weight: bold;
margin: 18px 0 6px 0;
margin: 0 0 12px 0;
border-bottom: 1px solid var(--tainacan-gray3);
box-shadow: 0 5px 12px -14px var(--tainacan-gray5);
p {
white-space: nowrap;
@ -929,6 +978,7 @@ export default {
margin-left: 12px;
margin-right: 12px;
height: 1px;
background: linear-gradient(90deg, #f2f2f2 ,#dbdbdb, #f2f2f2);
}
@media screen and (max-width: 768px) {

View File

@ -1,6 +1,25 @@
<template>
<div>
<b-loading :active.sync="isLoadingMetadatumMappers"/>
<b-loading
:can-cancel="false"
:active.sync="isLoadingMetadatumMappers"/>
<b-field>
<p style="line-height: 2.5em;">{{ $i18n.get('info_metadata_mapper_helper') }}</p>
<b-select
id="mappers-options-dropdown"
:placeholder="$i18n.get('instruction_select_a_mapper')"
:value="mapper"
@input="onSelectMetadataMapper($event)">
<option
v-for="metadatumMapper in metadatumMappers"
:key="metadatumMapper.slug"
:value="metadatumMapper">
{{ $i18n.get(metadatumMapper.name) }}
</option>
</b-select>
</b-field>
<!-- No metadata found warning -->
<section
v-if="activeMetadatumList.length <= 0 && !isLoadingMetadata"
class="field is-grouped-centered section">
@ -13,83 +32,69 @@
<p>{{ $i18n.get('info_there_is_no_metadatum') }}</p>
</div>
</section>
<section v-else>
<div class="field is-grouped form-submit">
<b-select
id="mappers-options-dropdown"
:placeholder="$i18n.get('instruction_select_a_mapper')"
@input="onSelectMetadataMapper($event)">
<option
v-for="metadatum_mapper in metadatum_mappers"
:key="metadatum_mapper.slug"
:value="metadatum_mapper">
{{ $i18n.get(metadatum_mapper.name) }}
</option>
</b-select>
<!-- Mapping list -->
<form
class="tainacan-form"
v-else>
<div class="mapping-control">
<div
class="control"
v-if="mapper != '' && !isLoadingMetadatumMappers">
<button
class="button is-outlined"
type="button"
@click="onCancelUpdateMetadataMapperMetadata">{{ $i18n.get('cancel') }}</button>
</div>
<div
class="control"
v-if="mapper != '' && !isLoadingMetadatumMappers">
<button
@click.prevent="onUpdateMetadataMapperMetadataClick"
class="button is-success">{{ $i18n.get('save') }}</button>
v-if="mapper != '' && mapper.allow_extra_metadata"
class="modal-new-link">
<a
v-if="collectionId != null && collectionId != undefined"
class="is-inline is-pulled-right add-link"
@click="onNewMetadataMapperMetadata()">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-add"/>
</span>
{{ $i18n.get('label_add_more_mapper_metadata') }}
</a>
</div>
</div>
</section>
<div
class="mapping-header"
v-if="mapperMetadata.length > 0">
<p>{{ $i18n.get('label_from_source_mapper') }}</p>
<hr>
<span class="icon">
<i class="tainacan-icon tainacan-icon-pointer tainacan-icon-1-25em" />
</span>
<hr>
<p>{{ $i18n.get('label_to_target_mapper') }}</p>
</div>
<br>
<div
v-for="(mapperMetadatum, index) of mapperMetadata"
:key="index"
class="source-metadatum">
<b-select
:name="'mappers-metadatum-select-' + mapperMetadatum.slug"
v-model="mapperMetadatum.selected"
@input="onSelectMetadatumForMapperMetadata">
<option
value="">
{{ $i18n.get('instruction_select_a_metadatum') }}
</option>
<option
v-for="(metadatum, metadatumIndex) in activeMetadatumList"
:key="metadatumIndex"
:value="metadatum.id"
:disabled="isMetadatumSelected(metadatum.id)">
{{ metadatum.name }}
</option>
</b-select>
<section>
<b-table
size="is-small"
:data="mapperMetadata"
:loading="isMapperMetadataLoading">
<b-table-column
v-slot="props"
field="label"
:label="$i18n.get('label_mapper_metadata')">
{{ props.row.label }}
</b-table-column>
<b-table-column
v-slot="props"
field="slug"
:label="$i18n.get('metadatum')">
<b-select
:name="'mappers-metadatum-select-' + props.row.slug"
v-model="props.row.selected"
@input="onSelectMetadatumForMapperMetadata">
<option
value="">
{{ $i18n.get('instruction_select_a_metadatum') }}
</option>
<option
v-for="(metadatum, index) in activeMetadatumList"
:key="index"
:value="metadatum.id"
:disabled="isMetadatumSelected(metadatum.id)">
{{ metadatum.name }}
</option>
</b-select>
</b-table-column>
<b-table-column
v-slot="props"
field="isCustom"
label="">
<p>
{{ mapperMetadatum.label }}
<a
:style="{ visibility:
props.row.isCustom
mapperMetadatum.isCustom
? 'visible' : 'hidden'
}"
@click.prevent="editMetadatumCustomMapper(props.row)">
@click.prevent="editMetadatumCustomMapper(mapperMetadatum)">
<span
v-tooltip="{
content: $i18n.get('edit'),
@ -103,10 +108,10 @@
</a>
<a
:style="{ visibility:
props.row.isCustom
mapperMetadatum.isCustom
? 'visible' : 'hidden'
}"
@click.prevent="removeMetadatumCustomMapper(props.row)">
@click.prevent="removeMetadatumCustomMapper(mapperMetadatum)">
<span
v-tooltip="{
content: $i18n.get('delete'),
@ -118,25 +123,27 @@
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-delete"/>
</span>
</a>
</b-table-column>
</b-table>
</section>
<section
v-if="mapper != '' && mapper.allow_extra_metadata">
<div
class="modal-new-link">
<a
v-if="collectionId != null && collectionId != undefined"
class="is-inline is-pulled-left add-link"
@click="onNewMetadataMapperMetadata()">
<span class="icon is-small">
<i class="tainacan-icon tainacan-icon-add"/>
</span>
{{ $i18n.get('label_add_more_mapper_metadata') }}
</a>
</p>
</div>
</section>
<div
v-if="mapper != '' && !isLoadingMetadatumMappers"
class="field is-grouped form-submit">
<div class="control">
<button
class="button is-outlined"
type="button"
@click="onCancelUpdateMetadataMapperMetadata">{{ $i18n.get('cancel') }}</button>
</div>
<div class="control">
<button
@click.prevent="onUpdateMetadataMapperMetadataClick"
class="button is-success">{{ $i18n.get('save') }}</button>
</div>
</div>
</form>
<b-modal
@close="onCancelNewMetadataMapperMetadata"
:active.sync="isMapperMetadataCreating"
@ -176,30 +183,15 @@
</div>
<div class="control">
<button
:class="{ 'is-loading': isMapperMetadataLoading, 'is-success': !isMapperMetadataLoading }"
@click.prevent="onSaveNewMetadataMapperMetadata"
:disabled="isNewMetadataMapperMetadataDisabled"
class="button is-success">{{ $i18n.get('save') }}</button>
:disabled="isNewMetadataMapperMetadataDisabled || isMapperMetadataLoading"
class="button">{{ $i18n.get('save') }}
</button>
</div>
</div>
</div>
</b-modal>
<section
v-if="mapper != '' && !isLoadingMetadatumMappers">
<div class="field is-grouped form-submit w-100">
<div class="control">
<button
class="button is-outlined"
type="button"
@click="onCancelUpdateMetadataMapperMetadata">{{ $i18n.get('cancel') }}</button>
</div>
<div class="control">
<button
@click.prevent="onUpdateMetadataMapperMetadataClick"
class="button is-success">{{ $i18n.get('save') }}</button>
</div>
</div>
</section>
</div>
</template>
@ -211,7 +203,7 @@ export default {
props: {
isRepositoryLevel: Boolean
},
data(){
data() {
return {
collectionId: '',
isLoadingMetadatumMappers: true,
@ -226,7 +218,7 @@ export default {
}
},
computed: {
metadatum_mappers() {
metadatumMappers() {
return this.getMetadatumMappers();
},
isNewMetadataMapperMetadataDisabled() {
@ -237,9 +229,13 @@ export default {
}
},
mounted() {
this.isLoadingMetadatumMappers = true;
this.fetchMetadatumMappers()
.then(() => {
this.isLoadingMetadatumMappers = false;
if (this.metadatumMappers.length == 1)
this.onSelectMetadataMapper(this.metadatumMappers[0])
})
.catch(() => {
this.isLoadingMetadatumMappers = false;
@ -254,23 +250,22 @@ export default {
'getMetadatumMappers',
'getMetadata'
]),
onSelectMetadataMapper(metadatum_mapper) {
onSelectMetadataMapper(metadatumMapper) {
this.isMapperMetadataLoading = true;
this.mapper = metadatum_mapper; //TODO try to use v-model again
this.mapper = metadatumMapper; //TODO try to use v-model again
this.mapperMetadata = [];
this.mappedMetadata = [];
if(metadatum_mapper != '') {
for (var k in metadatum_mapper.metadata) {
var item = metadatum_mapper.metadata[k];
if (metadatumMapper != '') {
for (var k in metadatumMapper.metadata) {
var item = metadatumMapper.metadata[k];
item.slug = k;
item.selected = '';
item.isCustom = false;
this.activeMetadatumList.forEach((metadatum) => {
if(
metadatum.exposer_mapping.hasOwnProperty(metadatum_mapper.slug) &&
metadatum.exposer_mapping[metadatum_mapper.slug] == item.slug
metadatum.exposer_mapping.hasOwnProperty(metadatumMapper.slug) &&
metadatum.exposer_mapping[metadatumMapper.slug] == item.slug
) {
item.selected = metadatum.id;
this.mappedMetadata.push(metadatum.id);
@ -280,12 +275,12 @@ export default {
}
this.activeMetadatumList.forEach((metadatum) => {
if(
metadatum.exposer_mapping.hasOwnProperty(metadatum_mapper.slug) &&
typeof metadatum.exposer_mapping[metadatum_mapper.slug] == 'object'
metadatum.exposer_mapping.hasOwnProperty(metadatumMapper.slug) &&
typeof metadatum.exposer_mapping[metadatumMapper.slug] == 'object'
) {
this.newMapperMetadataList.push(Object.assign({},metadatum.exposer_mapping[metadatum_mapper.slug]));
this.newMapperMetadataList.push(Object.assign({},metadatum.exposer_mapping[metadatumMapper.slug]));
this.mappedMetadata.push(metadatum.id);
var item = Object.assign({},metadatum.exposer_mapping[metadatum_mapper.slug]);
var item = Object.assign({},metadatum.exposer_mapping[metadatumMapper.slug]);
item.selected = metadatum.id;
item.isCustom = true;
this.mapperMetadata.push(item);
@ -338,7 +333,10 @@ export default {
}
});
});
this.updateMetadataMapperMetadata({metadataMapperMetadata: metadataMapperMetadata, mapper: this.mapper.slug}).then(() => {
this.updateMetadataMapperMetadata({
metadataMapperMetadata: metadataMapperMetadata,
mapper: this.mapper.slug
}).then(() => {
this.isLoadingMetadata = true;
this.refreshMetadata();
this.isMapperMetadataLoading = false;
@ -440,14 +438,120 @@ export default {
}
</script>
<style scoped>
.b-table {
<style lang="scss" scoped>
.tainacan-form {
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 247px;
}
.form-submit {
margin-top: 24px;
}
.add-link {
font-size: 0.875em;
}
.b-table td {
padding: 0.5em 0.75em 0.4em 0.75em;
.field {
position: relative;
}
.add-link {
font-size: 0.75em;
.mapping-control {
background-color: var(--tainacan-background-color, white);
position: sticky;
top: -34px;
z-index: 9;
height: 2.5rem;
padding-top: 12px;
}
.mapping-header {
background-color: var(--tainacan-background-color, white);
position: sticky;
top: 0;
z-index: 9;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
color: var(--tainacan-info-color);
font-size: 0.875em;
font-weight: bold;
margin: 0 0 12px 0;
border-bottom: 1px solid var(--tainacan-gray3);
box-shadow: 0 5px 12px -14px var(--tainacan-gray5);
p {
white-space: nowrap;
}
hr {
width: 100%;
margin-left: 12px;
margin-right: 12px;
height: 1px;
background: var(--tainacan-gray3);
}
@media screen and (max-width: 768px) {
p {
white-space: normal;
}
hr {
display: none;
}
}
}
.source-metadatum {
padding: 2px 0;
min-height: 35px;
width: 100%;
margin: 3px 16px 6px 16px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
&::before {
display: block;
content: '';
position: absolute;
height: 1px;
width: 100%;
background-color: var(--tainacan-gray2);
z-index: -1;
}
&>p {
font-weight: normal;
transition: font-weight 0.1s ease;
padding-left: 6px;
overflow: hidden;
word-wrap: break-word;
background-color: var(--tainacan-background-color, white);
}
.control {
max-width: 60%;
}
&:hover {
--tainacan-input-border-color: var(--tainacan-gray4);
&::before {
background-color: var(--tainacan-gray4);
}
&>p {
font-weight: bold;
}
}
}
.form-submit {
margin-top: 24px;
position: sticky !important;
bottom: 0;
background: var(--tainacan-background-color, white);
z-index: 9;
padding: 12px;
border-top: 1px solid var(--tainacan-gray3);
box-shadow: 0 -5px 12px -14px var(--tainacan-gray5);
}
</style>

View File

@ -725,6 +725,7 @@ export default {
.b-tabs .tab-content {
overflow: visible;
min-height: 300px;
padding-bottom: 0;
}
.column {

View File

@ -346,6 +346,8 @@ return apply_filters( 'tainacan-i18n', [
'label_from_source_collection' => __( 'From source file', 'tainacan' ),
/* translators: Header of the column where the existing collection metadata are in the Mapping Metadata Importer screen */
'label_to_target_collection' => __( 'To target collection', 'tainacan' ),
'label_from_source_mapper' => __( 'From the collection metadata', 'tainacan' ),
'label_to_target_mapper' => __( 'To the mapped value', 'tainacan' ),
'label_add_value' => __( 'Add value', 'tainacan' ),
'label_remove_value' => __( 'Remove value', 'tainacan' ),
'label_create_new_page' => __( 'Create new page', 'tainacan' ),
@ -894,6 +896,7 @@ return apply_filters( 'tainacan-i18n', [
'info_applied_filter' => __( 'filter applied', 'tainacan'),
'info_item_found' => __( 'item found', 'tainacan'),
'info_iframe_dimensions' => __( 'The dimension values will be passed to the iframe, but it\'s rendering may change according to the theme display settings. It is still important to keep an aproximate aspect ratio to the inner content.', 'tainacan'),
'info_metadata_mapper_helper' => __( 'Select the corresponding metadata so they can be exposed according to the mapper', 'tainacan'),
/* Activity actions */
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),