Adds UI to show separate page of mapper. #783.

This commit is contained in:
mateuswetah 2023-10-02 17:13:00 -03:00
parent d9eb5a6285
commit fa64b506bc
10 changed files with 170 additions and 177 deletions

View File

@ -1,13 +1,16 @@
<template>
<div class="page-container repository-level-page">
<div
:class="{ 'repository-level-page page-container': isRepositoryLevel }"
style="padding-bottom: 60px">
<tainacan-title
:bread-crumb-items="[
{ path: $routerHelper.getMappersPath(), label: $i18n.get('mappers') },
{ path: '', label: (mapper != null && mapper.name != undefined) ? mapper.name : $i18n.get('mapper') }
]"/>
]" />
<metadata-mapping-list
v-if="(isRepositoryLevel && $userCaps.hasCapability('tnc_rep_edit_metadata') || (!isRepositoryLevel && collection && collection.current_user_can_edit_metadata))"
:is-repository-level="isRepositoryLevel"/>
:is-repository-level="isRepositoryLevel"
:mapper="mapper" />
<section
v-else
class="section">
@ -36,13 +39,20 @@
mixins: [ wpAjax, formHooks ],
data(){
return {
mapper: null,
isLoading: false,
isUpdatingSlug: false,
isRepositoryLevel: false,
collectionId: null
}
},
computed: {
collection() {
return this.getCollection();
},
mapper() {
return this.getMapper();
}
},
created() {
this.isRepositoryLevel = (this.$route.params.collectionId === undefined);
this.collectionId = this.$route.params.collectionId;
@ -62,104 +72,15 @@
},
methods: {
...mapActions('metadata', [
'updateMapper',
'fetchMapper',
]),
...mapGetters('metadata',[
'getMapper',
]),
...mapGetters('collection',[
'getCollection',
]),
}
}
</script>
<style lang="scss" scoped>
.tab-content {
overflow: visible !important;
}
.status-radios {
display: flex;
}
.status-radios .control-lable {
display: flex;
align-items: center;
}
.tainacan-form>.columns {
margin-bottom: 48px;
}
.tainacan-form .column:last-of-type {
padding-left: var(--tainacan-one-column) !important;
}
.two-columns-fields {
column-width: 180px;
.field {
margin-bottom: 0px;
}
}
.form-submit {
align-items: center;
}
.updated-at {
margin: 0 1em 0 auto;
color: var(--tainacan-info-color);
font-style: italic;
}
.footer {
padding: 14px var(--tainacan-one-column);
position: fixed;
bottom: 0;
right: 0;
z-index: 9999;
background-color: var(--tainacan-gray1);
width: calc(100% - var(--tainacan-sidebar-width, 3.25em));
height: 60px;
display: flex;
justify-content: flex-end;
align-items: center;
transition: bottom 0.5s ease, width 0.2s linear;
.footer-message {
display: flex;
align-items: center;
}
.update-info-section {
color: var(--tainacan-info-color);
margin-right: auto;
display: flex;
flex-wrap: nowrap;
}
.help {
display: inline-flex;
font-size: 1.0em;
margin-top: 0;
margin-left: 24px;
.tainacan-help-tooltip-trigger {
margin-left: 0.25em;
}
}
.link-button {
background-color: transparent;
border: none;
}
@media screen and (max-width: 769px) {
padding: 13px 0.5em;
width: 100%;
flex-wrap: wrap;
height: auto;
position: fixed;
.update-info-section {
margin-left: auto;margin-bottom: 0.75em;
margin-top: -0.25em;
}
}
}
</style>

View File

@ -5,12 +5,19 @@
<div
class="mapper"
v-for="mapper in mappers"
:key="mapper.slug"
@click="goToMapperEditionPage(mapper.slug)">
<h4>{{ mapper.name }}</h4>
<p>{{ mapper.description }}</p>
:key="mapper.slug">
<button
class="mapper-clickable"
@click="goToMapperEditionPage(mapper.slug)">
<h4>{{ mapper.name }}</h4>
<p>{{ mapper.description }}</p>
</button>
<b-switch
v-model="mapper.enabled"
style="z-index: 1;position: relative;"
:false-value="true"
:true-value="false"
:value="mapper.disabled"
@input="updateCurrentMapper($event, mapper.slug)"
size="is-small" />
</div>
@ -24,15 +31,32 @@
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'MappersList',
props: {
isLoading: false,
isRepositoryLevel: false,
mappers: Array
},
methods: {
...mapActions('metadata', [
'updateMapper',
]),
goToMapperEditionPage(mapperSlug) {
this.$router.push(this.$routerHelper.getMapperEditPath(mapperSlug));
if ( this.isRepositoryLevel )
this.$router.push(this.$routerHelper.getMapperEditPath(mapperSlug));
else
this.$router.push(this.$routerHelper.getCollectionMapperEditPath(this.$route.params.collectionId, mapperSlug));
},
updateCurrentMapper($event, mapperSlug) {
this.updateMapper({
isRepositoryLevel: this.isRepositoryLevel,
collectionId: this.$route.params.collectionId,
disabled: $event,
mapper: mapperSlug
});
}
},
}
@ -49,7 +73,6 @@
border: 1px solid var(--tainacan-gray2);
padding: 15px;
min-height: 100px;
cursor: pointer;
background-color: var(--tainacan-item-background-color);
transition: border 0.3s ease, background-color 0.15s ease;
@ -57,6 +80,19 @@
background-color: var(--tainacan-item-hover-background-color);
border: 1px solid var(--tainacan-gray3);
}
.switch {
float: left;
margin-top: 12px;
}
.mapper-clickable {
text-align: start;
border: none;
background: none;
width: 100%;
cursor: pointer;
}
}
}
</style>

