Advanced search (see #22)

This commit is contained in:
weryques 2018-06-10 10:15:32 -03:00
parent d54f21f9c3
commit feeef1aaeb
10 changed files with 183 additions and 43 deletions

View File

@ -12,7 +12,7 @@
grouped> grouped>
<b-field class="column"> <b-field class="column">
<b-select <b-select
@input.native="addToAdvancedSearchQuery($event)"> @input="addToAdvancedSearchQuery($event, 'field_id', searchField)">
<option <option
v-for="metadata in metadataList" v-for="metadata in metadataList"
v-if="metadata.enabled" v-if="metadata.enabled"
@ -24,12 +24,12 @@
<b-field class="column is-two-thirds"> <b-field class="column is-two-thirds">
<b-input <b-input
@input.native="addValueToAdvancedSearchQuery($event)"/> @input="addValueToAdvancedSearchQuery($event, 'value', searchField)"/>
</b-field> </b-field>
<b-field class="column"> <b-field class="column">
<b-select <b-select
@input.native="addToAdvancedSearchQuery($event)"> @input="addToAdvancedSearchQuery($event, 'compare', searchField)">
<option <option
v-for="(opt, key) in compare" v-for="(opt, key) in compare"
:value="key" :value="key"
@ -71,6 +71,7 @@
</div> </div>
</div> </div>
</div> </div>
<pre>{{ advancedSearchQuery }}</pre>
</div> </div>
</template> </template>
@ -83,9 +84,19 @@
}, },
data() { data() {
return { return {
compare: {'=':'Igual', '!=':'Diferente', 'IN':'Contém', 'NOT IN':'Não Contém'}, compare: {
'=': this.$i18n.get('is_equal_to'),
'!=': this.$i18n.get('is_not_equal_to'),
'IN': this.$i18n.get('contains'),
'NOT IN': this.$i18n.get('not_contains')
},
totalSearchMetadata: 1, totalSearchMetadata: 1,
advancedSearchQuery: {}, advancedSearchQuery: {
advancedSearch: true,
metaquery: {
relation: 'AND',
}
},
} }
}, },
methods: { methods: {
@ -94,15 +105,35 @@
}, },
clearSearch(){ clearSearch(){
this.totalSearchMetadata = 1; this.totalSearchMetadata = 1;
this.advancedSearchQuery = {
advancedSearch: true,
relation: 'AND',
};
}, },
addValueToAdvancedSearchQuery: _.debounce(($event) => { addValueToAdvancedSearchQuery: _.debounce(function(value, type, relation) {
console.log($event); let vm = this;
vm.addToAdvancedSearchQuery(value, type, relation);
}, 900), }, 900),
searchAdvanced(){ searchAdvanced(){
this.$eventBusSearch.$emit('searchAdvanced', this.advancedSearchQuery);
}, },
addToAdvancedSearchQuery($event){ addToAdvancedSearchQuery(value, type, relation){
console.log($event); if(this.advancedSearchQuery.metaquery.hasOwnProperty(relation)){
//if(this.advancedSearchQuery[relation].compare === 'IN'){
//this.advancedSearchQuery[relation][type] = value.split(' ');
//} else {
this.advancedSearchQuery.metaquery[relation][type] = value;
//}
} else {
this.advancedSearchQuery.metaquery = Object.assign({}, this.advancedSearchQuery.metaquery, {
[`${relation}`]: {
[`${type}`]: value,
}
});
}
console.log(this.advancedSearchQuery);
}, },
} }
} }

View File

@ -46,7 +46,7 @@ import VueMask from 'v-mask';
// Configure and Register Plugins // Configure and Register Plugins
Vue.use(Buefy); Vue.use(Buefy);
Vue.use(VTooltip) Vue.use(VTooltip);
Vue.use(I18NPlugin); Vue.use(I18NPlugin);
Vue.use(UserPrefsPlugin); Vue.use(UserPrefsPlugin);
Vue.use(RouterHelperPlugin); Vue.use(RouterHelperPlugin);

View File

