Merge branch 'develop' into feature/gutenberg-terms-carousel

This commit is contained in:
Mateus Machado Luna 2019-10-11 17:58:40 -03:00
commit 013d38543b
118 changed files with 2179 additions and 1701 deletions

View File

@ -72,6 +72,7 @@ rsync -axz --exclude='vendor/bin/phpc*' --exclude='vendor/squizlabs' --exclude='
--exclude='vendor/respect/validation/docs' --exclude='vendor/respect/validation/tests' \
--exclude='pdf-viewer/pdfjs-dist/web/compressed.tracemonkey-pldi-09.pdf' \
--exclude='vendor/tecnickcom/tcpdf/fonts' \
--exclude='vendor/smalot/pdfparser/src/Smalot/PdfParser/Tests/' \
src/* $wp_plugin_dir/
rm -rf $wp_plugin_dir/scss

6
package-lock.json generated
View File

@ -1951,9 +1951,9 @@
}
},
"buefy": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/buefy/-/buefy-0.8.3.tgz",
"integrity": "sha512-01aHoCy4LAD08MmUahXC8mVqtGK/kzJ45ysXskwLWILAhyLMqkZ5fvdMKD9Ky6iDsMttPHdwUe2csmdnIx9caw==",
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/buefy/-/buefy-0.8.5.tgz",
"integrity": "sha512-yGQUhIsZWTodCx1rpfDTA32v5OjILpDIDAP+X6KoE6du3F3EZwJ/k5aT8D6Ba6AxNzVdDa2M7f0hzMddLbm38A==",
"requires": {
"bulma": "0.7.5"
}

View File

@ -8,7 +8,7 @@
},
"dependencies": {
"axios": "^0.19.0",
"buefy": "^0.8.3",
"buefy": "^0.8.5",
"bulma": "^0.7.5",
"mdi": "^2.2.43",
"moment": "^2.22.2",

View File

@ -1,5 +1,12 @@
<template>
<div class="tainacan-modal-content this-tainacan-modal-content">
<div
aria-labelledby="alert-dialog-title"
autofocus
role="alertdialog"
tabindex="-1"
aria-modal
class="tainacan-modal-content this-tainacan-modal-content"
ref="bulkEditionModal">
<header class="tainacan-modal-title">
<h2>{{ modalTitle }}
<small class="tainacan-total-objects-info">
@ -353,6 +360,10 @@
this.groupID = this.getGroupID();
});
},
mounted() {
if (this.$refs.bulkEditionModal)
this.$refs.bulkEditionModal.focus();
},
computed: {
metadata() {
return this.getMetadata();

View File

@ -204,7 +204,8 @@
ref="enabledViewModesDropdown"
:mobile-modal="true"
:disabled="Object.keys(registeredViewModes).length < 0"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
slot="trigger"

View File

@ -92,60 +92,67 @@
<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">
<b-loading
:is-full-page="isFullPage"
:active.sync="isLoadingMetadatumTypes"/>
:active.sync="isNewMetadatumModalActive"
trap-focus>
<div
v-if="selectedMetadatumType == undefined && !isEditingMetadatum"
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_select_metadatum_type') }}</h2>
<hr>
</div>
<section class="tainacan-form">
<div class="metadata-types-container">
<div
class="metadata-type"
v-for="(metadatumType, index) of metadatumTypes"
:key="index"
@click="onSelectMetadatumType(metadatumType)">
<h4>{{ metadatumType.name }}</h4>
</div>
autofocus="true"
tabindex="-1"
role="dialog"
aria-modal>
<b-loading
:is-full-page="isFullPage"
:active.sync="isLoadingMetadatumTypes"/>
<div
v-if="selectedMetadatumType == undefined && !isEditingMetadatum"
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_select_metadatum_type') }}</h2>
<hr>
</div>
<div class="field is-grouped form-submit">
<div class="control">
<button
id="button-cancel-importer-edition"
class="button is-outlined"
type="button"
@click="onMetadatumEditionCanceled(); isNewMetadatumModalActive = false">
{{ $i18n.get('cancel') }}</button>
<section class="tainacan-form">
<div class="metadata-types-container">
<div
class="metadata-type"
v-for="(metadatumType, index) of metadatumTypes"
:key="index"
@click="onSelectMetadatumType(metadatumType)">
<h4>{{ metadatumType.name }}</h4>
</div>
</div>
</div>
</section>
</div>
<div
v-if="isEditingMetadatum"
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_configure_new_metadatum') }}</h2>
<a
class="back-link"
@click="isEditingMetadatum = false">
{{ $i18n.get('back') }}
</a>
<hr>
<div class="field is-grouped form-submit">
<div class="control">
<button
id="button-cancel-importer-edition"
class="button is-outlined"
type="button"
@click="onMetadatumEditionCanceled(); isNewMetadatumModalActive = false">
{{ $i18n.get('cancel') }}</button>
</div>
</div>
</section>
</div>
<div
v-if="isEditingMetadatum"
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_configure_new_metadatum') }}</h2>
<a
class="back-link"
@click="isEditingMetadatum = false">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<metadatum-edition-form
:collection-id="collectionId"
:is-repository-level="false"
@onEditionFinished="onMetadatumEditionFinished()"
@onEditionCanceled="onMetadatumEditionCanceled()"
:index="0"
:original-metadatum="metadatum"
:edited-metadatum="editedMetadatum"
:is-on-modal="true"/>
</div>
<metadatum-edition-form
:collection-id="collectionId"
:is-repository-level="false"
@onEditionFinished="onMetadatumEditionFinished()"
@onEditionCanceled="onMetadatumEditionCanceled()"
:index="0"
:original-metadatum="metadatum"
:edited-metadatum="editedMetadatum"
:is-on-modal="true"/>
</div>
</b-modal>
<a

View File

@ -337,7 +337,8 @@ export default {
this.amountFinished --;
});
}
}
},
trapFocus: true
});
},
},

View File

@ -212,7 +212,8 @@
:can-cancel="false"
:active.sync="isTextModalActive"
:width="640"
scroll="keep">
scroll="keep"
trap-focus>
<div class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_write_text') }}</h2>
@ -248,7 +249,12 @@
:can-cancel="false"
:active.sync="isURLModalActive"
:width="640"
scroll="keep">
scroll="keep"
trap-focus
autofocus
role="dialog"
tabindex="-1"
aria-modal>
<div class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_insert_url') }}</h2>
@ -1095,7 +1101,8 @@ export default {
this.$console.error(error);
});
}
}
},
trapFocus: true
});
},
@ -1191,7 +1198,8 @@ export default {
this.deleteItem({ itemId: this.itemId, isPermanently: true });
this.$router.push(this.$routerHelper.getCollectionPath(this.form.collectionId))
}
}
},
trapFocus: true
});
},
loadExistingItem() {
@ -1372,7 +1380,8 @@ export default {
onConfirm: () => {
next();
},
}
},
trapFocus: true
});
} else {
next()

View File

@ -308,7 +308,8 @@ export default {
onConfirm: () => {
this.$router.push(this.$routerHelper.getCollectionItemsPath(this.collectionId));
}
}
},
trapFocus: true
});
} else if (status == 'trash') {
@ -336,7 +337,8 @@ export default {
this.isTrashingItems = false;
});
}
}
},
trapFocus: true
});
}
},

View File

@ -274,7 +274,8 @@
onConfirm: () => {
next();
}
}
},
trapFocus: true
});
} else if (this.isEditingTerm) {
this.$buefy.modal.open({
@ -287,7 +288,8 @@
onConfirm: () => {
next();
}
}
},
trapFocus: true
});
} else {
next();

View File

@ -177,7 +177,8 @@
events: {
approveActivity: (activityId) => this.approveActivity(activityId),
notApproveActivity: (activityId) => this.notApproveActivity(activityId)
}
},
trapFocus: true
});
},
},

View File

@ -91,7 +91,8 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_terms_not_saved'),
onConfirm: () => { this.removeTerm(); },
}
},
trapFocus: true
});
} else {
this.removeTerm();
@ -110,8 +111,9 @@ export default {
onConfirm: () => {
// If all checks passed, term can be deleted
this.$termsListBus.onDeleteBasicTermItem(this.term);
},
}
}
},
trapFocus: true
});
},
eventOnEditTerm() {

View File

@ -16,7 +16,8 @@
v-if="$userCaps.hasCapability('delete_tainacan-collections')"
:disabled="!isSelectingCollections"
id="bulk-actions-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
slot="trigger">
@ -54,7 +55,8 @@
<b-dropdown
inline
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }">
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }"
trap-focus>
<b-dropdown-item
@click="openCollection()"
v-if="!isOnTrash">
@ -387,8 +389,8 @@ export default {
// })
});
}
}
},
trapFocus: true
});
this.clearContextMenu();
},
@ -426,8 +428,9 @@ export default {
}
}
this.allCollectionsOnPageSelected = false;
},
}
}
},
trapFocus: true
});
},
openCollection() {

View File

@ -234,8 +234,13 @@
<b-modal
ref="filterTypeModal"
:width="680"
:active.sync="isSelectingFilterType">
:active.sync="isSelectingFilterType"
trap-focus>
<div
autofocus
role="dialog"
tabindex="-1"
aria-modal
class="tainacan-modal-content"
style="width: auto">
<header class="tainacan-modal-title">
@ -383,7 +388,8 @@ export default {
this.onEditionCanceled();
next();
},
}
},
trapFocus: true
});
} else {
next()

View File

@ -31,7 +31,8 @@
v-if="items.length > 0 && items[0].current_user_can_edit"
:disabled="selectedItems.length <= 1"
id="bulk-actions-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
slot="trigger">
@ -85,7 +86,8 @@
<b-dropdown
inline
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }">
:style="{ top: cursorPosY + 'px', left: cursorPosX + 'px' }"
trap-focus>
<b-dropdown-item
@click="openItem()"
v-if="!isOnTrash && !$route.query.iframemode">
@ -1030,6 +1032,7 @@ export default {
collectionID: this.$route.params.collectionId,
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
},
sequenceEditSelectedItems() {
@ -1068,7 +1071,8 @@ export default {
this.$eventBusSearch.loadItems();
}
}
}
},
trapFocus: true
});
this.clearContextMenu();
@ -1099,7 +1103,8 @@ export default {
});
});
}
}
},
trapFocus: true
});
},
deleteOneItem(itemId) {
@ -1121,7 +1126,8 @@ export default {
this.$eventBusSearch.loadItems();
});
}
}
},
trapFocus: true
});
this.clearContextMenu();
},
@ -1151,7 +1157,8 @@ export default {
});
});
}
}
},
trapFocus: true
});
},
deleteSelectedItems() {
@ -1189,7 +1196,8 @@ export default {
}
});
}
}
},
trapFocus: true
});
},
openItem() {

View File

@ -372,8 +372,13 @@
</section>
<b-modal
@close="onCancelNewMetadataMapperMetadata"
:active.sync="isMapperMetadataCreating">
:active.sync="isMapperMetadataCreating"
trap-focus>
<div
autofocus
role="dialog"
tabindex="-1"
aria-modal
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('instruction_insert_mapper_metadatum_info') }}</h2>
@ -527,7 +532,8 @@ export default {
this.onEditionCanceled();
next();
},
}
},
trapFocus: true
});
} else {
next()
@ -633,8 +639,9 @@ export default {
.catch(() => {
this.$console.log("Error deleting metadatum.")
});
},
}
}
},
trapFocus: true
});
},
toggleMetadatumEdition(metadatumId) {

View File

@ -15,7 +15,8 @@
<b-dropdown
position="is-bottom-left"
:disabled="!isSelecting"
id="bulk-actions-dropdown">
id="bulk-actions-dropdown"
trap-focus>
<button
class="button is-white"
slot="trigger">
@ -389,7 +390,8 @@
// });
});
}
}
},
trapFocus: true
});
},
deleteSelected() {
@ -427,7 +429,8 @@
}
this.allOnPageSelected = false;
}
}
},
trapFocus: true
});
},
getDate(rawDate) {
@ -451,7 +454,8 @@
onConfirm: () => {
this.updateProcess({ id: this.processes[index].ID, status: 'closed' });
},
}
},
trapFocus: true
});
}
},

View File

@ -218,7 +218,8 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_terms_not_saved'),
onConfirm: () => { this.removeTerm(); },
}
},
trapFocus: true
});
} else {
this.removeTerm();
@ -258,8 +259,9 @@ export default {
});
}
}
},
}
}
},
trapFocus: true
});
},
eventOnChildTermDeleted(parentTermId) {

View File

@ -17,7 +17,8 @@
v-if="$userCaps.hasCapability('delete_tainacan-taxonomies')"
:disabled="!isSelecting"
id="bulk-actions-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
slot="trigger">
@ -267,7 +268,8 @@
// });
});
}
}
},
trapFocus: true
});
},
deleteSelected() {
@ -305,7 +307,8 @@
}
this.allOnPageSelected = false;
}
}
},
trapFocus: true
});
},
onClickTaxonomy($event, taxonomyId, index) {

View File

@ -16,7 +16,8 @@
:mobile-modal="true"
:disabled="localTerms.length <= 0 || isLoadingTerms || isEditingTerm"
@input="onChangeOrder(order == 'asc' ? 'desc' : 'asc')"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting_direction')"
class="button is-white"

View File

@ -61,7 +61,8 @@
ref="advancedSearchShortcut"
class="advanced-search-header-dropdown"
position="is-bottom-left"
aria-role="list">
aria-role="list"
trap-focus>
<a
class="advanced-search-text"
slot="trigger">

View File

@ -130,7 +130,8 @@ export default {
props: {
sourceCollection: this.collectionId,
hideWhenManualCollection: true
}
},
trapFocus: true
});
}
}

View File

@ -1,5 +1,11 @@
<template>
<div class="tainacan-modal-content">
<div
autofocus
role="dialog"
class="tainacan-modal-content"
tabindex="-1"
aria-modal
ref="activityDetailsModal">
<header
v-if="!isLoadingActivity"
class="tainacan-modal-title">
@ -647,7 +653,7 @@
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-metadata"/></span>`;
case 'Tainacan\\Entities\\Filter':
return `${ this.$i18n.get('filter') }
<a href="${ this.adminFullURL + (this.activity.object.collection_id == 'default' || this.activity.object.collection_id == 'filter_in_repository' ? this.$routerHelper.getFilterEditPath(this.activity.object_id) : this.$routerHelper.getCollectionFilterEditPath(this.activity.object.collection_id, this.activity.object_id)) }">${ this.activity.object.name }</a>
<a href="${ this.adminFullURL + (this.activity.object.collection_id == 'default' ? this.$routerHelper.getFilterEditPath(this.activity.object_id) : this.$routerHelper.getCollectionFilterEditPath(this.activity.object.collection_id, this.activity.object_id)) }">${ this.activity.object.name }</a>
<span class="icon has-text-gray3">&nbsp;<i class="tainacan-icon tainacan-icon-20px tainacan-icon-filters"/></span>`;
case 'Tainacan\\Entities\\Term':
return `${ this.$i18n.get('term') }
@ -667,6 +673,10 @@
created() {
this.loadActivity();
},
mounted() {
if (this.$refs.activityDetailsModal)
this.$refs.activityDetailsModal.focus()
},
methods: {
...mapActions('activity', [
'fetchActivity'
@ -765,11 +775,11 @@
}
p.is-capitalized {
margin-bottom: 0.5rem;
margin-bottom: 0.125rem;
}
.tainacan-p-break {
word-break: break-word;
margin-bottom: 1rem;
margin-bottom: 0.5rem;
}
.tainacan-figure {

View File

@ -1,5 +1,12 @@
<template>
<form action="">
<form
action=""
autofocus
role="dialog"
class="tainacan-modal-content"
tabindex="-1"
aria-modal
ref="availableExportersModal">
<div
class="tainacan-modal-content"
style="width: auto">
@ -77,6 +84,9 @@
this.$console.log(error);
this.isLoading = false;
});
if (this.$refs.availableExportersModal)
this.$refs.availableExportersModal.focus();
}
}
</script>

View File

@ -1,5 +1,12 @@
<template>
<form action="">
<form
action=""
autofocus
role="dialog"
class="tainacan-modal-content"
tabindex="-1"
aria-modal
ref="availableImportersModal">
<div
class="tainacan-modal-content"
style="width: auto">
@ -79,6 +86,9 @@ export default {
this.$console.log(error);
this.isLoading = false;
});
if (this.$refs.availableImportersModal)
this.$refs.availableImportersModal.focus();
}
}
</script>

View File

@ -1,5 +1,11 @@
<template>
<div class="tainacan-modal-content">
<div
autofocus
role="dialog"
class="tainacan-modal-content"
tabindex="-1"
aria-modal
ref="checkboxRadioModal">
<header class="tainacan-modal-title">
<h2 v-if="isFilter">{{ $i18n.get('filter') }} <em>{{ filter.name }}</em></h2>
<h2 v-else>{{ $i18n.get('metadatum') }} <em>{{ metadatum.name }}</em></h2>
@ -272,11 +278,11 @@
<script>
import qs from 'qs';
import { tainacan as axios, isCancel } from '../../../js/axios/axios';
import { filter_type_mixin } from '../../../classes/filter-types/filter-types-mixin';
import { dynamicFilterTypeMixin } from '../../../classes/filter-types/filter-types-mixin';
export default {
name: 'CheckboxFilterModal',
mixins: [ filter_type_mixin ],
mixins: [ dynamicFilterTypeMixin ],
props: {
isFilter: {
type: Boolean,
@ -286,8 +292,8 @@
parent: Number,
taxonomy_id: Number,
taxonomy: String,
collection_id: Number,
metadatum_id: Number,
collectionId: Number,
metadatumId: Number,
metadatum: Object,
selected: Array,
isTaxonomy: {
@ -295,7 +301,7 @@
default: false,
},
metadatum_type: String,
metadatum_object: Object,
query: Object,
isRepositoryLevel: Boolean,
isCheckbox: {
type: Boolean,
@ -318,7 +324,6 @@
maxNumSearchResultsShow: 20,
maxNumOptionsCheckboxFinderColumns: 100,
checkboxListOffset: 0,
collection: this.collection_id,
isCheckboxListLoading: false,
isSearchingLoading: false,
noMorePage: 0,
@ -345,6 +350,10 @@
this.getOptions(0);
}
},
mounted() {
if (this.$refs.checkboxRadioModal)
this.$refs.checkboxRadioModal.focus()
},
methods: {
fetchSelectedLabels() {
@ -443,7 +452,7 @@
if ( this.metadatum_type === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true);
else
promise = this.getValuesPlainText( this.metadatum_id, this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true);
promise = this.getValuesPlainText( this.metadatumId, this.optionName, this.isRepositoryLevel, [], offset, this.maxNumOptionsCheckboxList, true);
promise.request
.then((data) => {
@ -486,10 +495,10 @@
if (!this.isFilter)
query += '&hideempty=0';
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
let route = `/collection/${this.collectionId}/facets/${this.metadatumId}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
if(this.collectionId == 'default'){
route = `/facets/${this.metadatumId}${query}`
}
axios.get(route)
@ -609,10 +618,10 @@
this.isColumnLoading = true;
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
let route = `/collection/${this.collectionId}/facets/${this.metadatumId}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
if (this.collectionId == 'default'){
route = `/facets/${this.metadatumId}${query}`
}
axios.get(route)
@ -646,10 +655,10 @@
this.isColumnLoading = true;
let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
let route = `/collection/${this.collectionId}/facets/${this.metadatumId}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
if (this.collectionId == 'default'){
route = `/facets/${this.metadatumId}${query}`
}
axios.get(route)
@ -674,21 +683,21 @@
applyFilter() {
this.$parent.close();
if(this.isTaxonomy && this.isFilter){
if (this.isTaxonomy && this.isFilter) {
this.$eventBusSearch.$emit('input', {
filter: 'checkbox',
taxonomy: this.taxonomy,
compare: 'IN',
metadatum_id: this.metadatum_id,
collection_id: this.collection_id,
metadatum_id: this.metadatumId ? this.metadatumId : this.filter.metatadum_id,
collection_id: this.collectionId ? this.collectionId : this.filter.collection_id,
terms: this.selected
});
} else if(this.isFilter) {
this.$eventBusSearch.$emit('input', {
filter: 'checkbox',
compare: 'IN',
metadatum_id: this.metadatum_id,
collection_id: this.collection_id ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId ? this.metadatumId : this.filter.metatadum_id,
collection_id: this.collectionId ? this.collectionId : this.filter.collection_id,
value: this.selected,
});
} else {

View File

@ -1,5 +1,12 @@
<template>
<form action="">
<form
action=""
autofocus
role="dialog"
class="tainacan-modal-content"
tabindex="-1"
aria-modal
ref="collectionsModal">
<div
class="tainacan-modal-content"
style="width: auto">
@ -74,6 +81,9 @@ export default {
this.$console.log(error);
this.isLoading = false;
});
if (this.$refs.collectionsModal)
this.$refs.collectionsModal.focus();
}
}
</script>

View File

@ -1,9 +1,11 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal="true"
aria-modal
autofocus
role="alertdialog"
class="tainacan-form dialog">
class="tainacan-form dialog"
ref="customDialog">
<div
class="modal-card"
style="width: auto">
@ -87,6 +89,10 @@
changeNeverShowMessageAgain($event) {
this.$userPrefs.set('neverShow' + this.messageKeyForUserPrefs + 'Dialog', $event);
}
},
mounted() {
if (this.$refs.customDialog)
this.$refs.customDialog.focus();
}
}
</script>

View File

@ -11,7 +11,8 @@
<!-- Preview Modal ----------------- -->
<b-modal
:active.sync="isPreviewModalActive"
scroll="keep">
scroll="keep"
trap-focus>
<!-- <div class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('label_document') }}</h2>
@ -20,7 +21,11 @@
class="back-link">{{ $i18n.get('exit') }}</a>
<hr>
</div> -->
<div
<div
autofocus
role="dialog"
tabindex="-1"
aria-modal
class="is-flex rendered-content"
v-html="documentHtml" />
<!-- </div> -->
@ -32,9 +37,13 @@
export default {
name: 'DocumentItem',
props: {
documentHtml: String,
isSelected: false,
isPreviewModalActive: false
documentHtml: String
},
data() {
return {
isSelected: false,
isPreviewModalActive: false
}
}
}
</script>

View File

@ -1,10 +1,13 @@
<template>
<div
aria-labelledby="exposers-modal-title"
autofocus
role="dialog"
aria-modal="true"
tabindex="-1"
aria-modal
class="tainacan-modal-content"
style="width: auto">
style="width: auto"
ref="exposersModal">
<header class="tainacan-modal-title">
<h2
id="exposers-modal-title"
@ -469,6 +472,9 @@ export default {
if (this.itemId)
this.shouldRespectFetchOnly = false;
if (this.$refs.exposersModal)
this.$refs.exposersModal.focus()
}
}
</script>

View File

@ -32,8 +32,14 @@
<b-modal
:active.sync="isPreviewModalActive"
:width="1024"
scroll="keep">
<div class="tainacan-modal-content">
scroll="keep"
trap-focus>
<div
autofocus
role="dialog"
tabindex="-1"
aria-modal
class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2 v-if="file.title != undefined">{{ file.title.rendered }}</h2>
</div>

View File

@ -1,9 +1,12 @@
<template>
<div
aria-labelledby="alert-dialog-title"
aria-modal="true"
autofocus
role="alertdialog"
class="tainacan-form dialog">
tabindex="-1"
aria-modal
class="tainacan-form dialog"
ref="itemCopyDialog">
<div
class="modal-card"
style="width: auto">
@ -183,6 +186,10 @@
this.isCreatingBulkEditGroup = false;
this.isCreatingSequenceEditGroup = false;
this.copyCount = 1;
},
mounted() {
if (this.$refs.itemCopyDialog)
this.$refs.itemCopyDialog.focus();
}
}
</script>

View File

@ -26,7 +26,7 @@
<b-checkbox
v-model="collectionsIdsToFilter"
:native-value="collection.id"
@input="apply_filter">
@input="applyFilter">
{{ collection.name }}
</b-checkbox>
</div>
@ -60,7 +60,7 @@
Array.isArray(routeQueries.metaquery[0].value)){
this.collectionsIdsToFilter = routeQueries.metaquery[0].value;
this.apply_filter();
this.applyFilter();
}
},
data(){
@ -84,7 +84,7 @@
...mapGetters('collection', [
'getCollections',
]),
apply_filter(){
applyFilter(){
this.$eventBusSearch.$emit( 'input', {
filter: 'checkbox',
metadatum_id: 'collection_id',

View File

@ -7,8 +7,8 @@
:key="index"
attached
closable
@close="removeMetaQuery(filterTag.filterId, filterTag.value, filterTag.singleValue)">
{{ filterTag.singleValue != undefined ? filterTag.singleValue : filterTag.value }}
@close="removeMetaQuery(filterTag)">
{{ filterTag.singleLabel != undefined ? filterTag.singleLabel : filterTag.label }}
</b-tag>
<button
@click="clearAllFilters()"
@ -19,7 +19,7 @@
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import { mapGetters } from 'vuex';
export default {
name: 'FiltersTagsList',
@ -31,9 +31,9 @@
let tags = this.getFilterTags();
let flattenTags = [];
for (let tag of tags) {
if (Array.isArray(tag.value)) {
for (let valueTag of tag.value)
flattenTags.push({filterId: tag.filterId, value: tag, singleValue: valueTag});
if (Array.isArray(tag.label)) {
for (let i = 0; i < tag.label.length; i++)
flattenTags.push({filterId: tag.filterId, label: tag.label, singleLabel: tag.label[i], value: tag.value[i], taxonomy: tag.taxonomy, metadatumId: tag.metadatumId});
} else {
flattenTags.push(tag);
}
@ -43,22 +43,22 @@
},
methods: {
...mapGetters('search',[
'getPostQuery',
'getFilterTags'
]),
...mapActions('metadata',[
'fetchMetadatum'
]),
removeMetaQuery(filterId, value, singleValue) {
if (singleValue != undefined)
this.$eventBusSearch.removeMetaFromFilterTag({ filterId: filterId, singleValue: singleValue });
else
this.$eventBusSearch.removeMetaFromFilterTag({ filterId: filterId, value: value });
removeMetaQuery({ filterId, value, singleLabel, label, taxonomy, metadatumId }) {
this.$eventBusSearch.removeMetaFromFilterTag({
filterId: filterId,
singleLabel: singleLabel,
label: label,
value: value,
taxonomy: taxonomy,
metadatumId: metadatumId
});
},
clearAllFilters() {
// this.$eventBusSearch.clearAllFilters();
for (let tag of this.filterTags) {
this.removeMetaQuery(tag.filterId, tag.value, tag.singleValue);
this.removeMetaQuery(tag);
}
}
}

View File

@ -69,7 +69,8 @@
<b-dropdown
position="is-top-right"
@change="onPageChange"
aria-role="list">
aria-role="list"
trap-focus>
<button
aria-labelledby="go-to-page-dropdown"
class="button is-white"

View File

@ -9,7 +9,8 @@
<div class="field is-pulled-right">
<b-dropdown
position="is-bottom-left"
disabled>
disabled
trap-focus>
<button
class="button is-white"
slot="trigger">

View File

@ -52,6 +52,10 @@ import eventBusSearch from '../../js/event-bus-search';
import termsListBus from './terms-list-bus.js';
import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, UserCapabilitiesPlugin, StatusHelperPlugin } from './utilities';
import FilterNumericListInterval from '../../classes/filter-types/numeric-list-interval/NumericListInterval.vue';
import FormNumericListInterval from '../../classes/filter-types/numeric-list-interval/FormNumericListInterval.vue';
// Configure and Register Plugins
Vue.use(Buefy, {
defaultTooltipAnimated: true
@ -92,9 +96,12 @@ Vue.component('tainacan-filter-taginput', FilterTaginput);
Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox);
Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput);
Vue.component('tainacan-filter-numeric-interval', FilterNumericInterval);
Vue.component('tainacan-filter-numeric-list-interval', FilterNumericListInterval);
/* Filter Metadata Option forms */
Vue.component('tainacan-filter-form-numeric', FormNumeric);
Vue.component('tainacan-filter-form-numeric-interval', FormNumericInterval);
Vue.component('tainacan-filter-form-numeric-list-interval', FormNumericListInterval);
// Vue.component('tainacan-filter-form-date', FormDate);
/* Others */