View File

@ -1,14 +1,13 @@
<template>
<div class="metadata-mappers-area">
<b-loading
:can-cancel="false"
:is-full-page="false"
:active.sync="isLoadingMapper"/>
<b-loading
:can-cancel="false"
:is-full-page="false"
:active.sync="isLoadingMetadata"/>
<p>{{ mapper.description }}</p>
<!-- No metadata found warning -->
<section
v-if="activeMetadatumList.length <= 0 && !isLoadingMetadata"
@ -44,8 +43,7 @@
</div>
</div>
<div
class="mapping-header"
v-if="mapperMetadata.length > 0">
class="mapping-header">
<p>{{ $i18n.get('label_from_source_mapper') }}</p>
<hr>
<span class="icon">
@ -55,7 +53,21 @@
<p>{{ $i18n.get('label_to_target_mapper') }}</p>
</div>
<section
v-if="mapperMetadata.length <= 0"
class="section">
<div class="content has-text-grey has-text-centered">
<p>
<span class="icon">
<i class="tainacan-icon tainacan-icon-30px tainacan-icon-processes tainacan-icon-rotate-90"/>
</span>
</p>
<p>{{ $i18n.get('info_no_metadata_from_mapper') }} <span v-if="mapper.allow_extra_metadata">{{ $i18n.get('info_mapper_extra_metadata') }}</span></p>
</div>
</section>
<div
v-else
v-for="(mapperMetadatum, index) of mapperMetadata"
:key="index"
class="source-metadatum">
@ -117,7 +129,7 @@
</div>
<div
v-if="mapper && !isLoadingMapper"
v-if="mapper"
class="field is-grouped form-submit fixed-form-submit">
<div class="control">
<button
@ -199,7 +211,6 @@ export default {
data() {
return {
collectionId: '',
isLoadingMapper: true,
isLoadingMetadata: false,
mapperMetadata: [],
isMapperMetadataLoading: false,
@ -220,33 +231,29 @@ export default {
},
mounted() {
/* If we're in a collection list, the metadata won't exist as they are read inside sections */
if ( !this.isRepositoryLevel ) {
this.collectionId = this.$route.params.collectionId;
this.collectionId = this.$route.params.collectionId;
this.isLoadingMetadata = true;
this.isLoadingMetadata = true;
this.cleanMetadata();
this.fetchMetadata({
collectionId: this.collectionId,
isRepositoryLevel: this.isRepositoryLevel,
isContextEdit: true,
includeDisabled: true,
includeOptionsAsHtml: false
}).then((resp) => {
resp.request
.then(() => {
this.loadMapperMetadata();
this.isLoadingMetadata = false;
})
.catch(() => {
this.isLoadingMetadata = false;
});
})
.catch(() => this.isLoadingMetadata = false);
this.cleanMetadata();
this.fetchMetadata({
collectionId: this.collectionId,
isRepositoryLevel: false,
isContextEdit: true,
includeDisabled: true,
includeOptionsAsHtml: false
}).then((resp) => {
resp.request
.then(() => {
this.loadMapperMetadata();
this.isLoadingMetadata = false;
})
.catch(() => {
this.isLoadingMetadata = false;
});
})
.catch(() => this.isLoadingMetadata = false);
} else {
this.loadMapperMetadata();
}
},
methods: {
...mapActions('metadata', [
@ -263,9 +270,9 @@ export default {
this.isMapperMetadataLoading = true;
this.mapperMetadata = [];
if (this.mapper) {
for (var k in this.mapper.metadata) {
var item = this.mapper.metadata[k];
if ( this.mapper && this.mapper.metadata ) {
for (let k in this.mapper.metadata) {
let item = this.mapper.metadata[k];
item.slug = k;
item.selected = '';
item.isCustom = false;
@ -287,7 +294,7 @@ export default {
) {
this.newMapperMetadataList.push(Object.assign({},metadatum.exposer_mapping[this.mapper.slug]));
this.mappedMetadata.push(metadatum.id);
var item = Object.assign({},metadatum.exposer_mapping[this.mapper.slug]);
let item = Object.assign({},metadatum.exposer_mapping[this.mapper.slug]);
item.selected = metadatum.id;
item.isCustom = true;
this.mapperMetadata.push(item);
@ -309,10 +316,10 @@ export default {
},
onUpdateMapperClick() {
this.isMapperMetadataLoading = true;
var metadataMapperMetadata = [];
let metadataMapperMetadata = [];
this.mapperMetadata.forEach((item) => {
if (item.selected.length != 0) {
var map = {
let map = {
metadatum_id: item.selected,
mapper_metadata: item.slug
};
@ -321,7 +328,7 @@ export default {
});
this.activeMetadatumList.forEach((item) => {
if(this.mappedMetadata.indexOf(item.id) == -1) {
var map = {
let map = {
metadatum_id: item.id,
mapper_metadata: ''
};
@ -329,10 +336,10 @@ export default {
}
});
this.newMapperMetadataList.forEach((item) => {
var slug = item.slug;
let slug = item.slug;
metadataMapperMetadata.forEach( (meta, index) => {
if(meta.mapper_metadata == slug) {
var item_clone = Object.assign({}, item); // TODO check if still need to clone
let item_clone = Object.assign({}, item); // TODO check if still need to clone
delete item_clone.selected;
delete item_clone.isCustom;
meta.mapper_metadata = item_clone;
@ -341,8 +348,10 @@ export default {
});
});
this.updateMapper({
metadataMapperMetadata: metadataMapperMetadata,
mapper: this.mapper.slug
isRepositoryLevel: this.isRepositoryLevel,
collectionId: this.collectionId,
metadataMapperMetadata: metadataMapperMetadata,
mapper: this.mapper.slug
}).then(() => {
this.isMapperMetadataLoading = false;
})
@ -366,13 +375,13 @@ export default {
},
onSaveNewMetadataMapperMetadata() {
this.isMapperMetadataLoading = true;
var newMapperMetadata = {
let newMapperMetadata = {
label: this.newMetadataLabel,
uri: this.newMetadataUri,
slug: this.stringToSlug(this.newMetadataLabel),
isCustom: true
};
var selected = '';
let selected = '';
if(this.new_metadata_slug != '') { // Editing
this.newMapperMetadataList.forEach((meta, index) => {
if(meta.slug == this.new_metadata_slug) {
@ -400,10 +409,10 @@ export default {
str = str.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
const from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
const to = "aaaaeeeeiiiioooouuuunc------";
for (var i=0, l=from.length ; i<l ; i++) {
for (let i=0, l=from.length ; i<l ; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
@ -421,11 +430,11 @@ export default {
this.isMapperMetadataCreating = true;
},
removeMetadatumCustomMapper(customMapperMeta) {
var itemid = 0;
let itemid = 0;
this.newMapperMetadataList.forEach((meta, index) => {
if(meta.slug == customMapperMeta.slug) {
this.newMapperMetadataList.splice(index);
var rem = this.mappedMetadata.indexOf(meta.selected);
let rem = this.mappedMetadata.indexOf(meta.selected);
this.mappedMetadata.splice(rem);
itemid = customMapperMeta.selected;
}
@ -554,13 +563,17 @@ export default {
}
.fixed-form-submit {
margin-top: 24px;
position: sticky !important;
padding: 14px var(--tainacan-one-column);
position: fixed;
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);
right: 0;
z-index: 9999;
background-color: var(--tainacan-gray1);
width: calc(100% - var(--tainacan-sidebar-width, 3.25em));
height: 60px;
display: flex;
justify-content: flex-end;
align-items: center;
transition: bottom 0.5s ease, width 0.2s linear;
}
</style>

View File

@ -281,6 +281,9 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
getCollectionActivityPath(collectionId, activityId) {
return '/collections/' + collectionId + '/activities/' + activityId;
},
getCollectionMapperEditPath(collectionId, mapperSlug) {
return '/collections/'+ collectionId + '/mappers/' + mapperSlug;
},
// New
getNewCollectionPath() {
return '/collections/new';

View File

@ -69,7 +69,7 @@ const routes = [
{ path: '/filters', name: 'FiltersPage', component: FiltersPage, meta: { title: i18nGet('title_repository_filters_page') } },
{ path: '/mappers', name: 'MappersPage', component: MappersPage, meta: { title: i18nGet('title_repository_mappers_page') } },
{ path: '/mappers/:mapperSlug', name: 'MappersEditionForm', component: MapperEditionForm, meta: { title: i18nGet('title_repository_mappers_edit_page') } },
{ path: '/mappers/:mapperSlug', name: 'MappersEditionForm', component: MapperEditionForm, meta: { title: i18nGet('title_repository_mappers_edit') } },
{ path: '/taxonomies', name: 'TaxonomyPage', component: TaxonomyPage, meta: { title: i18nGet('title_taxonomies_page') } },
{ path: '/taxonomies/new', name: 'TaxonomyCreationForm', component: TaxonomyEditionForm, meta: { title: i18nGet('title_create_taxonomy_page') } },

View File

@ -274,13 +274,24 @@ export const fetchMappers = ({commit}) => {
});
}
export const updateMapper = ({ dispatch }, {metadataMapperMetadata, mapper}) => {
export const updateMapper = ({ commit }, { isRepositoryLevel, collectionId, metadataMapperMetadata, disabled, mapper }) => {
return new Promise((resolve, reject) => {
var param = {
metadata_mappers: metadataMapperMetadata,
};
param[tainacan_plugin.exposer_mapper_param] = mapper;
axios.tainacan.post('/mappers', param).then((res) => {
let params = {};
if ( metadataMapperMetadata )
params['metadata_mappers'] = metadataMapperMetadata;
if ( disabled !== undefined )
params['disabled'] = disabled;
let endpoint = '/mappers/' + mapper;
if ( collectionId && !isRepositoryLevel )
endpoint = '/collection/' + collectionId + endpoint;
axios.tainacan.post(endpoint, params)
.then((res) => {
commit('updateMapper', mapper);
resolve(res.data);
})
.catch((error) => {
@ -439,8 +450,14 @@ export const fetchMetadataSectionMetadata = ({commit}, { collectionId , metadata
// MAPPERS
export const fetchMapper = ({commit}, { collectionId, mapperSlug }) => {
let endpoint = '/mappers/' + mapperSlug;
if ( collectionId )
endpoint = '/collection/' + collectionId + endpoint;
return new Promise((resolve, reject) => {
axios.tainacan.get('/mappers/' + mapperSlug)
axios.tainacan.get(endpoint)
.then((res) => {
let mapper = res.data;
commit('updateMapper', mapper);

View File

@ -14,6 +14,6 @@ export const getMappers = state => {
return state.mappers;
}
export const getMapper = (state, { mapperSlug }) => {
return state.mapper[0];
export const getMapper = (state) => {
return state.mapper;
}

View File

@ -6,6 +6,7 @@ const state = {
metadata: [],
metadatumTypes: [],
mappers: [],
mapper: {},
metadataSections: []
};

View File

@ -242,6 +242,6 @@ export const moveMetadatumDown = (state, { index, sectionIndex }) => {
state.metadataSections[sectionIndex].metadata_object_list.splice(index + 1, 0, state.metadataSections[sectionIndex].metadata_object_list.splice(index, 1)[0]);
}
export const updateMapper = (state, { mapper }) => {
//state.mappers ...;
export const updateMapper = (state, mapper) => {
state.mapper = mapper;
}

View File

@ -917,6 +917,7 @@ return apply_filters( 'tainacan-i18n', [
'info_target_collection_helper' => __( 'The collection where imported item will be added. Only those that you have permission are listed.', 'tainacan' ),
'info_source_file_upload' => __( 'The file containing the data to be imported.', 'tainacan' ),
'info_no_metadata_source_file' => __( 'No metadata was found from the source file.', 'tainacan' ),
'info_no_metadata_from_mapper' => __( 'No metadata was found from this mapper.', 'tainacan' ),
'info_no_special_fields_available' => __( 'No special field was found.', 'tainacan' ),
'info_special_fields_mapped_default' => __( 'Mapped to default field on collection.', 'tainacan' ),
'info_metadata_mapping_helper' => __( 'Map each file metadata with the corresponding one in selected collection.', 'tainacan' ),
@ -1051,6 +1052,7 @@ return apply_filters( 'tainacan-i18n', [
'info_%s_terms_created' => __( '%s terms created with success.', 'tainacan' ),
'info_terms_creation_failed_due_to_value_%s' => __( 'Terms creation failed due to value: %s.', 'tainacan' ),
'info_terms_creation_failed_due_to_values_%s' => __( 'Terms creation failed due to values: %s.', 'tainacan' ),
'info_mapper_extra_metadata' => __( 'You may create new metadata inside the mapper to map them to your own metadata.', 'tainacan' ),
/* Activity actions */
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),