Merge branch 'develop' of https://github.com/tainacan/tainacan into develop

This commit is contained in:
vnmedeiros 2019-06-04 15:20:11 -03:00
commit 7b3568c912
13 changed files with 492 additions and 6 deletions

1
.gitignore vendored
View File

@ -19,6 +19,7 @@ last-package-build.md5
src/admin/scss/.sass-cache
src/assets/css/tainacan-admin.css
src/assets/css/tainacan-admin.css.map
src/assets/report.html
cypress/videos
cypress/screenshots
.vscode

View File

@ -46,6 +46,7 @@
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17",
"webpack": "^4.22.0",
"webpack-bundle-analyzer": "^3.3.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": ">=3.1.11"
}

View File

@ -25,6 +25,7 @@ import FormSelectbox from '../../classes/metadata-types/selectbox/FormSelectbox.
import FilterCustomInterval from '../../classes/filter-types/custom-interval/CustomInterval.vue';
import FilterNumeric from '../../classes/filter-types/numeric/Numeric.vue';
import FilterDate from '../../classes/filter-types/date/Date.vue';
import FilterSelectbox from '../../classes/filter-types/selectbox/Selectbox.vue';
import FilterAutocomplete from '../../classes/filter-types/autocomplete/Autocomplete.vue';
import FilterCheckbox from '../../classes/filter-types/checkbox/Checkbox.vue';
@ -34,6 +35,7 @@ import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox
import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue';
import FormNumeric from '../../classes/filter-types/numeric/FormNumeric.vue';
import FormDate from '../../classes/filter-types/date/FormDate.vue';
import TainacanFormItem from '../../classes/metadata-types/tainacan-form-item.vue';
import TainacanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue';
@ -78,6 +80,7 @@ Vue.component('tainacan-filter-item', TainacanFiltersList);
/* Filters */
Vue.component('tainacan-filter-custom-interval', FilterCustomInterval);
Vue.component('tainacan-filter-numeric', FilterNumeric);
Vue.component('tainacan-filter-date', FilterDate);
Vue.component('tainacan-filter-selectbox', FilterSelectbox);
Vue.component('tainacan-filter-autocomplete', FilterAutocomplete);
Vue.component('tainacan-filter-checkbox', FilterCheckbox);
@ -86,6 +89,7 @@ Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox);
Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput);
/* Filter Metadata Option forms */
Vue.component('tainacan-filter-form-numeric', FormNumeric);
Vue.component('tainacan-filter-form-date', FormDate);
/* Others */
Vue.component('help-button', HelpButton);

View File

@ -7,6 +7,7 @@ import VueMasonry from 'vue-masonry-css';
// Custom elements
import FilterCustomInterval from '../../classes/filter-types/custom-interval/CustomInterval.vue';
import FilterNumeric from '../../classes/filter-types/numeric/Numeric.vue';
import FilterDate from '../../classes/filter-types/date/Date.vue';
import FilterSelectbox from '../../classes/filter-types/selectbox/Selectbox.vue';
import FilterAutocomplete from '../../classes/filter-types/autocomplete/Autocomplete.vue';
import FilterCheckbox from '../../classes/filter-types/checkbox/Checkbox.vue';
@ -46,6 +47,7 @@ Vue.component('tainacan-filter-item', TaincanFiltersList);
/* Filters */
Vue.component('tainacan-filter-custom-interval', FilterCustomInterval);
Vue.component('tainacan-filter-numeric', FilterNumeric);
Vue.component('tainacan-filter-date', FilterDate);
Vue.component('tainacan-filter-selectbox', FilterSelectbox);
Vue.component('tainacan-filter-autocomplete', FilterAutocomplete);
Vue.component('tainacan-filter-checkbox', FilterCheckbox);

View File

