Merge branch 'tainacan-develop' into develop

This commit is contained in:
Adrian 2021-11-13 19:48:49 +02:00
commit 148295e511
33 changed files with 900 additions and 679 deletions

View File

@ -620,7 +620,12 @@ a.pswp__share--download:hover {
width: 100%;
height: auto;
display: block;
background-color: var(--tainacan-media-background, transparent); }
background-color: var(--tainacan-media-background, transparent);
box-sizing: border-box; }
.tainacan-media-component .swiper-slide,
.tainacan-media-component .swiper-slide::after,
.tainacan-media-component .swiper-slide::before {
box-sizing: border-box; }
/* Style valid for both cases of carousel, main and thumbs */
.tainacan-media-component__swiper-main .swiper-button-prev::after,
@ -658,6 +663,8 @@ a.pswp__share--download:hover {
.tainacan-media-component__swiper-main ul.swiper-wrapper[data-pswp-uid]:not([data-pswp-uid='']) li.swiper-slide .swiper-slide-content video,
.tainacan-media-component__swiper-main ul.swiper-wrapper[data-pswp-uid]:not([data-pswp-uid='']) li.swiper-slide .swiper-slide-content audio {
pointer-events: none; }
.tainacan-media-component__swiper-main ul.swiper-wrapper[data-pswp-uid]:not([data-pswp-uid='']) li.swiper-slide .swiper-slide-content a {
cursor: zoom-in !important; }
.tainacan-media-component__swiper-main li.swiper-slide {
height: 100%;
max-width: 100%;

File diff suppressed because one or more lines are too long

View File

@ -38,6 +38,8 @@ class REST_Items_Controller extends REST_Controller {
$this->collections_repository = Repositories\Collections::get_instance();
$this->metadatum_repository = Repositories\Metadata::get_instance();
$this->terms_repository = \Tainacan\Repositories\Terms::get_instance();
$this->filters_repository = \Tainacan\Repositories\Filters::get_instance();
$this->taxonomies_repository = \Tainacan\Repositories\Taxonomies::get_instance();
}
/**
@ -408,6 +410,163 @@ class REST_Items_Controller extends REST_Controller {
return $rest_response;
}
/**
* @param array $args array of query arguments.
*
* @return array
* @throws \Exception
*/
private function prepare_filters_arguments ( $args, $collection_id = false ) {
$filters_arguments = array();
$meta_query = isset($args['meta_query']) ? $args['meta_query'] : [];
$tax_query = isset($args['tax_query']) ? $args['tax_query'] : [];
foreach($tax_query as $tax) {
$taxonomy = $tax['taxonomy'];
$taxonomy_id = $this->taxonomies_repository->get_id_by_db_identifier($taxonomy);
$terms_id = is_array($tax['terms']) ? $tax['terms']: [$tax['terms']];
$terms_name = array_map(function($term_id) {
$t = is_numeric($term_id) ? get_term($term_id) : get_term_by('slug', $term_id);
return $t != false ? $t->name : '--';
}, $terms_id);
$metas = $this->metadatum_repository->fetch(array(
'meta_query' => [
[
'key' => 'collection_id',
'value' => empty($collection_id) ? 'default' : $collection_id,
'compare' => '='
],
[
'key' => '_option_taxonomy_id',
'value' => $taxonomy_id,
'compate' => '='
]
]
), 'OBJECT' );
if( !empty($metas) ) {
$meta_query[] = array(
'key' => $metas[0]->get_id(),
'value' => $terms_id,
'label' => $terms_name,
);
}
}
foreach($meta_query as $meta) {
if ( !isset($meta['key']) || !isset($meta['value']) )
continue;
$meta_id = $meta['key'];
$meta_value = is_array($meta['value']) ? $meta['value'] : [$meta['value']];
$meta_label = isset($meta['label']) ? $meta['label'] : $meta_value;
$filter_type_component = false;
$arg_type = 'meta';
$f = false;
$m = false;
if ($meta_id === 'collection_id') {
$arg_type = 'collection';
$meta_label = array_map(function($collection_id) {
$collection = $this->collections_repository->fetch($collection_id);
return $collection->get_name();
}, $meta_value);
} else {
$filter = $this->filters_repository->fetch([
'meta_query' => array(
[
'key' => 'metadatum_id',
'value' => $meta_id,
'compare' => '='
]
)
], 'OBJECT'
);
if ( !empty($filter) ) {
$f = $filter[0]->_toArray();
$filter_type_component = $filter[0]->get_filter_type_object()->get_component();
$m = $f['metadatum'];
} else {
$metadatum = $this->metadatum_repository->fetch($meta_id, 'OBJECT');
if(!empty($metadatum)) {
$m = $metadatum->_toArray();
$meta_object = $metadatum->get_metadata_type_object();
if (is_object($meta_object)) {
$m['metadata_type_object'] = $meta_object->_toArray();
}
}
}
if ($m !== false) {
switch ($m['metadata_type_object']['primitive_type']) {
case 'date':
$meta_label = array_map(function($date) {
$date_format = get_option( 'date_format' ) != false ? get_option( 'date_format' ) : 'Y-m-d';
return empty($date) == false ? mysql2date($date_format, $date) : "";
}, $meta_label);
break;
case 'item':
$meta_label = array_map(function($item_id) {
$_post = get_post($item_id);
if ( ! $_post instanceof \WP_Post) {
return;
}
return $_post->post_title;
}, $meta_label);
break;
case 'control':
$control_metadatum = $m['metadata_type_object']['options']['control_metadatum'];
$metadata_type_object = new \Tainacan\Metadata_Types\Control();
$meta_label = array_map(function($control_value) use ($metadata_type_object, $control_metadatum) {
return $metadata_type_object->get_control_metadatum_value($control_value, $control_metadatum, 'string' );
}, $meta_label);
break;
case 'user':
$meta_label = array_map(function($user_id) {
$name = get_the_author_meta( 'display_name', $user_id );
return apply_filters("tainacan-item-get-author-name", $name);
}, $meta_label);
break;
}
}
}
$filter_name = is_string($filter_type_component)
? "tainacan-api-items-${filter_type_component}-filter-arguments"
: 'tainacan-api-items-filter-arguments';
$filters_arguments[] = apply_filters($filter_name, array(
'filter' => $f,
'metadatum' => $m,
'arg_type' => $arg_type,
'value' => $meta_value,
'label' => $meta_label,
'compare' => isset($meta['compare']) ? $meta['compare'] : '='
));
}
if (isset($args['post__in'])) {
$filters_arguments[] = array(
'filter' => false,
'metadatum' => false,
'arg_type' => 'postin',
'value' => $args['post__in'],
'label' => count($args['post__in']),
'compare' => 'IN'
);
}
return $filters_arguments;
}
/**
* @param \WP_REST_Request $request
*
@ -436,6 +595,7 @@ class REST_Items_Controller extends REST_Controller {
if($request['collection_id']) {
$collection_id = $request['collection_id'];
}
$filters_args = $this->prepare_filters_arguments($args, $collection_id);
$max_items_per_page = $TAINACAN_API_MAX_ITEMS_PER_PAGE;
if ( $max_items_per_page > -1 ) {
@ -454,6 +614,7 @@ class REST_Items_Controller extends REST_Controller {
// Filter right after the ->fetch() method. Elastic Search integration relies on this on its 'last_aggregations' hook
$response['filters'] = apply_filters('tainacan-api-items-filters-response', [], $request);
$response['filters_arguments'] = apply_filters('tainacan-api-items-filters-arguments-response', $filters_args, $args);
$query_end = microtime(true);

View File

@ -153,41 +153,42 @@ class Filters extends Repository {
* @param Entities\Metadatum $metadatum
* @return int
*
public function insert($metadatum) {
// First iterate through the native post properties
$map = $this->get_map();
foreach ($map as $prop => $mapped) {
if ($mapped['map'] != 'meta' && $mapped['map'] != 'meta_multi') {
$metadatum->WP_Post->{$mapped['map']} = $metadatum->get_mapped_property($prop);
}
}
// save post and get its ID
$metadatum->WP_Post->post_type = Entities\Filter::get_post_type();
$metadatum->WP_Post->post_status = 'publish';
$id = wp_insert_post($metadatum->WP_Post);
$metadatum->WP_Post = get_post($id);
// Now run through properties stored as postmeta
foreach ($map as $prop => $mapped) {
if ($mapped['map'] == 'meta') {
update_post_meta($id, $prop, $metadatum->get_mapped_property($prop));
} elseif ($mapped['map'] == 'meta_multi') {
$values = $metadatum->get_mapped_property($prop);
delete_post_meta($id, $prop);
if (is_array($values)){
foreach ($values as $value){
add_post_meta($id, $prop, $value);
}
}
}
}
// return a brand new object
return new Entities\Filter($metadatum->WP_Post);
}*/
* public function insert($metadatum) {
* // First iterate through the native post properties
* $map = $this->get_map();
* foreach ($map as $prop => $mapped) {
* if ($mapped['map'] != 'meta' && $mapped['map'] != 'meta_multi') {
* $metadatum->WP_Post->{$mapped['map']} = $metadatum->get_mapped_property($prop);
* }
* }
*
* // save post and get its ID
* $metadatum->WP_Post->post_type = Entities\Filter::get_post_type();
* $metadatum->WP_Post->post_status = 'publish';
* $id = wp_insert_post($metadatum->WP_Post);
* $metadatum->WP_Post = get_post($id);
*
* // Now run through properties stored as postmeta
* foreach ($map as $prop => $mapped) {
* if ($mapped['map'] == 'meta') {
* update_post_meta($id, $prop, $metadatum->get_mapped_property($prop));
* } elseif ($mapped['map'] == 'meta_multi') {
* $values = $metadatum->get_mapped_property($prop);
*
* delete_post_meta($id, $prop);
*
* if (is_array($values)){
* foreach ($values as $value){
* add_post_meta($id, $prop, $value);
* }
* }
* }
* }
*
* // return a brand new object
* return new Entities\Filter($metadatum->WP_Post);
*}
*/
public function update( $object, $new_values = null ) {
return $this->insert( $object );

View File

@ -57,7 +57,7 @@ abstract class Repository {
*/
protected function __construct() {
add_action( 'init', array( &$this, 'register_post_type' ) );
add_action( 'init', array( &$this, 'init_objects' ) );
add_action( 'init', array( &$this, 'init_objects' ) );
add_filter( 'tainacan-get-map-' . $this->get_name(), array( $this, 'get_default_properties' ) );
}

View File

@ -0,0 +1,26 @@
<?php
namespace Tainacan\Traits;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class for formatter texts
* @author Vinicius Nunus - L3P/Medialab
*
*/
trait Singleton_Instance {
private static $instance = null;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init();
}
}

View File

@ -149,12 +149,6 @@
} else {
this.label = '';
this.selected = '';
this.$emit('input', {
filter: 'autocomplete',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.selected
});
}
}, 500),
searchMore: _.debounce(function () {
@ -176,12 +170,9 @@
axios.get(endpoint)
.then( res => {
let item = res.data;
this.label = item.title;
this.selected = item.title;
this.$emit( 'sendValuesToTags', { label: this.label, value: this.selected, metadatumName: this.metadatumName });
})
.catch(error => {
this.$console.log(error);
@ -189,7 +180,6 @@
} else {
this.label = metadata.value;
this.selected = metadata.value;
this.$emit( 'sendValuesToTags', { label: this.label, value: this.selected, metadatumName: this.metadatumName });
}
} else {
this.label = '';

View File

@ -163,26 +163,8 @@
return false;
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 = [];
}
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, metadatumName: this.metadatumName });
this.selected = index >= 0 ? this.query.metaquery.slice()[ index ].value : [];
},
openCheckboxModal() {
this.$buefy.modal.open({

View File

@ -131,13 +131,6 @@
const dateValueEnd = new Date(metadata.value[1].replace(/-/g, '/'));
this.dateEnd = moment(dateValueEnd, moment.ISO_8601).toDate();
}
if (metadata.value[0] != undefined && metadata.value[1] != undefined)
this.$emit('sendValuesToTags', {
label: this.parseDateToNavigatorLanguage(metadata.value[0]) + ' - ' + this.parseDateToNavigatorLanguage(metadata.value[1]),
value: [metadata.value[0], metadata.value[1]],
metadatumName: this.metadatumName
});
} else {
this.dateInit = null;
this.dateEnd = null;
@ -167,13 +160,6 @@
collection_id: this.collectionId,
value: values
});
if (values[0] != undefined && values[1] != undefined)
this.$emit( 'sendValuesToTags', {
label: this.parseDateToNavigatorLanguage(values[0]) + ' - ' + this.parseDateToNavigatorLanguage(values[1]),
value: [ values[0], values[1] ],
metadatumName: this.metadatumName
});
}
}
}

