Basic logic for intersection filters without range by now. #887.

This commit is contained in:
mateuswetah 2024-06-07 15:57:20 -03:00
parent cd15cd1b78
commit 0ff12f3b67
8 changed files with 336 additions and 124 deletions

View File

@ -6,9 +6,11 @@
:message="metadataMessage"> :message="metadataMessage">
<label class="label is-inline"> <label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id') }}<span :class="metadataType">&nbsp;*&nbsp;</span> {{ $i18n.getHelperTitle('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id') }}<span :class="metadataType">&nbsp;*&nbsp;</span>
<span style="font-size: 1.35em;">
<help-button <help-button
:title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id')" :title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id')"
:message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id')" /> :message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'secondary_filter_metadatum_id')" />
</span>
</label> </label>
<b-select <b-select
v-model="secondDateMetadatumId" v-model="secondDateMetadatumId"
@ -29,17 +31,22 @@
</option> </option>
</b-select> </b-select>
</b-field> </b-field>
<div style="column-count: 2;"> <fieldset
<b-field :addons="false"> v-if="secondDateMetadatumId"
<label class="intersection-explainer-section">
style="line-height: normal;" <legend>
class="label is-inline"> <p>
{{ $i18n.getHelperTitle('tainacan-filter-dates-intersection', 'first_comparator') }}<span>&nbsp;*&nbsp;</span> <strong>{{ $i18n.get('info_intersection_explainer') }}</strong>
<span style="font-size: 1.35em;">
<help-button <help-button
:title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'first_comparator')" :title="$i18n.get('label_comparators')"
:message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'first_comparator')" /> :message="$i18n.get('info_intersection_rules')" />
</label> </span>
</p>
</legend>
<b-field :addons="false">
<b-select <b-select
v-if="showEditFirstComparatorOptions"
v-model="firstComparator" v-model="firstComparator"
@update:model-value="emitValues()"> @update:model-value="emitValues()">
<option <option
@ -48,17 +55,50 @@
:value="comparatorKey" :value="comparatorKey"
v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" /> v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" />
</b-select> </b-select>
<strong
v-else
v-html="comparatorsObject[firstComparator].symbol" />
<p v-if="filter.metadatum">
&nbsp;
<em>{{ filter.metadatum.metadatum_name }}</em>
</p>
<button
v-if="!showEditFirstComparatorOptions"
class="button is-white is-pulled-right"
@click.prevent="showEditFirstComparatorOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary" />
</span>
</button>
<button
v-else
class="button is-white is-pulled-right"
@click.prevent="showEditFirstComparatorOptions = false">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-approved has-text-secondary" />
</span>
</button>
</b-field> </b-field>
<div class="logic-divider">
<span>{{ $i18n.get('label_and') }}</span>
</div>
<b-field :addons="false"> <b-field :addons="false">
<label
style="line-height: normal;"
class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-dates-intersection', 'second_comparator') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'second_comparator')"
:message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'second_comparator')" />
</label>
<b-select <b-select
v-if="showEditSecondComparatorOptions"
v-model="secondComparator" v-model="secondComparator"
@update:model-value="emitValues()"> @update:model-value="emitValues()">
<option <option
@ -67,9 +107,44 @@
:value="comparatorKey" :value="comparatorKey"
v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" /> v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" />
</b-select> </b-select>
<strong
v-else
v-html="comparatorsObject[secondComparator].symbol" />
<p>&nbsp;<em>{{ secondDateMetadatumName }}</em></p>
<button
v-if="!showEditSecondComparatorOptions"
class="button is-white is-pulled-right"
@click.prevent="showEditSecondComparatorOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary" />
</span>
</button>
<button
v-else
class="button is-white is-pulled-right"
@click.prevent="showEditSecondComparatorOptions = false">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-approved has-text-secondary" />
</span>
</button>
</b-field> </b-field>
</div> </fieldset>
<b-field <!-- Much more complicated logic, will be possible if we implement #889 -->
<!-- <b-field
:addons="false" :addons="false"
:label="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'accept_date_interval')" :label="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'accept_date_interval')"
style="margin-top: 1.125rem;" style="margin-top: 1.125rem;"
@ -88,7 +163,7 @@
:title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'accept_date_interval')" :title="$i18n.getHelperTitle('tainacan-filter-dates-intersection', 'accept_date_interval')"
:message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'accept_date_interval')" /> :message="$i18n.getHelperMessage('tainacan-filter-dates-intersection', 'accept_date_interval')" />
</b-switch> </b-switch>
</b-field> </b-field> -->
</div> </div>
</template> </template>
@ -115,7 +190,9 @@
firstComparator: String, firstComparator: String,
secondComparator: String, secondComparator: String,
comparatorsObject: {}, comparatorsObject: {},
acceptDateInterval: String acceptDateInterval: String,
showEditFirstComparatorOptions: false,
showEditSecondComparatorOptions: false
} }
}, },
watch: { watch: {
@ -205,3 +282,37 @@
} }
} }
</script> </script>
<style lang="scss" scoped>
.intersection-explainer-section {
margin-top: 1.25rem;
padding: 0.75em 0.75em 0.25em 0.75em;
border: 1px solid var(--tainacan-gray1);
legend {
margin: -0.75em 0 0em 0;
background-color: var(--tainacan-background-color);
padding: 5px 5px 5px 0px;
}
.field {
display: flex;
gap: 0.5em;
margin: 0 -0.5em 0.5em 0em;
align-items: center;
strong {
margin-left: 0.75em;
}
}
button {
border-radius: 100em !important;
margin-left: auto;
}
.logic-divider {
display: none;
}
}
</style>