@ -456,6 +456,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_drag_and_drop_metadatum_sort' => __( 'Drag and drop to change metadatum order', 'tainacan' ),
'instruction_select_step_options_to_show' => __( 'Select which Step values to show', 'tainacan' ),
'instruction_select_maximum_options_to_show' => __( 'Select which amount of maximum of options to show', 'tainacan' ),
'instruction_select_a_date' => __( 'Select a date', 'tainacan' ),
// Info. Other feedback to user.
'info_%s_tab_all' => __( 'Every published %s, including those visible only to editors.', 'tainacan' ),
@ -610,6 +611,7 @@ return apply_filters( 'tainacan-admin-i18n', [
// Tainacan Filter Types
'tainacan-filter-custom-interval' => __( 'Custom Interval', 'tainacan' ),
'tainacan-filter-numeric' => __( 'Numeric', 'tainacan' ),
'tainacan-filter-date' => __( 'Date', 'tainacan' ),
'tainacan-filter-selectbox' => __( 'Select Box', 'tainacan' ),
'tainacan-filter-autocomplete' => __( 'Autocomplete', 'tainacan' ),
'tainacan-filter-taginput' => __( 'Tag Input', 'tainacan' ),

View File

@ -0,0 +1,256 @@
<template>
<div class="date-filter-container">
<b-dropdown
:mobile-modal="true"
@input="onChangeComparator($event)"
aria-role="list">
<button
:aria-label="$i18n.get('label_comparator')"
class="button is-white"
slot="trigger">
<span class="icon is-small">
<i v-html="comparatorSymbol" />
</span>
<span class="icon">
<i class="tainacan-icon tainacan-icon-20px tainacan-icon-arrowdown" />
</span>
</button>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '=' }"
:value="'='"
aria-role="listitem">
&#61;&nbsp; {{ $i18n.get('is_equal_to') }}
</b-dropdown-item>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '!=' }"
:value="'!='"
aria-role="listitem">
&#8800;&nbsp; {{ $i18n.get('is_not_equal_to') }}
</b-dropdown-item>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '>' }"
:value="'>'"
aria-role="listitem">
&#62;&nbsp; {{ $i18n.get('greater_than') }}
</b-dropdown-item>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '>=' }"
:value="'>='"
aria-role="listitem">
&#8805;&nbsp; {{ $i18n.get('greater_than_or_equal_to') }}
</b-dropdown-item>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '<' }"
:value="'<'"
aria-role="listitem">
&#60;&nbsp; {{ $i18n.get('less_than') }}
</b-dropdown-item>
<b-dropdown-item
role="button"
:class="{ 'is-active': comparator == '<=' }"
:value="'<='"
aria-role="listitem">
&#8804;&nbsp; {{ $i18n.get('less_than_or_equal_to') }}
</b-dropdown-item>
</b-dropdown>
<b-datepicker
position="is-bottom-left"
:aria-labelledby="labelId"
:placeholder="$i18n.get('instruction_select_a_date')"
v-model="value"
@input="validate_values()"
@focus="isTouched = true"
size="is-small"
icon="calendar-today"/>
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import { wpAjax } from "../../../admin/js/mixins";
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);
},
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,
},
computed: {
comparatorSymbol() {
switch(this.comparator) {
case '=': return '&#61;';
case '!=': return '&#8800;';
case '>': return '&#62;';
case '>=': return '&#8805;';
case '<': return '&#60;';
case '<=': return '&#8804;';
default: return '';
}
}
},
methods: {
validate_values: _.debounce( function (){
if (this.value == undefined)
this.value = new Date();
else
return;
this.emit();
}, 1000),
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 metadata = this.query.metaquery[ index ];
if ( metadata.value && metadata.value.length > 0)
this.value = Array.isArray(metadata.value) ? Number(metadata.value[0]) : Number(metadata.value);
if ( metadata.compare)
this.comparator = metadata.compare;
if (this.value != undefined) {
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + this.value
});
}
} else {
return false;
}
},
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;
},
// emit the operation for listeners
emit() {
if ( this.value === null || this.value === '')
return;
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
});
this.$eventBusSearch.$emit( 'sendValuesToTags', {
filterId: this.filter.id,
value: this.comparator + ' ' + this.value
});
},
onChangeComparator(newComparator) {
this.comparator = newComparator;
this.emit();
}
},
beforeDestroy() {
this.$eventBusSearch.$off('removeFromFilterTag', this.cleanSearchFromTags);
}
}
</script>
<style lang="scss" scoped>
.date-filter-container {
display: flex;
height: 28px;
.dropdown {
width: auto;
.dropdown-trigger button {
padding: 0 0.5rem !important;
height: 28px !important;
i:not(.tainacan-icon-arrowdown) {
margin-top: -3px;
font-size: 1.25rem;
font-style: normal;
color: #555758;
}
}
}
.b-numberinput.is-grouped {
flex-grow: 1;
}
}
</style>