View File

@ -9,35 +9,63 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Date_Interval extends Filter_Type {
function __construct(){
$this->set_name( __('Date Interval', 'tainacan') );
$this->set_supported_types(['date']);
$this->set_component('tainacan-filter-date-interval');
$this->set_use_max_options(false);
$this->set_preview_template('
<div>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
<p class="is-size-7 has-text-centered is-marginless">until</p>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
</div>
');
}
}
function __construct(){
$this->set_name( __('Date Interval', 'tainacan') );
$this->set_supported_types(['date']);
$this->set_component('tainacan-filter-date-interval');
$this->set_use_max_options(false);
$this->set_preview_template('
<div>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
<p class="is-size-7 has-text-centered is-marginless">until</p>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
</div>
');
}
}
class Date_Interval_Interval_Helper {
use \Tainacan\Traits\Singleton_Instance;
protected function init() {
add_filter( 'tainacan-api-items-tainacan-filter-date-interval-filter-arguments', [$this, 'format_filter_arguments']);
}
function format_filter_arguments( $filter_arguments ) {
if (
!isset($filter_arguments['compare']) ||
!isset($filter_arguments['label'])
) {
return $filter_arguments;
}
if (
strtoupper($filter_arguments['compare']) === 'BETWEEN' &&
is_array($filter_arguments['label']) &&
count($filter_arguments['label']) === 2
) {
$filter_arguments['label'] = $filter_arguments['label'][0] . ' - ' . $filter_arguments['label'][1];
}
return $filter_arguments;
}
}
Date_Interval_Interval_Helper::get_instance();

View File

@ -174,12 +174,6 @@
const dateValue = new Date(textValue.replace(/-/g, '/'));
this.value = moment(dateValue, moment.ISO_8601).toDate();
this.$emit('sendValuesToTags', {
label: this.comparator + ' ' + this.parseDateToNavigatorLanguage(textValue),
value: textValue,
metadatumName: this.metadatumName
});
}
} else {
@ -221,11 +215,6 @@
collection_id: this.collectionId,
value: valueQuery
});
this.$emit('sendValuesToTags', {
label: this.comparator + ' ' + moment(this.value, moment.ISO_8601).format(this.dateFormat),
value: valueQuery,
metadatumName: this.metadatumName
});
},
onChangeComparator(newComparator) {
this.comparator = newComparator;

View File

@ -9,67 +9,113 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Date extends Filter_Type {
function __construct(){
$this->set_name( __('Date', 'tainacan') );
$this->set_supported_types(['date']);
$this->set_component('tainacan-filter-date');
// $this->set_form_component('tainacan-filter-form-date');
$this->set_use_max_options(false);
// $this->set_default_options([
// 'type' => 'day'
// ]);
$this->set_preview_template('
<div>
<div>
<div class="date-filter-container">
<div class="dropdown is-active">
<div role="button" class="dropdown-trigger">
<button class="button is-white">
<span class="icon is-small">
<i>=</i>
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
</button>
</div>
<div class="background" style="display: none;"></div>
<div class="dropdown-menu" style="display: none;">
<div role="list" class="dropdown-content">
<a class="dropdown-item is-active">=&nbsp; ' . __('Equal', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Not equal', 'tainacan') .'</a>
<a class="dropdown-item">&gt;&nbsp; '. __('After', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('After (inclusive)', 'tainacan') .'</a>
<a class="dropdown-item">&lt;&nbsp; '. __('Before', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Before (inclusive)', 'tainacan') .'</a>
</div>
</div>
</div>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
');
}
function __construct(){
$this->set_name( __('Date', 'tainacan') );
$this->set_supported_types(['date']);
$this->set_component('tainacan-filter-date');
// $this->set_form_component('tainacan-filter-form-date');
$this->set_use_max_options(false);
// $this->set_default_options([
// 'type' => 'day'
// ]);
$this->set_preview_template('
<div>
<div>
<div class="date-filter-container">
<div class="dropdown is-active">
<div role="button" class="dropdown-trigger">
<button class="button is-white">
<span class="icon is-small">
<i>=</i>
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
</button>
</div>
<div class="background" style="display: none;"></div>
<div class="dropdown-menu" style="display: none;">
<div role="list" class="dropdown-content">
<a class="dropdown-item is-active">=&nbsp; ' . __('Equal', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Not equal', 'tainacan') .'</a>
<a class="dropdown-item">&gt;&nbsp; '. __('After', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('After (inclusive)', 'tainacan') .'</a>
<a class="dropdown-item">&lt;&nbsp; '. __('Before', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Before (inclusive)', 'tainacan') .'</a>
</div>
</div>
</div>
<div class="datepicker control is-small">
<div class="dropdown is-bottom-left is-mobile-modal">
<div role="button" class="dropdown-trigger">
<div class="control has-icons-left is-small is-clearfix">
<input type="text" autocomplete="off" placeholder=" '. __('Select a date', 'tainacan') .'" class="input is-small">
<span class="icon is-left is-small"><i class="mdi mdi-calendar-today"></i></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
');
}
// /**
// * @inheritdoc
// */
// public function get_form_labels(){
// return [
// 'type' => [
// 'title' => __( 'Type', 'tainacan' ),
// 'description' => __( 'The type of the date picker, may be for day, month or year.', 'tainacan' ),
// ]
// ];
// }
}
// /**
// * @inheritdoc
// */
// public function get_form_labels(){
// return [
// 'type' => [
// 'title' => __( 'Type', 'tainacan' ),
// 'description' => __( 'The type of the date picker, may be for day, month or year.', 'tainacan' ),
// ]
// ];
// }
}
class Date_Helper {
use \Tainacan\Traits\Singleton_Instance;
protected function init() {
add_filter( 'tainacan-api-items-tainacan-filter-date-filter-arguments', [$this, 'format_filter_arguments']);
}
function format_filter_arguments( $filter_arguments ) {
if (
!isset($filter_arguments['compare']) ||
!isset($filter_arguments['label'])
) {
return $filter_arguments;
}
if (count($filter_arguments['label']) === 1) {
switch ($filter_arguments['compare']) {
case '=':
$filter_arguments['label'] = '&#61; ' . $filter_arguments['label'][0];
break;
case '!=':
$filter_arguments['label'] = '&#8800; ' . $filter_arguments['label'][0];
break;
case '>':
$filter_arguments['label'] = '&#62; ' . $filter_arguments['label'][0];
break;
case '>=':
$filter_arguments['label'] = '&#8805; ' . $filter_arguments['label'][0];
break;
case '<':
$filter_arguments['label'] = '&#60; ' . $filter_arguments['label'][0];
break;
case '<=':
$filter_arguments['label'] = '&#8804; ' . $filter_arguments['label'][0];
break;
default:
$filter_arguments['label'] = $filter_arguments['label'][0];
}
}
return $filter_arguments;
}
}
Date_Helper::get_instance();

