Begins implementation of Importer interface.

This commit is contained in:
Mateus Machado Luna 2018-06-18 17:11:57 -03:00
parent e1a160fce2
commit e5979dc55a
10 changed files with 451 additions and 5 deletions

View File

@ -0,0 +1,204 @@
<template>
<div
class="page-container">
<tainacan-title />
<form
class="tainacan-form"
label-width="120px">
<div class="columns">
<div class="column">
<!-- Status -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_registered_importer_types')">
<help-button
:title="$i18n.get('label_registered_importer_types')"
:message="$i18n.get('info_registered_importer_types_helper')"/>
<b-select
id="tainacan-select-registered-importer-types"
v-model="importerType"
:placeholder="$i18n.get('instruction_select_an_importer_type')">
<option
v-for="anImporterType in importerTypes"
:key="anImporterType.slug"
:value="anImporterType.slug">{{ statusOption.label }}
</option>
</b-select>
</b-field>
<!-- Target collection selection -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_target_collection')">
<help-button
:title="$i18n.get('label_target_collection')"
:message="$i18n.get('info_target_collection_helper')"/>
<b-select
id="tainacan-select-target-collection"
v-model="form.collectionId"
:loading="isFetchingCollections"
:placeholder="$i18n.get('instruction_select_a_target_collection')">
<option
v-for="collection of collections"
:key="collection.id"
:value="collection.id">{{ collection.name }}
</option>
</b-select>
</b-field>
</div>
</div>
</form>
<b-loading
:active.sync="isLoading"
:can-cancel="false"/>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'ImporterEditionForm',
data(){
return {
importerId: Number,
importer: null,
isLoading: false,
isFetchingCollections: false,
form: {
collectionId
},
importerTypes: [],
importerType: '',
importerFile: {},
importerSourceInfo: {},
collections: [],
}
},
methods: {
...mapActions('importer', [
'fetchImporterTypes',
'fetchImporter',
'sendImporter',
'updateImporter',
'updateImporterFile',
'fetchImporterSourceInfo',
'runImporter'
]),
...mapActions('collection', [
'fetchCollectionsForParent',
]),
onSubmit() {
this.isLoading = true;
let data = {
collection_id: this.collectionId
};
this.updateImporter({ sessionId: this.sessionId, options: data })
.then(updatedImporter => {
this.importer = updatedImporter;
this.form = this.updateImporter.options;
this.$router.push(this.$routerHelper.getCollectionPath(this.collectionId));
})
.catch((errors) => {
this.$console.log(errors);
this.isLoading = false;
});
},
createImporter() {
// Puts loading on Draft Importer creation
this.isLoading = true;
// Creates draft Importer
let data = { collectionId: '' };
this.sendImporter(data).then(res => {
this.sessionId = res.id;
this.form = res.options;
this.isLoading = false;
})
.catch(error => this.$console.error(error));
},
cancelBack(){
this.$router.push(this.$routerHelper.getCollectionsPath());
},
runImporter() {
this.runImporter({ sessionId: this.sessionId })
.then(backgroundProcess => {
this.$console.log(backgroundProcess);
})
.catch((errors) => {
this.$console.log(errors);
});
}
},
created(){
if (this.$route.fullPath.split("/").pop() == "new") {
this.createImporter();
} else {
this.isLoading = true;
// Obtains current Session ID from URL
this.pathArray = this.$route.fullPath.split("/").reverse();
this.sessionId = this.pathArray[1];
this.fetchImporter(this.sessionId).then(res => {
this.importer = res;
this.form = res.options;
this.isLoading = false;
});
}
// Generates options for target collection
this.isFetchingCollections = true;
this.fetchCollectionsForParent()
.then((collections) => {
this.collections = collections;
this.isFetchingCollections = false;
})
.catch((error) => {
this.$console.error(error);
this.isFetchingCollections = false;
});
},
mounted() {
if (this.$route.fullPath.split("/").pop() != "new") {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
}
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
.field {
position: relative;
}
.section-label {
font-size: 16px !important;
font-weight: 500 !important;
color: $tertiary !important;
line-height: 1.2em;
}
</style>

View File

@ -16,8 +16,10 @@ import EventPage from '../pages/singles/event-page.vue'
// Edition Form Components
import CollectionEditionForm from '../components/edition/collection-edition-form.vue'
import ImporterEditionForm from '../components/edition/importer-edition-form.vue'
import ItemEditionForm from '../components/edition/item-edition-form.vue'
import TaxonomyEditionForm from '../components/edition/taxonomy-edition-form.vue'
import AvailableImportersPage from '../pages/lists/available-importers-page.vue';
// Listing components
import FiltersList from '../components/lists/filters-list.vue'
@ -66,6 +68,11 @@ const routes = [
{ path: '/events', name: 'EventsPage', component: EventsPage, meta: {title: i18nGet('title_repository_events_page'), icon: 'flash'} },
{ path: '/events/:eventId', name: 'EventPage', component: EventPage, meta: {title: i18nGet('title_event_page'), icon: 'flash'} },
{ path: '/importers', redirect:'/importers/new' },
{ path: '/importers/new', name: 'AvailableImportersPage', component: AvailableImportersPage, meta: {title: i18nGet('title_available_importers_page'), icon: 'file-multiple'} },
{ path: '/importers/:sessionId', name: 'ImporterEditionForm', component: ImporterEditionForm, meta: {title: i18nGet('title_importer_page'), icon: 'file-multiple'} },
{ path: '/importers/:sessionId/edit', name: 'ImporterEditionForm', component: ImporterEditionForm, meta: {title: i18nGet('title_importer_page'), icon: 'file-multiple'} },
{ path: '*', redirect: '/'}
];

View File

@ -202,6 +202,9 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
getEventsPath(query) {
return '/events/?' + qs.stringify(query);
},
getAvailableImportersPath() {
return '/importers/new';
},
// Singles
getCollectionPath(id) {
return '/collections/' + id;
@ -270,7 +273,10 @@ RouterHelperPlugin.install = function (Vue, options = {}) {
},
getEventEditPath(id) {
return '/events/' + id + '/edit';
}
},
getImporterEditionPath() {
return '/importers/session';
},
}
}