View File

@ -159,11 +159,16 @@
if (index >= 0) { if (index >= 0) {
let metadata = this.query.metaquery[ index ]; let metadata = this.query.metaquery[ index ];
if (metadata.value && metadata.value.length > 0) { if (metadata.value ) {
if ( Array.isArray(metadata.value) && metadata.value.length > 0 ) {
const dateValueInit = new Date(metadata.value[0].replace(/-/g, '/')); const dateValueInit = new Date(metadata.value[0].replace(/-/g, '/'));
this.dateInit = moment(dateValueInit, moment.ISO_8601).toDate(); this.dateInit = moment(dateValueInit, moment.ISO_8601).toDate();
const dateValueEnd = new Date(metadata.value[1].replace(/-/g, '/')); const dateValueEnd = new Date(metadata.value[1].replace(/-/g, '/'));
this.dateEnd = moment(dateValueEnd, moment.ISO_8601).toDate(); this.dateEnd = moment(dateValueEnd, moment.ISO_8601).toDate();
} else {
const dateValueInit = new Date(metadata.value.replace(/-/g, '/'));
this.dateInit = moment(dateValueInit, moment.ISO_8601).toDate();
}
} }
} else { } else {
this.dateInit = null; this.dateInit = null;
@ -186,13 +191,14 @@
values = [ dateInit, dateEnd ]; values = [ dateInit, dateEnd ];
} }
if ( this.filterTypeOptions.accept_date_interval !== 'yes' ) {
this.$emit('input', { this.$emit('input', {
filter: 'intersection', filter: 'intersection',
type: 'DATE', type: 'DATE',
compare: this.filterTypeOptions.first_comparator, compare: this.filterTypeOptions.first_comparator,
metadatum_id: this.metadatumId, metadatum_id: this.metadatumId,
collection_id: this.collectionId, collection_id: this.collectionId,
value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0] value: values[0]
}); });
this.$emit('input', { this.$emit('input', {
filter: 'intersection', filter: 'intersection',
@ -200,9 +206,12 @@
compare: this.filterTypeOptions.second_comparator, compare: this.filterTypeOptions.second_comparator,
metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id,
collection_id: this.collectionId, collection_id: this.collectionId,
value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0], value: values[0],
secondary: true secondary: true
}); });
} else {
// Much more complicated logic to be implemented in the future. See #889
}
} }
} }
} }

View File

@ -34,17 +34,6 @@ class Dates_Intersection extends Filter_Type {
</div> </div>
</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> </div>
'); ');

View File