View File

@ -90,25 +90,19 @@
collection_id: this.collectionId,
value: values
});
if (values[0] != undefined && values[1] != undefined)
this.$emit('sendValuesToTags', { label: values[0] + ' - ' + values[1], value: values, metadatumName: this.metadatumName });
},
updateSelectedValues(){
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 ){
if ( index >= 0 ) {
let metaquery = this.query.metaquery[ index ];
if ( metaquery.value && metaquery.value.length > 1 ) {
this.valueInit = new Number(metaquery.value[0]);
this.valueEnd = new Number(metaquery.value[1]);
}
if (metaquery.value[0] != undefined && metaquery.value[1] != undefined)
this.$emit('sendValuesToTags', { label: this.valueInit + ' - ' + this.valueEnd, value: metaquery.value, metadatumName: this.metadatumName });
} else {
this.valueInit = null;
this.valueEnd = null;

View File

@ -9,67 +9,95 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Numeric_Interval extends Filter_Type {
function __construct(){
$this->set_name( __('Numeric Interval', 'tainacan') );
$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
]);
$this->set_preview_template('
<div>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="6">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
<p class="is-size-7 has-text-centered is-marginless">until</p>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="10">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
</div>
');
}
public function get_form_labels(){
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on the filter control buttons. This also defines whether the input accepts decimal numbers.', 'tainacan' ),
],
'custom' => ['title' => __('Custom interval','tainacan')],
];
}
}
function __construct(){
$this->set_name( __('Numeric Interval', 'tainacan') );
$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
]);
$this->set_preview_template('
<div>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="6">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
<p class="is-size-7 has-text-centered is-marginless">until</p>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="10">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
</div>
');
}
public function get_form_labels(){
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on the filter control buttons. This also defines whether the input accepts decimal numbers.', 'tainacan' ),
],
'custom' => ['title' => __('Custom interval','tainacan')],
];
}
}
class Numeric_Interval_Interval_Helper {
use \Tainacan\Traits\Singleton_Instance;
protected function init() {
add_filter( 'tainacan-api-items-tainacan-filter-numeric-interval-filter-arguments', [$this, 'format_filter_arguments']);
}
function format_filter_arguments( $filter_arguments ) {
if (
!isset($filter_arguments['compare']) ||
!isset($filter_arguments['label'])
) {
return $filter_arguments;
}
if (
strtoupper($filter_arguments['compare']) === 'BETWEEN' &&
is_array($filter_arguments['label']) &&
count($filter_arguments['label']) === 2
) {
$filter_arguments['label'] = $filter_arguments['label'][0] . ' - ' . $filter_arguments['label'][1];
}
return $filter_arguments;
}
}
Numeric_Interval_Interval_Helper::get_instance();