View File

@ -0,0 +1,100 @@
<template>
<div>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-date', 'step') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-date', 'step')"
:message="$i18n.getHelperMessage('tainacan-filter-date', 'step')"/>
</label>
<div
v-if="!showEditStepOptions"
class="is-flex">
<b-select
name="step_options"
v-model="step"
@input="onUpdateStep"
:placeholder="$i18n.get('instruction_select_step_options_to_show')">
<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="onUpdateStep"
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>
<script>
export default {
props: {
filter: {
type: Object
},
value: [String, Number, Array],
id: '',
disabled: false,
},
data() {
return {
step: [Number, String],
showEditStepOptions: false
}
},
methods: {
onUpdateStep(value) {
this.$emit('input', { step: value });
},
},
created() {
this.step = this.value && this.value.step ? this.value.step : 1;
}
}
</script>

View File

@ -0,0 +1,112 @@
<?php
namespace Tainacan\Filter_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class TainacanFilterType
*/
class Date extends Filter_Type {
function __construct(){
$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([
'step' => 1
]);
$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</a>
<a class="dropdown-item">&nbsp; Not equal</a>
<a class="dropdown-item">&gt;&nbsp; Greater than</a>
<a class="dropdown-item">&nbsp; Greater than or equal to</a>
<a class="dropdown-item">&lt;&nbsp; Less than</a>
<a class="dropdown-item">&nbsp; Less than or equal to</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 filter control buttons.', 'tainacan' ),
]
];
}
/**
* @param $filter
* @return string
* @internal param $metadatum
*/
public function render( $filter ){
return '<tainacan-filter-date
step="' . $this->get_option('step') . '"
name="'.$filter->get_name().'"
collection_id="'.$filter->get_collection_id().'"
metadatum_id="'.$filter->get_metadatum_id().'"></tainacan-filter-custom-interval>';
}
/**
* @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')
];
}
return true;
}
}

View File

@ -174,6 +174,7 @@
max-width: 165px !important;
border-radius: 2px !important;
padding: 0px;
max-height: inherit;
}
}
}

View File

@ -179,8 +179,8 @@
if( metadata.length > 0 ){
this.metadata = [];
for( let metadatum of metadata ){
if( metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Relationship"){
for (let metadatum of metadata) {
if (metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Relationship" && metadatum.metadata_type !== "Tainacan\\Metadata_Types\\Taxonomy") {
this.metadata.push( metadatum );
this.hasMetadata = true;
this.checkMetadata()

View File

@ -134,6 +134,7 @@ $Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
//register filter type
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Custom_Interval');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Selectbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Autocomplete');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Taginput');

View File

@ -212,7 +212,7 @@
<script>
import axios from 'axios';
import qs from 'qs';
import { debounce } from 'lodash';
import debounce from 'lodash/debounce.js';
export default {
name: "DynamicItemsListTheme",

View File

@ -1,6 +1,7 @@
let path = require('path');
let webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: {
@ -38,7 +39,7 @@ module.exports = {
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
exclude: /node_modules/
},
{
test: /\.(png|jpg|jpeg|gif|eot|ttf|otf|woff|woff2|svg|svgz)(\?.+)?$/,
@ -113,7 +114,7 @@ if (production === true) {
module.exports.resolve = {
alias: {
'vue$': 'vue/dist/vue.min',
'swiper$': 'swiper/dist/js/swiper.js'
'swiper$': 'swiper/dist/js/swiper.min.js'
}
}
} else {
@ -128,12 +129,17 @@ if (production === true) {
},
}),
new VueLoaderPlugin(),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static'
})
];
module.exports.resolve = {
alias: {
//'vue$': 'vue/dist/vue.esm' // uncomment this and comment the above to use vue dev tools (can cause type error)
'vue$': 'vue/dist/vue.min'
'vue$': 'vue/dist/vue.min',
'swiper$': 'swiper/dist/js/swiper.min.js'
}
}
}