@ -3,9 +3,11 @@
<b-field :addons="false"> <b-field :addons="false">
<label class="label is-inline"> <label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step') }}<span>&nbsp;*&nbsp;</span> {{ $i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step') }}<span>&nbsp;*&nbsp;</span>
<span style="font-size: 1.35em;">
<help-button <help-button
:title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step')" :title="$i18n.getHelperTitle('tainacan-filter-numeric-interval', 'step')"
:message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'step')" /> :message="$i18n.getHelperMessage('tainacan-filter-numeric-interval', 'step')" />
</span>
</label> </label>
<div <div
v-if="!showEditStepOptions" v-if="!showEditStepOptions"
@ -116,17 +118,22 @@
</option> </option>
</b-select> </b-select>
</b-field> </b-field>
<div style="column-count: 2;"> <fieldset
<b-field :addons="false"> v-if="secondNumericMetadatumId"
<label class="intersection-explainer-section">
style="line-height: normal;" <legend>
class="label is-inline"> <p>
{{ $i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'first_comparator') }}<span>&nbsp;*&nbsp;</span> <strong>{{ $i18n.get('info_intersection_explainer') }}</strong>
<span style="font-size: 1.35em;">
<help-button <help-button
:title="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'first_comparator')" :title="$i18n.get('label_comparators')"
:message="$i18n.getHelperMessage('tainacan-filter-numerics-intersection', 'first_comparator')" /> :message="$i18n.get('info_intersection_rules')" />
</label> </span>
</p>
</legend>
<b-field :addons="false">
<b-select <b-select
v-if="showEditFirstComparatorOptions"
v-model="firstComparator" v-model="firstComparator"
@update:model-value="emitValues()"> @update:model-value="emitValues()">
<option <option
@ -135,17 +142,50 @@
:value="comparatorKey" :value="comparatorKey"
v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" /> v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" />
</b-select> </b-select>
<strong
v-else
v-html="comparatorsObject[firstComparator].symbol" />
<p v-if="filter.metadatum">
&nbsp;
<em>{{ filter.metadatum.metadatum_name }}</em>
</p>
<button
v-if="!showEditFirstComparatorOptions"
class="button is-white is-pulled-right"
@click.prevent="showEditFirstComparatorOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary" />
</span>
</button>
<button
v-else
class="button is-white is-pulled-right"
@click.prevent="showEditFirstComparatorOptions = false">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-approved has-text-secondary" />
</span>
</button>
</b-field> </b-field>
<div class="logic-divider">
<span>{{ $i18n.get('label_and') }}</span>
</div>
<b-field :addons="false"> <b-field :addons="false">
<label
style="line-height: normal;"
class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'second_comparator') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'second_comparator')"
:message="$i18n.getHelperMessage('tainacan-filter-numerics-intersection', 'second_comparator')" />
</label>
<b-select <b-select
v-if="showEditSecondComparatorOptions"
v-model="secondComparator" v-model="secondComparator"
@update:model-value="emitValues()"> @update:model-value="emitValues()">
<option <option
@ -154,9 +194,45 @@
:value="comparatorKey" :value="comparatorKey"
v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" /> v-html="comparatorObject.symbol + '&nbsp;' + comparatorObject.label" />
</b-select> </b-select>
<strong
v-else
v-html="comparatorsObject[secondComparator].symbol" />
<p>&nbsp;<em>{{ secondNumericMetadatumName }}</em></p>
<button
v-if="!showEditSecondComparatorOptions"
class="button is-white is-pulled-right"
@click.prevent="showEditSecondComparatorOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary" />
</span>
</button>
<button
v-else
class="button is-white is-pulled-right"
@click.prevent="showEditSecondComparatorOptions = false">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-approved has-text-secondary" />
</span>
</button>
</b-field> </b-field>
</div> </fieldset>
<b-field
<!-- Much more complicated logic, will be possible if we implement #889 -->
<!-- <b-field
:addons="false" :addons="false"
:label="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'accept_numeric_interval')" :label="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'accept_numeric_interval')"
style="margin-top: 1.125rem;" style="margin-top: 1.125rem;"
@ -175,7 +251,7 @@
:title="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'accept_numeric_interval')" :title="$i18n.getHelperTitle('tainacan-filter-numerics-intersection', 'accept_numeric_interval')"
:message="$i18n.getHelperMessage('tainacan-filter-numerics-intersection', 'accept_numeric_interval')" /> :message="$i18n.getHelperMessage('tainacan-filter-numerics-intersection', 'accept_numeric_interval')" />
</b-switch> </b-switch>
</b-field> </b-field> -->
</div> </div>
</template> </template>
@ -204,7 +280,9 @@
firstComparator: String, firstComparator: String,
secondComparator: String, secondComparator: String,
comparatorsObject: {}, comparatorsObject: {},
acceptNumericInterval: String acceptNumericInterval: String,
showEditFirstComparatorOptions: false,
showEditSecondComparatorOptions: false
} }
}, },
watch: { watch: {
@ -296,3 +374,37 @@
} }
} }
</script> </script>
<style lang="scss" scoped>
.intersection-explainer-section {
margin-top: 1.25rem;
padding: 0.75em 0.75em 0.25em 0.75em;
border: 1px solid var(--tainacan-gray1);
legend {
margin: -0.75em 0 0em 0;
background-color: var(--tainacan-background-color);
padding: 5px 5px 5px 0px;
}
.field {
display: flex;
gap: 0.5em;
margin: 0 -0.5em 0.5em 0em;
align-items: center;
strong {
margin-left: 0.75em;
}
}
button {
border-radius: 100em !important;
margin-left: auto;
}
.logic-divider {
display: none;
}
}
</style>