View File

@ -53,7 +53,6 @@
});
this.valueEnd = null;
this.valueInit = null;
this.$emit('sendValuesToTags', { label: '', value: null, metadatumName: this.metadatumName });
}
},
// emit the operation for listeners
@ -67,11 +66,6 @@
collection_id: this.collectionId,
value: values
});
if (values[0] != undefined && values[1] != undefined && this.selectedInterval !== '') {
let labelValue = this.filterTypeOptions.intervals[this.selectedInterval].label + (this.filterTypeOptions.showIntervalOnTag ? ` (${values[0]}-${values[1]})` : '');
this.$emit('sendValuesToTags', { label: labelValue, value: values, metadatumName: this.metadatumName });
}
},
updateSelectedValues(){
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
@ -95,10 +89,6 @@
);
this.selectedInterval = this.selectedInterval >= 0 ? this.selectedInterval : '';
if (this.selectedInterval !== '') {
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 ], metadatumName: this.metadatumName });
}
} else {
this.valueInit = null;
this.valueEnd = null;

View File

@ -9,50 +9,85 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Numeric_List_Interval extends Filter_Type {
function __construct(){
$this->set_name( __('Numeric Interval List', 'tainacan') );
$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' => __('A list of predefined intervals that the filter will offer on a selection box.','tainacan')
],
'showIntervalOnTag' => [
'title' => __('Interval on tags', 'tainacan'),
'description' => __('Whether the applied interval values should appear on filter tags.')
]
];
}
function __construct(){
$this->set_name( __('Numeric Interval List', 'tainacan') );
$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' => __('A list of predefined intervals that the filter will offer on a select box.','tainacan')
],
'showIntervalOnTag' => [
'title' => __('Interval on tags', 'tainacan'),
'description' => __('Whether the applyed interval values should appear on filter tags.')
]
];
}
}
class Numeric_List_Interval_Helper {
use \Tainacan\Traits\Singleton_Instance;
protected function init() {
add_filter( 'tainacan-api-items-tainacan-filter-numeric-list-interval-filter-arguments', [$this, 'format_filter_arguments']);
}
function format_filter_arguments( $filter_arguments ) {
if (
!isset($filter_arguments['filter']) ||
!isset($filter_arguments['filter']['filter_type_options']) ||
!isset($filter_arguments['filter']['filter_type_options']['intervals'])
) {
return $filter_arguments;
}
$intervals = $filter_arguments['filter']['filter_type_options']['intervals'];
foreach($intervals as $interval) {
if (
$interval['from'] == $filter_arguments['value'][0] &&
$interval['to'] == $filter_arguments['value'][1]
) {
$filter_arguments['label'] = $interval['label'];
if ( isset($filter_arguments['filter']['filter_type_options']['showIntervalOnTag']) && $filter_arguments['filter']['filter_type_options']['showIntervalOnTag'] )
$filter_arguments['label'] .= ' (' . $filter_arguments['value'][0] . '-' . $filter_arguments['value'][1] . ')';
break;
}
}
return $filter_arguments;
}
}
Numeric_List_Interval_Helper::get_instance();

View File