View File

@ -15,6 +15,7 @@ import FilterTaginput from '../../classes/filter-types/taginput/Taginput.vue';
import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue';
import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue';
import FilterNumericInterval from '../../classes/filter-types/numeric-interval/NumericInterval.vue';
import FilterNumericListInterval from '../../classes/filter-types/numeric-list-interval/NumericListInterval.vue';
import TaincanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue';
import ItemsPage from '../pages/lists/items-page.vue';
@ -57,6 +58,7 @@ Vue.component('tainacan-filter-taginput', FilterTaginput);
Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox);
Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput);
Vue.component('tainacan-filter-numeric-interval', FilterNumericInterval);
Vue.component('tainacan-filter-numeric-list-interval', FilterNumericListInterval);
/* Others */
Vue.component('items-page', ItemsPage);

View File

@ -11,7 +11,8 @@
<div class="header-item">
<b-dropdown
aria-role="list"
id="collection-creation-options-dropdown">
id="collection-creation-options-dropdown"
trap-focus>
<button
class="button is-secondary"
slot="trigger">
@ -62,7 +63,8 @@
:mobile-modal="true"
:disabled="collections.length <= 0 || isLoading"
@input="onChangeOrder(order == 'asc' ? 'desc' : 'asc')"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting_direction')"
class="button is-white"
@ -195,7 +197,8 @@
<b-dropdown
:disabled="isLoadingMetadatumMappers"
id="collection-creation-options-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-secondary"
slot="trigger">
@ -421,7 +424,8 @@ export default {
this.$buefy.modal.open({
parent: this,
component: AvailableImportersModal,
hasModalCard: true
hasModalCard: true,
trapFocus: true
});
}
},

View File