View File

@ -94,6 +94,7 @@
let values = [ this.valueInit, this.valueEnd ]; let values = [ this.valueInit, this.valueEnd ];
let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL(20,3)' : 'NUMERIC'; let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL(20,3)' : 'NUMERIC';
if ( this.filterTypeOptions.accept_numeric_interval !== 'yes' ) {
this.$emit('input', { this.$emit('input', {
filter: 'intersection', filter: 'intersection',
type: type, type: type,
@ -110,6 +111,9 @@
collection_id: this.collectionId, collection_id: this.collectionId,
value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0] value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0]
}); });
} else {
// Much more complicated logic to be implemented in the future. See #889
}
}, },
updateSelectedValues(){ updateSelectedValues(){
if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) ) if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) )
@ -119,9 +123,13 @@
if ( index >= 0 ) { if ( index >= 0 ) {
let metaquery = this.query.metaquery[ index ]; let metaquery = this.query.metaquery[ index ];
if ( metaquery.value && metaquery.value.length > 1 ) { if ( metaquery.value ) {
if ( Array.isArray(metaquery.value) && metaquery.value.length > 1 ) {
this.valueInit = new Number(metaquery.value[0]); this.valueInit = new Number(metaquery.value[0]);
this.valueEnd = new Number(metaquery.value[1]); this.valueEnd = new Number(metaquery.value[1]);
} else {
this.valueInit = new Number(metaquery.value);
}
} }
} else { } else {
this.valueInit = null; this.valueInit = null;

View File

@ -44,26 +44,6 @@ class Numerics_Intersection extends Filter_Type {
</button> </button>
</p> </p>
</div> </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> </div>
'); ');
} }

View File

@ -976,7 +976,7 @@ export default {
} }
&:not(.available-metadata-area){ &:not(.available-metadata-area){
margin-right: var(--tainacan-one-column); margin-right: 30px;
flex-grow: 2; flex-grow: 2;
@media screen and (max-width: 769px) { @media screen and (max-width: 769px) {

View File

@ -529,6 +529,7 @@ return apply_filters( 'tainacan-i18n', [
'label_view_all_%s_collections' => __( 'View all %s collections', 'tainacan' ), 'label_view_all_%s_collections' => __( 'View all %s collections', 'tainacan' ),
'label_view_collections_list' => __( 'View collections list', 'tainacan' ), 'label_view_collections_list' => __( 'View collections list', 'tainacan' ),
'label_comparator' => __( 'Comparator', 'tainacan' ), 'label_comparator' => __( 'Comparator', 'tainacan' ),
'label_comparators' => __( 'Comparators', 'tainacan' ),
'label_table_of_items' => __( 'Table of Items', 'tainacan' ), 'label_table_of_items' => __( 'Table of Items', 'tainacan' ),
'label_create_another_item' => __( 'Create another item', 'tainacan' ), 'label_create_another_item' => __( 'Create another item', 'tainacan' ),
'label_recent_collections' => __( 'Recent Collections', 'tainacan' ), 'label_recent_collections' => __( 'Recent Collections', 'tainacan' ),
@ -1066,6 +1067,8 @@ return apply_filters( 'tainacan-i18n', [
'info_terms_creation_failed_due_to_value_%s' => __( 'Terms creation failed due to value: %s.', 'tainacan' ), 'info_terms_creation_failed_due_to_value_%s' => __( 'Terms creation failed due to value: %s.', 'tainacan' ),
'info_terms_creation_failed_due_to_values_%s' => __( 'Terms creation failed due to values: %s.', 'tainacan' ), 'info_terms_creation_failed_due_to_values_%s' => __( 'Terms creation failed due to values: %s.', 'tainacan' ),
'info_autodraft_updated' => __( 'Autodraft updated. Please create the item to keep your changes.', 'tainacan' ), 'info_autodraft_updated' => __( 'Autodraft updated. Please create the item to keep your changes.', 'tainacan' ),
'info_intersection_explainer' => __( 'Will show items if the selected value is:', 'tainacan' ),
'info_intersection_rules' => __( 'The value must match both rules to appear in the filter.', 'tainacan' ),
/* Activity actions */ /* Activity actions */
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'), 'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),