@ -315,11 +315,38 @@
<!-- ITEMS LISTING RESULTS ------------------------- --> <!-- ITEMS LISTING RESULTS ------------------------- -->
<div class="above-search-control"> <div class="above-search-control">
<div
v-if="openAdvancedSearch && advancedSearchResults">
<div class="advanced-search-results-title">
<h1>{{ $i18n.get('info_search_results') }}</h1>
<hr>
</div>
</div>
<!-- Admin Table --> <!-- Admin Table -->
<!-- When advanced search -->
<items-list <items-list
v-if="!isOnTheme && v-if="!isOnTheme &&
!isLoadingItems && !isLoadingItems &&
totalItems > 0" totalItems > 0 &&
openAdvancedSearch &&
advancedSearchResults"
:collection-id="collectionId"
:table-fields="tableFields"
:items="items"
:is-loading="isLoadingItems"
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"/>
<!-- Regular -->
<items-list
v-else-if="!isOnTheme &&
!isLoadingItems &&
totalItems > 0 &&
!openAdvancedSearch"
:collection-id="collectionId" :collection-id="collectionId"
:table-fields="tableFields" :table-fields="tableFields"
:items="items" :items="items"
@ -371,7 +398,18 @@
</section> </section>
<!-- Pagination --> <!-- Pagination -->
<pagination v-if="totalItems > 0 && (!isOnTheme || registeredViewModes[viewMode].show_pagination)"/>
<!-- When advanced search -->
<pagination
v-if="totalItems > 0 &&
(!isOnTheme || registeredViewModes[viewMode].show_pagination) &&
advancedSearchResults"/>
<!-- Regular -->
<pagination
v-else-if="totalItems > 0 &&
(!isOnTheme || registeredViewModes[viewMode].show_pagination) &&
!openAdvancedSearch"/>
</div> </div>
</div> </div>
@ -405,6 +443,7 @@
registeredViewModes: tainacan_plugin.registered_view_modes, registeredViewModes: tainacan_plugin.registered_view_modes,
adminViewMode: 'table', adminViewMode: 'table',
openAdvancedSearch: false, openAdvancedSearch: false,
advancedSearchResults: false,
} }
}, },
props: { props: {
@ -669,6 +708,23 @@
@import '../../scss/_variables.scss'; @import '../../scss/_variables.scss';
.advanced-search-results-title {
padding: 0 $table-side-padding;
h1 {
font-size: 20px;
font-weight: 500;
color: $tertiary;
display: inline-block;
}
hr{
margin: 3px 0px 4px 0px;
height: 1px;
background-color: $secondary;
}
}
.tnc-advanced-search-close { .tnc-advanced-search-close {
padding-top: 47px; padding-top: 47px;
padding-right: $page-side-padding; padding-right: $page-side-padding;

View File

@ -1,6 +1,13 @@
<?php <?php
return [ return [
// Advanced search comparators
'is_equal_to' => __( 'Equal', 'tainacan' ),
'is_not_equal_to' => __( 'Not Equal', 'tainacan'),
'contains' => __( 'Contains', 'tainacan'),
'not_contains' => __( 'Not Contains', 'tainacan' ),
// Tainacan common terms // Tainacan common terms
'repository' => __( 'Repository', 'tainacan' ), 'repository' => __( 'Repository', 'tainacan' ),
'collections' => __( 'Collections', 'tainacan' ), 'collections' => __( 'Collections', 'tainacan' ),
@ -228,6 +235,7 @@ return [
'instruction_search_on_repository' => __( 'Search on repository', 'tainacan' ), 'instruction_search_on_repository' => __( 'Search on repository', 'tainacan' ),
// Info. Other feedback to user. // Info. Other feedback to user.
'info_search_results' => __( 'Search Results', 'tainacan' ),
'info_name_is_required' => __( 'Name is required.', 'tainacan' ), 'info_name_is_required' => __( 'Name is required.', 'tainacan' ),
'info_no_collection_created' => __( 'No collection was created in this repository.', 'tainacan' ), 'info_no_collection_created' => __( 'No collection was created in this repository.', 'tainacan' ),
'info_no_collection_draft' => __( 'No draft collection found.', 'tainacan' ), 'info_no_collection_draft' => __( 'No draft collection found.', 'tainacan' ),

View File

@ -24,6 +24,16 @@ export default {
this.updateURLQueries(); this.updateURLQueries();
}); });
this.$root.$on('searchAdvanced', advancedSearchQuery => {
this.$store.dispatch('search/setPage', 1);
console.log('Emit caught', advancedSearchQuery);
this.searchAdvanced(advancedSearchQuery);
this.updateURLQueries();
});
}, },
watch: { watch: {
'$route' (to, from) { '$route' (to, from) {
@ -40,7 +50,15 @@ export default {
if (this.$route.query.orderby == undefined) if (this.$route.query.orderby == undefined)
this.$route.query.orderby = 'date'; this.$route.query.orderby = 'date';
if(this.$route.query.advancedSearch){
delete this.$route.query.advancedSearch;
console.log('Route watch: '+ this.$route.query);
this.$store.dispatch('search/set_advanced_query', this.$route.query);
} else {
this.$store.dispatch('search/set_postquery', this.$route.query); this.$store.dispatch('search/set_postquery', this.$route.query);
}
this.loadItems(to); this.loadItems(to);
} }
@ -48,6 +66,10 @@ export default {
} }
}, },
methods: { methods: {
searchAdvanced(data) {
this.$store.dispatch('search/set_advanced_query', data);
this.updateURLQueries(true);
},
add_metaquery( data ){ add_metaquery( data ){
if ( data && data.collection_id ){ if ( data && data.collection_id ){
this.$store.dispatch('search/add_metaquery', data ); this.$store.dispatch('search/add_metaquery', data );
@ -112,9 +134,15 @@ export default {
this.$store.dispatch('search/setViewMode', viewMode); this.$store.dispatch('search/setViewMode', viewMode);
this.updateURLQueries(); this.updateURLQueries();
}, },
updateURLQueries() { updateURLQueries(isAdvancedSearch = false) {
this.$router.push({ query: {}}); this.$router.push({ query: {}});
if(isAdvancedSearch) {
this.$router.push({query: this.$store.getters['search/getAdvancedSearchQuery']});
console.log(this.$route);
} else {
this.$router.push({query: this.$store.getters['search/getPostQuery']}); this.$router.push({query: this.$store.getters['search/getPostQuery']});
}
}, },
updateStoreFromURL() { updateStoreFromURL() {
this.$store.dispatch('search/set_postquery', this.$route.query); this.$store.dispatch('search/set_postquery', this.$route.query);
@ -126,8 +154,9 @@ export default {
this.$emit( 'hasToPrepareFieldsAndFilters', to); this.$emit( 'hasToPrepareFieldsAndFilters', to);
} else { } else {
this.$emit( 'isLoadingItems', true); this.$emit( 'isLoadingItems', true);
this.$store.dispatch('collection/fetchItems',
{ 'collectionId': this.collectionId, this.$store.dispatch('collection/fetchItems', {
'collectionId': this.collectionId,
'isOnTheme': (this.$route.name == null) 'isOnTheme': (this.$route.name == null)
}) })
.then((res) => { .then((res) => {

View File

@ -3,6 +3,7 @@ import qs from 'qs';
export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, isOnTheme }) => { export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, isOnTheme }) => {
commit('cleanItems'); commit('cleanItems');
return new Promise ((resolve, reject) => { return new Promise ((resolve, reject) => {
// Adds queries for filtering // Adds queries for filtering
@ -48,7 +49,7 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
}); });
} };
export const deleteItem = ({ commit }, { itemId, isPermanently }) => { export const deleteItem = ({ commit }, { itemId, isPermanently }) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -86,7 +87,7 @@ export const fetchCollections = ({commit} , { page, collectionsPerPage, status }
reject(error); reject(error);
}); });
}); });
} };
export const fetchCollection = ({ commit }, id) => { export const fetchCollection = ({ commit }, id) => {
commit('cleanCollection'); commit('cleanCollection');
@ -101,7 +102,7 @@ export const fetchCollection = ({ commit }, id) => {
reject(error); reject(error);
}) })
}); });
} };
export const fetchCollectionName = ({ commit }, id) => { export const fetchCollectionName = ({ commit }, id) => {
//commit('cleanCollectionName'); //commit('cleanCollectionName');
@ -116,7 +117,7 @@ export const fetchCollectionName = ({ commit }, id) => {
reject(error); reject(error);
}) })
}); });
} };
export const deleteCollection = ({ commit }, { collectionId, isPermanently }) => { export const deleteCollection = ({ commit }, { collectionId, isPermanently }) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -134,7 +135,7 @@ export const deleteCollection = ({ commit }, { collectionId, isPermanently }) =>
reject(error); reject(error);
}) })
}); });
} };
export const updateCollection = ({ commit }, { export const updateCollection = ({ commit }, {
collection_id, collection_id,
@ -181,7 +182,7 @@ export const updateCollection = ({ commit }, {
}); });
}); });
} };
export const sendCollection = ( { commit }, { name, description, status }) => { export const sendCollection = ( { commit }, { name, description, status }) => {
return new Promise(( resolve, reject ) => { return new Promise(( resolve, reject ) => {
@ -329,4 +330,4 @@ export const fetchCollectionsForParent = ({ commit }) => {
reject(error); reject(error);
}) })
}); });
} };