@ -232,7 +232,8 @@
<b-dropdown
:mobile-modal="true"
id="item-creation-options-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-secondary"
slot="trigger">
@ -306,7 +307,8 @@
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show metadata-options-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_displayed_metadata')"
class="button is-white"
@ -348,7 +350,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeOrder()"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting_direction')"
class="button is-white"
@ -395,7 +398,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeOrderBy($event)"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting')"
class="button is-white"
@ -431,7 +435,8 @@
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization')"
class="button is-white"
@ -472,7 +477,8 @@
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_view_mode')"
class="button is-white"
@ -811,12 +817,18 @@
role="region"
aria-labelledby="filters-label-landmark-modal"
id="filters-mobile-modal"
ref="filters-mobile-modal"
class="tainacan-form is-hidden-tablet"
:active.sync="isFilterModalActive"
:width="736"
animation="slide-menu">
<div class="modal-inner-content">
animation="slide-menu"
trap-focus>
<div
ref="filters-mobile-modal"
class="modal-inner-content"
autofocus="true"
tabindex="-1"
aria-modal
role="dialog">
<h3
id="filters-label-landmark-modal"
class="has-text-weight-semibold">
@ -1035,6 +1047,14 @@
orderByName() {
if (this.isSortingByCustomMetadata)
this.hasAnOpenAlert = true;
},
isFilterModalActive() {
if (this.isFilterModalActive) {
setTimeout(() => {
if (this.$refs['filters-mobile-modal'])
this.$refs['filters-mobile-modal'].focus();
}, 800);
}
}
},
methods: {
@ -1097,7 +1117,8 @@
props: {
targetCollection: this.collectionId,
hideWhenManualCollection: true
}
},
trapFocus: true
});
},
openExposersModal() {
@ -1108,14 +1129,16 @@
props: {
collectionId: this.collectionId,
totalItems: this.totalItems
}
},
trapFocus: true
})
},
onOpenCollectionsModal() {
this.$buefy.modal.open({
parent: this,
component: CollectionsModal,
hasModalCard: true
hasModalCard: true,
trapFocus: true
});
},
updateSearch() {
@ -1489,7 +1512,8 @@
hideCancel: true,
showNeverShowAgainOption: offerCheckbox && tainacan_plugin.user_caps != undefined && tainacan_plugin.user_caps.length != undefined && tainacan_plugin.user_caps.length > 0,
messageKeyForUserPrefs: 'ItemsHiddenDueSorting'
}
},
trapFocus: true
});
},
adjustSearchControlHeight: _.debounce( function() {

View File

@ -25,7 +25,8 @@
:mobile-modal="true"
:disabled="taxonomies.length <= 0 || isLoading"
@input="onChangeOrder(order == 'asc' ? 'desc' : 'asc')"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting_direction')"
class="button is-white"

View File

@ -223,7 +223,8 @@
<b-dropdown
:mobile-modal="true"
id="item-creation-options-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-secondary"
slot="trigger">
@ -283,7 +284,8 @@
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show metadata-options-dropdown"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_displayed_metadata')"
class="button is-white"
@ -325,7 +327,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeOrder()"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting_direction')"
class="button is-white"
@ -372,7 +375,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeOrderBy($event)"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_sorting')"
class="button is-white"
@ -408,7 +412,8 @@
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
:aria-label="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].label : $i18n.get('label_visualization')"
@ -449,7 +454,8 @@
:mobile-modal="true"
position="is-bottom-left"
:aria-label="$i18n.get('label_view_mode')"
aria-role="list">
aria-role="list"
trap-focus>
<button
class="button is-white"
:aria-label="$i18n.get('label_view_mode')"
@ -791,8 +797,14 @@
class="tainacan-form is-hidden-tablet"
:active.sync="isFilterModalActive"
:width="736"
animation="slide-menu">
<div class="modal-inner-content">
animation="slide-menu"
trap-focus>
<div
autofocus="true"
tabindex="-1"
role="dialog"
aria-modal
class="modal-inner-content">
<h3
id="filters-label-landmark-modal"
class="has-text-weight-semibold">
@ -989,6 +1001,14 @@
orderByName() {
if (this.isSortingByCustomMetadata)
this.hasAnOpenAlert = true;
},
isFilterModalActive() {
if (this.isFilterModalActive) {
setTimeout(() => {
if (this.$refs['filters-mobile-modal'])
this.$refs['filters-mobile-modal'].focus();
}, 800);
}
}
},
methods: {
@ -1047,7 +1067,8 @@
props: {
targetCollection: this.collectionId,
hideWhenManualCollection: true
}
},
trapFocus: true
});
},
openExposersModal() {
@ -1058,8 +1079,9 @@
props: {
collectionId: this.collectionId,
totalItems: this.totalItems
}
})
},
trapFocus: true
});
},
updateSearch() {
this.$eventBusSearch.setSearchQuery(this.futureSearchQuery);
@ -1419,7 +1441,8 @@
hideCancel: true,
showNeverShowAgainOption: offerCheckbox && tainacan_plugin.user_caps != undefined && tainacan_plugin.user_caps.length != undefined && tainacan_plugin.user_caps.length > 0,
messageKeyForUserPrefs: 'ItemsHiddenDueSorting'
}
},
trapFocus: true
});
},
adjustSearchControlHeight: _.debounce( function() {

View File

@ -384,8 +384,9 @@
itemId: this.itemId,
itemURL: this.item.url,
totalItems: 1,
}
})
},
trapFocus: true
});
}
},
created() {

View File

@ -133,9 +133,10 @@ return apply_filters( 'tainacan-admin-i18n', [
'title_exporter_page' => __( 'Exporter', 'tainacan'),
// Labels (used mainly on Aria Labels and Inputs)
'label' => __( 'label', 'tainacan' ),
'label_clean' => __( 'Clear', 'tainacan' ),
'label_clear_filters' => __( 'Clear filters', 'tainacan' ),
'label_and' => __( 'and', 'tainacan' ),
'label_and' => __( 'and', 'tainacan' ),
'label_selected' => __( 'Selected', 'tainacan' ),
'label_relationship_new_search' => __( 'New Search', 'tainacan' ),
'label_relationship_items_found' => __( 'Items found', 'tainacan' ),
@ -479,11 +480,13 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_click_or_drag_metadatum_create' => __( 'Click or drag and drop to create a new metadatum', 'tainacan' ),
'instruction_drag_and_drop_filter_sort' => __( 'Drag and drop to change filter order', 'tainacan' ),
'instruction_drag_and_drop_metadatum_sort' => __( 'Drag and drop to change metadatum order', 'tainacan' ),
'instruction_select_a_date' => __( 'Select a date', 'tainacan' ),
'instruction_select_a_month' => __( 'Select a month', 'tainacan' ),
'instruction_type_value_year' => __( 'Type year value', 'tainacan' ),
'instruction_select_the_amount_of_copies' => __( 'Select the amount of copies of the item that you want to create', 'tainacan'),
'instruction_filter_activities_date' => __( 'Range of dates', 'tainacan'),
'instruction_select_a_date' => __( 'Select a date', 'tainacan' ),
'instruction_select_a_month' => __( 'Select a month', 'tainacan' ),
'instruction_type_value_year' => __( 'Type year value', 'tainacan' ),
'instruction_select_the_amount_of_copies' => __( 'Select the amount of copies of the item that you want to create', 'tainacan'),
'instruction_select_a_interval' => __( 'Select an interval', 'tainacan'),
// Info. Other feedback to user.
'info_items_tab_all' => __( 'Every published item, including those visible only to editors.', 'tainacan' ),
@ -607,11 +610,11 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_updated_at' => __( 'Updated at', 'tainacan' ),
'info_editing_metadata_values' => __( 'Editing metadata values...', 'tainacan' ),
'info_updating_metadata_values' => __( 'Updating metadata values...', 'tainacan' ),
'info_type_to_add_items' => __( 'Add items...', 'tainacan' ),
'info_type_to_add_items' => __( 'Add items to filter...', 'tainacan' ),
'info_type_to_search_items' => __( 'Search items...', 'tainacan' ),
'info_type_to_add_terms' => __( 'Add terms...', 'tainacan' ),
'info_type_to_add_terms' => __( 'Add terms to filter...', 'tainacan' ),
'info_type_to_search_metadata' => __( 'Search metadata...', 'tainacan' ),
'info_type_to_add_metadata' => __( 'Add metadata...', 'tainacan' ),
'info_type_to_add_metadata' => __( 'Add metadata to filter...', 'tainacan' ),
'info_visibility_helper' => __( 'How the item will be available to visualization.', 'tainacan' ),
'info_errors_in_form' => __( 'There are errors in the form', 'tainacan' ),
'info_no_document_to_item' => __( 'No document was uploaded to this item.', 'tainacan' ),
@ -646,7 +649,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_process_status_cancelled' => __('Cancelled', 'tainacan'),
'info_process_status_paused' => __('Paused', 'tainacan'),
'info_process_status_running' => __('Running', 'tainacan'),
'info_warning_process_cancelled' => __( 'Are you sure? This process will be cancelled', 'tainacan' ),
'info_warning_process_cancelled' => __( 'Are you sure? This process will be cancelled', 'tainacan' ),
'info_empty' => __( 'empty', 'tainacan' ),
'info_url_copied' => __( 'URL link copied', 'tainacan' ),
'info_other_options' => __( 'Other options: ', 'tainacan'),
@ -659,6 +662,9 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_await_while_item_copy' => __( 'Please wait while copy is being created...', 'tainacan'),
'info_await_while_item_copies' => __( 'Please wait while copies are being created. This may take a while...', 'tainacan'),
'info_expose_only_displayed_metadata' => __( 'By checking this option, only metatada that are displayed on the current list will be exposed', 'tainacan' ),
'info_initial_value' => __( 'Initial value', 'tainacan' ),
'info_final_value' => __( 'Final value', 'tainacan' ),
'info_show_interval_on_tag' => __( 'Show interval on tag', 'tainacan' ),
// Tainacan Metadatum Types
'tainacan-text' => __( 'Text', 'tainacan' ),
@ -681,6 +687,8 @@ return apply_filters( 'tainacan-admin-i18n', [
'tainacan-filter-taxonomy-taginput' => __( 'Taxonomy Tag Input', 'tainacan' ),
'tainacan-filter-taxonomy-checkbox' => __( 'Taxonomy Check Box', 'tainacan' ),
'tainacan-filter-taxonomy-selectbox' => __( 'Taxonomy Select Box', 'tainacan' ),
'tainacan-filter-numeric-interval' => __( 'Numeric Interval', 'tainacan' ),
'tainacan-filter-numeric-list-interval' => __( 'Numeric Interval List', 'tainacan' ),
// Datepicker months
'datepicker_month_january' => __( 'January', 'tainacan' ),

View File

@ -92,7 +92,8 @@ class REST_Controller extends \WP_REST_Controller {
'metatype' => 'meta_type',
'hierarchical' => 'hierarchical',
'exclude' => 'exclude',
'excludetree' => 'exclude_tree'
'excludetree' => 'exclude_tree',
'include' => 'include'
];
$meta_query = [
@ -259,6 +260,23 @@ class REST_Controller extends \WP_REST_Controller {
return false;
}
/**
* Return the fetch_only param
*
* @param string $object_name
*
* @return array|void
*/
public function get_fetch_only_param(){
return [
'fetch_only' => [
'type' => 'string/array',
'description' => __( 'Fetch only specific attribute. The specifics attributes are the same in schema.', 'tainacan' ),
//TODO: explicar o fetch only meta.. cabe aqui?
]
];
}
/**
* Return the common params
@ -267,21 +285,21 @@ class REST_Controller extends \WP_REST_Controller {
*
* @return array|void
*/
public function get_collection_params($object_name = null){
public function get_wp_query_params(){
$query_params['id'] = array(
'description' => __("Limit result to $object_name with specific id."),
'description' => __("Limit result to objects with specific id.", 'tainacan'),
'type' => 'integer',
);
$query_params['search'] = array(
'description' => __( 'Limit results to those matching a string.' ),
'description' => __( 'Limit results to those matching a string.', 'tainacan' ),
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'validate_callback' => 'rest_validate_request_arg',
);
$query_params['authorid'] = array(
'description' => __("Limit result set to $object_name assigned to specific authors by id."),
'description' => __("Limit result set to objects assigned to specific authors by id.", 'tainacan'),
'type' => 'array',
'items' => array(
'type' => 'integer',
@ -289,12 +307,12 @@ class REST_Controller extends \WP_REST_Controller {
);
$query_params['authorname'] = array(
'description' => __("Limit result set to $object_name assigned to specific authors by name"),
'description' => __("Limit result set to objects assigned to specific authors by name", 'tainacan'),
'type' => 'string',
);
$query_params['status'] = array(
'description' => __("Limit result set to $object_name assigned one or more statuses."),
'description' => __("Limit result set to objects assigned one or more statuses.", 'tainacan'),
'type' => 'array',
'items' => array(
'enum' => array_merge(array_keys(get_post_stati()), array('any')),
@ -303,19 +321,19 @@ class REST_Controller extends \WP_REST_Controller {
);
$query_params['offset'] = array(
'description' => __( "Offset the result set by a specific number of $object_name." ),
'description' => __( "Offset the result set by a specific number of objects.", 'tainacan' ),
'type' => 'integer',
);
$query_params['order'] = array(
'description' => __( 'Order sort attribute ascending or descending.' ),
'description' => __( 'Order sort attribute ascending or descending.', 'tainacan' ),
'type' => 'string/array',
'default' => 'desc',
'enum' => array( 'asc', 'desc' ),
);
$query_params['orderby'] = array(
'description' => __( "Sort $object_name by object attribute." ),
'description' => __( "Sort objects by object attribute.", 'tainacan' ),
'type' => 'string/array',
'default' => 'date',
'enum' => array(
@ -335,13 +353,13 @@ class REST_Controller extends \WP_REST_Controller {
);
$query_params['perpage'] = array(
'description' => __( "Maximum number of $object_name to be returned in result set." ),
'description' => __( "Maximum number of objects to be returned in result set.", 'tainacan' ),
'type' => 'numeric',
'default' => 10,
);
$query_params['paged'] = array(
'description' => __("Show the $object_name that would normally show up just on page X"),
'description' => __("The results page to be return.", 'tainacan'),
'type' => 'integer',
);
@ -492,6 +510,54 @@ class REST_Controller extends \WP_REST_Controller {
),
);
}
function get_repository_schema( \Tainacan\Repositories\Repository $repository ) {
$schema = [];
$map = $repository->get_map();
foreach ($map as $mapped => $value){
$schema[$mapped] = [
'description' => $value['description'],
'type' => $value['type']
];
}
return $schema;
}
function get_permissions_schema() {
return [
'current_user_can_edit' => [
'description' => esc_html__('Whether current user can edit this object', 'tainacan'),
'type' => 'boolean',
'context' => 'edit'
],
'current_user_can_delete' => [
'description' => esc_html__('Whether current user can delete this object', 'tainacan'),
'type' => 'boolean',
'context' => 'edit'
]
];
}
function get_base_properties_schema() {
return [
'id' => [
'description' => esc_html__( 'Unique identifier for the object.', 'tainacan' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true
]
];
}
}
?>

View File

@ -457,7 +457,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
public function get_create_params($object_name = null) {
$query_params['context']['default'] = 'view';
array_merge($query_params, parent::get_collection_params('item'));
array_merge($query_params, parent::get_wp_query_params());
$query_params['title'] = array(
'description' => __('Limits the result set to items with a specific title'),

View File

@ -43,7 +43,7 @@ class REST_Collections_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
),
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -51,6 +51,7 @@ class REST_Collections_Controller extends REST_Controller {
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE),
),
'schema' => [$this, 'get_schema'],
));
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<collection_id>[\d]+)', array(
array(
@ -58,6 +59,7 @@ class REST_Collections_Controller extends REST_Controller {
'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE),
),
array(
'methods' => \WP_REST_Server::EDITABLE,
@ -76,6 +78,7 @@ class REST_Collections_Controller extends REST_Controller {
),
)
),
'schema' => [$this, 'get_schema'],
));
}
@ -474,16 +477,25 @@ class REST_Collections_Controller extends REST_Controller {
public function get_endpoint_args_for_item_schema( $method = null ) {
$endpoint_args = [];
if($method === \WP_REST_Server::READABLE) {
$endpoint_args['fetch_only'] = array(
'type' => 'string/array',
'description' => __( 'Fetch only specific attribute. The specifics attributes are the same in schema.' ),
);
$endpoint_args['context'] = array(
'type' => 'string',
'default' => 'view',
'items' => array( 'view, edit' )
);
$endpoint_args['name'] = array(
'description' => __('Limits the result set to collections with a specific name'),
'type' => 'string',
);
$endpoint_args = array_merge(
$endpoint_args,
parent::get_wp_query_params(),
parent::get_fetch_only_param(),
parent::get_meta_queries_params()
);
} elseif ($method === \WP_REST_Server::CREATABLE || $method === \WP_REST_Server::EDITABLE) {
$map = $this->collections_repository->get_map();
@ -501,29 +513,30 @@ class REST_Collections_Controller extends REST_Controller {
return $endpoint_args;
}
/**
*
* Return the queries supported when getting a collection of objects
*
* @param null $object_name
*
* @return array
*/
public function get_collection_params($object_name = null) {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('collection'));
$query_params['name'] = array(
'description' => __('Limits the result set to collections with a specific name'),
'type' => 'string',
);
$query_params = array_merge($query_params, parent::get_meta_queries_params());
return $query_params;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'collection',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->collections_repository );
$permissions_schema = parent::get_permissions_schema();
// transformation done in $this->prepare_item_for_response()
$main_schema['moderators'] = $main_schema['moderators_ids'];
$main_schema['moderators']['contex'] = 'edit';
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
);
return $schema;
}
}
?>

View File

@ -70,7 +70,7 @@ class REST_Export_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
)
)
);

View File

@ -121,6 +121,7 @@ class REST_Exporters_Controller extends REST_Controller {
if ($object = $Tainacan_Exporter_Handler->initialize_exporter($slug)) {
$response = $object->_to_Array();
$Tainacan_Exporter_Handler->save_exporter_instance($object);
return new \WP_REST_Response($response, 201);
} else {
return new \WP_REST_Response([
@ -146,13 +147,14 @@ class REST_Exporters_Controller extends REST_Controller {
foreach ($body as $att => $value) {
$attributes[$att] = $value;
}
$importer = $_SESSION['tainacan_exporter'][$session_id];
if($importer) {
global $Tainacan_Exporter_Handler;
$exporter = $Tainacan_Exporter_Handler->get_exporter_instance_by_session_id($session_id);
if($exporter) {
foreach ($body as $att => $value) {
if ($att == 'collection') {
if (is_array($value) && isset($value['id'])) {
$importer->add_collection($value);
$exporter->add_collection($value);
continue;
} else {
return new \WP_REST_Response([
@ -162,12 +164,13 @@ class REST_Exporters_Controller extends REST_Controller {
}
}
$method = 'set_' . $att;
if (method_exists($importer, $method)) {
$importer->$method($value);
if (method_exists($exporter, $method)) {
$exporter->$method($value);
}
}
$response = $importer->_to_Array();
$response = $exporter->_to_Array();
$Tainacan_Exporter_Handler->save_exporter_instance($exporter);
return new \WP_REST_Response( $response, 200 );
}
@ -192,7 +195,8 @@ class REST_Exporters_Controller extends REST_Controller {
*/
public function run($request) {
$session_id = $request['session_id'];
$exporter = $_SESSION['tainacan_exporter'][$session_id];
global $Tainacan_Exporter_Handler;
$exporter = $Tainacan_Exporter_Handler->get_exporter_instance_by_session_id($session_id);
if(!$exporter) {
return new \WP_REST_Response([
@ -212,6 +216,7 @@ class REST_Exporters_Controller extends REST_Controller {
$response = [
'bg_process_id' => $process->ID
];
$Tainacan_Exporter_Handler->delete_exporter_instance($exporter);
return new \WP_REST_Response( $response, 200 );
}

View File

@ -28,6 +28,9 @@ class REST_Filter_Types_Controller extends REST_Controller {
'className' => [
'type' => 'string'
],
'name' => [
'type' => 'string'
],
'component' => [
'type' => 'string'
],

View File

@ -44,34 +44,37 @@ class REST_Filters_Controller extends REST_Controller {
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
),
'schema' => [$this, 'get_schema']
));
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base, array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params()
'args' => $this->get_wp_query_params()
),
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_item'),
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
)
),
'schema' => [$this, 'get_schema']
));
register_rest_route($this->namespace, '/' . $this->rest_base, array(
array(
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params()
'args' => $this->get_wp_query_params()
),
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_item'),
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
)
),
'schema' => [$this, 'get_schema']
));
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<filter_id>[\d]+)', array(
array(
@ -96,7 +99,8 @@ class REST_Filters_Controller extends REST_Controller {
'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
));
}
@ -148,7 +152,7 @@ class REST_Filters_Controller extends REST_Controller {
$filter_obj->set_metadatum_id($body['metadatum_id']);
} else {
$filter_obj->set_collection_id( 'filter_in_repository' );
$filter_obj->set_collection_id( 'default' );
if(!isset($body['metadatum_id'])){
throw new \InvalidArgumentException('You need provide a metadatum id');
@ -375,7 +379,7 @@ class REST_Filters_Controller extends REST_Controller {
if(!isset($request['collection_id'])) {
$args['meta_query'][] = [
'key' => 'collection_id',
'value' => 'filter_in_repository',
'value' => 'default',
'compare' => '='
];
@ -495,10 +499,10 @@ class REST_Filters_Controller extends REST_Controller {
*
* @return array|void
*/
public function get_collection_params( $object_name = null ) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('filter'));
$query_params = array_merge($query_params, parent::get_wp_query_params());
$query_params['name'] = array(
'description' => __('Limits the result set to filters with a specific name'),
@ -509,5 +513,30 @@ class REST_Filters_Controller extends REST_Controller {
return $query_params;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'filter',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->filter_repository );
$permissions_schema = parent::get_permissions_schema();
// $collection_scheme = parent::get_repository_schema( $this->collection_repository );
// $metadatum_scheme = parent::get_repository_schema( $this->metadatum_repository );
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
// $collection_scheme,
// $metadatum_scheme
);
return $schema;
}
}
?>

View File

@ -165,6 +165,7 @@ class REST_Importers_Controller extends REST_Controller {
if ($object = $Tainacan_Importer_Handler->initialize_importer($slug)) {
$response = $object->_to_Array();
$Tainacan_Importer_Handler->save_importer_instance($object);
return new \WP_REST_Response($response, 201);
} else {
return new \WP_REST_Response([
@ -192,9 +193,10 @@ class REST_Importers_Controller extends REST_Controller {
foreach ($body as $att => $value){
$attributes[$att] = $value;
}
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
if($importer) {
foreach ($body as $att => $value){
@ -218,6 +220,7 @@ class REST_Importers_Controller extends REST_Controller {
}
$response = $importer->_to_Array();
$Tainacan_Importer_Handler->save_importer_instance($importer);
return new \WP_REST_Response( $response, 200 );
}
@ -237,7 +240,8 @@ class REST_Importers_Controller extends REST_Controller {
public function source_info( $request ) {
$session_id = $request['session_id'];
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
if(!$importer) {
return new \WP_REST_Response([
@ -271,7 +275,8 @@ class REST_Importers_Controller extends REST_Controller {
public function get_saved_mapping( $request ){
$session_id = $request['session_id'];
$collection_id = $request['collection_id'];
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
$response = false;
if(!$importer) {
@ -290,7 +295,8 @@ class REST_Importers_Controller extends REST_Controller {
public function get_item( $request ) {
$session_id = $request['session_id'];
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
if(!$importer) {
return new \WP_REST_Response([
@ -306,7 +312,8 @@ class REST_Importers_Controller extends REST_Controller {
public function add_file( $request ) {
$session_id = $request['session_id'];
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
if(!$importer) {
return new \WP_REST_Response([
@ -320,6 +327,7 @@ class REST_Importers_Controller extends REST_Controller {
if ( isset($files['file']) && $importer->add_file($files['file']) ) {
$response = $importer->_to_Array();
$Tainacan_Importer_Handler->save_importer_instance($importer);
return new \WP_REST_Response( $response, 200 );
} else {
return new \WP_REST_Response([
@ -335,7 +343,8 @@ class REST_Importers_Controller extends REST_Controller {
public function run($request) {
$session_id = $request['session_id'];
$importer = $_SESSION['tainacan_importer'][$session_id];
global $Tainacan_Importer_Handler;
$importer = $Tainacan_Importer_Handler->get_importer_instance_by_session_id($session_id);
if(!$importer) {
return new \WP_REST_Response([
@ -358,6 +367,7 @@ class REST_Importers_Controller extends REST_Controller {
$response = [
'bg_process_id' => $process->ID
];
$Tainacan_Importer_Handler->delete_importer_instance($importer);
return new \WP_REST_Response( $response, 200 );
}

View File

@ -56,7 +56,7 @@ class REST_Item_Metadata_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
)
)
);
@ -289,7 +289,7 @@ class REST_Item_Metadata_Controller extends REST_Controller {
*
* @return array
*/
public function get_collection_params($object_name = null) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
return $query_params;

View File

@ -49,7 +49,7 @@ class REST_Items_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
),
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -94,7 +94,7 @@ class REST_Items_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
),
)
);
@ -790,10 +790,10 @@ class REST_Items_Controller extends REST_Controller {
*
* @return array|void
*/
public function get_collection_params($object_name = null) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
array_merge($query_params, parent::get_collection_params('item'));
array_merge($query_params, parent::get_wp_query_params());
$query_params['title'] = array(
'description' => __('Limits the result set to items with a specific title'),

View File

@ -17,6 +17,7 @@ class REST_Logs_Controller extends REST_Controller {
public function __construct() {
$this->rest_base = 'logs';
parent::__construct();
$this->logs_repository = Repositories\Logs::get_instance();
}
public function register_routes() {
@ -27,7 +28,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<log_id>[\d]+)',
@ -37,7 +39,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base,
@ -47,7 +50,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/item/(?P<item_id>[\d]+)/' . $this->rest_base,
@ -57,7 +61,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/filter/(?P<filter_id>[\d]+)/' . $this->rest_base,
@ -67,7 +72,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/metadatum/(?P<metadatum_id>[\d]+)/' . $this->rest_base,
@ -77,7 +83,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/taxonomy/(?P<taxonomy_id>[\d]+)/' . $this->rest_base,
@ -87,7 +94,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/term/(?P<term_id>[\d]+)/' . $this->rest_base,
@ -97,7 +105,8 @@ class REST_Logs_Controller extends REST_Controller {
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
}
@ -333,8 +342,6 @@ class REST_Logs_Controller extends REST_Controller {
return false;
}
/**
* @param string $method
@ -353,6 +360,25 @@ class REST_Logs_Controller extends REST_Controller {
return $endpoint_args;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'log',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->logs_repository );
$permissions_schema = parent::get_permissions_schema();
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
);
return $schema;
}
}
?>

View File

@ -62,6 +62,7 @@ class REST_Metadata_Controller extends REST_Controller {
'permission_callback' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE),
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base,
@ -70,7 +71,7 @@ class REST_Metadata_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
'args' => $this->get_wp_query_params(),
),
array(
'methods' => \WP_REST_Server::CREATABLE,
@ -78,6 +79,7 @@ class REST_Metadata_Controller extends REST_Controller {
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE),
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace, '/' . $this->rest_base,
@ -92,8 +94,9 @@ class REST_Metadata_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params(),
)
'args' => $this->get_wp_query_params(),
),
'schema' => [$this, 'get_schema'],
)
);
register_rest_route($this->namespace, '/'. $this->rest_base . '/(?P<metadatum_id>[\d]+)',
@ -115,7 +118,8 @@ class REST_Metadata_Controller extends REST_Controller {
'callback' => array($this, 'get_item'),
'permission' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema'],
)
);
}
@ -536,10 +540,10 @@ class REST_Metadata_Controller extends REST_Controller {
*
* @return array|void
*/
public function get_collection_params( $object_name = null ) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('metadatum'));
$query_params = array_merge($query_params, parent::get_wp_query_params());
$query_params['name'] = array(
'description' => __('Limits the result set to metadata with a specific name'),
@ -582,6 +586,32 @@ class REST_Metadata_Controller extends REST_Controller {
return $endpoint_args;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'metadatum',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->metadatum_repository );
$permissions_schema = parent::get_permissions_schema();
// $item_metadata_scheme = parent::get_repository_schema( $this->item_metadata_repository );
// $item_scheme = parent::get_repository_schema( $this->item_repository );
// $collection_scheme = parent::get_repository_schema( $this->collection_repository );
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
// $item_metadata_scheme,
// $item_scheme,
// $collection_scheme
);
return $schema;
}
}
?>

View File

@ -36,14 +36,15 @@ class REST_Taxonomies_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params()
'args' => $this->get_wp_query_params()
),
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'create_item'),
'permission_callback' => array($this, 'create_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::CREATABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route(
@ -71,7 +72,8 @@ class REST_Taxonomies_Controller extends REST_Controller {
'callback' => array($this, 'update_item'),
'permission_callback' => array($this, 'update_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::EDITABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route(
@ -82,7 +84,8 @@ class REST_Taxonomies_Controller extends REST_Controller {
'callback' => array($this, 'update_item'),
'permission_callback' => array($this, 'update_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::EDITABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
}
@ -485,10 +488,10 @@ class REST_Taxonomies_Controller extends REST_Controller {
*
* @return array
*/
public function get_collection_params($object_name = null) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('tax'));
$query_params = array_merge($query_params, parent::get_wp_query_params());
$query_params['name'] = array(
'description' => __('Limits the result set to a taxonomy with a specific name.'),
@ -499,6 +502,26 @@ class REST_Taxonomies_Controller extends REST_Controller {
return $query_params;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'taxonomy',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->taxonomy_repository );
$permissions_schema = parent::get_permissions_schema();
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
);
return $schema;
}
}
?>

View File

@ -44,8 +44,9 @@ class REST_Terms_Controller extends REST_Controller {
'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_items'),
'permission_callback' => array($this, 'get_items_permissions_check'),
'args' => $this->get_collection_params()
)
'args' => $this->get_wp_query_params()
),
'schema' => [$this, 'get_schema']
)
);
register_rest_route($this->namespace,'/taxonomy/(?P<taxonomy_id>[\d]+)/'. $this->rest_base . '/(?P<term_id>[\d]+)' ,
@ -71,7 +72,8 @@ class REST_Terms_Controller extends REST_Controller {
'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'get_item_permissions_check'),
'args' => $this->get_endpoint_args_for_item_schema(\WP_REST_Server::READABLE)
)
),
'schema' => [$this, 'get_schema']
)
);
}
@ -449,10 +451,10 @@ class REST_Terms_Controller extends REST_Controller {
*
* @return array
*/
public function get_collection_params($object_name = null) {
public function get_wp_query_params() {
$query_params['context']['default'] = 'view';
$query_params = array_merge($query_params, parent::get_collection_params('term'));
$query_params = array_merge($query_params, parent::get_wp_query_params());
$query_params['name'] = array(
'description' => __('Limits the result set to terms with a specific name'),
@ -463,6 +465,28 @@ class REST_Terms_Controller extends REST_Controller {
return $query_params;
}
function get_schema() {
$schema = [
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'term',
'type' => 'object'
];
$main_schema = parent::get_repository_schema( $this->terms_repository );
$permissions_schema = parent::get_permissions_schema();
// $taxonomy_scheme = parent::get_repository_schema( $this->taxonomy_repository );
$schema['properties'] = array_merge(
parent::get_base_properties_schema(),
$main_schema,
$permissions_schema
// $taxonomy_scheme
);
return $schema;
}
}
?>

View File

@ -12,18 +12,10 @@ namespace Tainacan;
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WP_Async_Request', false ) ) {
include_once TAINACAN_CLASSES_DIR . '/lib/wp-async-request.php';
}
if ( ! class_exists( 'WP_Background_Process', false ) ) {
include_once TAINACAN_CLASSES_DIR . '/lib/wp-background-process.php';
}
/**
* Tainacan_Background_Process class.
*/
abstract class Background_Process extends \WP_Background_Process {
abstract class Background_Process extends \Tainacan_WP_Background_Process {
/**
* Table name where the queue is stored

View File

@ -275,6 +275,21 @@ class Filter extends Entity {
if (false === $is_valid)
return false;
$status = $this->get_status();
$status_obj = get_post_status_object($status);
if ($status_obj->public) {
$metadatum = $this->get_metadatum();
if ($metadatum) {
$metadatum_status_obj = get_post_status_object($metadatum->get_status());
if ( ! $metadatum_status_obj->public ) {
$this->add_error('status', __('Filter can not be public because the related metadatum is private', 'tainacan'));
return false;
}
}
}
$fto = $this->get_filter_type_object();
if (is_object($fto)) {
$is_valid = $fto->validate_options( $this );

View File

@ -93,10 +93,10 @@ class Item extends Entity {
}
$attachments_query = [
'post_type' => 'attachment',
'post_per_page' => -1,
'post_parent' => $item_id,
'exclude' => $to_exclude,
'post_type' => 'attachment',
'posts_per_page' => -1,
'post_parent' => $item_id,
'exclude' => $to_exclude,
];
$attachments = get_posts( $attachments_query );

View File

@ -145,6 +145,16 @@ class Term extends Entity {
return wp_get_attachment_url( $this->get_header_image_id() );
}
/**
* @return false|string
*/
function get_url(){
$url = get_term_link( $this->get_id() );
if (is_wp_error($url))
return "";
return $url;
}
// Setters
/**

View File

@ -3,15 +3,15 @@
<b-autocomplete
icon="magnify"
size="is-small"
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
v-model="selected"
:data="options"
expanded
:loading="isLoadingOptions"
@input="search"
field="label"
@select="option => setResults(option) "
:placeholder="(type == 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_search_items') : $i18n.get('info_type_to_search_metadata')">
@select="onSelect"
:placeholder="(metadatumType === 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_search_items') : $i18n.get('info_type_to_search_metadata')">
<template slot-scope="props">
<div class="media">
<div
@ -41,83 +41,54 @@
<script>
import { tainacan as axios, isCancel } from '../../../js/axios/axios'
import { filter_type_mixin } from '../filter-types-mixin'
// import qs from 'qs';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id;
const vm = this;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
in_route = '/metadata/'+ this.metadatum;
}
axios.get(in_route)
.then( res => {
let result = res.data;
if( result && result.metadata_type ){
vm.metadatum_object = result;
vm.type = result.metadata_type;
vm.selectedValues();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
},
mixins: [filterTypeMixin, dynamicFilterTypeMixin],
data(){
return {
results:'',
selected:'',
options: [],
type: '',
collection: '',
metadatum: '',
metadatum_object: {},
label: ''
}
},
props: {
isRepositoryLevel: Boolean,
labelId: String
watch: {
'query.metaquery'() {
this.selectedValues();
},
},
mounted() {
this.selectedValues();
},
mixins: [filter_type_mixin],
methods: {
setResults(option){
onSelect(option){
if(!option)
return;
this.results = option.value;
this.selected = option.value;
this.label = option.label;
this.onSelect()
},
onSelect(){
this.$emit('input', {
filter: 'autocomplete',
metadatum_id: this.metadatum,
collection_id: this.collection,
value: this.results
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.selected
});
this.selectedValues();
},
search: _.debounce( function(query) {
if (query != '') {
let promise = null;
this.options = [];
// Cancels previous Request
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' )
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( query, this.isRepositoryLevel );
else
promise = this.getValuesPlainText( this.metadatum, query, this.isRepositoryLevel );
promise = this.getValuesPlainText( this.metadatumId, query, this.isRepositoryLevel );
promise.request.catch( error => {
if (isCancel(error))
@ -130,71 +101,48 @@
this.getOptionsValuesCancel = promise.source;
} else {
this.cleanSearch();
this.label = '';
this.selected = '';
this.$emit('input', {
filter: 'autocomplete',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.selected
});
}
}, 500),
selectedValues(){
const instance = this;
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
if (!this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ))
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
if ( index >= 0){
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId);
if (index >= 0) {
let metadata = this.query.metaquery[ index ];
// let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ?
// this.metadatum_object.metadata_type_options.collection_id : this.collection_id;
if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' ) {
// let query = qs.stringify({ postin: metadata.value });
if (this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship') {
axios.get('/items/' + metadata.value)
axios.get('/items/' + metadata.value + '?fetch_only=title,thumbnail')
.then( res => {
let item = res.data;
instance.results = item.title;
instance.label = item.title;
instance.selected = item.title;
this.label = item.title;
this.selected = item.title;
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: instance.filter.id,
value: instance.label
});
this.$emit( 'sendValuesToTags', { label: this.label, value: this.selected });
})
.catch(error => {
this.$console.log(error);
});
} else {
instance.results = metadata.value;
instance.label = metadata.value;
instance.selected = metadata.value;
this.label = metadata.value;
this.selected = metadata.value;
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: instance.filter.id,
value: metadata.value
});
this.$emit( 'sendValuesToTags', { label: this.label, value: this.selected });
}
} else {
return false;
}
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.cleanSearch();
},
cleanSearch(){
this.results = '';
this.label = '';
this.selected = '';
this.$emit('input', {
filter: 'autocomplete',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: ''
});
},
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
}
</script>

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Autocomplete extends Filter_Type {
function __construct(){
$this->set_name('Autocomplete');
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-autocomplete');
$this->set_use_max_options(false);

View File

@ -39,63 +39,36 @@
</template>
<script>
import { tainacan as axios, isCancel } from '../../../js/axios/axios';
import { filter_type_mixin } from '../filter-types-mixin';
import { isCancel } from '../../../js/axios/axios';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
import CheckboxRadioModal from '../../../admin/components/other/checkbox-radio-modal.vue';
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id;
let route = '/collection/' + this.collection + '/metadata/' + this.metadatum +'?nopaging=1';
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
route = '/metadata?nopaging=1';
axios.get(route)
.then( res => {
let result = res.data;
if ( result && result.metadata_type ){
this.metadatum_object = result;
this.type = result.metadata_type;
if (!this.isUsingElasticSearch)
this.loadOptions();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
if (this.isUsingElasticSearch) {
this.isLoadingOptions = false;
this.$eventBusSearch.$on('isLoadingItems', this.updatesIsLoading);
}
},
props: {
isRepositoryLevel: Boolean,
},
mixins: [filterTypeMixin, dynamicFilterTypeMixin],
data(){
return {
options: [],
type: '',
collection: '',
metadatum: '',
selected: [],
metadatum_object: {}
selected: []
}
},
mixins: [filter_type_mixin],
watch: {
selected: function(){
//this.selected = val;
this.onSelect();
selected(newVal, oldVal) {
const isEqual = (newVal.length == oldVal.length) && newVal.every((element, index) => {
return element === oldVal[index];
});
if (!isEqual)
this.onSelect();
},
'query.metaquery'() {
if (!this.isUsingElasticSearch)
this.loadOptions();
}
},
mounted() {
if (!this.isUsingElasticSearch)
this.loadOptions();
},
methods: {
loadOptions(skipSelected) {
let promise = null;
@ -104,11 +77,11 @@
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' )
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1');
else
promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1' );
promise = this.getValuesPlainText( this.metadatumId, null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1' );
if (skipSelected != undefined && skipSelected == true) {
promise.request
.then(() => {
@ -125,7 +98,8 @@
.catch( (error) => {
if (isCancel(error)) {
this.$console.log('Request canceled: ' + error.message);
}else
this.selectedValues();
} else
this.$console.error( error );
});
}
@ -136,41 +110,36 @@
this.$emit('input', {
filter: 'checkbox',
compare: 'IN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.selected
});
let onlyLabels = [];
if(!isNaN(this.selected[0])){
for (let aSelected of this.selected) {
let valueIndex = this.options.findIndex(option => option.value == aSelected);
if (valueIndex >= 0) {
onlyLabels.push(this.options[valueIndex].label);
}
}
}
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: onlyLabels.length ? onlyLabels : this.selected,
});
},
selectedValues() {
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
let query = this.query.metaquery.slice();
this.selected = query[ index ].value;
} else {
this.selected = [];
return false;
}
let onlyLabels = [];
if (!isNaN(this.selected[0])){
for (let aSelected of this.selected) {
let valueIndex = this.options.findIndex(option => option.value == aSelected);
if (valueIndex >= 0) {
onlyLabels.push(this.options[valueIndex].label);
}
}
}
this.$emit( 'sendValuesToTags', { label: onlyLabels.length ? onlyLabels : this.selected, value: this.selected });
},
openCheckboxModal() {
this.$buefy.modal.open({
@ -181,11 +150,10 @@
filter: this.filter,
//taxonomy_id: this.taxonomy_id,
selected: this.selected,
metadatum_id: this.metadatum,
metadatumId: this.metadatumId,
//taxonomy: this.taxonomy,
collection_id: this.collection,
metadatum_type: this.type,
metadatum_object: this.metadatum_object,
collectionId: this.collectionId,
metadatum_type: this.metadatumType,
isRepositoryLevel: this.isRepositoryLevel,
query: this.query
},
@ -193,50 +161,13 @@
appliedCheckBoxModal: () => {
this.loadOptions();
}
}
},
trapFocus: true
});
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id) {
let selectedIndex = this.selected.findIndex(option => option == filterTag.singleValue);
let optionIndex = this.options.findIndex(option => option.label == filterTag.singleValue);
let alternativeIndex;
if (optionIndex >= 0) {
alternativeIndex = this.selected.findIndex(option => this.options[optionIndex].value == option);
}
if (selectedIndex >= 0 || alternativeIndex >= 0) {
selectedIndex >= 0 ? this.selected.splice(selectedIndex, 1) : this.selected.splice(alternativeIndex, 1);
this.$emit('input', {
filter: 'checkbox',
compare: 'IN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: this.selected
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.selected
});
this.selectedValues();
}
}
},
updatesIsLoading(isLoading) {
this.isLoadingOptions = isLoading;
updatesIsLoading(isLoadingOptions) {
this.isLoadingOptions = isLoadingOptions;
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
if (this.isUsingElasticSearch)
this.$eventBusSearch.$off('isLoadingItems', this.updatesIsLoading);
}
}
</script>

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Checkbox extends Filter_Type {
function __construct(){
$this->set_name('Checkbox List');
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-checkbox');
$this->set_preview_template('

View File

@ -1,9 +1,9 @@
<template>
<div>
<!-- Date -->
<div v-if="type === 'date'">
<div v-if="metadatumType === 'Tainacan\\Metadata_Types\\Date'">
<b-datepicker
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
:placeholder="$i18n.get('label_selectbox_init')"
v-model="date_init"
size="is-small"
@ -24,7 +24,7 @@
]"/>
<p class="is-size-7 has-text-centered is-marginless">{{ $i18n.get('label_until') }}</p>
<b-datepicker
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
:placeholder="$i18n.get('label_selectbox_init')"
v-model="date_end"
size="is-small"
@ -47,18 +47,20 @@
<!-- Numeric -->
<div v-else>
<b-numberinput
:aria-labelledby="labelId"
<b-input
type="number"
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
step="any"
@input="validate_values()"
@input="validate_values"
v-model="value_init"/>
<p class="is-size-7 has-text-centered is-marginless">{{ $i18n.get('label_until') }}</p>
<b-numberinput
:aria-labelledby="labelId"
<b-input
type="number"
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
step="any"
@input="validate_values()"
@input="validate_values"
@focus="isTouched = true"
v-model="value_end"/>
</div>
@ -66,62 +68,31 @@
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import { wpAjax, dateInter } from "../../../admin/js/mixins";
import { filterTypeMixin } from '../filter-types-mixin';
import moment from 'moment';
export default {
mixins: [ wpAjax, dateInter ],
created() {
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
in_route = '/metadata/'+ this.metadatum;
}
axios.get(in_route)
.then( res => {
let result = res.data;
if( result && result.metadata_type ){
this.metadatum_object = result;
this.type = ( result.metadata_type === 'Tainacan\\Metadata_Types\\Date') ? 'date' : 'numeric';
this.selectedValues();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
mixins: [
wpAjax,
dateInter,
filterTypeMixin
],
mounted() {
this.selectedValues();
},
data(){
return {
value_init: null,
value_end: null,
value_init: '',
value_end: '',
date_init: undefined,
date_end: undefined,
isTouched: false,
isValid: false,
clear: false,
type: 'numeric',
collection: '',
metadatum: '',
metadatum_object: {}
type: 'DECIMAL'
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
labelId: '',
query: Object,
isRepositoryLevel: Boolean,
},
watch: {
isTouched( val ){
if ( val && this.date_init === null)
@ -129,39 +100,46 @@
if ( val && this.date_end === null)
this.date_end = new Date();
this.isTouched = val;
},
'query.metaquery'() {
this.selectedValues();
}
},
methods: {
// only validate if the first value is higher than first
validate_values: _.debounce( function (){
if( this.type === 'date' ){
if (this.date_init === undefined)
if( this.metadatumType === 'Tainacan\\Metadata_Types\\Date' ){
if (this.date_init === undefined)
this.date_init = new Date();
if (this.date_end === undefined)
this.date_end = new Date();
if ( this.date_init > this.date_end ) {
let result = this.date_init;
result.setDate(result.getDate() + 1);
this.date_end = result;
result.setDate(result.getDate() - 1);
this.date_init = result;
//this.error_message();
this.error_message();
return
}
} else {
if ( parseFloat( this.value_init ) > parseFloat( this.value_end )) {
//this.value_end = parseFloat( this.value_init ) + 1;
//this.error_message();
if (this.value_init.constructor == Number)
this.value_init = this.value_init.valueOf();
if (this.value_end.constructor == Number)
this.value_end = this.value_end.valueOf();
this.value_init = parseFloat(this.value_init);
this.value_end = parseFloat(this.value_end);
if (isNaN(this.value_init) || isNaN(this.value_end))
return
if (this.value_init > this.value_end) {
this.error_message();
return;
}
}
this.emit();
}, 1000),
}, 800),
// message for error
error_message(){
if ( !this.isTouched ) return false;
@ -173,91 +151,56 @@
type: 'is-danger'
})
},
dateFormatter(dateObject) {
dateFormatter(dateObject){
return moment(dateObject, moment.ISO_8601).format(this.dateFormat);
},
dateParser(dateString) {
dateParser(dateString){
return moment(dateString, this.dateFormat).toDate();
},
selectedValues(){
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
if ( index >= 0){
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId);
if (index >= 0) {
let metadata = this.query.metaquery[ index ];
if( metadata.value && metadata.value.length > 0 && this.type === 'numeric'){
this.value_init = metadata.value[0];
this.value_end = metadata.value[1];
if( metadata.value && metadata.value.length > 0 && this.metadatumType === 'Tainacan\\Metadata_Types\\Numeric'){
this.value_init = parseFloat(metadata.value[0]);
this.value_end = parseFloat(metadata.value[1]);
this.isValid = true;
} else if( metadata.value && metadata.value.length > 0 ){
this.date_init = new Date( metadata.value[0] );
this.date_end = new Date( metadata.value[1] );
this.date_init = new Date(metadata.value[0]);
this.date_end = new Date(metadata.value[1]);
this.isValid = true;
}
if (metadata.value[0] != undefined && metadata.value[1] != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.parseDateToNavigatorLanguage(metadata.value[0]) + ' - ' + this.parseDateToNavigatorLanguage(metadata.value[1])
if (metadata.value[0] != undefined && metadata.value[1] != undefined)
this.$emit('sendValuesToTags', {
label: (this.metadatumType === 'Tainacan\\Metadata_Types\\Numeric' ? (metadata.value[0] + ' - ' + metadata.value[1]) : this.parseDateToNavigatorLanguage(metadata.value[0]) + ' - ' + this.parseDateToNavigatorLanguage(metadata.value[1])),
value: [metadata.value[0], metadata.value[1]]
});
}
} else {
return false;
}
},
showSearch(){
if( this.type === 'date' ){
if( this.date_init === null || this.date_end === null ){
this.clear = true;
return '';
if (this.metadatumType === 'Tainacan\\Metadata_Types\\Numeric') {
this.value_init = '';
this.value_end = '';
} else {
this.date_init = null;
this.date_end = null;
}
return this.date_init.toLocaleString().split(' ')[0] + ' - ' + this.date_end.toLocaleString().split(' ')[0];
}
// else {
// return this.value_init + ' - ' +this.value_end;
// }
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.clearSearch();
},
clearSearch(){
this.clear = true;
this.$emit('input', {
filter: 'range',
compare: 'BETWEEN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: ''
});
if( this.type === 'date' ){
this.date_init = null;
this.date_end = null;
this.isTouched = false;
} else {
this.value_end = null;
this.value_init = null;
this.isTouched = false;
}
},
// emit the operation for listeners
emit() {
let values = [];
let type = '';
if (this.metadatumType === 'Tainacan\\Metadata_Types\\Date') {
if( this.type === 'date' ){
if( this.date_init === null && this.date_end === null ){
if (this.date_init === null && this.date_end === null) {
values = [];
type = 'DATE';
this.type = 'DATE';
this.isValid = false;
this.clear = true;
} else {
@ -268,29 +211,29 @@
('00' + (this.date_end.getUTCMonth() + 1)).slice(-2) + '-' +
('00' + this.date_end.getUTCDate()).slice(-2);
values = [ date_init, date_end ];
type = 'DATE';
this.type = 'DATE';
this.isValid = true;
this.clear = false;
}
} else {
if( this.value_init === null || this.value_end === null
if (this.value_init === null || this.value_end === null
|| this.value_init === '' || this.value_end === ''){
return;
} else {
values = [ this.value_init, this.value_end ];
if(this.value_init !== this.value_end && (this.value_init % 1 !== 0 && this.value_end % 1 == 0)) {
type = 'DECIMAL';
this.type = 'DECIMAL';
} else if(this.value_init !== this.value_end &&
this.value_init % 1 !== 0 &&
this.value_end % 1 !== 0) {
type = '';
this.type = '';
} else if(this.value_init !== this.value_end &&
!(this.value_init % 1 == 0 && this.value_end % 1 !== 0)){
type = 'DECIMAL';
this.type = 'DECIMAL';
} else {
type = '';
this.type = '';
}
//this.isValid = true;
//this.clear = false;
@ -299,23 +242,19 @@
this.$emit('input', {
filter: 'range',
type: type,
type: this.type,
compare: 'BETWEEN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: values
});
if (values[0] != undefined && values[1] != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.parseDateToNavigatorLanguage(values[0]) + ' - ' + this.parseDateToNavigatorLanguage(values[1])
if (values[0] != undefined && values[1] != undefined)
this.$emit( 'sendValuesToTags', {
label: (this.metadatumType === 'Tainacan\\Metadata_Types\\Numeric' ? (values[0] + ' - ' + values[1]) : this.parseDateToNavigatorLanguage(values[0]) + ' - ' + this.parseDateToNavigatorLanguage(values[1])),
value: [ values[0], values[1] ]
});
}
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -10,6 +10,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Custom_Interval extends Filter_Type {
function __construct(){
$this->set_name('Custom Interval');
$this->set_supported_types(['float','date']);
$this->set_component('tainacan-filter-custom-interval');
$this->set_use_max_options(false);

View File

@ -3,7 +3,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeComparator($event)"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_comparator')"
class="button is-white"
@ -59,16 +60,16 @@
</b-dropdown-item>
</b-dropdown>
<!-- <b-numberinput
v-if="options.type == 'year'"
v-if="filterTypeOptions.type == 'year'"
:placeholder="$i18n.get('instruction_type_value_year')"
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
step="1"
@input="emitOnlyYear($event)"
v-model="yearsOnlyValue"/> -->
<b-datepicker
position="is-bottom-left"
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
:placeholder="$i18n.get('instruction_select_a_date')"
v-model="value"
@input="emit()"
@ -100,67 +101,38 @@
$i18n.get('datepicker_month_november'),
$i18n.get('datepicker_month_december')
]"/>
<!-- OPTIONS FOR TYPE
<!-- filterTypeOptions FOR TYPE
v-else
:type="options.type == 'month' ? 'month' : null"
:placeholder="options.type == 'month' ? $i18n.get('instruction_select_a_date') : $i18n.get('instruction_select_a_month')"
:type="filterTypeOptions.type == 'month' ? 'month' : null"
:placeholder="filterTypeOptions.type == 'month' ? $i18n.get('instruction_select_a_date') : $i18n.get('instruction_select_a_month')"
-->
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import { wpAjax, dateInter } from "../../../admin/js/mixins";
import { filterTypeMixin } from '../filter-types-mixin';
import moment from 'moment';
export default {
mixins: [ wpAjax, dateInter ],
created() {
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : (typeof this.filter.metadatum.metadatum_id == 'object' ? this.filter.metadatum.metadatum_id.metadatum_id : this.filter.metadatum.metadatum_id);
this.options = this.filter.filter_type_options;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
in_route = '/metadata/'+ this.metadatum;
axios.get(in_route)
.then( res => {
let result = res.data;
if ( result && result.metadata_type ){
this.metadatum_object = result;
this.selectedValues();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
},
mixins: [
wpAjax,
dateInter,
filterTypeMixin
],
mounted() {
this.selectedValues();
},
data(){
return {
value: null,
clear: false,
options: [],
collection: '',
metadatum: '',
metadatum_object: {},
comparator: '=', // =, !=, >, >=, <, <=
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
labelId: '',
query: Object,
isRepositoryLevel: Boolean,
watch: {
'query.metaquery'() {
this.selectedValues();
}
},
computed: {
yearsOnlyValue() {
@ -183,8 +155,8 @@
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
let metadata = this.query.metaquery[ index ];
@ -199,35 +171,15 @@
this.value = new Date(textValue);
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + moment(this.value, moment.ISO_8601).format(this.dateFormat)
this.$emit('sendValuesToTags', {
label: this.comparator + ' ' + moment(this.value, moment.ISO_8601).format(this.dateFormat),
value: textValue
});
}
} else {
return false;
this.value = null;
}
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.clearSearch();
},
clearSearch(){
this.clear = true;
this.$emit('input', {
filter: 'date',
type: 'DATE',
compare: this.comparator,
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: ''
});
this.value = null;
},
dateFormatter(dateObject) {
return moment(dateObject, moment.ISO_8601).format(this.dateFormat);
@ -260,13 +212,13 @@
filter: 'date',
type: 'DATE',
compare: this.comparator,
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: valueQuery
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + moment(this.value, moment.ISO_8601).format(this.dateFormat)
this.$emit('sendValuesToTags', {
label: this.comparator + ' ' + moment(this.value, moment.ISO_8601).format(this.dateFormat),
value: valueQuery
});
},
@ -274,9 +226,6 @@
this.comparator = newComparator;
this.emit();
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -27,7 +27,6 @@
type: Object
},
value: [String, Number, Array],
id: '',
disabled: false,
},
data() {
@ -39,9 +38,6 @@
onUpdateType(type) {
this.$emit('input', { type: type });
},
},
created() {
this.type = this.type && this.value.type ? this.value.type : 'day';
}
}
</script>

View File

@ -10,6 +10,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Date extends Filter_Type {
function __construct(){
$this->set_name('Date');
$this->set_supported_types(['date']);
$this->set_component('tainacan-filter-date');
// $this->set_form_component('tainacan-filter-form-date');

View File

@ -24,6 +24,12 @@ abstract class Filter_Type {
*/
private $default_options = [];
/**
* The name of the filter type that will be rendered on labels
* @var string
*/
private $name;
/**
* The name of the web component used by this filter type
* @var string
@ -56,6 +62,20 @@ abstract class Filter_Type {
}
/**
* @param string $name for the filter type
*/
public function set_name($name){
$this->name = $name;
}
/**
* @return string
*/
public function get_name() {
return $this->name;
}
/**
* @return array Supported types by the filter
*/
@ -103,6 +123,7 @@ abstract class Filter_Type {
$attributes = [];
$attributes['className'] = get_class($this);
$attributes['name'] = $this->get_name();
$attributes['component'] = $this->get_component();
$attributes['options'] = $this->get_options();
$attributes['supported_types'] = $this->get_supported_types();

View File

@ -2,34 +2,48 @@ import qs from 'qs';
import axios from '../../js/axios/axios';
import { mapGetters } from 'vuex';
export const filter_type_mixin = {
export const filterTypeMixin = {
data () {
return {
collectionId: '',
metadatumId: '',
metadatumType: '',
filterTypeOptions: [],
}
},
props: {
filter: Object,
query: Object,
isRepositoryLevel: Boolean,
isUsingElasticSearch: Boolean,
isLoadingItems: Boolean
},
created() {
this.collectionId = this.filter.collection_id ? this.filter.collection_id : this.collectionId;
this.metadatumId = this.filter.metadatum.metadatum_id ? this.filter.metadatum.metadatum_id : this.metadatumId;
this.filterTypeOptions = this.filter.filter_type_options ? this.filter.filter_type_options : this.filterTypeOptions;
this.metadatumType = this.filter.metadatum.metadata_type_object.className ? this.filter.metadatum.metadata_type_object.className : this.metadatumType;
}
};
export const dynamicFilterTypeMixin = {
data () {
return {
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
getOptionsValuesCancel: undefined,
isUsingElasticSearch: tainacan_plugin.wp_elasticpress == "1" ? true : false,
isLoadingOptions: false
isLoadingOptions: false,
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
id: '',
query: {}
},
created() {
// We listen to event, but reload event if hasFiltered is negative, as
// an empty query also demands filters reloading.
this.$eventBusSearch.$on('hasFiltered', this.reloadOptionsDueToFiltering);
},
computed: {
facetsFromItemSearch() {
return this.getFacets();
}
},
watch: {
isLoadingItems() {
this.isLoadingOptions = this.isLoadingItems;
}
},
methods: {
...mapGetters('search', [
'getFacets'
@ -39,7 +53,7 @@ export const filter_type_mixin = {
if (isInCheckboxModal || search || !this.isUsingElasticSearch) {
const source = axios.CancelToken.source();
let currentQuery = JSON.parse(JSON.stringify(this.query));
if (currentQuery.fetch_only != undefined) {
delete currentQuery.fetch_only;
@ -51,10 +65,10 @@ export const filter_type_mixin = {
let query_items = { 'current_query': currentQuery };
let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'filter_in_repository')
if (isRepositoryLevel || this.filter.collection_id == 'default')
url = `/facets/${metadatumId}?getSelected=${getSelected}&`;
else
url = `/collection/${this.collection}/facets/${metadatumId}?getSelected=${getSelected}&`;
url = `/collection/${this.filter.collection_id}/facets/${metadatumId}?getSelected=${getSelected}&`;
if (offset != undefined && number != undefined) {
if (!this.isUsingElasticSearch)
@ -130,7 +144,7 @@ export const filter_type_mixin = {
let query_items = { 'current_query': currentQuery };
let url = '';
if (isRepositoryLevel || this.filter.collection_id == 'filter_in_repository')
if (isRepositoryLevel || this.filter.collection_id == 'default')
url = '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;
else
url = '/collection/' + this.filter.collection_id + '/facets/' + this.filter.metadatum.metadatum_id + `?getSelected=${getSelected}&`;
@ -300,7 +314,7 @@ export const filter_type_mixin = {
this.noMorePage = 1;
if(this.options.length < this.maxNumOptionsCheckboxList)
if (this.options.length < this.maxNumOptionsCheckboxList)
this.noMorePage = 1;
if (this.filter.max_options && this.options.length >= this.filter.max_options) {
@ -313,16 +327,10 @@ export const filter_type_mixin = {
}
}
},
reloadOptionsDueToFiltering() {
if (typeof this.loadOptions == "function")
this.loadOptions(true);
}
},
beforeDestroy() {
// Cancels previous Request
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
this.$eventBusSearch.$off('hasFiltered', this.reloadOptionsDueToFiltering);
},
};

View File

@ -2,156 +2,72 @@
<div>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'input-mode') }}<span>&nbsp;*&nbsp;</span>
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'input-mode')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'input-mode')"/>
:title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'step')"/>
</label>
<b-radio
v-model="inputMode"
name="inputMode"
native-value="custom"
@input="onUpdate">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'custom') }}
</b-radio>
<b-radio
v-model="inputMode"
name="inputMode"
native-value="list"
@input="onUpdate">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'list') }}
</b-radio>
</b-field>
<template v-if="inputMode == 'custom'">
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'step')"/>
</label>
<div
v-if="!showEditStepOptions"
class="is-flex">
<b-select
name="step_options"
v-model="step"
@input="onUpdate">
<option value="0.001">0.001</option>
<option value="0.01">0.01</option>
<option value="0.1">0.1</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="100">100</option>
<option value="1000">1000</option>
<option
v-if="step && ![0.001,0.01,0.1,1,2,5,10,100,1000].find( (element) => element == step )"
:value="step">
{{ step }}</option>
</b-select>
<button
class="button is-white is-pulled-right"
:aria-label="$i18n.get('edit')"
@click.prevent="showEditStepOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary"/>
</span>
</button>
</div>
<div
v-if="showEditStepOptions"
class="is-flex">
<b-input
name="max_options"
v-model="step"
@input="onUpdate"
type="number"
step="1" />
<button
@click.prevent="showEditStepOptions = false"
class="button is-white is-pulled-right">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-close has-text-secondary"/>
</span>
</button>
</div>
</b-field>
</template>
<template v-if="inputMode == 'list'">
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', '') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'step')"/>
</label>
<a
role="button"
v-if="intervals.length == 0"
@click="addInterval()"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
<div
v-if="!showEditStepOptions"
class="is-flex">
<b-select
name="step_options"
v-model="step"
@input="onUpdate">
<option value="0.001">0.001</option>
<option value="0.01">0.01</option>
<option value="0.1">0.1</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="100">100</option>
<option value="1000">1000</option>
<option
v-if="step && ![0.001,0.01,0.1,1,2,5,10,100,1000].find( (element) => element == step )"
:value="step">
{{ step }}</option>
</b-select>
<button
class="button is-white is-pulled-right"
:aria-label="$i18n.get('edit')"
@click.prevent="showEditStepOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary"/>
</span>
&nbsp;add new
</a>
<div
v-for="(interval, index) of intervals"
:key="index">
<b-field label="c1">
<b-input
@input="onUpdate"
v-model="interval.label" />
</b-field>
<b-field label="c2">
<b-numberinput
@input="onUpdate"
v-model="interval.from" />
</b-field>
<b-field label="c3">
<b-numberinput
@input="onUpdate"
v-model="interval.to" />
</b-field>
<a
role="button"
@click="addInterval(index)"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;add new
</a>
<a
role="button"
@click="removeInterval(index)"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-remove"/>
</span>
&nbsp;remove
</a>
</div>
</b-field>
</template>
</button>
</div>
<div
v-if="showEditStepOptions"
class="is-flex">
<b-input
name="max_options"
v-model="step"
@input="onUpdate"
type="number"
step="1" />
<button
@click.prevent="showEditStepOptions = false"
class="button is-white is-pulled-right">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-close has-text-secondary"/>
</span>
</button>
</div>
</b-field>
</div>
</template>
@ -163,49 +79,24 @@
type: Object
},
value: [String, Number, Array],
id: '',
disabled: false,
},
data() {
return {
step: [Number, String],
inputMode: 'custom',
showEditStepOptions: false,
intervals: [],
showEditStepOptions: false
}
},
methods: {
onUpdate() {
this.$emit('input', {
step: this.step,
intervals: this.intervals,
inputMode: this.inputMode
step: this.step
});
},
removeInterval(index) {
this.intervals.splice(index, 1);
},
addInterval(index) {
if (index) {
this.intervals.splice(index + 1, 0, {
label: '',
to: 0,
from: 0
})
} else {
this.intervals.push({
label: '',
to: 0,
from: 0
});
}
}
},
created() {
this.step = this.value && this.value.step ? this.value.step : 1;
this.inputMode = this.value && this.value.inputMode ? this.value.inputMode : 'custom';
this.intervals = this.value && this.value.intervals ? this.value.intervals : [];
}
}
</script>

View File

@ -1,82 +1,52 @@
<template>
<div>
<template v-if="options.inputMode == 'custom'">
<b-numberinput
:aria-labelledby="labelId"
size="is-small"
@input="validate_values()"
:step="options.step"
v-model="valueInit"/>
<p class="is-size-7 has-text-centered is-marginless">{{ $i18n.get('label_until') }}</p>
<b-numberinput
:aria-labelledby="labelId"
size="is-small"
@input="validate_values()"
:step="options.step"
v-model="valueEnd"/>
</template>
<template v-if="options.inputMode == 'list'">
<b-select
placeholder="Select a name"
@input="changeInterval"
v-model="selectedInterval">
<option
v-for="(interval, index) in options.intervals"
:value="index"
:key="index">
{{ interval.label }}
</option>
</b-select>
</template>
<b-numberinput
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
@input="validate_values()"
:step="filterTypeOptions.step"
v-model="valueInit"
/>
<p class="is-size-7 has-text-centered is-marginless">{{ $i18n.get('label_until') }}</p>
<b-numberinput
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
@input="validate_values()"
:step="filterTypeOptions.step"
v-model="valueEnd"/>
</div>
</template>
<script>
import { filterTypeMixin } from '../filter-types-mixin';
export default {
created() {
this.collectionId = this.filter.collection_id;
this.metadatumId = this.filter.metadatum.metadatum_id;
this.options = this.filter.filter_type_options;
console.log(this.options);
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
},
mixins: [ filterTypeMixin ],
data(){
return {
valueInit: 0,
valueEnd: 10,
isValid: false,
collectionId: '',
metadatum: '',
options: [],
selectedInterval: ''
withError: false
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
labelId: '',
query: Object,
isRepositoryLevel: Boolean,
inputMode: String,
step: Number
mounted() {
this.selectedValues();
},
methods: {
// only validate if the first value is higher than first
validate_values: _.debounce( function (){
if ( parseFloat( this.valueInit ) > parseFloat( this.valueEnd )) {
//this.valueEnd = parseFloat( this.valueInit ) + 1;
//this.error_message();
//this.withError = true;
return;
}
console.log('pssou');
//this.withError = false;
this.emit();
}, 600),
// message for error
error_message(){
if ( !this.isTouched ) return false;
this.$buefy.toast.open({
duration: 3000,
message: this.$i18n.get('info_error_first_value_greater'),
@ -84,40 +54,11 @@
type: 'is-danger'
})
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.clearSearch();
},
changeInterval() {
if (this.selectedInterval !== '') {
this.valueInit = this.options.intervals[this.selectedInterval].from;
this.valueEnd = this.options.intervals[this.selectedInterval].to;
this.emit();
} else {
this.clearSearch();
}
},
clearSearch(){
this.$emit('input', {
filter: 'range',
compare: 'BETWEEN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: ''
});
this.valueEnd = null;
this.valueInit = null;
},
// emit the operation for listeners
emit() {
let values = [ this.valueInit, this.valueEnd ];
let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL' : 'NUMERIC';
console.log(values);
console.log(type, Number.isInteger( this.valueInit ), Number.isInteger( this.valueEnd ));
let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL(20,3)' : 'NUMERIC';
this.$emit('input', {
type: type,
//filter: 'range',
@ -127,12 +68,8 @@
value: values
});
if (values[0] != undefined && values[1] != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: values[0] + ' - ' + values[1]
});
}
if (values[0] != undefined && values[1] != undefined)
this.$emit('sendValuesToTags', { label: values[0] + ' - ' + values[1], value: values });
},
selectedValues(){
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
@ -146,29 +83,13 @@
this.valueEnd = metaquery.value[1];
}
if (metaquery.value[0] != undefined && metaquery.value[1] != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.valueInit + ' - ' + this.valueEnd
});
}
if (this.options.inputMode == 'list') {
this.selectedInterval = this.options.intervals.findIndex(
anInterval => anInterval.from == this.valueInit && anInterval.to == this.valueEnd
);
}
if (metaquery.value[0] != undefined && metaquery.value[1] != undefined)
this.$emit('sendValuesToTags', { label: this.valueInit + ' - ' + this.valueEnd, value: metaquery.values });
} else {
return false;
}
},
},
mounted() {
this.selectedValues();
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -10,14 +10,13 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Numeric_Interval extends Filter_Type {
function __construct(){
$this->set_name('Numeric Interval');
$this->set_supported_types(['float']);
$this->set_component('tainacan-filter-numeric-interval');
$this->set_form_component('tainacan-filter-form-numeric-interval');
$this->set_use_max_options(false);
$this->set_default_options([
'step' => 1,
'input-mode' => 'custom',
'intervals' => []
'step' => 1
]);
$this->set_preview_template('
<div>
@ -68,14 +67,9 @@ class Numeric_Interval extends Filter_Type {
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on filter control buttons.', 'tainacan' ),
],
'input-mode' => [
'title' => __( 'Input mode', 'tainacan' ),
'description' => __( 'Input mode', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on filter control buttons. This alo defines whether the input accepts decimal numbers.', 'tainacan' ),
],
'custom' => ['title' => __('Custom interval','tainacan')],
'list' => ['title' => __('Predefined intervals','tainacan')],
];
}

View File

@ -0,0 +1,170 @@
<template>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-list-interval', 'intervals') }}<span>&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-numeric-list-interval', 'intervals')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-list-interval', 'intervals')"/>
</label>
<div>
<b-field>
<b-checkbox v-model="showIntervalOnTag">
{{ $i18n.get('info_show_interval_on_tag') }}
</b-checkbox>
</b-field>
</div>
<div v-if="intervals.length == 0" >
<br>
<a
role="button"
@click="addInterval()"
class="is-inline add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('add_value') }}
</a>
</div>
<transition-group name="filter-item">
<div
class="options-input"
v-for="(interval, index) of intervals"
:key="index">
<b-field>
<b-input
expanded="true"
:placeholder="$i18n.get('label')"
@input="onUpdate(interval)"
v-model="interval.label" />
</b-field>
<b-field>
<b-input
type="number"
step="0.01"
:placeholder="$i18n.get('info_initial_value')"
@input="onUpdate(interval)"
v-model="interval.from" />
<b-input
type="number"
step="0.01"
:placeholder="$i18n.get('info_final_value')"
@input="onUpdate(interval)"
v-model="interval.to" />
</b-field>
<p class="control">
<a
role="button"
@click="addInterval(index)"
class="is-inline add-link"
:title="$i18n.get('add_value')">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('add_value') }}
</a>
</p>
<p class="control">
<a
role="button"
@click="removeInterval(index)"
class="is-inline add-link"
:title="$i18n.get('remove_value')">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-repprovedcircle"/>
</span>
&nbsp;{{ $i18n.get('remove_value') }}
</a>
</p>
</div>
</transition-group>
</b-field>
</template>
<script>
export default {
props: {
filter: Object,
value: [String, Number, Array],
id: '',
disabled: false,
},
data() {
return {
showIntervalOnTag: true,
intervals: [],
isValid: true,
}
},
methods: {
onUpdate(interval) {
if (interval.to == null || interval.from == null ||
interval.to == "" || interval.from == "" ||
Number(interval.to) < Number(interval.from)) {
if(this.isValid) {
this.isValid = false;
this.error_message()
}
} else {
this.isValid = true;
this.$emit('input', {
intervals: this.intervals,
showIntervalOnTag: this.showIntervalOnTag
});
}
},
error_message() {
this.$buefy.toast.open({
duration: 3000,
message: this.$i18n.get('info_error_first_value_greater'),
position: 'is-bottom',
type: 'is-danger'
})
},
removeInterval(index) {
this.intervals.splice(index, 1);
},
addInterval(index) {
if (index != undefined) {
this.intervals.splice(index + 1, 0, {
label: '',
to: null,
from: null
})
} else {
this.intervals.push({
label: '',
to: null,
from: null
});
}
}
},
created() {
this.intervals = this.value && this.value.intervals ? this.value.intervals : [];
this.showIntervalOnTag = this.value && this.value.showIntervalOnTag != undefined ? this.value.showIntervalOnTag : true;
}
}
</script>
<style scoped lang="scss">
@import '../../scss/_variables.scss';
.options-input {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.field:first-child {
width: 100%;
margin-top: 1rem;
margin-bottom: -1px;
}
.field.has-addons {
margin-bottom: 0.125rem;
}
}
</style>

View File

@ -0,0 +1,109 @@
<template>
<div>
<b-select
:placeholder="$i18n.get('instruction_select_a_interval')"
@input="changeInterval"
v-model="selectedInterval">
<option value="">
{{ $i18n.get('label_clean') }}
</option>
<option
v-for="(interval, index) in filterTypeOptions.intervals"
:value="index"
:key="index">
{{ interval.label }}
</option>
</b-select>
</div>
</template>
<script>
import { filterTypeMixin } from '../filter-types-mixin';
export default {
mixins: [ filterTypeMixin ],
data() {
return {
valueInit: 0,
valueEnd: 10,
isValid: false,
selectedInterval: ''
}
},
mounted() {
this.selectedValues();
},
methods: {
changeInterval() {
if (this.selectedInterval !== '') {
this.valueInit = this.filterTypeOptions.intervals[this.selectedInterval].from;
this.valueEnd = this.filterTypeOptions.intervals[this.selectedInterval].to;
this.emit();
} else {
this.$emit('input', {
filter: 'range',
compare: 'BETWEEN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: ''
});
this.valueEnd = null;
this.valueInit = null;
}
},
// emit the operation for listeners
emit() {
let values = [ this.valueInit, this.valueEnd ];
let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL' : 'NUMERIC';
this.$emit('input', {
type: type,
compare: 'BETWEEN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: values
});
if (values[0] != undefined && values[1] != undefined) {
let labelValue = this.filterTypeOptions.intervals[this.selectedInterval].label + (this.filterTypeOptions.showIntervalOnTag ? `(${values[0]}-${values[1]})` : '');
this.$emit('sendValuesToTags', { label: labelValue, value: values });
}
},
selectedValues(){
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0 ) {
let metaquery = this.query.metaquery[ index ];
if ( !metaquery.value ||
!metaquery.value.length > 1 ||
metaquery.value[0] == undefined ||
metaquery.value[1] == undefined )
return false
this.valueInit = metaquery.value[0];
this.valueEnd = metaquery.value[1];
this.selectedInterval = this.filterTypeOptions.intervals.findIndex(
anInterval => anInterval.from == this.valueInit && anInterval.to == this.valueEnd
);
let labelValue = this.filterTypeOptions.intervals[this.selectedInterval].label + (this.filterTypeOptions.showIntervalOnTag ? `(${this.valueInit}-${this.valueEnd})` : '');
this.$emit('sendValuesToTags', { label: labelValue, value: [ this.valueInit, this.valueEnd ] });
} else {
return false;
}
},
}
}
</script>
<style scoped>
.field {
margin-bottom: 0.125rem !important;
}
p.is-size-7 {
margin-bottom: 0.125rem !important;
}
</style>

View File

@ -0,0 +1,66 @@
<?php
namespace Tainacan\Filter_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class TainacanMetadatumType
*/
class Numeric_List_Interval extends Filter_Type {
function __construct(){
$this->set_name('Numeric Interval List');
$this->set_supported_types(['float']);
$this->set_component('tainacan-filter-numeric-list-interval');
$this->set_form_component('tainacan-filter-form-numeric-list-interval');
$this->set_use_max_options(false);
$this->set_default_options([
'intervals' => [],
'showIntervalOnTag' => false
]);
$this->set_preview_template('
<div class="collapse show">
<div class="dropdown is-active">
<div role="button" class="dropdown-trigger">
<button class="button is-white">
List
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
</button>
</div>
<div class="background"></div>
<div class="dropdown-menu">
<div role="list" class="dropdown-content">
<a class="dropdown-item is-active">Top 10</a>
<a class="dropdown-item">Top 20</a>
<a class="dropdown-item">Top 30</a>
</div>
</div>
</div>
</div>
');
}
public function get_form_labels() {
return [
'intervals' => [
'title' => __('Predefined intervals','tainacan'),
'description' => __('Predefined intervals','tainacan')
]
];
}
/**
* @param $filter
* @return string
* @internal param $metadatum
*/
public function render( $filter ) {
return '<tainacan-filter-numeric-list-interval
name="'.$filter->get_name().'"
collection_id="'.$filter->get_collection_id().'"
metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-form-numeric-list-interval>';
}
}

View File

@ -74,11 +74,8 @@
export default {
props: {
filter: {
type: Object
},
filter: Object,
value: [String, Number, Array],
id: '',
disabled: false,
},
data() {

View File

@ -3,7 +3,8 @@
<b-dropdown
:mobile-modal="true"
@input="onChangeComparator($event)"
aria-role="list">
aria-role="list"
trap-focus>
<button
:aria-label="$i18n.get('label_comparator')"
class="button is-white"
@ -60,67 +61,33 @@
</b-dropdown>
<b-numberinput
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
size="is-small"
:step="Number(options.step)"
:step="Number(filterTypeOptions.step)"
@input="emit()"
v-model="value"/>
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import { wpAjax } from "../../../admin/js/mixins";
import { wpAjax } from '../../../admin/js/mixins';
import { filterTypeMixin } from '../filter-types-mixin';
export default {
mixins: [ wpAjax ],
created() {
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : (typeof this.filter.metadatum.metadatum_id == 'object' ? this.filter.metadatum.metadatum_id.metadatum_id : this.filter.metadatum.metadatum_id);
this.options = this.filter.filter_type_options;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if (this.isRepositoryLevel || this.collection == 'filter_in_repository')
in_route = '/metadata/'+ this.metadatum;
axios.get(in_route)
.then( res => {
let result = res.data;
if ( result && result.metadata_type ){
this.metadatum_object = result;
this.selectedValues();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
},
mixins: [
wpAjax,
filterTypeMixin
],
mounted() {
this.selectedValues();
},
data(){
return {
value: null,
clear: false,
options: [],
collection: '',
metadatum: '',
metadatum_object: {},
filterTypeOptions: [],
comparator: '=' // =, !=, >, >=, <, <=
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
labelId: '',
query: Object,
isRepositoryLevel: Boolean,
},
computed: {
comparatorSymbol() {
switch(this.comparator) {
@ -139,7 +106,7 @@
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
let metadata = this.query.metaquery[ index ];
@ -150,37 +117,14 @@
if ( metadata.compare)
this.comparator = metadata.compare;
if (this.value != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + this.value
});
}
if (this.value != undefined)
this.$emit('sendValuesToTags', { label: this.comparator + ' ' + this.value, value: this.value });
} else {
return false;
}
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.clearSearch();
},
clearSearch(){
this.clear = true;
this.$emit('input', {
filter: 'numeric',
compare: this.comparator,
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: '',
type: 'NUMERIC'
});
this.value = null;
},
// emit the operation for listeners
emit() {
@ -190,25 +134,19 @@
this.$emit('input', {
filter: 'numeric',
compare: this.comparator,
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.value,
type: 'NUMERIC'
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + this.value
});
this.$emit('sendValuesToTags', { label: this.comparator + ' ' + this.value, value: this.value });
},
onChangeComparator(newComparator) {
this.comparator = newComparator;
this.emit();
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -10,6 +10,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Numeric extends Filter_Type {
function __construct(){
$this->set_name('Numeric');
$this->set_supported_types(['float']);
$this->set_component('tainacan-filter-numeric');
$this->set_form_component('tainacan-filter-form-numeric');

View File

@ -5,7 +5,7 @@
<b-select
v-if="!isLoadingOptions"
:value="selected"
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
@input="onSelect($event)"
:placeholder="$i18n.get('label_selectbox_init')"
expanded>
@ -25,72 +25,27 @@
</template>
<script>
import { tainacan as axios, isCancel } from '../../../js/axios/axios';
import { filter_type_mixin } from '../filter-types-mixin'
import { isCancel } from '../../../js/axios/axios';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id;
const vm = this;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
in_route = '/metadata/'+ this.metadatum;
}
axios.get(in_route)
.then( res => {
let result = res.data;
if( result && result.metadata_type ){
vm.metadatum_object = result;
vm.type = result.metadata_type;
if (!this.isUsingElasticSearch)
vm.loadOptions();
}
})
.catch(error => {
this.$console.error(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
if (this.isUsingElasticSearch) {
this.$eventBusSearch.$on('isLoadingItems', isLoading => {
this.isLoadingOptions = isLoading;
});
}
},
props: {
isRepositoryLevel: Boolean,
labelId: String
},
mixins: [filterTypeMixin, dynamicFilterTypeMixin],
data(){
return {
options: [],
type: '',
collection: '',
metadatum: ''
options: []
}
},
mixins: [filter_type_mixin],
watch: {
selected(value) {
if (value) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: value
});
}
if (value)
this.$emit('sendValuesToTags', { label: value, value: value });
}
},
computed: {
selected() {
if ( this.query && this.query.metaquery && Array.isArray( this.query.metaquery ) ) {
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key === this.metadatum );
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
let metadata = this.query.metaquery[ index ];
return metadata.value;
@ -99,6 +54,10 @@
return undefined;
}
},
mounted(){
if (!this.isUsingElasticSearch)
this.loadOptions();
},
methods: {
loadOptions(){
// Cancels previous Request
@ -106,7 +65,7 @@
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
let promise = null;
promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel );
promise = this.getValuesPlainText( this.metadatumId, null, this.isRepositoryLevel );
promise.request
.then(() => {
})
@ -121,24 +80,13 @@
this.getOptionsValuesCancel = promise.source;
},
onSelect(value){
//this.selected = value;
this.$emit('input', {
filter: 'selectbox',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: ( value ) ? value : ''
});
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id)
this.onSelect();
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
if (this.isUsingElasticSearch)
this.$eventBusSearch.$off('isLoadingItems');
}
}
</script>

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Selectbox extends Filter_Type {
function __construct(){
$this->set_name('Select Box');
$this->set_supported_types(['string', 'long_string']);
$this->set_component('tainacan-filter-selectbox');
$this->set_use_max_options(false);

View File

@ -13,8 +13,8 @@
attached
@typing="search"
:aria-close-label="$i18n.get('remove_value')"
:aria-labelledby="labelId"
:placeholder="(type == 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_search_items') : $i18n.get('info_type_to_add_metadata')">
:aria-labelledby="'filter-label-id-' + filter.id"
:placeholder="(metadatumType == 'Tainacan\\Metadata_Types\\Relationship') ? $i18n.get('info_type_to_add_items') : $i18n.get('info_type_to_add_metadata')">
<template slot-scope="props">
<div class="media">
<div
@ -44,78 +44,31 @@
<script>
import { tainacan as axios, isCancel } from '../../../js/axios/axios';
import { filter_type_mixin } from '../filter-types-mixin'
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
import qs from 'qs';
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id;
const vm = this;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
in_route = '/metadata/'+ this.metadatum + '?nopaging=1';
}
axios.get(in_route)
.then( res => {
let result = res.data;
if( result && result.metadata_type ){
vm.metadatum_object = result;
vm.type = result.metadata_type;
vm.selectedValues();
}
})
.catch(error => {
this.$console.log(error);
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTags);
},
mixins: [filterTypeMixin, dynamicFilterTypeMixin],
data(){
return {
results:'',
selected:[],
options: [],
type: '',
collection: '',
metadatum: '',
metadatum_object: {}
options: []
}
},
props: {
isRepositoryLevel: Boolean,
labelId: String
},
mixins: [filter_type_mixin],
watch: {
selected( value ){
this.selected = value;
let values = [];
let labels = [];
if( this.selected.length > 0 ){
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: values
selected(newVal, oldVal) {
const isEqual = (newVal.length == oldVal.length) && newVal.every((element, index) => {
return element === oldVal[index];
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: labels
});
if (!isEqual)
this.onSelect();
}
},
mounted() {
this.selectedValues();
},
methods: {
search: _.debounce( function(query) {
let promise = null;
@ -129,10 +82,10 @@
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' )
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' )
promise = this.getValuesRelationship( query, this.isRepositoryLevel, valuesToIgnore );
else
promise = this.getValuesPlainText( this.metadatum, query, this.isRepositoryLevel, valuesToIgnore );
promise = this.getValuesPlainText( this.metadatumId, query, this.isRepositoryLevel, valuesToIgnore );
promise.request
.catch( error => {
@ -147,25 +100,26 @@
}, 500),
selectedValues(){
const instance = this;
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatum );
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
let metadata = this.query.metaquery[ index ];
let collectionTarget = ( this.metadatum_object && this.metadatum_object.metadata_type_options.collection_id ) ?
this.metadatum_object.metadata_type_options.collection_id : this.collection_id;
if ( this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship' ) {
let query = qs.stringify({ postin: metadata.value, fetch_only: 'title,thumbnail', fetch_only_meta: '' });
if ( this.type === 'Tainacan\\Metadata_Types\\Relationship' ) {
let query = qs.stringify({ postin: metadata.value });
axios.get('/collection/' + collectionTarget + '/items?' + query)
axios.get('/items?' + query)
.then( res => {
if (res.data.items) {
for (let item of res.data) {
instance.selected.push({ label: item.title, value: item.id, img: item.thumbnail.thumbnail[0] });
for (let item of res.data.items) {
this.selected.push({
label: item.title,
value: item.id,
img: item.thumbnail && item.thumbnail.thumbnail && item.thumbnail.thumbnail[0] ? item.thumbnail.thumbnail[0] : null
});
}
}
})
@ -174,47 +128,32 @@
});
} else {
for (let item of metadata.value) {
instance.selected.push({ label: item, value: item, img: '' });
this.selected.push({ label: item, value: item, img: null });
}
}
} else {
return false;
}
},
cleanSearchFromTags(filterTag) {
if (filterTag.filterId == this.filter.id) {
let selectedIndex = this.selected.findIndex(option => option.label == filterTag.singleValue);
if (selectedIndex >= 0) {
this.selected.splice(selectedIndex, 1);
let values = [];
let labels = [];
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
value: values
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: labels
});
onSelect() {
let values = [];
let labels = [];
if( this.selected.length > 0 ){
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: values
});
this.$emit( 'sendValuesToTags', { label: labels, value: values });
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class Taginput extends Filter_Type {
function __construct(){
$this->set_name('Tag Input');
$this->set_supported_types(['string','long_string','item']);
$this->set_component('tainacan-filter-taginput');
$this->set_use_max_options(false);

View File

@ -31,15 +31,15 @@
</span>
<span class="collapse-label">{{ filter.name }}</span>
</button>
<div
:id="'filter-input-id-' + filter.id">
<div :id="'filter-input-id-' + filter.id">
<component
:label-id="'filter-label-id-' + filter.id"
:is="filter.filter_type_object.component"
:filter="filter"
:query="query"
:is-repository-level="isRepositoryLevel"
@input="listen( $event )"/>
:is-loading-items.sync="isLoadingItems"
@input="onInput"
@sendValuesToTags="onSendValuesToTags"/>
</div>
</b-collapse>
</b-field>
@ -52,17 +52,47 @@
filter: Object,
query: Object,
isRepositoryLevel: Boolean,
open: true,
open: true
},
data(){
data() {
return {
inputs: [],
isLoadingItems: Boolean,
isUsingElasticSearch: tainacan_plugin.wp_elasticpress == "1" ? true : false,
reloadDueFiltering: Boolean
}
},
mounted() {
if (this.isUsingElasticSearch) {
this.$eventBusSearch.$on('isLoadingItems', isLoadingItems => {
this.isLoadingOptions = isLoadingItems;
});
}
// We listen to event, but reload event if hasFiltered is negative, as
// an empty query also demands filters reloading.
this.$eventBusSearch.$on('hasFiltered', this.reloadFilter);
},
methods: {
listen( inputEvent ){
this.$eventBusSearch.$emit( 'input', ( inputEvent.metadatum_id ) ? inputEvent : inputEvent.detail[0] );
onInput(inputEvent){
this.$eventBusSearch.$emit('input', inputEvent);
},
onSendValuesToTags($event) {
this.$eventBusSearch.$emit('sendValuesToTags', {
filterId: this.filter.id,
label: $event.label,
value: $event.value,
taxonomy: $event.taxonomy,
metadatumId: this.filter.metadatum_id
});
},
reloadFilter() {
this.reloadDueFiltering = !this.reloadDueFiltering;
}
},
beforeDestroy() {
if (this.isUsingElasticSearch)
this.$eventBusSearch.$off('isLoadingItems');
this.$eventBusSearch.$off('hasFiltered', this.reloadFilter);
}
}
</script>

View File

@ -1,17 +1,17 @@
<template>
<div
:style="{ 'height': isLoading ? (Number(filter.max_options)*28) + 'px' : 'auto' }"
:class="{ 'skeleton': isLoading }"
:style="{ 'height': isLoadingOptions ? (Number(filter.max_options)*28) + 'px' : 'auto' }"
:class="{ 'skeleton': isLoadingOptions }"
class="block">
<!-- <span
v-if="isLoading"
v-if="isLoadingOptions"
style="width: 100%"
class="icon has-text-centered loading-icon">
<div class="control has-icons-right is-loading is-clearfix" />
</span> -->
<div
v-for="(option, index) in options.slice(0, filter.max_options)"
v-if="!isLoading"
v-if="!isLoadingOptions"
:key="index"
:value="index"
class="control">
@ -38,7 +38,7 @@
</button>
</div>
<p
v-if="!isLoading && options.length != undefined && options.length <= 0"
v-if="!isLoadingOptions && options.length != undefined && options.length <= 0"
class="no-options-placeholder">
{{ $i18n.get('info_no_options_avialable_filtering') }}
</p>
@ -50,68 +50,39 @@
import { tainacan as axios, CancelToken, isCancel } from '../../../js/axios/axios';
import { mapGetters } from 'vuex';
import CheckboxRadioModal from '../../../admin/components/other/checkbox-radio-modal.vue';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
export default {
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id ;
this.type = this.filter.metadatum.metadata_type;
this.loadOptions();
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTag);
if (this.isUsingElasticSearch)
this.$eventBusSearch.$on('isLoadingItems', this.updatesIsLoading);
},
mounted(){
// We listen to event, but reload event if hasFiltered is negative, as
// an empty query also demands filters reloading.
this.$eventBusSearch.$on('hasFiltered', () => {
if (typeof this.loadOptions == "function")
this.loadOptions(true);
});
},
mixins: [ filterTypeMixin, dynamicFilterTypeMixin ],
data(){
return {
isLoading: true,
isLoadingOptions: true,
options: [],
type: '',
collection: '',
metadatum: '',
selected: [],
taxonomy: '',
taxonomy_id: Number,
getOptionsValuesCancel: undefined,
isUsingElasticSearch: tainacan_plugin.wp_elasticpress == "1" ? true : false
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
labelId: '',
query: {
type: Object // concentrate all attributes metadatum id and type
taxonomy_id: Number
}
},
watch: {
selected: function(){
//this.selected = val;
this.onSelect();
selected(newVal, oldVal) {
const isEqual = (newVal.length == oldVal.length) && newVal.every((element, index) => {
return element === oldVal[index];
});
if (!isEqual)
this.onSelect();
},
facetsFromItemSearch() {
if (this.isUsingElasticSearch)
this.loadOptions();
},
'query.taxquery'() {
this.loadOptions();
}
},
computed: {
facetsFromItemSearch() {
return this.getFacets();
}
},
mounted(){
this.loadOptions();
},
methods: {
...mapGetters('search', [
'getFacets'
@ -125,15 +96,15 @@
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
this.isLoading = true;
this.isLoadingOptions = true;
let query_items = { 'current_query': this.query };
let route = '';
if(this.collection == 'filter_in_repository')
route = `/facets/${this.metadatum}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
if (this.collectionId == 'default')
route = `/facets/${this.metadatumId}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
else
route = `/collection/${this.collection}/facets/${this.metadatum}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
route = `/collection/${this.collectionId}/facets/${this.metadatumId}?getSelected=1&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
this.options = [];
@ -153,14 +124,14 @@
promise.request
.then((res) => {
this.prepareOptionsForTaxonomy(res.data.values ? res.data.values : res.data, skipSelected);
this.isLoading = false;
this.isLoadingOptions = false;
})
.catch( error => {
if (isCancel(error)) {
this.$console.log('Request canceled: ' + error.message);
} else {
this.$console.log('Error on facets request: ', error);
this.isLoading = false;
this.isLoadingOptions = false;
}
});
@ -177,14 +148,13 @@
this.prepareOptionsForTaxonomy(Object.values(this.facetsFromItemSearch[facet]), skipSelected);
}
}
}
},
selectedValues(){
if ( !this.query || !this.query.taxquery || !Array.isArray( this.query.taxquery ) )
return false;
let index = this.query.taxquery.findIndex(newMetadatum => newMetadatum.taxonomy == this.taxonomy );
if ( index >= 0){
let metadata = this.query.taxquery[ index ];
@ -193,16 +163,7 @@
this.selected = [];
return false;
}
},
onSelect(){
this.$emit('input', {
filter: 'checkbox',
taxonomy: this.taxonomy,
compare: 'IN',
metadatum_id: this.metadatum,
collection_id: this.collection,
terms: this.selected
});
let onlyLabels = [];
@ -224,10 +185,10 @@
// let route = '';
// if (this.collection == 'filter_in_repository')
// route = '/facets/' + this.metadatum +`?term_id=${selected}&fetch_only=name,id`;
// if (this.collectionId == 'default')
// route = '/facets/' + this.metadatumId +`?term_id=${selected}&fetch_only=name,id`;
// else
// route = '/collection/'+ this.collection +'/facets/' + this.metadatum +`?term_id=${selected}&fetch_only=name,id`;
// route = '/collection/'+ this.collectionId +'/facets/' + this.metadatumId +`?term_id=${selected}&fetch_only=name,id`;
// axios.get(route)
// .then( res => {
@ -260,9 +221,16 @@
}
}
this.$eventBusSearch.$emit("sendValuesToTags", {
filterId: this.filter.id,
value: onlyLabels
this.$emit('sendValuesToTags', { label: onlyLabels, taxonomy: this.taxonomy, value: this.selected });
},
onSelect(){
this.$emit('input', {
filter: 'checkbox',
taxonomy: this.taxonomy,
compare: 'IN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
terms: this.selected
});
},
openCheckboxModal(parent) {
@ -274,9 +242,9 @@
filter: this.filter,
taxonomy_id: this.taxonomy_id,
selected: this.selected,
metadatum_id: this.metadatum,
metadatumId: this.metadatumId,
taxonomy: this.taxonomy,
collection_id: this.collection,
collectionId: this.collectionId,
isTaxonomy: true,
query: this.query
},
@ -285,40 +253,10 @@
this.loadOptions();
}
},
width: 'calc(100% - 8.333333333%)',
width: 'calc(100% - 16.6666%)',
trapFocus: true
});
},
cleanSearchFromTag(filterTag) {
if (filterTag.filterId == this.filter.id) {
let selectedOption = this.options.find(option => option.label == filterTag.singleValue);
if (selectedOption) {
let selectedIndex = this.selected.findIndex(option => option == selectedOption.value);
if (selectedIndex >= 0) {
this.selected.splice(selectedIndex, 1);
this.$emit('input', {
filter: 'checkbox',
compare: 'IN',
taxonomy: this.taxonomy,
metadatum_id: this.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
terms: this.selected
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.selected
});
this.selectedValues();
}
}
}
},
prepareOptionsForTaxonomy(items, skipSelected) {
if (items[0] != undefined) {
@ -349,24 +287,19 @@
}
}
}
if (skipSelected == undefined || skipSelected == false) {
this.selectedValues();
}
},
updatesIsLoading(isLoading) {
this.isLoading = isLoading;
updatesIsLoading(isLoadingOptions) {
this.isLoadingOptions = isLoadingOptions;
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
// Cancels previous Request
if (this.getOptionsValuesCancel != undefined)
this.getOptionsValuesCancel.cancel('Facet search Canceled.');
if (this.isUsingElasticSearch)
this.$eventBusSearch.$off('isLoadingItems', this.updatesIsLoading);
}
}
</script>

View File

@ -6,13 +6,13 @@
v-model="selected"
:data="options"
autocomplete
:loading="isLoading"
:loading="isLoadingOptions"
expanded
:remove-on-keys="[]"
field="label"
attached
:aria-close-label="$i18n.get('remove_value')"
:aria-labelledby="labelId"
:aria-labelledby="'filter-label-id-' + filter.id"
:class="{'has-selected': selected != undefined && selected != []}"
@typing="search"
:placeholder="$i18n.get('info_type_to_add_terms')">
@ -27,7 +27,7 @@
</div>
</template>
<template
v-if="!isLoading"
v-if="!isLoadingOptions"
slot="empty">
{{ $i18n.get('info_no_options_found' ) }}
</template>
@ -38,82 +38,34 @@
<script>
import qs from 'qs';
import { tainacan as axios } from '../../../js/axios/axios';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../filter-types-mixin';
export default {
mixins: [ filterTypeMixin, dynamicFilterTypeMixin ],
created(){
this.collection = ( this.collection_id ) ? this.collection_id : this.filter.collection_id;
this.metadatum = ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum.metadatum_id ;
this.type = this.filter.metadatum.metadata_type;
let endpoint = '/collection/' + this.collectionId + '/metadata/' + this.metadatumId;
let in_route = '/collection/' + this.collection + '/metadata/' + this.metadatum;
if(this.isRepositoryLevel || this.collection == 'filter_in_repository'){
in_route = '/metadata/'+ this.metadatum;
if (this.isRepositoryLevel || this.collectionId == 'default'){
endpoint = '/metadata/' + this.metadatumId;
}
axios.get(in_route)
axios.get(endpoint)
.then( res => {
let metadatum = res.data;
this.selectedValues( metadatum.metadata_type_options.taxonomy_id );
});
this.$eventBusSearch.$on('removeFromFilterTag', this.cleanSearchFromTag);
},
data(){
return {
results:'',
selected:[],
options: [],
isLoading: false,
type: '',
collection: '',
metadatum: '',
taxonomy: '',
isUsingElasticSearch: tainacan_plugin.wp_elasticpress == "1" ? true : false
}
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
labelId: '',
query: {
type: Object // concentrate all attributes metadatum id and type
},
isRepositoryLevel: Boolean,
},
watch: {
selected( value ){
this.selected = value;
let values = [];
let labels = [];
if( this.selected.length > 0 ){
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
taxonomy: this.taxonomy,
metadatum_id: ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
terms: values
});
this.$eventBusSearch.$emit("sendValuesToTags", {
filterId: this.filter.id,
value: labels
});
taxonomy: ''
}
},
methods: {
search: _.debounce( function(query) {
this.isLoading = true;
this.isLoadingOptions = true;
this.options = [];
let query_items = {
@ -121,7 +73,7 @@
'search': query
};
let endpoint = this.isRepositoryLevel ? '/facets/' + this.metadatum : '/collection/'+ this.collection +'/facets/' + this.metadatum;
let endpoint = this.isRepositoryLevel ? '/facets/' + this.metadatumId : '/collection/'+ this.collectionId +'/facets/' + this.metadatumId;
endpoint += '?order=asc&' + qs.stringify(query_items);
let valuesToIgnore = [];
@ -155,10 +107,10 @@
}
}
}
this.isLoading = false;
this.isLoadingOptions = false;
})
.catch(error => {
this.isLoading = false;
this.isLoadingOptions = false;
this.$console.log(error);
});
}, 500),
@ -179,6 +131,26 @@
return false;
}
},
onSelect() {
let values = [];
let labels = [];
if( this.selected.length > 0 ){
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
taxonomy: this.taxonomy,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
terms: values
});
this.$emit('sendValuesToTags', { label: labels, taxonomy: this.taxonomy, value: values });
},
getTerm( taxonomy, id ){
//getting a specific value from api, does not need be in fecat api
return axios.get('/taxonomy/' + taxonomy + '/terms/' + id + '?order=asc' )
@ -188,41 +160,7 @@
.catch(error => {
this.$console.log(error);
});
},
cleanSearchFromTag(filterTag) {
if (filterTag.filterId == this.filter.id) {
let selectedIndex = this.selected.findIndex(option => option.label == filterTag.singleValue);
if (selectedIndex >= 0) {
this.selected.splice(selectedIndex, 1);
let values = [];
let labels = [];
for(let val of this.selected){
values.push( val.value );
labels.push( val.label );
}
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
taxonomy: this.taxonomy,
metadatum_id: ( this.metadatum_id ) ? this.metadatum_id : this.filter.metadatum,
collection_id: ( this.collection_id ) ? this.collection_id : this.filter.collection_id,
terms: values
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: labels
});
}
}
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class TaxonomyCheckbox extends Filter_Type {
function __construct(){
$this->set_name('Taxonomy Checkbox List');
$this->set_supported_types(['term']);
$this->set_component('tainacan-filter-taxonomy-checkbox');
$this->set_preview_template('

View File

@ -9,6 +9,7 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
class TaxonomyTaginput extends Filter_Type {
function __construct(){
$this->set_name('Taxonomy Tag Input');
$this->set_supported_types(['term']);
$this->set_component('tainacan-filter-taxonomy-taginput');
$this->set_use_max_options(false);

View File

@ -5,14 +5,14 @@
* @package WP-Background-Processing
*/
if ( ! class_exists( 'WP_Async_Request' ) ) {
//if ( ! class_exists( 'WP_Async_Request' ) ) {
/**
* Abstract WP_Async_Request class.
*
* @abstract
*/
abstract class WP_Async_Request {
abstract class Tainacan_WP_Async_Request {
/**
* Prefix
@ -160,4 +160,4 @@ if ( ! class_exists( 'WP_Async_Request' ) ) {
abstract protected function handle();
}
}
//}

View File

@ -5,7 +5,7 @@
* @package WP-Background-Processing
*/
if ( ! class_exists( 'WP_Background_Process' ) ) {
//if ( ! class_exists( 'WP_Background_Process' ) ) {
/**
* Abstract WP_Background_Process class.
@ -13,7 +13,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* @abstract
* @extends WP_Async_Request
*/
abstract class WP_Background_Process extends WP_Async_Request {
abstract class Tainacan_WP_Background_Process extends Tainacan_WP_Async_Request {
/**
* Action
@ -554,4 +554,4 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
}
}
}
//}

View File

@ -40,17 +40,20 @@
:title="$i18n.getHelperTitle('tainacan-relationship', 'search')"
:message="$i18n.getHelperMessage('tainacan-relationship', 'search')"/>
</label>
<div
v-for="(option, index) in metadata"
:key="index"
class="field">
<b-checkbox
name="metadata_type_relationship[search][]"
v-model="modelSearch"
:native-value="option.id">
<b-select
name="metadata_type_relationship[search]"
v-model="modelSearch">
<option
v-for="(option, index) in metadata"
:key="index"
:value="option.id"
class="field">
{{ option.name }}
</b-checkbox>
</div>
</option>
</b-select>
</b-field>
</transition>
@ -98,7 +101,7 @@
hasMetadata: false,
loadingMetadata: false,
modelRepeated: 'yes',
modelSearch:[],
modelSearch:'',
collectionType: '',
collectionMessage: ''
}
@ -111,7 +114,7 @@
} else {
this.metadata = [];
this.hasMetadata = false;
this.modelSearch = [];
this.modelSearch = '';
this.emitValues();
}
@ -180,7 +183,7 @@
this.metadata = [];
for (let metadatum of metadata) {
if (metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Relationship" && metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Taxonomy") {
if (metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Relationship") {
this.metadata.push( metadatum );
this.hasMetadata = true;
this.checkMetadata()
@ -207,14 +210,14 @@
},
checkMetadata(){
if( this.value && this.value.search.length > 0 ){
if( this.value && this.value.search ){
this.modelSearch = this.value.search;
} else {
try {
const json = JSON.parse( this.search );
this.modelSearch = json;
} catch(e){
this.modelSearch = [];
this.modelSearch = '';
}
}
},

View File

@ -26,11 +26,12 @@
let collectionId = ( this.metadatum && this.metadatum.metadatum.metadata_type_options.collection_id ) ? this.metadatum.metadatum.metadata_type_options.collection_id : this.collection_id;
if ( this.metadatum.value && (Array.isArray( this.metadatum.value ) ? this.metadatum.value.length > 0 : true )){
let query = qs.stringify({ postin: ( Array.isArray( this.metadatum.value ) ) ? this.metadatum.value : [ this.metadatum.value ] });
query += this.metadatum.metadatum.metadata_type_options.search ? '&fetch_only_meta=' + this.metadatum.metadatum.metadata_type_options.search : '';
axios.get('/collection/'+collectionId+'/items?' + query + '&nopaging=1&fetch_only=title,thumbnail')
.then( res => {
if (res.data.items) {
for (let item of res.data.items) {
this.selected.push({ label: item.title, value: item.id, img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : '' });
this.selected.push({ label: this.getItemLabel(item), value: item.id, img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : '' });
}
}
})
@ -104,7 +105,7 @@
if (result.items) {
for (let item of result.items) {
this.options.push({ label: item.title, value: item.id })
this.options.push({ label: this.getItemLabel(item), value: item.id })
}
}
})
@ -115,28 +116,39 @@
this.options = [];
}
}, 500),
getItemLabel(item) {
let label = '';
for (let m in item.metadata) {
if (item.metadata[m].id == this.metadatum.metadatum.metadata_type_options.search) {
label = item.metadata[m].value_as_string;
}
}
if (label != '' && label != item.title && item.title != '') {
label += ' (' + item.title + ')';
} else if (label == '') {
label = item.title;
}
return label;
},
mountQuery( search ) {
let query = [];
if ( this.metadatum.metadatum.metadata_type_options &&
this.metadatum.metadatum.metadata_type_options.search &&
this.metadatum.metadatum.metadata_type_options.search.length > 0)
this.metadatum.metadatum.metadata_type_options.search)
{
query['metaquery'] = [];
const metaquery = query['metaquery'];
metaquery['relation'] = 'OR'
for ( let i = 0; i < this.metadatum.metadatum.metadata_type_options.search.length; i++ ){
metaquery[i] = {
key: this.metadatum.metadatum.metadata_type_options.search[i],
value: search,
compare: 'LIKE'
}
query['metaquery'][0] = {
key: this.metadatum.metadatum.metadata_type_options.search,
value: search,
compare: 'LIKE'
}
query['metaquery'] = metaquery;
} else {
query['search'] = search;
}
query['fetch_only'] = 'title,thumbnail';
query['fetch_only_meta'] = this.metadatum.metadatum.metadata_type_options.search;
return query;
}

View File

@ -56,8 +56,8 @@ class Relationship extends Metadata_Type {
'description' => __( 'Select the collection to fetch items', 'tainacan' ),
],
'search' => [
'title' => __( 'Metadata to search', 'tainacan' ),
'description' => __( 'Select the metadata to use as search criteria in the target collection', 'tainacan' ),
'title' => __( 'Related Metadatum', 'tainacan' ),
'description' => __( 'Select the metadata to use as search criteria in the target collection and as a label when representing the relationship', 'tainacan' ),
],
'repeated' => [
'title' =>__( 'Allow repeated items', 'tainacan' ),
@ -93,10 +93,10 @@ class Relationship extends Metadata_Type {
'collection_id' => __('The related collection is required','tainacan')
];
}
if ( !is_array($this->get_option('search')) ) {
// empty is ok
if ( !empty($this->get_option('search')) && !is_numeric($this->get_option('search')) ) {
return [
'search' => __('Search option must be an array','tainacan')
'search' => __('Search option must be a numeric Metadatum ID','tainacan')
];
}
@ -137,7 +137,7 @@ class Relationship extends Metadata_Type {
$return .= $prefix;
$return .= $item->_toHtml();
$return .= $this->get_item_html($item);
$return .= $suffix;
@ -161,7 +161,7 @@ class Relationship extends Metadata_Type {
$item = new \Tainacan\Entities\Item($value);
if ( $item instanceof \Tainacan\Entities\Item ) {
$return .= $item->_toHtml();
$return .= $this->get_item_html($item);
}
} catch (Exception $e) {
@ -174,6 +174,46 @@ class Relationship extends Metadata_Type {
}
private function get_item_html($item) {
$return = '';
$id = $item->get_id();
$search_meta_id = $this->get_option('search');
if ( $id && $search_meta_id ) {
$link = get_permalink( (int) $id );
$search_meta_id = $this->get_option('search');
$metadatum = \Tainacan\Repositories\Metadata::get_instance()->fetch((int) $search_meta_id);
$label = '';
if ($metadatum instanceof \Tainacan\Entities\Metadatum) {
$item_meta = new \Tainacan\Entities\Item_Metadata_Entity($item, $metadatum);
$label = $item_meta->get_value_as_string();
}
if ( empty($label) ) {
$label = $item->get_title();
}
if (is_string($link)) {
$return = "<a data-linkto='item' data-id='$id' href='$link'>";
$return.= $label;
$return .= "</a>";
}
}
return $return;
}
/**
* Get related Collection object
* @return \Tainacan\Entities\Collection|false The Collection object or false

View File

@ -120,9 +120,9 @@
parent: 0,
taxonomy_id: this.taxonomy_id,
selected: !this.valueComponent ? [] : this.valueComponent,
metadatum_id: this.metadatum.metadatum.id,
metadatumId: this.metadatum.metadatum.id,
taxonomy: this.taxonomy,
collection_id: this.collectionId,
collectionId: this.collectionId,
isTaxonomy: true,
query: '',
metadatum: this.metadatum.metadatum,
@ -134,6 +134,7 @@
}
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
},
getTermsFromTaxonomy(){

View File

@ -167,7 +167,7 @@ class Collections extends Repository {
'cover_page_id' => [
'map' => 'meta',
'title' => __( 'Cover Page ID', 'tainacan' ),
'type' => 'string',
'type' => 'integer/string',
'description' => __( 'If enabled, this custom page will be used as cover for this collection, instead of default items list.', 'tainacan' ),
'on_error' => __( 'Invalid page', 'tainacan' ),
//'validation' => v::numeric(),
@ -187,7 +187,7 @@ class Collections extends Repository {
'title' => __( 'Moderators', 'tainacan' ),
'type' => 'array/object/string',
'items' => [ 'type' => 'array/string/integer/object' ],
'description' => __( 'To assign users as Moderators of this collection', 'tainacan' ),
'description' => __( 'Moderators of this collection', 'tainacan' ),
'validation' => ''
],
'_thumbnail_id' => [

View File

@ -25,6 +25,7 @@ class Filters extends Repository {
protected function __construct() {
parent::__construct();
add_action( 'tainacan-deleted-tainacan-metadatum', array( &$this, 'hook_delete_when_metadata_deleted' ), 10, 2 );
add_action( 'tainacan-insert-tainacan-metadatum', array( &$this, 'hook_update_when_metadata_saved_as_private' ), 10, 2 );
}
protected function _get_map() {
@ -64,7 +65,7 @@ class Filters extends Repository {
'map' => 'meta',
'title' => __( 'Type', 'tainacan' ),
'type' => 'string',
'description' => __( 'The filter type', 'tainacan' ),
'description' => __( 'The filter type class name, such as filter_type: Tainacan\Filter_Types\Checkbox', 'tainacan' ),
'validation' => ''
],
'collection_id' => [
@ -365,7 +366,7 @@ class Filters extends Repository {
$parents[] = $collection_id;
//search for default metadatum
$parents[] = 'filter_in_repository';
$parents[] = 'default';
$meta_query = array(
'key' => 'collection_id',
@ -416,7 +417,7 @@ class Filters extends Repository {
$parents[] = $collection_id;
//search for default metadatum
$parents[] = 'filter_in_repository';
$parents[] = 'default';
$meta_query = array(
'key' => 'collection_id',
@ -508,10 +509,10 @@ class Filters extends Repository {
return $result;
}
public function hook_delete_when_metadata_deleted($filter, $permanent) {
public function hook_delete_when_metadata_deleted($metadatum, $permanent) {
if ( $filter instanceof Entities\Metadatum ) {
$metadatum_id = $filter->get_id();
if ( $metadatum instanceof Entities\Metadatum ) {
$metadatum_id = $metadatum->get_id();
$filters = $this->fetch(['metadatum_id' => $metadatum_id, 'post_status' => 'any'], 'OBJECT');
foreach ($filters as $filter) {
if ($permanent) {
@ -525,4 +526,33 @@ class Filters extends Repository {
}
public function hook_update_when_metadata_saved_as_private($metadatum) {
if ( $metadatum instanceof Entities\Metadatum ) {
$status_obj = get_post_status_object( $metadatum->get_status() );
if ( ! $status_obj->public ) {
$stati = get_post_stati(['public' => true]);
$metadatum_id = $metadatum->get_id();
$filters = $this->fetch(['metadatum_id' => $metadatum_id, 'post_status' => $stati], 'OBJECT');
foreach ($filters as $filter) {
$filter->set_status( $metadatum->get_status() );
if ( $filter->validate() ) {
$this->insert($filter);
}
}
}
}
}
}

View File

@ -93,7 +93,7 @@ class Metadata extends Repository {
'map' => 'meta',
'title' => __( 'Type', 'tainacan' ),
'type' => 'string',
'description' => __( 'The metadata type', 'tainacan' ),
'description' => __( 'The metadata type class name, such as Tainacan\Metadata_Types\Core_Title', 'tainacan' ),
'on_error' => __( 'Metadata type is empty', 'tainacan' ),
'validation' => v::stringType()->notEmpty(),
],

Some files were not shown because too many files have changed in this diff Show More