@ -113,7 +113,7 @@
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if ( index >= 0){
if ( index >= 0) {
let metadata = this.query.metaquery[ index ];
if ( metadata.value && metadata.value.length > 0)
@ -122,9 +122,6 @@
if ( metadata.compare)
this.comparator = metadata.compare;
if (this.value != undefined)
this.$emit('sendValuesToTags', { label: this.comparator + ' ' + this.value, value: this.value, metadatumName: this.metadatumName });
} else {
this.value = null;
}
@ -144,8 +141,6 @@
value: this.value,
type: 'NUMERIC'
});
this.$emit('sendValuesToTags', { label: this.comparator + ' ' + this.value, value: this.value, metadatumName: this.metadatumName });
},
onChangeComparator(newComparator) {

View File

@ -9,92 +9,135 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
*/
class Numeric extends Filter_Type {
function __construct(){
$this->set_name( __('Numeric', 'tainacan') );
$this->set_supported_types(['float']);
$this->set_component('tainacan-filter-numeric');
$this->set_form_component('tainacan-filter-form-numeric');
$this->set_use_max_options(false);
$this->set_default_options([
'step' => 1
]);
$this->set_preview_template('
<div>
<div>
<div class="numeric-filter-container">
<div class="dropdown is-active">
<div role="button" class="dropdown-trigger">
<button class="button is-white">
<span class="icon is-small">
<i>=</i>
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
</button>
</div>
<div class="background" style="display: none;"></div>
<div class="dropdown-menu" style="display: none;">
<div role="list" class="dropdown-content">
<a class="dropdown-item is-active">=&nbsp; ' . __('Equal', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Not equal', 'tainacan') .'</a>
<a class="dropdown-item">&gt;&nbsp; '. __('Greater than', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Greater than or equal to', 'tainacan') .'</a>
<a class="dropdown-item">&lt;&nbsp; '. __('Less than', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Less than or equal to', 'tainacan') .'</a>
</div>
</div>
</div>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="1.5">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
</div>
</div>
');
}
function __construct(){
$this->set_name( __('Numeric', 'tainacan') );
$this->set_supported_types(['float']);
$this->set_component('tainacan-filter-numeric');
$this->set_form_component('tainacan-filter-form-numeric');
$this->set_use_max_options(false);
$this->set_default_options([
'step' => 1
]);
$this->set_preview_template('
<div>
<div>
<div class="numeric-filter-container">
<div class="dropdown is-active">
<div role="button" class="dropdown-trigger">
<button class="button is-white">
<span class="icon is-small">
<i>=</i>
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown"></i>
</span>
</button>
</div>
<div class="background" style="display: none;"></div>
<div class="dropdown-menu" style="display: none;">
<div role="list" class="dropdown-content">
<a class="dropdown-item is-active">=&nbsp; ' . __('Equal', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Not equal', 'tainacan') .'</a>
<a class="dropdown-item">&gt;&nbsp; '. __('Greater than', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Greater than or equal to', 'tainacan') .'</a>
<a class="dropdown-item">&lt;&nbsp; '. __('Less than', 'tainacan') .'</a>
<a class="dropdown-item">&nbsp; '. __('Less than or equal to', 'tainacan') .'</a>
</div>
</div>
</div>
<div class="b-numberinput field is-grouped">
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-minus"></i>
</span>
</button>
</p>
<div class="control is-small is-clearfix">
<input type="number" step="0.01" class="input is-small" value="1.5">
</div>
<p class="control">
<button type="button" class="button is-primary is-small">
<span class="icon is-small">
<i class="mdi mdi-plus"></i>
</span>
</button>
</p>
</div>
</div>
</div>
');
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on the filter control buttons. This also defines whether the input accepts decimal numbers.', 'tainacan' ),
]
];
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on the filter control buttons. This also defines whether the input accepts decimal numbers.', 'tainacan' ),
]
];
}
/**
* @param \Tainacan\Entities\Filter $filter
* @return array|bool true if is validate or array if has error
*/
public function validate_options(\Tainacan\Entities\Filter $filter) {
if ( !in_array($filter->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
/**
* @param \Tainacan\Entities\Filter $filter
* @return array|bool true if is validate or array if has error
*/
public function validate_options(\Tainacan\Entities\Filter $filter) {
if ( !in_array($filter->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
if ( empty($this->get_option('step')) ) {
return [
'step' => __('"Step" value is required','tainacan')
];
}
if ( empty($this->get_option('step')) ) {
return [
'step' => __('"Step" value is required','tainacan')
];
}
return true;
}
}
return true;
}
}
class Numeric_Helper {
use \Tainacan\Traits\Singleton_Instance;
protected function init() {
add_filter( 'tainacan-api-items-tainacan-filter-numeric-filter-arguments', [$this, 'format_filter_arguments']);
}
function format_filter_arguments( $filter_arguments ) {
if (
!isset($filter_arguments['compare']) ||
!isset($filter_arguments['label'])
) {
return $filter_arguments;
}
if (count($filter_arguments['label']) === 1) {
switch ($filter_arguments['compare']) {
case '=':
$filter_arguments['label'] = '&#61; ' . $filter_arguments['label'][0];
break;
case '!=':
$filter_arguments['label'] = '&#8800; ' . $filter_arguments['label'][0];
break;
case '>':
$filter_arguments['label'] = '&#62; ' . $filter_arguments['label'][0];
break;
case '>=':
$filter_arguments['label'] = '&#8805; ' . $filter_arguments['label'][0];
break;
case '<':
$filter_arguments['label'] = '&#60; ' . $filter_arguments['label'][0];
break;
case '<=':
$filter_arguments['label'] = '&#8804; ' . $filter_arguments['label'][0];
break;
}
}
return $filter_arguments;
}
}
Numeric_Helper::get_instance();

View File

@ -103,8 +103,6 @@
} else {
this.selected = '';
}
this.$emit('sendValuesToTags', { label: this.selected, value: this.selected, metadatumName: this.metadatumName })
},
onSelect(value) {
this.$emit('input', {

View File

@ -3,7 +3,6 @@
<b-taginput
icon="magnify"
size="is-small"
v-model="selected"
:data="options"
autocomplete
expanded
@ -46,16 +45,15 @@
</template>
<script>
import { tainacan as axios, isCancel, wp as wpAxios } from '../../../js/axios';
import { isCancel } from '../../../js/axios';
import { filterTypeMixin, dynamicFilterTypeMixin } from '../../../js/filter-types-mixin';
import qs from 'qs';
export default {
mixins: [filterTypeMixin, dynamicFilterTypeMixin],
data() {
return {
results:'',
selected:[],
selected:[], // Simple array of IDs, no more objects and not bound to the taginput
options: [],
relatedCollectionId: '',
searchQuery: '',
@ -113,10 +111,6 @@
return;
let promise = null;
let valuesToIgnore = [];
for (let val of this.selected)
valuesToIgnore.push( val.value );
// Cancels previous Request
if (this.getOptionsValuesCancel != undefined)
@ -126,7 +120,7 @@
promise = this.getValuesRelationship({
search: this.searchQuery,
isRepositoryLevel: this.isRepositoryLevel,
valuesToIgnore: valuesToIgnore,
valuesToIgnore: this.selected,
offset: this.searchOffset,
number: this.searchNumber
});
@ -135,7 +129,7 @@
metadatumId: this.metadatumId,
search: this.searchQuery,
isRepositoryLevel: this.isRepositoryLevel,
valuesToIgnore: valuesToIgnore,
valuesToIgnore: this.selected,
offset: this.searchOffset,
number: this.searchNumber
});
@ -157,7 +151,6 @@
}, 500),
searchMore: _.debounce(function () {
this.shouldAddOptions = true;
this.search(this.searchQuery);
}, 250),
updateSelectedValues() {
@ -165,91 +158,23 @@
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
return false;
let index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
// Cleared either way, we might be coming from a situation where all the filters were removed.
this.selected = [];
const index = this.query.metaquery.findIndex(newMetadatum => newMetadatum.key == this.metadatumId );
if (index >= 0) {
let metadata = this.query.metaquery[ index ];
if (this.metadatumType === 'Tainacan\\Metadata_Types\\Relationship') {
let query = qs.stringify({ postin: metadata.value, fetch_only: 'title,thumbnail,document_mimetype', fetch_only_meta: '' });
let endpoint = '/items/';
if (this.relatedCollectionId != '')
endpoint = '/collection/' + this.relatedCollectionId + endpoint;
axios.get(endpoint + '?' + query)
.then( res => {
if (res.data.items) {
this.selected = [];
for (let item of res.data.items) {
let existingItem = this.selected.findIndex((anItem) => item.id == anItem.id);
if (existingItem < 0) {
this.selected.push({
label: item.title,
value: item.id,
img: item.thumbnail ? this.$thumbHelper.getSrc(item['thumbnail'], 'tainacan-small', item.document_mimetype) : null
});
}
}
this.$emit( 'sendValuesToTags', {
label: this.selected.map((option) => option.label),
value: this.selected.map((option) => option.value),
metadatumName: this.metadatumName
});
}
})
.catch(error => {
this.$console.log(error);
});
} else if (this.metadatumType === 'Tainacan\\Metadata_Types\\User') {
let query = qs.stringify({ include: metadata.value });
let endpoint = '/users/';
wpAxios.get(endpoint + '?' + query)
.then( res => {
if (res.data) {
this.selected = [];
for (let user of res.data) {
let existingUser = this.selected.findIndex((anUser) => user.id == anUser.id);
if (existingUser < 0) {
this.selected.push({
label: user.name,
value: user.id,
img: user.avatar_urls && user.avatar_urls['24'] ? user.avatar_urls['24'] : null
});
}
}
this.$emit( 'sendValuesToTags', {
label: this.selected.map((option) => option.label),
value: this.selected.map((option) => option.value),
metadatumName: this.metadatumName
});
}
})
.catch(error => {
this.$console.log(error);
});
} else {
this.selected = [];
for (let item of metadata.value)
this.selected.push({ label: item, value: item, img: null });
this.$emit( 'sendValuesToTags', {
label: this.selected.map((option) => option.label),
value: this.selected.map((option) => option.value),
metadatumName: this.metadatumName
});
}
} else {
this.selected = [];
const metadata = this.query.metaquery[ index ];
for (let item of metadata.value)
this.selected.push(item);
}
},
onSelect() {
onSelect(selection) {
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
value: this.selected.map((option) => option.value)
value: _.union(this.selected, selection.map(anOption => anOption.value))
});
}
}

View File