View File

@ -7,6 +7,10 @@ export const set_postquery = ({ commit }, postquery ) => {
commit('setPostQuery', postquery ); commit('setPostQuery', postquery );
}; };
export const set_advanced_query = ({commit}, advancedSearchQuery) => {
commit('setAdvancedSearchQuery', advancedSearchQuery);
};
// Meta Queries from filters // Meta Queries from filters
export const add_metaquery = ( { commit }, filter ) => { export const add_metaquery = ( { commit }, filter ) => {
if( filter && filter.value.length === 0 ){ if( filter && filter.value.length === 0 ){

View File

@ -1,25 +1,29 @@
export const getPostQuery = state => { export const getPostQuery = state => {
return state.postquery; return state.postquery;
} };
export const getAdvancedSearchQuery = state => {
return state.advancedSearchQuery;
};
export const getMetaQuery = state => { export const getMetaQuery = state => {
return state.metaquery; return state.metaquery;
} };
export const getTaxQuery = state => { export const getTaxQuery = state => {
return state.taxquery; return state.taxquery;
} };
export const getTotalItems = state => { export const getTotalItems = state => {
return state.totalItems; return state.totalItems;
} };
export const getPage = state => { export const getPage = state => {
if (state.postquery.paged == undefined) if (state.postquery.paged == undefined)
return 1; return 1;
else else
return Number(state.postquery.paged); return Number(state.postquery.paged);
} };
export const getItemsPerPage = state => { export const getItemsPerPage = state => {
if (state.postquery.paged == undefined) if (state.postquery.paged == undefined)
@ -30,7 +34,7 @@ export const getItemsPerPage = state => {
export const getOrder = state => { export const getOrder = state => {
return state.postquery.order; return state.postquery.order;
} };
export const getOrderBy = state => { export const getOrderBy = state => {
return state.postquery.orderby; return state.postquery.orderby;
@ -38,20 +42,20 @@ export const getOrderBy = state => {
export const getSearchQuery = state => { export const getSearchQuery = state => {
return state.postquery.search; return state.postquery.search;
} };
export const getStatus = state => { export const getStatus = state => {
return state.postquery.status; return state.postquery.status;
} };
export const getViewMode = state => { export const getViewMode = state => {
return state.postquery.view_mode; return state.postquery.view_mode;
} };
export const getFetchOnly = state => { export const getFetchOnly = state => {
return state.postquery.fetch_only; return state.postquery.fetch_only;
} };
export const getFetchOnlyMeta = state => { export const getFetchOnlyMeta = state => {
return ( ! state.postquery.fetch_only['meta'] ) ? [] : state.postquery.fetch_only['meta']; return ( ! state.postquery.fetch_only['meta'] ) ? [] : state.postquery.fetch_only['meta'];
} };

View File

@ -21,6 +21,7 @@ const state = {
}, },
view_mode: 'table' view_mode: 'table'
}, },
advancedSearchQuery: {},
totalItems: 0 totalItems: 0
}; };

View File

@ -8,9 +8,15 @@ export const setPostQuery = ( state, postquery ) => {
state.postquery = postquery; state.postquery = postquery;
}; };
export const setAdvancedSearchQuery = (state, advancedSearchQuery) => {
state.advancedSearchQuery = advancedSearchQuery;
};
export const addMetaQuery = ( state, filter ) => { export const addMetaQuery = ( state, filter ) => {
state.postquery.metaquery = ( ! state.postquery.metaquery ) ? [] : state.postquery.metaquery; state.postquery.metaquery = ( ! state.postquery.metaquery ) ? [] : state.postquery.metaquery;
let index = state.postquery.metaquery.findIndex( item => item.key === filter.field_id); let index = state.postquery.metaquery.findIndex( item => item.key === filter.field_id);
if ( index >= 0 ){ if ( index >= 0 ){
Vue.set( state.postquery.metaquery, index, { Vue.set( state.postquery.metaquery, index, {
key: filter.field_id, key: filter.field_id,