View File

@ -0,0 +1,63 @@
<template>
<div class="page-container">
<tainacan-title />
<h3>{{ $i18n.get('label_available_importers') }}</h3>
<p>{{ $i18n.get('info_available_importers_helper') }}</p>
<p>{{ $i18n.get('instruction_select_an_importer_type') }}</p>
<div
v-for="importerType in availableImporters"
:key="importerType.slug"
@click="onSelectImporter(importerType)">
<p>{{ importerType.label }}</p>
<p>{{ importerType.description }}</p>
</div>
<b-loading
:active.sync="isLoading"
:can-cancel="false"/>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
name: 'ImporterEditionForm',
data(){
return {
availableImporters: [],
isLoading: false
}
},
methods: {
...mapActions('importer', [
'fetchAvailableImporters'
]),
onSelectImporter() {
this.$router.push(this.$routerHelper.getImporterEditionPath());
}
},
created() {
this.isLoading = true;
this.fetchAvailableImporters()
.then((res) => {
this.availableImporters = res;
this.isLoading = false;
}).catch((error) => {
this.$console.log(error);
this.isLoading = false;
});
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
</style>

View File

@ -66,14 +66,14 @@ return apply_filters('tainacan-admin-i18n',[
// Page Titles (used mainly on Router)
'title_repository_collections_page' => __( 'Repository Collections', 'tainacan' ),
'title_items_page' => __( 'Items', 'tainacan' ),
'title_repository_metadata_page' => __( 'Repository Metadata', 'tainacan' ),
'title_repository_metadata_page' => __( 'Repository Metadata', 'tainacan' ),
'title_repository_filters_page' => __( 'Repository Filters', 'tainacan' ),
'title_taxonomies_page' => __( 'Taxonomies Page', 'tainacan' ),
'title_terms_page' => __( 'Terms', 'tainacan' ),
'title_repository_events_page' => __( 'Repository Events', 'tainacan' ),
'title_collection_page' => __( 'Collection', 'tainacan' ),
'title_item_page' => __( 'Item', 'tainacan' ),
'title_metadatum_page' => __( 'Metadata', 'tainacan' ),
'title_metadatum_page' => __( 'Metadata', 'tainacan' ),
'title_collection_events' => __( 'Collection Events', 'tainacan' ),
'title_filter_page' => __( 'Filter', 'tainacan' ),
'title_taxonomy_page' => __( 'Taxonomy', 'tainacan' ),
@ -87,9 +87,11 @@ return apply_filters('tainacan-admin-i18n',[
'title_edit_item' => __( 'Edit Item', 'tainacan' ),
'title_taxonomy_edition_page' => __( 'Taxonomy Edition', 'tainacan' ),
'title_filter_edition' => __( 'Filter Edition', 'tainacan' ),
'title_metadatum_edition' => __( 'Metadata Edition', 'tainacan' ),
'title_collection_metadata_edition' => __( 'Edit Metadata of', 'tainacan' ),
'title_metadatum_edition' => __( 'Metadata Edition', 'tainacan' ),
'title_collection_metadata_edition' => __( 'Edit Metadata of', 'tainacan' ),
'title_collection_filters_edition' => __( 'Edit Filters of', 'tainacan' ),
'title_importer_page' => __( 'Importer', 'tainacan' ),
'title_available_importers_page' => __( 'Available Importers', 'tainacan' ),
// Labels (used mainly on Aria Labels and Inputs)
'label_clean' => __( 'Clear', 'tainacan' ),
@ -214,6 +216,7 @@ return apply_filters('tainacan-admin-i18n',[
'label_table' => __( 'Table', 'tainacan' ),
'label_cards' => __( 'Cards', 'tainacan' ),
'label_visualization' => __( 'Visualization', 'tainacan' ),
'label_available_importers' => __( 'Available Importers', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -303,6 +306,8 @@ return apply_filters('tainacan-admin-i18n',[
'info_create_filters' => __( 'Click or Drag and Drop Metadata here for creating a new Filter.', 'tainacan' ),
'info_create_metadata' => __( 'Click or Drag and Drop Metadata Types here for creating a new Metadata.', 'tainacan' ),
'info_choose_your_metadata' => __( 'Choose your metadata.', 'tainacan' ),
'info_available_importers_helper' => __( 'The available importer type will affect the file or link that will provide your data besides deciding wich options are available to the importer.', 'tainacan' ),
'info_select_a_target_collection' => __( 'The collection to which imported data will be send.', 'tainacan' ),
// Tainacan Metadatum Types
'tainacan-text' => __( 'Text', 'tainacan' ),

View File

@ -0,0 +1,109 @@
import axios from '../../../axios/axios';
// IMPORTER ----------------------------------------------------
export const fetchAvailableImporters = ({ commit }) => {
return new Promise((resolve, reject) => {
axios.tainacan.get('importers/available')
.then((res) => {
let availableImporters = res.data;
commit('setAvailableImporters', availableImporters);
resolve (availableImporters);
})
.catch((error) => {
reject(error);
});
});
};
export const fetchImporter = ( { commit } , { importerId }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('importers/session/' + importerId)
.then( res => {
let importer = res.data;
commit('setImporter', importer);
resolve( importer );
})
.catch(error => {
reject( error );
});
});
};
export const sendImporter = ( { commit }, importerTypeSlug) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('importers/session/', {
importer_slug: importerTypeSlug
})
.then( res => {
let importer = res.data;
commit('setImporter', importer);
resolve( importer );
})
.catch(error => {
reject( error );
});
});
};
export const updateImporter = ( { commit }, { sessionId, options }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.put('importers/session/' + sessionId, options)
.then( res => {
let importer = res.data;
commit('setImporter', importer);
resolve( importer );
})
.catch(error => {
reject(error);
});
});
};
export const updateImporterFile = ( { commit }, { sessionId, file }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.put('importers/session/' + sessionId + '/file/' + file)
.then( res => {
let importerFile = res.data;
commit('setImporterFile', importerFile);
resolve( importerFile );
})
.catch(error => {
reject(error);
});
});
};
export const fetchImporterSourceInfo = ({ commit }, sessionId ) => {
return new Promise((resolve, reject) => {
axios.tainacan.get('/importers/' + sessionId + 'sessionId')
.then((res) => {
let importerSourceInfo = res.data;
commit('setImporterSourceInfo', importerSourceInfo);
resolve (importerSourceInfo);
})
.catch((error) => {
reject(error);
});
});
};
export const runImporter = ( { commit } , { importerId }) => {
return new Promise(( resolve, reject ) => {
axios.tainacan.post('importers/' + importerId + '/run')
.then( res => {
let backgroundProcessId = res.data;
// probably send this a dedicated store to background process
//commit('background/addBackgroundProcess', backgroundProcessId);
resolve( backgroundProcessId );
})
.catch(error => {
reject( error );
});
});
};

View File

@ -0,0 +1,15 @@
export const getgetAvailableImporters = state => {
return state.available_importers;
}
export const getImporter = state => {
return state.importer
}
export const getImporterSourceInfo = state => {
return state.importer_source_info;
}
export const getImporterFile = state => {
return state.importer_file;
}

View File

@ -0,0 +1,18 @@
import * as actions from './actions';
import * as getters from './getters';
import * as mutations from './mutations';
const state = {
importer: {},
available_importers: [],
importer_file: {},
importer_source_info: {}
};
export default {
namespaced: true,
state,
mutations,
actions,
getters
}

View File

@ -0,0 +1,17 @@
import Vue from 'vue';
export const setAvailableImporters = (state, availableImporters) => {
state.available_importers = availableImporters;
}
export const setImporter = (state, importer) => {
state.importer = importer
}
export const setImporterFile = (state, importerFile) => {
state.importer_file = importerFile;
}
export const setImporterSourceInfo= (state, importerSourceInfo) => {
state.importer_source_info = importerSourceInfo;
}

View File

@ -8,6 +8,7 @@ import filter from './modules/filter/';
import search from './modules/search/';
import taxonomy from './modules/taxonomy/';
import event from './modules/event';
import importer from './modules/importer';
Vue.use(Vuex);
@ -28,5 +29,6 @@ export default new Vuex.Store({
search,
taxonomy,
event,
importer
}
})