@ -42,7 +42,6 @@
:is-loading-items.sync="isLoadingItems"
:current-collection-id="$eventBusSearch.collectionId"
@input="onInput"
@sendValuesToTags="onSendValuesToTags"
@updateParentCollapse="onFilterUpdateParentCollapse"
:filters-as-modal="filtersAsModal"/>
</div>
@ -70,16 +69,6 @@
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,
metadatumName: this.filter.metadatum && this.filter.metadatum.metadatum_name ? this.filter.metadatum.metadatum_name : ''
});
},
onFilterUpdateParentCollapse(open) {
const componentsThatShouldCollapseIfEmpty = ['tainacan-filter-taxonomy-checkbox', 'tainacan-filter-selectbox', 'tainacan-filter-checkbox'];
if (componentsThatShouldCollapseIfEmpty.includes(this.filter.filter_type_object.component))

View File

@ -217,78 +217,15 @@
}
}
},
updateSelectedValues(){
updateSelectedValues() {
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 ];
this.selected = metadata.terms;
} else {
this.selected = [];
}
let onlyLabels = [];
for (let selected of this.selected) {
let valueIndex = this.options.findIndex(option => option.value == selected );
if (valueIndex >= 0) {
let existingLabelIndex = onlyLabels.findIndex(aLabel => aLabel == this.options[valueIndex].label)
if (existingLabelIndex < 0)
onlyLabels.push(this.options[valueIndex].label);
else
this.$set(onlyLabels, onlyLabels.push(this.options[valueIndex].label), existingLabelIndex);
} else {
// Not finding all options will happen on elastic search,
// as the facetsFromItemSearch will not be ready yet
if (!this.isUsingElasticSearch)
this.$console.log("Looking for terms that are not in the options list... ");
// let route = '';
// if (this.collectionId == 'default')
// route = '/facets/' + this.metadatumId +`?term_id=${selected}&fetch_only=name,id`;
// else
// route = '/collection/'+ this.collectionId +'/facets/' + this.metadatumId +`?term_id=${selected}&fetch_only=name,id`;
// axios.get(route)
// .then( res => {
// if(!res || !res.data || !res.data.values){
// return false;
// }
// let existingLabelIndex = onlyLabels.findIndex(aLabel => aLabel == res.data.values[0].label)
// if (existingLabelIndex < 0) {
// onlyLabels.push(res.data.values[0].label);
// this.options.push({
// isChild: true,
// label: res.data.values[0].label,
// value: res.data.values[0].value
// });
// } else {
// this.$set(onlyLabels, onlyLabels.push(res.data.values[0].label), existingLabelIndex);
// this.$set(this.options, {
// isChild: true,
// label: res.data.values[0].label,
// value: res.data.values[0].value
// }
// , existingLabelIndex);
// }
// })
// .catch(error => {
// this.$console.log(error);
// });
}
}
this.$emit('sendValuesToTags', { label: onlyLabels, taxonomy: this.taxonomy, value: this.selected, metadatumName: this.metadatumName });
this.selected = index >= 0 ? this.query.taxquery[ index ].terms : [];
},
onSelect() {
this.$emit('input', {
filter: 'checkbox',
taxonomy: this.taxonomy,

View File

@ -3,7 +3,6 @@
<b-taginput
size="is-small"
icon="magnify"
v-model="selected"
:data="options"
autocomplete
:loading="isLoadingOptions"
@ -49,7 +48,7 @@
return {
isLoadingOptions: false,
results:'',
selected:[],
selected:[], // Simple array of IDs, no more objects and not bound to the taginput
options: [],
taxonomy: '',
taxonomyId: '',
@ -125,11 +124,8 @@
endpoint += '?order=asc&' + qs.stringify(query_items);
let valuesToIgnore = [];
const valuesToIgnore = JSON.parse(JSON.stringify(this.selected));
for (let val of this.selected)
valuesToIgnore.push( val.value );
return axios.get(endpoint).then( res => {
for (let term of res.data.values) {
@ -168,56 +164,30 @@
searchMore: _.debounce(function () {
this.search(this.searchQuery)
}, 250),
updateSelectedValues(){
updateSelectedValues() {
if ( !this.query || !this.query.taxquery || !Array.isArray( this.query.taxquery ) )
return false;
// Cleared either way, we might be coming from a situation where all the filters were removed.
this.selected = [];
let index = this.query.taxquery.findIndex(newMetadatum => newMetadatum.taxonomy == this.taxonomy);
const index = this.query.taxquery.findIndex(newMetadatum => newMetadatum.taxonomy == this.taxonomy);
if (index >= 0) {
let metadata = this.query.taxquery[ index ];
this.selected = [];
if (metadata.terms && metadata.terms.length) {
this.getTerms(metadata)
.then(() => {
this.$emit( 'sendValuesToTags', {
label: this.selected.map((option) => option.label),
value: this.selected.map((option) => option.value),
taxonomy: this.taxonomy,
metadatumName: this.metadatumName
});
});
}
} else {
this.selected = [];
const metadata = this.query.taxquery[ index ];
for (let termId of metadata.terms)
this.selected.push(termId);
}
},
onSelect() {
onSelect(selection) {
this.$emit('input', {
filter: 'taginput',
compare: 'IN',
taxonomy: this.taxonomy,
metadatum_id: this.metadatumId,
collection_id: this.collectionId,
terms: this.selected.map((option) => option.value)
terms: _.union(this.selected, selection.map(anOption => anOption.value))
});
},
getTerms(metadata) {
let params = {
'include': metadata.terms,
'order': 'asc',
'fetchonly': 0
};
return axios.get('/taxonomy/' + this.taxonomyId + '/terms/?' + qs.stringify(params) )
.then( res => {
this.selected = res.data.map(term => { return { label: term.name, value: term.id } });
})
.catch(error => {
this.$console.log(error);
})
}
}
}

View File

@ -26,10 +26,7 @@
<span
class="selected-items-info"
v-if="selectedItems.length && items.length > 1 && !isAllItemsSelected">
{{ (selectedItems.length - amountOfSelectedItemsInOtherPages != 1) ? ((selectedItems.length - amountOfSelectedItemsInOtherPages) + ' ' + $i18n.get('label_selected_items')) : ('1 ' + $i18n.get('label_selected_item')) }}
<span v-if="amountOfSelectedItemsInOtherPages">
&nbsp;({{ $i18n.getWithVariables('label_+_%s_other_listings', [ amountOfSelectedItemsInOtherPages ]) }})
</span>
{{ selectedItems.length != 1 ? (selectedItems.length + ' ' + $i18n.get('label_selected_items')) : ('1 ' + $i18n.get('label_selected_item')) }}<span v-if="selectedItems.length != amountOfSelectedItemsOnThisPage && amountOfSelectedItemsOnThisPage > 0">,&nbsp;({{ $i18n.getWithVariables('label_%s_on_this_page', [ amountOfSelectedItemsOnThisPage ]) }})</span>
<button
class="link-style"
@click="cleanSelectedItems()">
@ -50,7 +47,9 @@
</span>
</button>
</span>
<div class="field">
<div
style="margin-left: auto;"
class="field">
<b-dropdown
:mobile-modal="true"
position="is-bottom-left"
@ -68,6 +67,12 @@
</span>
</button>
<b-dropdown-item
v-if="!isAllItemsSelected && selectedItems.length"
@click="filterBySelectedItems()"
aria-role="listitem">
{{ $i18n.get('label_view_only_selected_items') }}
</b-dropdown-item>
<b-dropdown-item
v-if="$route.params.collectionId && !isOnTrash"
@click="openBulkEditionModal()"
@ -1324,9 +1329,9 @@ export default {
return this.getSelectedItems();
},
amountOfSelectedItemsInOtherPages() {
amountOfSelectedItemsOnThisPage() {
if (this.selectedItems.length)
return this.selectedItems.length - this.items.filter( anItem => this.selectedItems.includes(anItem.id) ).length;
return this.items.filter( anItem => this.selectedItems.includes(anItem.id) ).length;
return 0;
},
@ -1627,6 +1632,9 @@ export default {
closeButtonAriaLabel: this.$i18n.get('close')
});
},
filterBySelectedItems() {
this.$eventBusSearch.filterBySelectedItems(this.selectedItems);
},
openItem() {
if (this.contextMenuItem != null) {
this.$router.push(this.$routerHelper.getItemPath(this.contextMenuItem.collection_id, this.contextMenuItem.id));
@ -1738,6 +1746,7 @@ export default {
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
.select-all {
color: var(--tainacan-info-color);
@ -1752,7 +1761,7 @@ export default {
}
.selected-items-info {
margin: 0 10px 0 auto;
margin: 0 auto 0 auto;
font-size: 00.875em;
color: var(--tainacan-info-color);

View File

@ -24,16 +24,18 @@
<swiper-slide
v-for="(filterTag, index) of filterTags"
:key="index"
class="filter-tag">
class="filter-tag"
:class="{ 'is-readonly': !filterTag.filterId && filterTag.argType != 'postin' }">
<span class="">
<div class="filter-tag-metadatum-name">
{{ filterTag.metadatumName }}
</div>
<div class="filter-tag-metadatum-value">
{{ filterTag.singleLabel != undefined ? filterTag.singleLabel : filterTag.label }}
</div>
<div
class="filter-tag-metadatum-value"
v-html="filterTag.singleLabel != undefined ? filterTag.singleLabel : filterTag.label"/>
</span>
<a
v-if="filterTag.filterId || filterTag.argType == 'postin'"
role="button"
tabindex="0"
class="tag is-delete"
@ -103,24 +105,35 @@
computed: {
filterTags() {
let tags = this.getFilterTags();
let flattenTags = [];
for (let tag of tags) {
tags.forEach( tag => {
if (Array.isArray(tag.label)) {
for (let i = 0; i < tag.label.length; i++)
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],
filterId: tag.filterId,
label: tag.argType != 'postin' ? tag.label : ( tag.label + ' ' + (tag.label == 1 ? this.$i18n.get('item') : this.$i18n.get('items') )),
taxonomy: tag.taxonomy,
metadatumName: tag.metadatumName,
metadatumId: tag.metadatumId
});
metadatumName: this.getMetadatumName(tag),
metadatumId: tag.metadatumId,
argType: tag.argType
});
}
} else {
flattenTags.push(tag);
flattenTags.push({
value: tag.value,
filterId: tag.filterId,
label: tag.argType != 'postin' ? tag.label : ( tag.label + ' ' + (tag.label == 1 ? this.$i18n.get('item') : this.$i18n.get('items') )),
taxonomy: tag.taxonomy,
metadatumName: this.getMetadatumName(tag),
metadatumId: tag.metadatumId,
argType: tag.argType
});
}
}
});
return flattenTags;
},
totalItems() {
@ -132,7 +145,7 @@
'getFilterTags',
'getTotalItems'
]),
removeMetaQuery({ filterId, value, singleLabel, label, taxonomy, metadatumId, metadatumName }) {
removeMetaQuery({ filterId, value, singleLabel, label, taxonomy, metadatumId, metadatumName, argType }) {
this.$eventBusSearch.resetPageOnStore();
this.$eventBusSearch.removeMetaFromFilterTag({
filterId: filterId,
@ -141,14 +154,21 @@
value: value,
taxonomy: taxonomy,
metadatumId: metadatumId,
metadatumName
metadatumName:metadatumName,
argType: argType
});
},
clearAllFilters() {
this.$eventBusSearch.resetPageOnStore();
for (let tag of this.filterTags) {
this.removeMetaQuery(tag);
}
this.$eventBusSearch.clearAllFilters();
},
getMetadatumName(tag) {
if (tag.argType == 'postin')
return this.$i18n.get('label_items_selection');
else if (tag.argType == 'collection')
return this.$i18n.get('collection');
else
return tag.metadatumName;
}
}
}
@ -204,6 +224,9 @@
background-color: transparent;
}
}
&.is-readonly {
border-style: dashed;
}
}
.swiper-container {

View File

@ -21,10 +21,6 @@ export default {
this.addMetaquery(data);
});
this.$on('sendValuesToTags', data => {
this.$store.dispatch('search/addFilterTag', data);
});
this.$root.$on('closeAdvancedSearch', () => {
this.$store.dispatch('search/setPage', 1);
@ -190,7 +186,7 @@ export default {
if (to.fullPath != from.fullPath) {
this.loadItems(to);
}
}
}
}
},
methods: {
@ -214,22 +210,26 @@ export default {
if (filterTag.singleLabel != undefined || filterTag.label != undefined) {
if (filterTag.taxonomy) {
this.$store.dispatch('search/remove_taxquery', {
filterId: filterTag.filterId,
label: filterTag.singleLabel ? filterTag.singleLabel : filterTag.label,
isMultiValue: filterTag.singleLabel ? false : true,
taxonomy: filterTag.taxonomy,
value: filterTag.value
});
if (filterTag.argType !== 'postin') {
if (filterTag.taxonomy) {
this.$store.dispatch('search/remove_taxquery', {
filterId: filterTag.filterId,
label: filterTag.singleLabel ? filterTag.singleLabel : filterTag.label,
isMultiValue: filterTag.singleLabel ? false : true,
taxonomy: filterTag.taxonomy,
value: filterTag.value
});
} else {
this.$store.dispatch('search/remove_metaquery', {
filterId: filterTag.filterId,
label: filterTag.singleLabel ? filterTag.singleLabel : filterTag.label,
isMultiValue: filterTag.singleLabel ? false : true,
metadatum_id: filterTag.metadatumId,
value: filterTag.value
});
}
} else {
this.$store.dispatch('search/remove_metaquery', {
filterId: filterTag.filterId,
label: filterTag.singleLabel ? filterTag.singleLabel : filterTag.label,
isMultiValue: filterTag.singleLabel ? false : true,
metadatum_id: filterTag.metadatumId,
value: filterTag.value
});
this.$store.dispatch('search/remove_postin');
}
this.$store.dispatch('search/removeFilterTag', filterTag);
}
@ -340,7 +340,7 @@ export default {
if (singleSelection)
this.$store.dispatch('search/cleanSelectedItems');
this.$store.dispatch('search/setSelectedItems', selectedItems);
this.$store.dispatch('search/setSelectedItems', selectedItems);
let currentSelectedItems = this.$store.getters['search/getSelectedItems'];
@ -357,6 +357,10 @@ export default {
cleanSelectedItems() {
this.$store.dispatch('search/cleanSelectedItems');
},
filterBySelectedItems(selectedItems) {
this.$router.replace({ query: {} });
this.$router.replace({ query: { postin: selectedItems } });
},
highlightsItem(itemId) {
this.$store.dispatch('search/highlightsItem', itemId);
this.updateURLQueries();
@ -416,7 +420,7 @@ export default {
},
clearAllFilters() {
this.$store.dispatch('search/cleanFilterTags');
this.$store.dispatch('search/cleanMetaQueries');
this.$store.dispatch('search/cleanMetaQueries', { keepCollections: true });
this.$store.dispatch('search/cleanTaxQueries');
this.updateURLQueries();
}

View File

@ -27,11 +27,18 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
let hasFiltered = false;
let advancedSearchResults = false;
if ( (postQueries.metaquery != undefined &&
(Object.keys(postQueries.metaquery).length > 0 ||
postQueries.metaquery.length > 0)) || (postQueries.taxquery != undefined &&
(Object.keys(postQueries.taxquery).length > 0 ||
postQueries.taxquery.length > 0)) ) {
// We mark as filtered if there is a metaquery, taxquery or a postin
if (
(postQueries.metaquery != undefined &&
(Object.keys(postQueries.metaquery).length > 0 || postQueries.metaquery.length > 0)
) ||
(postQueries.taxquery != undefined &&
(Object.keys(postQueries.taxquery).length > 0 ||postQueries.taxquery.length > 0)
) ||
(postQueries.postin != undefined &&
postQueries.postin.length
)
) {
hasFiltered = true;
@ -71,7 +78,8 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
if (postQueries.admin_view_mode != undefined)
postQueries.admin_view_mode = null;
}
axios.tainacan.get(endpoint+query, {
axios.tainacan.get(endpoint + query, {
cancelToken: source.token
})
.then(res => {
@ -106,6 +114,12 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, { collectionId, is
else
dispatch('search/setFacets', {}, { root: true } );
if (res.data.filters_arguments && res.data.filters_arguments.length > 0)
dispatch('search/setFilterTags', res.data.filters_arguments, { root: true } );
else
dispatch('search/cleanFilterTags', [], { root: true } );
})
.catch((thrown) => {
if (axios.isCancel(thrown)) {

View File

@ -83,4 +83,8 @@ export const setAttachments = ( state, attachments ) => {
export const cleanAttachments = (state) => {
state.attachments = [];
}
export const setFilterTags = ( state, filterTags ) => {
state.filter_tags = filterTags;
}

View File

@ -55,6 +55,10 @@ export const remove_taxquery = ( { commit }, filter ) => {
commit('removeTaxQuery', filter );
};
export const remove_postin = ( { commit } ) => {
commit('removePostIn');
};
// Pagination queries
export const setTotalItems = ({ commit }, total ) => {
commit('setTotalItems', total);
@ -157,6 +161,11 @@ export const addFilterTag = ( { commit }, filterTag ) => {
commit('addFilterTag', filterTag);
};
// Set filter tags
export const setFilterTags = ({ commit }, filterTags ) => {
commit('setFilterTags', filterTags );
};
// Remove filter tag
export const removeFilterTag = ( { commit }, filterTag ) => {
commit('removeFilterTag', filterTag);
@ -167,8 +176,8 @@ export const cleanFilterTags = ( { commit } ) => {
commit('cleanFilterTags');
};
export const cleanMetaQueries = ( { commit } ) => {
commit('cleanMetaQueries');
export const cleanMetaQueries = ( { commit }, { keepCollections } ) => {
commit('cleanMetaQueries', { keepCollections });
};
export const cleanTaxQueries = ({ commit }) => {

View File

@ -120,6 +120,10 @@ export const removeTaxQuery = ( state, filter ) => {
}
};
export const removePostIn = ( state ) => {
delete state.postquery.postin;
};
export const setTotalItems = ( state, total ) => {
state.totalItems = total;
};
@ -160,7 +164,7 @@ export const setOrderByName = ( state, orderByName ) => {
};
export const addFilterTag = ( state, filterTag ) => {
state.filter_tags = ( ! state.filter_tags) ? [] : state.filter_tags;
state.filter_tags = ( ! state.filter_tags) ? [] : state.filter_tags;
let index = state.filter_tags.findIndex( tag => tag.filterId == filterTag.filterId);
if (index >= 0)
@ -169,21 +173,43 @@ export const addFilterTag = ( state, filterTag ) => {
state.filter_tags.push(filterTag);
};
export const setFilterTags = ( state, filterArguments ) => {
let filterTags = filterArguments.map((aFilterArgument) => {
return {
filterId: aFilterArgument.filter ? aFilterArgument.filter.id : null,
label: aFilterArgument.label,
value: aFilterArgument.value,
taxonomy: (aFilterArgument.metadatum &&
aFilterArgument.metadatum.metadata_type_object &&
aFilterArgument.metadatum.metadata_type_object.options &&
aFilterArgument.metadatum.metadata_type_object.options.taxonomy
) ? aFilterArgument.metadatum.metadata_type_object.options.taxonomy : '',
argType: aFilterArgument.arg_type ? aFilterArgument.arg_type : '',
metadatumId: aFilterArgument.metadatum && aFilterArgument.metadatum.metadatum_id ? aFilterArgument.metadatum.metadatum_id : '',
metadatumName: aFilterArgument.metadatum && aFilterArgument.metadatum.metadatum_name ? aFilterArgument.metadatum.metadatum_name : ''
}
});
state.filter_tags = filterTags;
};
export const removeFilterTag = ( state, filterTag ) => {
state.filter_tags = ( ! state.filter_tags ) ? [] : state.filter_tags;
let index = state.filter_tags.findIndex( tag => tag.filterId == filterTag.filterId);
if (index >= 0)
state.filter_tags.splice(index, 1);
};
export const cleanFilterTags = ( state ) => {
state.filter_tags = [];
};
export const cleanMetaQueries = (state) => {
state.postquery.metaquery = [];
export const cleanMetaQueries = (state, { keepCollections }) => {
if (keepCollections === true)
state.postquery.metaquery = state.postquery.metaquery.filter(aMetaQuery => aMetaQuery.key === 'collection_id');
else
state.postquery.metaquery = [];
};
export const cleanTaxQueries = (state) => {

View File

@ -346,7 +346,7 @@
.pagination {
font-size: 1.1em;
flex-wrap: wrap;
flex-wrap: nowrap;
.pagination-list {
margin-bottom: 0.5em;

View File

@ -24,6 +24,13 @@ $pswp__include-minimal-style: true !default;
height: auto;
display: block;
background-color: var(--tainacan-media-background, transparent);
box-sizing: border-box;
.swiper-slide,
.swiper-slide::after,
.swiper-slide::before {
box-sizing: border-box;
}
}
/* Style valid for both cases of carousel, main and thumbs */
@ -68,6 +75,9 @@ $pswp__include-minimal-style: true !default;
audio {
pointer-events: none;
}
a {
cursor: zoom-in !important;
}
}
}
li.swiper-slide {

View File

@ -296,6 +296,7 @@ return apply_filters( 'tainacan-i18n', [
'label_send_to_trash' => __( 'Send to trash', 'tainacan' ),
'label_keep_on_trash' => __( 'Keep on trash', 'tainacan' ),
'label_delete_selected_taxonomies' => __( 'Delete selected taxonomies', 'tainacan' ),
'label_view_only_selected_items' => __( 'View only selected items', 'tainacan' ),
'label_bulk_edit_selected_items' => __( 'Bulk edit selected items', 'tainacan' ),
'label_sequence_edit_selected_items' => __( 'Edit selected items in sequence', 'tainacan' ),
'label_edit_selected_taxonomies' => __( 'Edit selected taxonomies', 'tainacan' ),
@ -417,8 +418,8 @@ return apply_filters( 'tainacan-i18n', [
'label_selected_items' => __( 'Selected items', 'tainacan' ),
'label_selected_item' => __( 'Selected item', 'tainacan' ),
'label_all_items_selected' => __( 'All items selected', 'tainacan' ),
/* translators: Before this there is a number of items that are present in another listing */
'label_+_%s_other_listings' => __( '+ %s in other listings', 'tainacan' ),
/* translators: Here there is a number of items that are selected in this listing */
'label_%s_on_this_page' => __( '%s on this page', 'tainacan' ),
'label_all_metadatum_values' => __( 'All metadatum values', 'tainacan' ),
'label_selected_metadatum_values' => __( 'Selected metadatum values', 'tainacan' ),
/* translators: 'n.' here comes from 'number' */
@ -606,6 +607,7 @@ return apply_filters( 'tainacan-i18n', [
'label_document_option_iframe_width' => __( 'Iframe width (px)', 'tainacan'),
'label_document_option_is_image' => __( 'Is link to external image', 'tainacan' ),
'label_limit_max_values' => __( 'Limit the amount of multiple values', 'tainacan'),
'label_items_selection' => __( 'Items selection', 'tainacan'),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),