Advanced search for metaquery and taxquery (#22)
This commit is contained in:
parent
65dc6f1667
commit
a4133f819e
|
@ -10,33 +10,65 @@
|
||||||
<b-field
|
<b-field
|
||||||
class="columns"
|
class="columns"
|
||||||
grouped>
|
grouped>
|
||||||
|
|
||||||
|
<!-- Metadata (Search criterias) -->
|
||||||
<b-field class="column">
|
<b-field class="column">
|
||||||
<b-select
|
<b-select
|
||||||
@input="addToAdvancedSearchQuery($event, 'key', searchCriteria)">
|
:disabled="advancedSearchQuery.taxquery[searchCriteria] ||
|
||||||
|
advancedSearchQuery.metaquery[searchCriteria] ? true : false"
|
||||||
|
@input="addToAdvancedSearchQuery($event, 'metadatum', searchCriteria)">
|
||||||
<option
|
<option
|
||||||
v-for="metadata in metadataList"
|
v-for="metadatum in metadata"
|
||||||
v-if="metadata.enabled"
|
v-if="metadatum.enabled"
|
||||||
:value="metadata.id"
|
:value="`${metadatum.id}-${metadatum.metadata_type_options.taxonomy}`"
|
||||||
:key="metadata.id"
|
:key="metadatum.id"
|
||||||
>{{ metadata.name }}</option>
|
>{{ metadatum.name }}</option>
|
||||||
</b-select>
|
</b-select>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field class="column is-two-thirds">
|
<!-- Inputs -->
|
||||||
|
<b-field
|
||||||
|
class="column is-two-thirds">
|
||||||
<b-input
|
<b-input
|
||||||
@input="addValueToAdvancedSearchQuery($event, 'value', searchCriteria)"/>
|
v-if="advancedSearchQuery.metaquery[searchCriteria]"
|
||||||
|
@input="addValueToAdvancedSearchQuery($event, 'value', searchCriteria)"
|
||||||
|
/>
|
||||||
|
<b-taginput
|
||||||
|
v-else-if="advancedSearchQuery.taxquery[searchCriteria]"
|
||||||
|
:data="terms"
|
||||||
|
autocomplete
|
||||||
|
attached
|
||||||
|
ellipsis
|
||||||
|
@add="addValueToAdvancedSearchQuery($event, 'terms', searchCriteria)"
|
||||||
|
@typing="autoCompleteTerm($event, searchCriteria)"
|
||||||
|
/>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field class="column">
|
<!-- Comparators -->
|
||||||
|
<b-field
|
||||||
|
class="column">
|
||||||
<b-select
|
<b-select
|
||||||
@input="addToAdvancedSearchQuery($event, 'compare', searchCriteria)">
|
v-if="advancedSearchQuery.taxquery[searchCriteria] ||
|
||||||
<option
|
advancedSearchQuery.metaquery[searchCriteria] ? true : false"
|
||||||
v-for="(opt, key) in compare"
|
@input="addToAdvancedSearchQuery($event, 'comparator', searchCriteria)">
|
||||||
:value="key"
|
|
||||||
|
<option
|
||||||
|
v-for="(comparator, key) in getComparators(searchCriteria)"
|
||||||
:key="key"
|
:key="key"
|
||||||
>{{ opt }}</option>
|
:value="key"
|
||||||
|
>{{ comparator }}</option>
|
||||||
</b-select>
|
</b-select>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<button
|
||||||
|
@click="removeThis(searchCriteria)"
|
||||||
|
class="button is-white is-pulled-right">
|
||||||
|
<b-icon
|
||||||
|
size="is-small"
|
||||||
|
icon="close"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,12 +84,12 @@
|
||||||
<a
|
<a
|
||||||
@click="addSearchCriteria"
|
@click="addSearchCriteria"
|
||||||
class="is-secondary is-small">
|
class="is-secondary is-small">
|
||||||
{{ $i18n.get('add_more_one_search_criteria') }}</a>
|
{{ $i18n.get('add_another_search_criteria') }}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:class="{'tag-container-border': Object.keys(advancedSearchQuery).length > 1}"
|
:class="{'tag-container-border': Object.keys(advancedSearchQuery.taxquery).length > 0 || Object.keys(advancedSearchQuery.metaquery).length > 0}"
|
||||||
class="field column is-12">
|
class="field column is-12">
|
||||||
<b-field
|
<b-field
|
||||||
:style="{'padding': '0.3rem 0 0 0'}"
|
:style="{'padding': '0.3rem 0 0 0'}"
|
||||||
|
@ -68,15 +100,26 @@
|
||||||
:key="searchCriteria"
|
:key="searchCriteria"
|
||||||
class="control taginput-container">
|
class="control taginput-container">
|
||||||
<b-tag
|
<b-tag
|
||||||
v-if="advancedSearchQuery[searchCriteria] && advancedSearchQuery[searchCriteria].value"
|
v-if="(advancedSearchQuery.taxquery[searchCriteria] && advancedSearchQuery.taxquery[searchCriteria].terms)"
|
||||||
type="is-white"
|
type="is-white"
|
||||||
@close="removeThis(searchCriteria)"
|
@close="removeValueOf(searchCriteria)"
|
||||||
attached
|
attached
|
||||||
closable>
|
closable>
|
||||||
{{ Array.isArray(advancedSearchQuery[searchCriteria].value) ?
|
{{ Array.isArray(advancedSearchQuery.taxquery[searchCriteria].terms) ?
|
||||||
advancedSearchQuery[searchCriteria].value.toString() :
|
advancedSearchQuery.taxquery[searchCriteria].btags.toString() :
|
||||||
advancedSearchQuery[searchCriteria].value }}
|
advancedSearchQuery.taxquery[searchCriteria].btags }}
|
||||||
</b-tag>
|
</b-tag>
|
||||||
|
<b-tag
|
||||||
|
v-else-if="(advancedSearchQuery.metaquery[searchCriteria] && advancedSearchQuery.metaquery[searchCriteria].value)"
|
||||||
|
type="is-white"
|
||||||
|
@close="removeValueOf(searchCriteria)"
|
||||||
|
attached
|
||||||
|
:loading="isFetching"
|
||||||
|
closable>
|
||||||
|
{{ Array.isArray(advancedSearchQuery.metaquery[searchCriteria].value) ?
|
||||||
|
advancedSearchQuery.metaquery[searchCriteria].value:
|
||||||
|
advancedSearchQuery.metaquery[searchCriteria].value }}
|
||||||
|
</b-tag>
|
||||||
</div>
|
</div>
|
||||||
</b-field>
|
</b-field>
|
||||||
</div>
|
</div>
|
||||||
|
@ -95,42 +138,108 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<pre>{{ advancedSearchQuery }}</pre>
|
<!-- <pre>{{ advancedSearchQuery }}</pre> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AdvancedSearch",
|
name: "AdvancedSearch",
|
||||||
props: {
|
props: {
|
||||||
metadataList: Array,
|
metadata: Array,
|
||||||
isRepositoryLevel: false,
|
isRepositoryLevel: false,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
compare: {
|
metaqueryOperators: {
|
||||||
'=': this.$i18n.get('is_equal_to'),
|
'=': this.$i18n.get('is_equal_to'),
|
||||||
'!=': this.$i18n.get('is_not_equal_to'),
|
'!=': this.$i18n.get('is_not_equal_to'),
|
||||||
|
'LIKE': this.$i18n.get('contains'),
|
||||||
|
'NOT LIKE': this.$i18n.get('not_contains')
|
||||||
|
},
|
||||||
|
taxqueryOperators: {
|
||||||
'IN': this.$i18n.get('contains'),
|
'IN': this.$i18n.get('contains'),
|
||||||
'NOT IN': this.$i18n.get('not_contains')
|
'NOT IN': this.$i18n.get('not_contains')
|
||||||
},
|
},
|
||||||
searchCriterias: [1],
|
searchCriterias: [1],
|
||||||
advancedSearchQuery: {
|
advancedSearchQuery: {
|
||||||
advancedSearch: true,
|
advancedSearch: true,
|
||||||
|
metaquery: {},
|
||||||
|
taxquery: {},
|
||||||
},
|
},
|
||||||
|
termList: [],
|
||||||
|
terms: [],
|
||||||
|
isFetching: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions('taxonomy', [
|
||||||
|
'fetchTerms'
|
||||||
|
]),
|
||||||
|
...mapGetters('taxonomy', [
|
||||||
|
'getTerms'
|
||||||
|
]),
|
||||||
|
autoCompleteTerm: _.debounce( function(value, searchCriteria){
|
||||||
|
this.termList = [];
|
||||||
|
this.terms = [];
|
||||||
|
this.isFetching = true;
|
||||||
|
|
||||||
|
this.fetchTerms({
|
||||||
|
taxonomyId: this.advancedSearchQuery.taxquery[searchCriteria].taxonomy_id,
|
||||||
|
fetchOnly: {
|
||||||
|
fetch_only: {
|
||||||
|
0: 'name',
|
||||||
|
1: 'id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search: {
|
||||||
|
searchterm: value
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
this.termList = res;
|
||||||
|
|
||||||
|
for(let term in this.termList){
|
||||||
|
this.terms.push(this.termList[term].name);
|
||||||
|
let i = this.terms.length - 1;
|
||||||
|
this.termList[term].i = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isFetching = false;
|
||||||
|
}).catch((error) => {
|
||||||
|
this.isFetching = false;
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}, 300),
|
||||||
|
getComparators(searchCriteria){
|
||||||
|
if(this.advancedSearchQuery.taxquery[searchCriteria]){
|
||||||
|
return this.taxqueryOperators;
|
||||||
|
} else if(this.advancedSearchQuery.metaquery[searchCriteria]){
|
||||||
|
return this.metaqueryOperators;
|
||||||
|
}
|
||||||
|
},
|
||||||
removeThis(searchCriteria){
|
removeThis(searchCriteria){
|
||||||
console.log(searchCriteria);
|
|
||||||
let criteriaIndex = this.searchCriterias.findIndex((element) => {
|
let criteriaIndex = this.searchCriterias.findIndex((element) => {
|
||||||
return element == searchCriteria;
|
return element == searchCriteria;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchCriterias.splice(criteriaIndex, 1);
|
this.searchCriterias.splice(criteriaIndex, 1);
|
||||||
delete this.advancedSearchQuery[searchCriteria];
|
|
||||||
|
|
||||||
console.log(this.advancedSearchQuery);
|
if(this.advancedSearchQuery.taxquery[searchCriteria]){
|
||||||
|
delete this.advancedSearchQuery.taxquery[searchCriteria];
|
||||||
|
} else if(this.advancedSearchQuery.metaquery[searchCriteria]){
|
||||||
|
delete this.advancedSearchQuery.metaquery[searchCriteria];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeValueOf(searchCriteria){
|
||||||
|
if(this.advancedSearchQuery.taxquery[searchCriteria]){
|
||||||
|
this.$set(this.advancedSearchQuery.taxquery[searchCriteria], 'btags', []);
|
||||||
|
this.$set(this.advancedSearchQuery.taxquery[searchCriteria], 'terms', []);
|
||||||
|
} else if(this.advancedSearchQuery.metaquery[searchCriteria]){
|
||||||
|
this.$set(this.advancedSearchQuery.metaquery[searchCriteria], 'value', '');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
addSearchCriteria(){
|
addSearchCriteria(){
|
||||||
let aleatoryKey = Math.floor(Math.random() * 1000) + 2;
|
let aleatoryKey = Math.floor(Math.random() * 1000) + 2;
|
||||||
|
@ -149,74 +258,79 @@
|
||||||
this.searchCriterias = [1];
|
this.searchCriterias = [1];
|
||||||
this.advancedSearchQuery = {
|
this.advancedSearchQuery = {
|
||||||
advancedSearch: true,
|
advancedSearch: true,
|
||||||
|
metaquery: {},
|
||||||
|
taxquery: {}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
addValueToAdvancedSearchQuery: _.debounce(function(value, type, searchCriteria) {
|
addValueToAdvancedSearchQuery: _.debounce(function(value, type, searchCriteria) {
|
||||||
let vm = this;
|
this.addToAdvancedSearchQuery(value, type, searchCriteria);
|
||||||
|
|
||||||
vm.addToAdvancedSearchQuery(value, type, searchCriteria);
|
|
||||||
}, 900),
|
}, 900),
|
||||||
searchAdvanced(){
|
searchAdvanced(){
|
||||||
if(Object.keys(this.advancedSearchQuery).length > 2){
|
if(Object.keys(this.advancedSearchQuery).length > 2){
|
||||||
this.advancedSearchQuery.relation = 'AND';
|
this.advancedSearchQuery.relation = 'AND';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Object.keys(this.advancedSearchQuery.taxquery).length > 1){
|
||||||
|
this.advancedSearchQuery.taxquery.relation = 'AND';
|
||||||
|
} else if(this.advancedSearchQuery.taxquery.hasOwnProperty('relation')){
|
||||||
|
delete this.advancedSearchQuery.taxquery.relation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(this.advancedSearchQuery.metaquery).length > 1){
|
||||||
|
this.advancedSearchQuery.metaquery.relation = 'AND';
|
||||||
|
} else if(this.advancedSearchQuery.metaquery.hasOwnProperty('relation')){
|
||||||
|
delete this.advancedSearchQuery.metaquery.relation;
|
||||||
|
}
|
||||||
|
|
||||||
if(this.advancedSearchQuery.hasOwnProperty('relation') && Object.keys(this.advancedSearchQuery).length <= 2){
|
if(this.advancedSearchQuery.hasOwnProperty('relation') && Object.keys(this.advancedSearchQuery).length <= 3){
|
||||||
delete this.advancedSearchQuery.relation;
|
delete this.advancedSearchQuery.relation;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$eventBusSearch.$emit('searchAdvanced', this.advancedSearchQuery);
|
this.$eventBusSearch.$emit('searchAdvanced', this.advancedSearchQuery);
|
||||||
},
|
},
|
||||||
addToAdvancedSearchQuery(value, type, searchCriteria){
|
addToAdvancedSearchQuery(value, type, searchCriteria){
|
||||||
if(this.advancedSearchQuery.hasOwnProperty(searchCriteria)){
|
|
||||||
if(type == 'value' && (this.advancedSearchQuery[searchCriteria]['compare'] == 'IN' ||
|
if(type == 'metadatum'){
|
||||||
this.advancedSearchQuery[searchCriteria]['compare'] == 'NOT IN')){
|
const criteriaKey = value.split('-');
|
||||||
if(value.includes(';')){
|
|
||||||
this.advancedSearchQuery[searchCriteria].value = value.split(';');
|
if(criteriaKey[1] != 'undefined'){
|
||||||
} else {
|
// Was selected a taxonomy criteria
|
||||||
this.advancedSearchQuery[searchCriteria].value.pop();
|
this.advancedSearchQuery.taxquery = Object.assign({}, this.advancedSearchQuery.taxquery, {
|
||||||
if(!this.advancedSearchQuery[searchCriteria].value.includes(value)){
|
[`${searchCriteria}`]: {
|
||||||
this.advancedSearchQuery[searchCriteria].value.push(value);
|
taxonomy: criteriaKey[1],
|
||||||
|
terms: [],
|
||||||
|
btags: [],
|
||||||
|
field: 'term_id',
|
||||||
|
taxonomy_id: Number(criteriaKey[1].match(/[\d]+/))
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
} else {
|
} else {
|
||||||
if(type == 'compare' &&
|
// Was selected a metadatum criteria
|
||||||
this.advancedSearchQuery[searchCriteria].compare &&
|
this.advancedSearchQuery.metaquery = Object.assign({}, this.advancedSearchQuery.metaquery, {
|
||||||
!Array.isArray(this.advancedSearchQuery[searchCriteria].value) &&
|
[`${searchCriteria}`]: {
|
||||||
(this.advancedSearchQuery.compare != 'IN' && value == 'IN' ||
|
key: Number(criteriaKey[0]),
|
||||||
this.advancedSearchQuery.compare != 'NOT IN' && value == 'NOT IN')){
|
}
|
||||||
|
});
|
||||||
let valueAsArray = this.advancedSearchQuery[searchCriteria].value.split(' ');
|
|
||||||
this.advancedSearchQuery[searchCriteria].value = valueAsArray;
|
|
||||||
} else if(type == 'compare' &&
|
|
||||||
this.advancedSearchQuery[searchCriteria].compare &&
|
|
||||||
(this.advancedSearchQuery.compare != '=' && value == '=' ||
|
|
||||||
this.advancedSearchQuery.compare != '!=' && value == '!=')){
|
|
||||||
|
|
||||||
let valueAsString = this.advancedSearchQuery[searchCriteria].value.toString().replace(/,/g, ' ');
|
|
||||||
this.advancedSearchQuery[searchCriteria].value = valueAsString;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$set(this.advancedSearchQuery[searchCriteria], `${type}`, value);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if(type == 'terms'){
|
||||||
if(type == 'compare' && (value == 'IN' || value == 'NOT IN')){
|
let termIndex = this.terms.findIndex((element, index) => {
|
||||||
|
if(element == value && index == this.termList[index].i){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.advancedSearchQuery = Object.assign({}, this.advancedSearchQuery, {
|
this.advancedSearchQuery.taxquery[searchCriteria].terms.push(this.termList[termIndex].id);
|
||||||
[`${searchCriteria}`]: {
|
this.advancedSearchQuery.taxquery[searchCriteria].btags.push(value);
|
||||||
[`${type}`]: [value],
|
this.terms = [];
|
||||||
}
|
} else if(type == 'value'){
|
||||||
});
|
this.$set(this.advancedSearchQuery.metaquery[searchCriteria], 'value', value);
|
||||||
} else {
|
} else if(type == 'comparator'){
|
||||||
this.advancedSearchQuery = Object.assign({}, this.advancedSearchQuery, {
|
if(this.advancedSearchQuery.taxquery[searchCriteria]){
|
||||||
[`${searchCriteria}`]: {
|
this.$set(this.advancedSearchQuery.taxquery[searchCriteria], 'operator', value);
|
||||||
[`${type}`]: value,
|
} else if(this.advancedSearchQuery.metaquery[searchCriteria]){
|
||||||
}
|
this.$set(this.advancedSearchQuery.metaquery[searchCriteria], 'compare', value);
|
||||||
});
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(this.advancedSearchQuery);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +348,12 @@
|
||||||
|
|
||||||
.tag-container-border {
|
.tag-container-border {
|
||||||
border: 1px solid $tainacan-input-background;
|
border: 1px solid $tainacan-input-background;
|
||||||
|
|
||||||
|
span.tag{
|
||||||
|
color: $secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
padding: 0 0.3rem 0.3rem !important;
|
padding: 0 0.3rem 0.3rem !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,7 +314,7 @@ export default {
|
||||||
},
|
},
|
||||||
loadTerms() {
|
loadTerms() {
|
||||||
this.isLoadingTerms = true;
|
this.isLoadingTerms = true;
|
||||||
this.fetchTerms(this.taxonomyId)
|
this.fetchTerms({ taxonomyId: this.taxonomyId, fetchOnly: '', search: ''})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// Fill this.form data with current data.
|
// Fill this.form data with current data.
|
||||||
this.isLoadingTerms = false;
|
this.isLoadingTerms = false;
|
||||||
|
|
|
@ -292,7 +292,7 @@
|
||||||
</div>
|
</div>
|
||||||
<advanced-search
|
<advanced-search
|
||||||
:is-repository-level="isRepositoryLevel"
|
:is-repository-level="isRepositoryLevel"
|
||||||
:metadata-list="metadata" />
|
:metadata="metadata" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -362,16 +362,34 @@
|
||||||
registeredViewModes[viewMode] != undefined &&
|
registeredViewModes[viewMode] != undefined &&
|
||||||
registeredViewModes[viewMode].type == 'template'"
|
registeredViewModes[viewMode].type == 'template'"
|
||||||
v-html="itemsListTemplate"/>
|
v-html="itemsListTemplate"/>
|
||||||
|
|
||||||
|
<!-- When advanced search -->
|
||||||
<component
|
<component
|
||||||
v-if="isOnTheme &&
|
v-if="isOnTheme &&
|
||||||
!isLoadingItems &&
|
!isLoadingItems &&
|
||||||
registeredViewModes[viewMode] != undefined &&
|
registeredViewModes[viewMode] != undefined &&
|
||||||
registeredViewModes[viewMode].type == 'component'"
|
registeredViewModes[viewMode].type == 'component' &&
|
||||||
|
openAdvancedSearch &&
|
||||||
|
advancedSearchResults"
|
||||||
:collection-id="collectionId"
|
:collection-id="collectionId"
|
||||||
:displayed-metadata="tableMetadata"
|
:displayed-metadata="tableMetadata"
|
||||||
:items="items"
|
:items="items"
|
||||||
:is-loading="isLoadingItems"
|
:is-loading="isLoadingItems"
|
||||||
:is="registeredViewModes[viewMode].component"/>
|
:is="registeredViewModes[viewMode].component"/>
|
||||||
|
|
||||||
|
<!-- Regular -->
|
||||||
|
<component
|
||||||
|
v-else-if="isOnTheme &&
|
||||||
|
!isLoadingItems &&
|
||||||
|
registeredViewModes[viewMode] != undefined &&
|
||||||
|
registeredViewModes[viewMode].type == 'component' &&
|
||||||
|
!openAdvancedSearch"
|
||||||
|
:collection-id="collectionId"
|
||||||
|
:displayed-metadata="tableMetadata"
|
||||||
|
:items="items"
|
||||||
|
:is-loading="isLoadingItems"
|
||||||
|
:is="registeredViewModes[viewMode].component"/>
|
||||||
|
|
||||||
|
|
||||||
<!-- Empty Placeholder (only used in Admin) -->
|
<!-- Empty Placeholder (only used in Admin) -->
|
||||||
<section
|
<section
|
||||||
|
@ -696,14 +714,14 @@
|
||||||
|
|
||||||
this.$eventBusSearch.setViewMode(this.defaultViewMode);
|
this.$eventBusSearch.setViewMode(this.defaultViewMode);
|
||||||
|
|
||||||
if(this.$router.query && this.$router.query.metaquery && this.$router.query.metaquery.advancedSearch) {
|
if(this.$route.query && this.$route.query.advancedSearch) {
|
||||||
this.openAdvancedSearch = this.$router.query.metaquery.advancedSearch;
|
this.openAdvancedSearch = this.$route.query.advancedSearch;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
||||||
if(this.$router.query && this.$router.query.metaquery && this.$router.query.metaquery.advancedSearch) {
|
if(this.$route.query && this.$route.query.advancedSearch) {
|
||||||
this.openAdvancedSearch = this.$router.query.advancedSearch;
|
this.openAdvancedSearch = this.$route.query.advancedSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.prepareMetadataAndFilters();
|
this.prepareMetadataAndFilters();
|
||||||
|
|
|
@ -51,7 +51,7 @@ return apply_filters('tainacan-admin-i18n',[
|
||||||
'new_blank_collection' => __( 'New Blank Collection', 'tainacan' ),
|
'new_blank_collection' => __( 'New Blank Collection', 'tainacan' ),
|
||||||
'split' => __( 'Split', 'tainacan' ),
|
'split' => __( 'Split', 'tainacan' ),
|
||||||
'unified' => __( 'Unified', 'tainacan' ),
|
'unified' => __( 'Unified', 'tainacan' ),
|
||||||
'add_more_one_search_criteria' => __( 'Add more one search criteria', 'tainacan' ),
|
'add_another_search_criteria' => __( 'Add another search criteria', 'tainacan' ),
|
||||||
'clear_search' => __( 'Clear search', 'tainacan' ),
|
'clear_search' => __( 'Clear search', 'tainacan' ),
|
||||||
|
|
||||||
// Wordpress Status
|
// Wordpress Status
|
||||||
|
@ -140,7 +140,7 @@ return apply_filters('tainacan-admin-i18n',[
|
||||||
'label_yes' => __( 'Yes', 'tainacan' ),
|
'label_yes' => __( 'Yes', 'tainacan' ),
|
||||||
'label_no' => __( 'No', 'tainacan' ),
|
'label_no' => __( 'No', 'tainacan' ),
|
||||||
'label_approved' => __( 'Approved', 'tainacan' ),
|
'label_approved' => __( 'Approved', 'tainacan' ),
|
||||||
'label_collection_related' => __( 'Collection Related', 'tainacan' ),
|
'label_related_collection' => __( 'Related Collection', 'tainacan' ),
|
||||||
'label_metadata_for_search' => __( 'Metadata for search', 'tainacan' ),
|
'label_metadata_for_search' => __( 'Metadata for search', 'tainacan' ),
|
||||||
'label_allow_repeated_items' => __( 'Allow repeated items', 'tainacan' ),
|
'label_allow_repeated_items' => __( 'Allow repeated items', 'tainacan' ),
|
||||||
'label_select_taxonomy' => __( 'Select taxonomy', 'tainacan' ),
|
'label_select_taxonomy' => __( 'Select taxonomy', 'tainacan' ),
|
||||||
|
@ -269,7 +269,7 @@ return apply_filters('tainacan-admin-i18n',[
|
||||||
'info_warning_selected_items_delete' => __( 'Do you really want to permanently delete the selected items?', 'tainacan' ),
|
'info_warning_selected_items_delete' => __( 'Do you really want to permanently delete the selected items?', 'tainacan' ),
|
||||||
'info_warning_selected_items_trash' => __( 'Do you really want to trash the selected items?', 'tainacan' ),
|
'info_warning_selected_items_trash' => __( 'Do you really want to trash the selected items?', 'tainacan' ),
|
||||||
'info_warning_selected_taxonomies_delete' => __( 'Do you really want to delete the selected taxonomies?', 'tainacan' ),
|
'info_warning_selected_taxonomies_delete' => __( 'Do you really want to delete the selected taxonomies?', 'tainacan' ),
|
||||||
'info_warning_collection_related' => __( 'The metadata Collection related is required', 'tainacan' ),
|
'info_warning_related_collection' => __( 'The metadata Collection related is required', 'tainacan' ),
|
||||||
'info_warning_no_metadata_found' => __( 'No metadata found in this collection', 'tainacan' ),
|
'info_warning_no_metadata_found' => __( 'No metadata found in this collection', 'tainacan' ),
|
||||||
'info_showing_items' => __( 'Showing items ', 'tainacan' ),
|
'info_showing_items' => __( 'Showing items ', 'tainacan' ),
|
||||||
'info_showing_collections' => __( 'Showing collections ', 'tainacan' ),
|
'info_showing_collections' => __( 'Showing collections ', 'tainacan' ),
|
||||||
|
|
|
@ -64,6 +64,7 @@ class REST_Controller extends \WP_REST_Controller {
|
||||||
'authorid' => 'author_id',
|
'authorid' => 'author_id',
|
||||||
'authorname' => 'author_name',
|
'authorname' => 'author_name',
|
||||||
'search' => 's',
|
'search' => 's',
|
||||||
|
'searchterm' => 'search',
|
||||||
'status' => 'post_status',
|
'status' => 'post_status',
|
||||||
'offset' => 'offset',
|
'offset' => 'offset',
|
||||||
'metaquery' => 'meta_query',
|
'metaquery' => 'meta_query',
|
||||||
|
@ -245,7 +246,7 @@ class REST_Controller extends \WP_REST_Controller {
|
||||||
foreach ( $request_meta_query as $index1 => $a ) {
|
foreach ( $request_meta_query as $index1 => $a ) {
|
||||||
|
|
||||||
// handle core metadatum
|
// handle core metadatum
|
||||||
if( is_array($a) && array_key_exists("key", $a) ){
|
if( is_array($a) && array_key_exists("key", $a) && !$request['advancedSearch'] ){
|
||||||
$metadatum = new \Tainacan\Entities\Metadatum($a['key']);
|
$metadatum = new \Tainacan\Entities\Metadatum($a['key']);
|
||||||
if( strpos( $metadatum->get_metadata_type(), 'Core_Title') !== false ){
|
if( strpos( $metadatum->get_metadata_type(), 'Core_Title') !== false ){
|
||||||
$args[ 'post_title_in' ] = [
|
$args[ 'post_title_in' ] = [
|
||||||
|
|
|
@ -217,7 +217,7 @@ class REST_Items_Controller extends REST_Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
|
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
|
||||||
|
|
||||||
$response = [];
|
$response = [];
|
||||||
|
|
||||||
$return_template = false;
|
$return_template = false;
|
||||||
|
|
|
@ -298,6 +298,12 @@ class REST_Metadata_Controller extends REST_Controller {
|
||||||
$item_arr = $item->_toArray();
|
$item_arr = $item->_toArray();
|
||||||
|
|
||||||
$item_arr['metadata_type_object'] = $item->get_metadata_type_object()->_toArray();
|
$item_arr['metadata_type_object'] = $item->get_metadata_type_object()->_toArray();
|
||||||
|
|
||||||
|
if(isset($item_arr['metadata_type_options']) && isset($item_arr['metadata_type_options']['taxonomy_id'])){
|
||||||
|
$taxonomy = new Entities\Taxonomy($item_arr['metadata_type_options']['taxonomy_id']);
|
||||||
|
|
||||||
|
$item_arr['metadata_type_options']['taxonomy'] = $taxonomy->get_db_identifier();
|
||||||
|
}
|
||||||
|
|
||||||
if($request['context'] === 'edit'){
|
if($request['context'] === 'edit'){
|
||||||
$item_arr['current_user_can_edit'] = $item->can_edit();
|
$item_arr['current_user_can_edit'] = $item->can_edit();
|
||||||
|
@ -326,7 +332,7 @@ class REST_Metadata_Controller extends REST_Controller {
|
||||||
|
|
||||||
$args = $this->prepare_filters( $request );
|
$args = $this->prepare_filters( $request );
|
||||||
|
|
||||||
if ($request['context'] === 'edit') {
|
if ($request['include_disabled'] === 'true') {
|
||||||
$args['include_disabled'] = true;
|
$args['include_disabled'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:type="collectionType"
|
:type="collectionType"
|
||||||
:message="collectionMessage">
|
:message="collectionMessage">
|
||||||
<label class="label is-inline">
|
<label class="label is-inline">
|
||||||
{{ $i18n.get('label_collection_related') }}<span :class="collectionType" > * </span>
|
{{ $i18n.get('label_related_collection') }}<span :class="collectionType" > * </span>
|
||||||
<help-button
|
<help-button
|
||||||
:title="$i18n.getHelperTitle('tainacan-relationship', 'collection_id')"
|
:title="$i18n.getHelperTitle('tainacan-relationship', 'collection_id')"
|
||||||
:message="$i18n.getHelperMessage('tainacan-relationship', 'collection_id')"/>
|
:message="$i18n.getHelperMessage('tainacan-relationship', 'collection_id')"/>
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Relationship extends Metadata_Type {
|
||||||
public function get_form_labels(){
|
public function get_form_labels(){
|
||||||
return [
|
return [
|
||||||
'collection_id' => [
|
'collection_id' => [
|
||||||
'title' => __( 'Collection Related', 'tainacan' ),
|
'title' => __( 'Related Collection', 'tainacan' ),
|
||||||
'description' => __( 'Select the collection to fetch items', 'tainacan' ),
|
'description' => __( 'Select the collection to fetch items', 'tainacan' ),
|
||||||
],
|
],
|
||||||
'search' => [
|
'search' => [
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Taxonomy extends Metadata_Type {
|
||||||
public function get_form_labels(){
|
public function get_form_labels(){
|
||||||
return [
|
return [
|
||||||
'taxonomy_id' => [
|
'taxonomy_id' => [
|
||||||
'title' => __( 'Collection Related', 'tainacan' ),
|
'title' => __( 'Related Collection', 'tainacan' ),
|
||||||
'description' => __( 'Select the collection to fetch items', 'tainacan' ),
|
'description' => __( 'Select the collection to fetch items', 'tainacan' ),
|
||||||
],
|
],
|
||||||
'input_type' => [
|
'input_type' => [
|
||||||
|
|
|
@ -34,7 +34,10 @@ trait Entity_Collection_Relation {
|
||||||
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
$Tainacan_Collections = \Tainacan\Repositories\Collections::get_instance();
|
||||||
|
|
||||||
$this->collection = $Tainacan_Collections->fetch($this->get_collection_id());
|
$this->collection = $Tainacan_Collections->fetch($this->get_collection_id());
|
||||||
return $this->collection;
|
|
||||||
|
if($this->collection instanceof Entities\Collection){
|
||||||
|
return $this->collection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -21,7 +21,11 @@ trait Entity_Collections_Relation {
|
||||||
$this->collections = [];
|
$this->collections = [];
|
||||||
|
|
||||||
foreach ($this->get_collections_ids() as $col_id) {
|
foreach ($this->get_collections_ids() as $col_id) {
|
||||||
$this->collections[] = $Tainacan_Collections->fetch($col_id);
|
$collection = $Tainacan_Collections->fetch($col_id);
|
||||||
|
|
||||||
|
if($collection instanceof \Tainacan\Entities\Collection){
|
||||||
|
$this->collections[] = $collection;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->collections;
|
return $this->collections;
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route' (to, from) {
|
'$route' (to, from) {
|
||||||
|
|
||||||
this.collectionId = !this.$route.params.collectionId ? this.$route.params.collectionId : parseInt(this.$route.params.collectionId);
|
this.collectionId = !this.$route.params.collectionId ? this.$route.params.collectionId : parseInt(this.$route.params.collectionId);
|
||||||
|
|
||||||
if (this.$route.name == null || this.$route.name == undefined || this.$route.name == 'CollectionItemsPage' || this.$route.name == 'ItemsPage') {
|
if (this.$route.name == null || this.$route.name == undefined || this.$route.name == 'CollectionItemsPage' || this.$route.name == 'ItemsPage') {
|
||||||
|
@ -60,23 +60,23 @@ export default {
|
||||||
let orderBy = this.$userPrefs.get(orderByKey);
|
let orderBy = this.$userPrefs.get(orderByKey);
|
||||||
|
|
||||||
if (orderBy) {
|
if (orderBy) {
|
||||||
if (orderBy.slug == 'creation_date') {
|
// if (orderBy.slug == 'creation_date') {
|
||||||
this.$route.query.orderby = 'date';
|
// this.$route.query.orderby = 'date';
|
||||||
} else if (orderBy.slug == 'author_name') {
|
// } else if (orderBy.slug == 'author_name') {
|
||||||
this.$route.query.orderby = 'author_name';
|
// this.$route.query.orderby = 'author_name';
|
||||||
} else if (orderBy.metadata_type_object.primitive_type == 'float' || orderBy.metadata_type_object.primitive_type == 'int') {
|
// } else if (orderBy.metadata_type_object.primitive_type == 'float' || orderBy.metadata_type_object.primitive_type == 'int') {
|
||||||
this.$route.query.orderby = 'meta_value_num';
|
// this.$route.query.orderby = 'meta_value_num';
|
||||||
this.$route.query.meta_key = orderBy.id;
|
// this.$route.query.meta_key = orderBy.id;
|
||||||
} else if (orderBy.metadata_type_object.primitive_type == 'date') {
|
// } else if (orderBy.metadata_type_object.primitive_type == 'date') {
|
||||||
this.$route.query.orderby = 'meta_value';
|
// this.$route.query.orderby = 'meta_value';
|
||||||
this.$route.query.meta_key = orderBy.id;
|
// this.$route.query.meta_key = orderBy.id;
|
||||||
this.$route.query.meta_type = 'DATETIME';
|
// this.$route.query.meta_type = 'DATETIME';
|
||||||
} else if (orderBy.metadata_type_object.core) {
|
// } else if (orderBy.metadata_type_object.core) {
|
||||||
this.$route.query.orderby = orderBy.metadata_type_object.related_mapped_prop;
|
// this.$route.query.orderby = orderBy.metadata_type_object.related_mapped_prop;
|
||||||
} else {
|
// } else {
|
||||||
this.$route.query.orderby = 'meta_value';
|
// this.$route.query.orderby = 'meta_value';
|
||||||
this.$route.query.meta_key = orderBy.id;
|
// this.$route.query.meta_key = orderBy.id;
|
||||||
}
|
// }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.$route.query.orderby = 'date';
|
this.$route.query.orderby = 'date';
|
||||||
|
@ -87,8 +87,8 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.$route.query.metaquery && this.$route.query.metaquery.advancedSearch){
|
if(this.$route.query && this.$route.query.advancedSearch){
|
||||||
this.$store.dispatch('search/set_advanced_query', this.$route.query.metaquery);
|
this.$store.dispatch('search/set_advanced_query', this.$route.query);
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('search/set_postquery', this.$route.query);
|
this.$store.dispatch('search/set_postquery', this.$route.query);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
searchAdvanced(data) {
|
searchAdvanced(data) {
|
||||||
this.$store.dispatch('search/set_advanced_query', data);
|
this.$store.dispatch('search/set_advanced_query', data);
|
||||||
this.updateURLQueries(true);
|
this.updateURLQueries();
|
||||||
},
|
},
|
||||||
add_metaquery( data ){
|
add_metaquery( data ){
|
||||||
if ( data && data.collection_id ){
|
if ( data && data.collection_id ){
|
||||||
|
@ -174,9 +174,8 @@ export default {
|
||||||
this.$store.dispatch('search/setViewMode', viewMode);
|
this.$store.dispatch('search/setViewMode', viewMode);
|
||||||
this.updateURLQueries();
|
this.updateURLQueries();
|
||||||
},
|
},
|
||||||
updateURLQueries(isAdvancedSearch) {
|
updateURLQueries() {
|
||||||
this.$router.push({query: {}});
|
this.$router.push({query: {}});
|
||||||
this.$route.meta['advancedSearch'] = isAdvancedSearch;
|
|
||||||
this.$router.push({query: this.$store.getters['search/getPostQuery']});
|
this.$router.push({query: this.$store.getters['search/getPostQuery']});
|
||||||
},
|
},
|
||||||
updateStoreFromURL() {
|
updateStoreFromURL() {
|
||||||
|
@ -199,6 +198,7 @@ export default {
|
||||||
this.$emit( 'hasFiltered', res.hasFiltered);
|
this.$emit( 'hasFiltered', res.hasFiltered);
|
||||||
|
|
||||||
if(res.advancedSearchResults){
|
if(res.advancedSearchResults){
|
||||||
|
this.$router.push({query: this.$store.getters['search/getPostQuery'],});
|
||||||
this.$emit('advancedSearchResults', res.advancedSearchResults);
|
this.$emit('advancedSearchResults', res.advancedSearchResults);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,39 +14,39 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
|
||||||
let hasFiltered = false;
|
let hasFiltered = false;
|
||||||
let advancedSearchResults = false;
|
let advancedSearchResults = false;
|
||||||
|
|
||||||
if (postQueries.metaquery != undefined &&
|
if ( (postQueries.metaquery != undefined &&
|
||||||
(Object.keys(postQueries.metaquery).length > 0 ||
|
(Object.keys(postQueries.metaquery).length > 0 ||
|
||||||
postQueries.metaquery.length > 0)){
|
postQueries.metaquery.length > 0)) || (postQueries.taxquery != undefined &&
|
||||||
|
(Object.keys(postQueries.taxquery).length > 0 ||
|
||||||
|
postQueries.taxquery.length > 0)) ) {
|
||||||
|
|
||||||
hasFiltered = true;
|
hasFiltered = true;
|
||||||
|
|
||||||
if(postQueries.metaquery.advancedSearch){
|
if(postQueries.advancedSearch){
|
||||||
|
advancedSearchResults = postQueries.advancedSearch;
|
||||||
advancedSearchResults = postQueries.metaquery.advancedSearch;
|
|
||||||
|
|
||||||
delete postQueries.metaquery.advancedSearch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query = qs.stringify(postQueries);
|
|
||||||
} else {
|
|
||||||
query = qs.stringify(postQueries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query = qs.stringify(postQueries);
|
||||||
|
|
||||||
// Garanttees at least empty fetch_only are passed in case none is found
|
// Garanttees at least empty fetch_only are passed in case none is found
|
||||||
if (qs.stringify(postQueries.fetch_only) == '')
|
if (qs.stringify(postQueries.fetch_only) == ''){
|
||||||
dispatch('search/add_fetchonly', {} , { root: true });
|
dispatch('search/add_fetchonly', {}, { root: true });
|
||||||
|
}
|
||||||
|
|
||||||
if (qs.stringify(postQueries.fetch_only['meta']) == '')
|
if (qs.stringify(postQueries.fetch_only['meta']) == ''){
|
||||||
dispatch('search/add_fetchonly_meta', 0 , { root: true });
|
dispatch('search/add_fetchonly_meta', 0, { root: true });
|
||||||
|
}
|
||||||
|
|
||||||
// Differentiates between repository level and collection level queries
|
// Differentiates between repository level and collection level queries
|
||||||
let endpoint = '/collection/'+collectionId+'/items?'
|
let endpoint = '/collection/'+ collectionId +'/items?';
|
||||||
|
|
||||||
if (collectionId == undefined){
|
if (collectionId == undefined){
|
||||||
endpoint = '/items?'
|
endpoint = '/items?';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isOnTheme){
|
if (!isOnTheme){
|
||||||
endpoint = endpoint + 'context=edit&'
|
endpoint = endpoint + 'context=edit&';
|
||||||
}
|
}
|
||||||
|
|
||||||
axios.tainacan.get(endpoint+query)
|
axios.tainacan.get(endpoint+query)
|
||||||
|
|
|
@ -13,8 +13,9 @@ export const setPostQuery = ( state, postquery ) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setAdvancedSearchQuery = (state, advancedSearchQuery) => {
|
export const setAdvancedSearchQuery = (state, advancedSearchQuery) => {
|
||||||
console.log(advancedSearchQuery);
|
state.postquery.advancedSearch = advancedSearchQuery.advancedSearch;
|
||||||
state.postquery.metaquery = advancedSearchQuery;
|
state.postquery.metaquery = advancedSearchQuery.metaquery;
|
||||||
|
state.postquery.taxquery = advancedSearchQuery.taxquery;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addMetaQuery = ( state, filter ) => {
|
export const addMetaQuery = ( state, filter ) => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import axios from '../../../axios/axios'
|
import axios from '../../../axios/axios'
|
||||||
|
import qs from 'qs'
|
||||||
|
|
||||||
// TAXONOMIES
|
// TAXONOMIES
|
||||||
export const createTaxonomy = ({commit}, taxonomy) => {
|
export const createTaxonomy = ({commit}, taxonomy) => {
|
||||||
|
@ -169,9 +170,18 @@ export const updateTerm = ({ commit }, { taxonomyId, termId, name, description,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchTerms = ({ commit }, taxonomyId ) => {
|
export const fetchTerms = ({ commit }, {taxonomyId, fetchOnly, search}) => {
|
||||||
|
|
||||||
|
let query = '';
|
||||||
|
|
||||||
|
if(fetchOnly && search){
|
||||||
|
query = `?order=asc&${qs.stringify(fetchOnly)}&${qs.stringify(search)}`;
|
||||||
|
} else {
|
||||||
|
query = '?hideempty=0&order=asc';
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios.tainacan.get(`/taxonomy/${taxonomyId}/terms/?hideempty=0&order=asc`)
|
axios.tainacan.get(`/taxonomy/${taxonomyId}/terms${query}`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let terms = res.data;
|
let terms = res.data;
|
||||||
commit('setTerms', terms);
|
commit('setTerms', terms);
|
||||||
|
|
|
@ -563,7 +563,7 @@ msgstr "Aprovado"
|
||||||
#: admin/tainacan-admin-i18n.php:130
|
#: admin/tainacan-admin-i18n.php:130
|
||||||
#: classes/metadata-types/taxonomy/class-tainacan-taxonomy.php:35
|
#: classes/metadata-types/taxonomy/class-tainacan-taxonomy.php:35
|
||||||
#: classes/metadata-types/relationship/class-tainacan-relationship.php:26
|
#: classes/metadata-types/relationship/class-tainacan-relationship.php:26
|
||||||
msgid "Collection Related"
|
msgid "Related Collection"
|
||||||
msgstr "Coleção relacionada"
|
msgstr "Coleção relacionada"
|
||||||
|
|
||||||
#: admin/tainacan-admin-i18n.php:131
|
#: admin/tainacan-admin-i18n.php:131
|
||||||
|
|
Loading…
Reference in New Issue