From 161fc5cc9f1267dbea4078602a902f6d25eb26e0 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Fri, 31 May 2024 09:40:38 -0300 Subject: [PATCH 01/39] Begins implementation of enabled comparators for date filter. #886. --- .../edition/filter-edition-form.vue | 2 + .../components/filter-types/date/FormDate.vue | 80 +++++++++++++ .../filter-types/date/TainacanFilterDate.vue | 113 ++++++++---------- .../filter-types/date/class-tainacan-date.php | 33 +++++ 4 files changed, 163 insertions(+), 65 deletions(-) create mode 100644 src/views/admin/components/filter-types/date/FormDate.vue diff --git a/src/views/admin/components/edition/filter-edition-form.vue b/src/views/admin/components/edition/filter-edition-form.vue index e3c609502..b13491c9f 100644 --- a/src/views/admin/components/edition/filter-edition-form.vue +++ b/src/views/admin/components/edition/filter-edition-form.vue @@ -249,6 +249,7 @@ import { nextTick } from 'vue'; import { mapActions } from 'vuex'; import { formHooks } from "../../js/mixins"; +import FormFilterDate from '../filter-types/date/FormDate.vue'; import FormFilterNumeric from '../filter-types/numeric/FormNumeric.vue'; import FormFilterNumericInterval from '../filter-types/numeric-interval/FormNumericInterval.vue'; import FormFilterNumericListInterval from '../filter-types/numeric-list-interval/FormNumericListInterval.vue'; @@ -256,6 +257,7 @@ import FormFilterNumericListInterval from '../filter-types/numeric-list-interval export default { name: 'FilterEditionForm', components: { + 'tainacan-filter-form-date': FormFilterDate, 'tainacan-filter-form-numeric': FormFilterNumeric, 'tainacan-filter-form-numeric-interval': FormFilterNumericInterval, 'tainacan-filter-form-numeric-list-interval': FormFilterNumericListInterval diff --git a/src/views/admin/components/filter-types/date/FormDate.vue b/src/views/admin/components/filter-types/date/FormDate.vue new file mode 100644 index 000000000..feab75549 --- /dev/null +++ b/src/views/admin/components/filter-types/date/FormDate.vue @@ -0,0 +1,80 @@ + + + \ No newline at end of file diff --git a/src/views/admin/components/filter-types/date/TainacanFilterDate.vue b/src/views/admin/components/filter-types/date/TainacanFilterDate.vue index 5c6e30649..749dc0fe9 100644 --- a/src/views/admin/components/filter-types/date/TainacanFilterDate.vue +++ b/src/views/admin/components/filter-types/date/TainacanFilterDate.vue @@ -10,66 +10,25 @@ :aria-label="$i18n.get('label_comparator')" class="button is-white"> - + - - =  {{ $i18n.get('is_equal_to') }} - - - ≠  {{ $i18n.get('is_not_equal_to') }} - - - >  {{ $i18n.get('after') }} - - - ≥  {{ $i18n.get('after_or_on_day') }} - - - <  {{ $i18n.get('before') }} - - - ≤  {{ $i18n.get('before_or_on_day') }} - + - ': return '>'; - case '>=': return '≥'; - case '<': return '<'; - case '<=': return '≤'; - default: return ''; - } } }, watch: { @@ -156,6 +105,40 @@ deep: true, }, }, + created() { + this.comparatorsObject = { + '=': { + symbol: '=', + label: this.$i18n.get('is_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('=') < 0 ? 'no' : 'yes' + }, + '!=': { + symbol: '≠', + label: this.$i18n.get('is_not_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('!=') < 0 ? 'no' : 'yes' + }, + '>': { + symbol: '>', + label: this.$i18n.get('after'), + enabled: this.filterTypeOptions.comparators.indexOf('>') < 0 ? 'no' : 'yes' + }, + '>=': { + symbol: '≥', + label: this.$i18n.get('after_or_on_day'), + enabled: this.filterTypeOptions.comparators.indexOf('>=') < 0 ? 'no' : 'yes' + }, + '<': { + symbol: '<', + label: this.$i18n.get('before'), + enabled: this.filterTypeOptions.comparators.indexOf('<') < 0 ? 'no' : 'yes' + }, + '<=': { + symbol: '≤', + label: this.$i18n.get('before_or_on_day'), + enabled: this.filterTypeOptions.comparators.indexOf('<=') < 0 ? 'no' : 'yes' + }, + }; + }, mounted() { this.updateSelectedValues(); }, diff --git a/src/views/admin/components/filter-types/date/class-tainacan-date.php b/src/views/admin/components/filter-types/date/class-tainacan-date.php index 7c76022d6..255fc6988 100644 --- a/src/views/admin/components/filter-types/date/class-tainacan-date.php +++ b/src/views/admin/components/filter-types/date/class-tainacan-date.php @@ -13,7 +13,11 @@ class Date extends Filter_Type { $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([ + 'comparators' => [ '=', '!=', '>', '>=', '<', '<=' ] + ]); $this->set_preview_template('
@@ -57,6 +61,35 @@ class Date extends Filter_Type { '); } + + /** + * @inheritdoc + */ + public function get_form_labels(){ + return [ + 'comparators' => [ + 'title' => __( 'Enabled comparators', 'tainacan' ), + 'description' => __( 'A list of comparators to be available in the filter, such as equal, greater than, smaller than, etc.', '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; + + if ( empty( $this->get_option('comparators') ) ) + return [ + 'comparators' => __('"Comparators" array is required', 'tainacan') + ]; + + return true; + } + } class Date_Helper { From 685b61b0b110f7601b73757782c6683d22054aa1 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 3 Jun 2024 11:50:50 -0300 Subject: [PATCH 02/39] Creates first version of dates intersection filter. #887. --- .../edition/filter-edition-form.vue | 4 +- .../FormDatesIntersection.vue | 98 +++++++++ .../TainacanFilterDatesIntersection.vue | 187 ++++++++++++++++++ .../class-tainacan-dates-intersection.php | 119 +++++++++++ .../class-tainacan-filter-type-helper.php | 1 + .../filter-types/tainacan-filter-item.vue | 1 + src/views/tainacan-i18n.php | 1 + 7 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue create mode 100644 src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue create mode 100644 src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php diff --git a/src/views/admin/components/edition/filter-edition-form.vue b/src/views/admin/components/edition/filter-edition-form.vue index e3c609502..3f0e845ab 100644 --- a/src/views/admin/components/edition/filter-edition-form.vue +++ b/src/views/admin/components/edition/filter-edition-form.vue @@ -252,13 +252,15 @@ import { formHooks } from "../../js/mixins"; import FormFilterNumeric from '../filter-types/numeric/FormNumeric.vue'; import FormFilterNumericInterval from '../filter-types/numeric-interval/FormNumericInterval.vue'; import FormFilterNumericListInterval from '../filter-types/numeric-list-interval/FormNumericListInterval.vue'; +import FormFilterDatesIntersection from '../filter-types/dates-intersection/FormDatesIntersection.vue'; export default { name: 'FilterEditionForm', components: { 'tainacan-filter-form-numeric': FormFilterNumeric, 'tainacan-filter-form-numeric-interval': FormFilterNumericInterval, - 'tainacan-filter-form-numeric-list-interval': FormFilterNumericListInterval + 'tainacan-filter-form-numeric-list-interval': FormFilterNumericListInterval, + 'tainacan-filter-form-dates-intersection': FormFilterDatesIntersection }, mixins: [ formHooks ], props: { diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue new file mode 100644 index 000000000..83ddf0de3 --- /dev/null +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -0,0 +1,98 @@ + + + \ No newline at end of file diff --git a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue new file mode 100644 index 000000000..c2f16c362 --- /dev/null +++ b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php new file mode 100644 index 000000000..cf3162042 --- /dev/null +++ b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php @@ -0,0 +1,119 @@ +set_name( __('Dates Intersection', 'tainacan') ); + $this->set_supported_types(['date']); + $this->set_component('tainacan-filter-dates-intersection'); + $this->set_form_component('tainacan-filter-form-dates-intersection'); + $this->set_default_options([ + 'secondary_filter_metadatum_id' => '', + 'secondary_filter_metadatum_name' => '', + ]); + $this->set_use_max_options(false); + $this->set_preview_template(' +
+
+ +
+

until

+
+ +
+
+ '); + + } + + /** + * @inheritdoc + */ + public function get_form_labels(){ + return [ + 'secondary_filter_metadatum_id' => [ + 'title' => __( 'Second date metadatum', 'tainacan' ), + 'description' => __( 'The other metadatum to which this filter will compare values to find if there is an intersection of dates.', 'tainacan' ), + ], + 'secondary_filter_metadatum_name' => [ + 'title' => __( 'Second date metadatum', 'tainacan' ), + 'description' => __( 'Label of the other metadatum to which this filter will compare values to find if there is an intersection of dates.', '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; + + if ( empty($this->get_option('secondary_filter_metadatum_id')) ) { + return [ + 'secondary_filter_metadatum_id' => __('The secondary date metadatum is required.','tainacan') + ]; + } + + // Validate if the second date metadatum is a date metadatum + + return true; + } + +} + +class Dates_Intersection_Interval_Helper { + use \Tainacan\Traits\Singleton_Instance; + + protected function init() { + add_filter( 'tainacan-api-items-tainacan-filter-dates-intersection-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 ( + is_array($filter_arguments['label']) && + count($filter_arguments['label']) === 2 + ) { + $filter_arguments['label'] = $filter_arguments['label'][0] . ' - ' . $filter_arguments['label'][1]; + } + if ( + isset( $filter_arguments['filter'] ) && + isset( $filter_arguments['filter']['filter_type_options'] ) && + isset( $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name'] ) && + !empty( $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name'] ) + ) { + $filter_arguments['filter']['name'] = $filter_arguments['filter']['name'] . ' - ' . $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name']; + } + return $filter_arguments; + } +} +Dates_Intersection_Interval_Helper::get_instance(); \ No newline at end of file diff --git a/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php b/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php index 594589ec6..cb4ffa3b5 100644 --- a/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php +++ b/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php @@ -38,6 +38,7 @@ class Filter_Type_Helper { $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Selectbox'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Autocomplete'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Date_Interval'); + $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Dates_Intersection'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_Interval'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox'); diff --git a/src/views/admin/components/filter-types/tainacan-filter-item.vue b/src/views/admin/components/filter-types/tainacan-filter-item.vue index 73479b805..bd3f4609f 100644 --- a/src/views/admin/components/filter-types/tainacan-filter-item.vue +++ b/src/views/admin/components/filter-types/tainacan-filter-item.vue @@ -100,6 +100,7 @@ TainacanFilterTaxonomyCheckbox: defineAsyncComponent(() => import('./taxonomy/TainacanFilterCheckbox.vue')), TainacanFilterTaxonomyTaginput: defineAsyncComponent(() => import('./taxonomy/TainacanFilterTaginput.vue')), TainacanFilterDateInterval: defineAsyncComponent(() => import('./date-interval/TainacanFilterDateInterval.vue')), + TainacanFilterDatesIntersection: defineAsyncComponent(() => import('./dates-intersection/TainacanFilterDatesIntersection.vue')), TainacanFilterNumericInterval: defineAsyncComponent(() => import('./numeric-interval/TainacanFilterNumericInterval.vue')), TainacanFilterNumericListInterval: defineAsyncComponent(() => import('./numeric-list-interval/TainacanFilterNumericListInterval.vue')) }, diff --git a/src/views/tainacan-i18n.php b/src/views/tainacan-i18n.php index c63e44a7b..4bb2101c4 100644 --- a/src/views/tainacan-i18n.php +++ b/src/views/tainacan-i18n.php @@ -788,6 +788,7 @@ return apply_filters( 'tainacan-i18n', [ 'instruction_click_to_add_a_point' => __( 'Drag to reposition or click to insert a marker', 'tainacan' ), 'instruction_select_geocoordinate_metadatum' => __( 'Select a geocoordinate metadatum', 'tainacan' ), 'instruction_multiple_terms_insertion' => __( 'Type or paste here a list of names using a separator to create multiple terms at once.', 'tainacan' ), + 'instruction_select_second_date_to_compare' => __( 'Select the second date metadatum', 'tainacan' ), // Info. Other feedback to user. 'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ), From a9df08c15f746c7822a794b321117277d501772b Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 3 Jun 2024 15:11:07 -0300 Subject: [PATCH 03/39] Adds first and second comparator options to intersection metadata. #887. --- .../edition/filter-edition-form.vue | 2 +- .../FormDatesIntersection.vue | 96 ++++++++++++++++++- .../TainacanFilterDatesIntersection.vue | 4 +- .../class-tainacan-dates-intersection.php | 30 +++++- 4 files changed, 119 insertions(+), 13 deletions(-) diff --git a/src/views/admin/components/edition/filter-edition-form.vue b/src/views/admin/components/edition/filter-edition-form.vue index 3f0e845ab..1dd6b4183 100644 --- a/src/views/admin/components/edition/filter-edition-form.vue +++ b/src/views/admin/components/edition/filter-edition-form.vue @@ -420,7 +420,7 @@ export default { -webkit-column-gap: 0; -webkit-column-rule: none; column-count: 2; - column-gap: 4em; + column-gap: 3em; column-rule: none; padding-bottom: 0.5em; diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue index 83ddf0de3..346b90b3a 100644 --- a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -29,6 +29,46 @@ +
+ + + + + + + + + + +
@@ -50,7 +90,11 @@ loading: true, metadataType: '', metadataMessage: '', - secondDateMetadatumId: [Number, String] + secondDateMetadatumId: [Number, String], + secondDateMetadatumName: String, + firstComparator: String, + secondComparator: String, + comparatorsObject: {} } }, watch: { @@ -63,13 +107,46 @@ }, created() { this.secondDateMetadatumId = this.modelValue && this.modelValue.secondary_filter_metadatum_id ? this.modelValue.secondary_filter_metadatum_id : ''; + this.secondDateMetadatumName = this.modelValue && this.modelValue.secondary_filter_metadatum_name ? this.modelValue.secondary_filter_metadatum_name : ''; + this.firstComparator = this.modelValue && this.modelValue.first_comparator ? this.modelValue.first_comparator : '>='; + this.secondComparator = this.modelValue && this.modelValue.second_comparator ? this.modelValue.second_comparator : '<='; + this.loading = true; this.fetchMetadata(); - console.log(this.filter) + + this.comparatorsObject = { + '=': { + symbol: '=', + label: this.$i18n.get('is_equal_to') + }, + '!=': { + symbol: '≠', + label: this.$i18n.get('is_not_equal_to') + }, + '>': { + symbol: '>', + label: this.$i18n.get('after') + }, + '>=': { + symbol: '≥', + label: this.$i18n.get('after_or_on_day') + }, + '<': { + symbol: '<', + label: this.$i18n.get('before') + }, + '<=': { + symbol: '≤', + label: this.$i18n.get('before_or_on_day') + } + }; }, methods: { async fetchMetadata() { - let endpoint = this.filter.collectionId && this.filter.collectionId !== 'default' ? ( '/collections/' + this.filter.collectionId + '/metadata' ) : '/metadata'; + + let endpoint = this.filter.collection_id && this.filter.collection_id !== 'default' ? ( '/collection/' + this.filter.collection_id + '/metadata' ) : '/metadata'; + endpoint += '?metaquery[0][key]=metadata_type&metaquery[0][value]=Tainacan\\Metadata_Types\\Date&nopaging=1&exclude=' + this.filter.metadatum_id; + return await tainacanApi.get(endpoint) .then(res => { this.loading = false; @@ -82,8 +159,17 @@ }, onUpdateSecondDateMetadatumId() { const selectedMetadatum = this.metadata.find( aMetadatum => aMetadatum.id == this.secondDateMetadatumId ); - const selectedMetadatumName = selectedMetadatum ? selectedMetadatum.name : ''; - this.$emit('update:model-value', { secondary_filter_metadatum_id: this.secondDateMetadatumId, secondary_filter_metadatum_name: selectedMetadatumName}); + this.selectedMetadatumName = selectedMetadatum ? selectedMetadatum.name : ''; + this.selectedMetadatumId = selectedMetadatum ? selectedMetadatum.id : ''; + this.emitValues(); + }, + emitValues() { + this.$emit('update:model-value', { + first_comparator: this.firstComparator, + second_comparator: this.secondComparator, + secondary_filter_metadatum_id: this.secondDateMetadatumId, + secondary_filter_metadatum_name: this.secondDateMetadatumName + }); }, setErrorsAttributes( type, message ) { this.metadataType = type; diff --git a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue index c2f16c362..cd9a67aa6 100644 --- a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue @@ -159,7 +159,7 @@ this.$emit('input', { filter: 'intersection', type: 'DATE', - compare: '>=', + compare: this.filterTypeOptions.first_comparator, metadatum_id: this.metadatumId, collection_id: this.collectionId, value: values @@ -167,7 +167,7 @@ this.$emit('input', { filter: 'intersection', type: 'DATE', - compare: '<=', + compare: this.filterTypeOptions.second_comparator, metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, collection_id: this.collectionId, value: values diff --git a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php index cf3162042..eb43af28e 100644 --- a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php +++ b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php @@ -17,6 +17,8 @@ class Dates_Intersection extends Filter_Type { $this->set_default_options([ 'secondary_filter_metadatum_id' => '', 'secondary_filter_metadatum_name' => '', + 'first_comparator' => '>=', + 'second_comparator' => '<=' ]); $this->set_use_max_options(false); $this->set_preview_template(' @@ -59,6 +61,14 @@ class Dates_Intersection extends Filter_Type { 'secondary_filter_metadatum_name' => [ 'title' => __( 'Second date metadatum', 'tainacan' ), 'description' => __( 'Label of the other metadatum to which this filter will compare values to find if there is an intersection of dates.', 'tainacan' ), + ], + 'first_comparator' => [ + 'title' => __( 'First comparator', 'tainacan' ), + 'description' => __( 'Comparator to be used for checking the first metadata value.', 'tainacan' ), + ], + 'second_comparator' => [ + 'title' => __( 'Second comparator', 'tainacan' ), + 'description' => __( 'Comparator to be used for checking the second metadata value.', 'tainacan' ), ] ]; } @@ -68,18 +78,28 @@ class Dates_Intersection extends Filter_Type { * @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('secondary_filter_metadatum_id')) ) { - return [ + $errors = []; + + if ( empty($this->get_option('secondary_filter_metadatum_id')) ) + $errors[] = [ 'secondary_filter_metadatum_id' => __('The secondary date metadatum is required.','tainacan') ]; - } - // Validate if the second date metadatum is a date metadatum + if ( empty($this->get_option('first_comparator')) ) + $errors[] = [ + 'first_comparator' => __('The first comparator is required.','tainacan') + ]; + + if ( empty($this->get_option('second_comparator')) ) + $errors[] = [ + 'second_comparator' => __('The second comparator is required.','tainacan') + ]; - return true; + return count($errors) > 0 ? $errors : true; } } From ebf478d5ff7ade98fb5b7dd78fb9512e1288c638 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 3 Jun 2024 15:53:13 -0300 Subject: [PATCH 04/39] Adds option to display the filter as a range instead of one date. #887. --- .../TainacanFilterDateInterval.vue | 30 ++++++++++++- .../FormDatesIntersection.vue | 25 ++++++++++- .../TainacanFilterDatesIntersection.vue | 44 ++++++++++++++++--- .../class-tainacan-dates-intersection.php | 12 ++++- 4 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/views/admin/components/filter-types/date-interval/TainacanFilterDateInterval.vue b/src/views/admin/components/filter-types/date-interval/TainacanFilterDateInterval.vue index 1a4e4b1b5..79c9ddb0a 100644 --- a/src/views/admin/components/filter-types/date-interval/TainacanFilterDateInterval.vue +++ b/src/views/admin/components/filter-types/date-interval/TainacanFilterDateInterval.vue @@ -3,7 +3,7 @@

diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue index 346b90b3a..19a9b7e0c 100644 --- a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -69,6 +69,24 @@ + +   + + + + @@ -94,7 +112,8 @@ secondDateMetadatumName: String, firstComparator: String, secondComparator: String, - comparatorsObject: {} + comparatorsObject: {}, + acceptDateInterval: String } }, watch: { @@ -110,6 +129,7 @@ this.secondDateMetadatumName = this.modelValue && this.modelValue.secondary_filter_metadatum_name ? this.modelValue.secondary_filter_metadatum_name : ''; this.firstComparator = this.modelValue && this.modelValue.first_comparator ? this.modelValue.first_comparator : '>='; this.secondComparator = this.modelValue && this.modelValue.second_comparator ? this.modelValue.second_comparator : '<='; + this.acceptDateInterval = this.modelValue && this.modelValue.accept_date_interval ? this.modelValue.accept_date_interval : 'no'; this.loading = true; this.fetchMetadata(); @@ -168,7 +188,8 @@ first_comparator: this.firstComparator, second_comparator: this.secondComparator, secondary_filter_metadatum_id: this.secondDateMetadatumId, - secondary_filter_metadatum_name: this.secondDateMetadatumName + secondary_filter_metadatum_name: this.secondDateMetadatumName, + accept_date_interval: this.acceptDateInterval }); }, setErrorsAttributes( type, message ) { diff --git a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue index cd9a67aa6..b43d7a002 100644 --- a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue @@ -3,7 +3,7 @@

{{ $i18n.get('label_until') }}

@@ -92,13 +122,13 @@ // only validate if the first value is higher than first validadeValues: _.debounce( function (){ - if (this.dateInit === undefined) + if ( this.dateInit === undefined ) this.dateInit = new Date(); - if (this.dateEnd === undefined) + if ( this.dateEnd === undefined ) this.dateEnd = new Date(); - if (this.dateInit > this.dateEnd) { + if ( this.filterTypeOptions.accept_date_interval === 'yes' && this.dateInit > this.dateEnd ) { this.showErrorMessage(); return } @@ -162,7 +192,7 @@ compare: this.filterTypeOptions.first_comparator, metadatum_id: this.metadatumId, collection_id: this.collectionId, - value: values + value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0] }); this.$emit('input', { filter: 'intersection', @@ -170,7 +200,7 @@ compare: this.filterTypeOptions.second_comparator, metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, collection_id: this.collectionId, - value: values + value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0] }); } } diff --git a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php index eb43af28e..59860e686 100644 --- a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php +++ b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php @@ -18,7 +18,8 @@ class Dates_Intersection extends Filter_Type { 'secondary_filter_metadatum_id' => '', 'secondary_filter_metadatum_name' => '', 'first_comparator' => '>=', - 'second_comparator' => '<=' + 'second_comparator' => '<=', + 'accept_date_interval' => 'no' ]); $this->set_use_max_options(false); $this->set_preview_template(' @@ -69,6 +70,10 @@ class Dates_Intersection extends Filter_Type { 'second_comparator' => [ 'title' => __( 'Second comparator', 'tainacan' ), 'description' => __( 'Comparator to be used for checking the second metadata value.', 'tainacan' ), + ], + 'accept_date_interval' => [ + 'title' => __( 'Accept date interval', 'tainacan' ), + 'description' => __( 'If checked, the filter will accept date intervals as values.', 'tainacan' ), ] ]; } @@ -99,6 +104,11 @@ class Dates_Intersection extends Filter_Type { 'second_comparator' => __('The second comparator is required.','tainacan') ]; + if ( empty($this->get_option('accept_date_interval')) ) + $errors[] = [ + 'accept_date_interval' => __('The filter should define if it accepts date interval.','tainacan') + ]; + return count($errors) > 0 ? $errors : true; } From 658789e2bb5867d857d074d81e372b5befca01ce Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 3 Jun 2024 16:32:48 -0300 Subject: [PATCH 05/39] Disables comparator dropdown if only one option is available. #886. --- .../admin/components/filter-types/date/FormDate.vue | 11 +++++++---- .../filter-types/date/TainacanFilterDate.vue | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/views/admin/components/filter-types/date/FormDate.vue b/src/views/admin/components/filter-types/date/FormDate.vue index feab75549..d23c3a073 100644 --- a/src/views/admin/components/filter-types/date/FormDate.vue +++ b/src/views/admin/components/filter-types/date/FormDate.vue @@ -12,7 +12,8 @@ v-for="(comparatorObject, comparatorKey) in comparatorsObject" :key="comparatorKey" v-model="comparators" - :native-value="comparatorObject.key" + :native-value="comparatorKey" + :disabled="comparators.indexOf(comparatorKey) >= 0 && comparators.length <= 1" name="metadata_type_relationship[display_related_item_metadata]" @update:model-value="emitValues()"> @@ -33,7 +34,8 @@ ], data() { return { - comparatorsObject: Object + comparatorsObject: Object, + comparators: Array } }, created() { @@ -72,8 +74,9 @@ }; }, methods: { - onUpdateComparators(value) { - this.$emit('update:model-value', { comparators: value }); + emitValues() { + console.log(this.comparators) + this.$emit('update:model-value', { comparators: this.comparators }); } } } diff --git a/src/views/admin/components/filter-types/date/TainacanFilterDate.vue b/src/views/admin/components/filter-types/date/TainacanFilterDate.vue index 749dc0fe9..22e552e80 100644 --- a/src/views/admin/components/filter-types/date/TainacanFilterDate.vue +++ b/src/views/admin/components/filter-types/date/TainacanFilterDate.vue @@ -1,6 +1,7 @@ @@ -102,15 +122,50 @@ data() { return { step: [Number, String], - showEditStepOptions: false + showEditStepOptions: false, + comparatorsObject: Object, + comparators: Array } }, created() { this.step = this.modelValue && this.modelValue.step ? this.modelValue.step : 1; + this.comparators = ( this.modelValue && this.modelValue.comparators ) ? this.modelValue.comparators : [ '=', '!=', '>', '>=', '<', '<=' ]; + this.comparatorsObject = { + '=': { + symbol: '=', + label: this.$i18n.get('is_equal_to'), + enabled: this.comparators.indexOf('=') < 0 ? 'no' : 'yes' + }, + '!=': { + symbol: '≠', + label: this.$i18n.get('is_not_equal_to'), + enabled: this.comparators.indexOf('!=') < 0 ? 'no' : 'yes' + }, + '>': { + symbol: '>', + label: this.$i18n.get('after'), + enabled: this.comparators.indexOf('>') < 0 ? 'no' : 'yes' + }, + '>=': { + symbol: '≥', + label: this.$i18n.get('after_or_on_day'), + enabled: this.comparators.indexOf('>=') < 0 ? 'no' : 'yes' + }, + '<': { + symbol: '<', + label: this.$i18n.get('before'), + enabled: this.comparators.indexOf('<') < 0 ? 'no' : 'yes' + }, + '<=': { + symbol: '≤', + label: this.$i18n.get('before_or_on_day'), + enabled: this.comparators.indexOf('<=') < 0 ? 'no' : 'yes' + } + }; }, methods: { - onUpdateStep(modelValue) { - this.$emit('update:model-value', { step: modelValue }); + emitValues() { + this.$emit('update:model-value', { step: this.step, comparators: this.comparators }); } } } diff --git a/src/views/admin/components/filter-types/numeric/TainacanFilterNumeric.vue b/src/views/admin/components/filter-types/numeric/TainacanFilterNumeric.vue index 4d6a77ea2..25ca61d2a 100644 --- a/src/views/admin/components/filter-types/numeric/TainacanFilterNumeric.vue +++ b/src/views/admin/components/filter-types/numeric/TainacanFilterNumeric.vue @@ -1,6 +1,7 @@ - - =  {{ $i18n.get('is_equal_to') }} - - - ≠  {{ $i18n.get('is_not_equal_to') }} - - - >  {{ $i18n.get('greater_than') }} - - - ≥  {{ $i18n.get('greater_than_or_equal_to') }} - - - <  {{ $i18n.get('less_than') }} - - - ≤  {{ $i18n.get('less_than_or_equal_to') }} - + - ': return '>'; - case '>=': return '≥'; - case '<': return '<'; - case '<=': return '≤'; - default: return ''; - } - } - }, watch: { 'query': { handler() { @@ -110,6 +66,41 @@ deep: true } }, + created() { + this.comparatorsObject = { + '=': { + symbol: '=', + label: this.$i18n.get('is_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('=') < 0 ? 'no' : 'yes' + }, + '!=': { + symbol: '≠', + label: this.$i18n.get('is_not_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('!=') < 0 ? 'no' : 'yes' + }, + '>': { + symbol: '>', + label: this.$i18n.get('greater_than'), + enabled: this.filterTypeOptions.comparators.indexOf('>') < 0 ? 'no' : 'yes' + }, + '>=': { + symbol: '≥', + label: this.$i18n.get('greater_than_or_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('>=') < 0 ? 'no' : 'yes' + }, + '<': { + symbol: '<', + label: this.$i18n.get('less_than'), + enabled: this.filterTypeOptions.comparators.indexOf('<') < 0 ? 'no' : 'yes' + }, + '<=': { + symbol: '≤', + label: this.$i18n.get('less_than_or_equal_to'), + enabled: this.filterTypeOptions.comparators.indexOf('<=') < 0 ? 'no' : 'yes' + }, + }; + this.comparator = this.filterTypeOptions.comparators[0]; + }, mounted() { this.updateSelectedValues(); }, diff --git a/src/views/admin/components/filter-types/numeric/class-tainacan-numeric.php b/src/views/admin/components/filter-types/numeric/class-tainacan-numeric.php index b973d8460..e5bb818c7 100644 --- a/src/views/admin/components/filter-types/numeric/class-tainacan-numeric.php +++ b/src/views/admin/components/filter-types/numeric/class-tainacan-numeric.php @@ -16,7 +16,8 @@ class Numeric extends Filter_Type { $this->set_form_component('tainacan-filter-form-numeric'); $this->set_use_max_options(false); $this->set_default_options([ - 'step' => 1 + 'step' => 1, + 'comparators' => [ '=', '!=', '>', '>=', '<', '<=' ] ]); $this->set_preview_template('
@@ -77,6 +78,10 @@ class Numeric extends Filter_Type { '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' ), + ], + 'comparators' => [ + 'title' => __( 'Enabled comparators', 'tainacan' ), + 'description' => __( 'A list of comparators to be available in the filter, such as equal, greater than, smaller than, etc.', 'tainacan' ), ] ]; } @@ -89,13 +94,24 @@ class Numeric extends Filter_Type { if ( !in_array($filter->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) ) return true; - if ( empty($this->get_option('step')) ) { - return [ + $errors = []; + + if ( empty($this->get_option('step')) ) + $errors[] = [ 'step' => __('"Step" value is required','tainacan') ]; - } - return true; + if ( empty($this->get_option('comparators')) ) + $errors[] = [ + 'comparators' => __('"Comparators" array is required', 'tainacan') + ]; + + if ( count( $this->get_option('comparators') ) < 1 ) + $errors[] = [ + 'comparators' => __('At least one comparator should be provided', 'tainacan') + ]; + + return count($errors) ? $errors : true; } } @@ -134,6 +150,8 @@ class Numeric_Helper { case '<=': $filter_arguments['label'] = '≤ ' . $filter_arguments['label'][0]; break; + default: + $filter_arguments['label'] = $filter_arguments['label'][0]; } } From d215c9a9cee092468677faa2d8a0a40bdacafee4 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 3 Jun 2024 18:21:53 -0300 Subject: [PATCH 07/39] Creates intersection filter for numeric as well. #887. --- .../edition/filter-edition-form.vue | 2 + .../FormDatesIntersection.vue | 8 +- .../class-tainacan-dates-intersection.php | 16 +- .../class-tainacan-filter-type-helper.php | 1 + .../FormNumericsIntersection.vue | 298 ++++++++++++++++++ .../TainacanFilterNumericsIntersection.vue | 139 ++++++++ .../class-tainacan-numerics-intersection.php | 161 ++++++++++ .../filter-types/tainacan-filter-item.vue | 3 +- src/views/tainacan-i18n.php | 1 + 9 files changed, 613 insertions(+), 16 deletions(-) create mode 100644 src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue create mode 100644 src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue create mode 100644 src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php diff --git a/src/views/admin/components/edition/filter-edition-form.vue b/src/views/admin/components/edition/filter-edition-form.vue index 1dd6b4183..a243bc665 100644 --- a/src/views/admin/components/edition/filter-edition-form.vue +++ b/src/views/admin/components/edition/filter-edition-form.vue @@ -252,6 +252,7 @@ import { formHooks } from "../../js/mixins"; import FormFilterNumeric from '../filter-types/numeric/FormNumeric.vue'; import FormFilterNumericInterval from '../filter-types/numeric-interval/FormNumericInterval.vue'; import FormFilterNumericListInterval from '../filter-types/numeric-list-interval/FormNumericListInterval.vue'; +import FormFilterNumericsIntersection from '../filter-types/numerics-intersection/FormNumericsIntersection.vue'; import FormFilterDatesIntersection from '../filter-types/dates-intersection/FormDatesIntersection.vue'; export default { @@ -260,6 +261,7 @@ export default { 'tainacan-filter-form-numeric': FormFilterNumeric, 'tainacan-filter-form-numeric-interval': FormFilterNumericInterval, 'tainacan-filter-form-numeric-list-interval': FormFilterNumericListInterval, + 'tainacan-filter-form-numerics-intersection': FormFilterNumericsIntersection, 'tainacan-filter-form-dates-intersection': FormFilterDatesIntersection }, mixins: [ formHooks ], diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue index 19a9b7e0c..a44aaa777 100644 --- a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -72,7 +72,9 @@ + style="margin-top: 1.125rem;" + :type="errors && errors['accept_date_interval'] != undefined ? 'is-danger' : ''" + :message="errors && errors['accept_date_interval'] != undefined ? errors['accept_date_interval'] : ''">   aMetadatum.id == this.secondDateMetadatumId ); - this.selectedMetadatumName = selectedMetadatum ? selectedMetadatum.name : ''; - this.selectedMetadatumId = selectedMetadatum ? selectedMetadatum.id : ''; + this.secondDateMetadatumName = selectedMetadatum ? selectedMetadatum.name : ''; + this.secondDateMetadatumId = selectedMetadatum ? selectedMetadatum.id : ''; this.emitValues(); }, emitValues() { diff --git a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php index 59860e686..13ae80953 100644 --- a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php +++ b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php @@ -90,24 +90,16 @@ class Dates_Intersection extends Filter_Type { $errors = []; if ( empty($this->get_option('secondary_filter_metadatum_id')) ) - $errors[] = [ - 'secondary_filter_metadatum_id' => __('The secondary date metadatum is required.','tainacan') - ]; + $errors['secondary_filter_metadatum_id'] = __('The secondary date metadatum is required.','tainacan'); if ( empty($this->get_option('first_comparator')) ) - $errors[] = [ - 'first_comparator' => __('The first comparator is required.','tainacan') - ]; + $errors['first_comparator'] = __('The first comparator is required.','tainacan'); if ( empty($this->get_option('second_comparator')) ) - $errors[] = [ - 'second_comparator' => __('The second comparator is required.','tainacan') - ]; + $errors['second_comparator'] = __('The second comparator is required.','tainacan'); if ( empty($this->get_option('accept_date_interval')) ) - $errors[] = [ - 'accept_date_interval' => __('The filter should define if it accepts date interval.','tainacan') - ]; + $errors['accept_date_interval'] = __('The filter should define if it accepts date interval.','tainacan'); return count($errors) > 0 ? $errors : true; } diff --git a/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php b/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php index cb4ffa3b5..fd91b2a50 100644 --- a/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php +++ b/src/views/admin/components/filter-types/filter-type-helper/class-tainacan-filter-type-helper.php @@ -43,6 +43,7 @@ class Filter_Type_Helper { $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox'); $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numeric_List_Interval'); + $this->Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Numerics_Intersection'); // the priority should see less than on function // `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php diff --git a/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue b/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue new file mode 100644 index 000000000..bb2384fbd --- /dev/null +++ b/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue @@ -0,0 +1,298 @@ + + + \ No newline at end of file diff --git a/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue b/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue new file mode 100644 index 000000000..6805d6acc --- /dev/null +++ b/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue @@ -0,0 +1,139 @@ + + + + + diff --git a/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php b/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php new file mode 100644 index 000000000..b53da5ab8 --- /dev/null +++ b/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php @@ -0,0 +1,161 @@ +set_name( __('Numerics Intersection', 'tainacan') ); + $this->set_supported_types(['float']); + $this->set_component('tainacan-filter-numerics-intersection'); + $this->set_form_component('tainacan-filter-form-numerics-intersection'); + $this->set_default_options([ + 'step' => 1, + 'secondary_filter_metadatum_id' => '', + 'secondary_filter_metadatum_name' => '', + 'first_comparator' => '>=', + 'second_comparator' => '<=', + 'accept_numeric_interval' => 'no' + ]); + $this->set_use_max_options(false); + $this->set_preview_template(' +
+
+

+ +

+
+ +
+

+ +

+
+

until

+
+

+ +

+
+ +
+

+ +

+
+
+ '); + } + + 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' ), + ], + 'secondary_filter_metadatum_id' => [ + 'title' => __( 'Second numeric metadatum', 'tainacan' ), + 'description' => __( 'The other metadatum to which this filter will compare values to find if there is an intersection of numeric values.', 'tainacan' ), + ], + 'secondary_filter_metadatum_name' => [ + 'title' => __( 'Second numeric metadatum', 'tainacan' ), + 'description' => __( 'Label of the other metadatum to which this filter will compare values to find if there is an intersection of numeric values.', 'tainacan' ), + ], + 'first_comparator' => [ + 'title' => __( 'First comparator', 'tainacan' ), + 'description' => __( 'Comparator to be used for checking the first metadata value.', 'tainacan' ), + ], + 'second_comparator' => [ + 'title' => __( 'Second comparator', 'tainacan' ), + 'description' => __( 'Comparator to be used for checking the second metadata value.', 'tainacan' ), + ], + 'accept_numeric_interval' => [ + 'title' => __( 'Accept numeric interval', 'tainacan' ), + 'description' => __( 'If checked, the filter will accept numeric intervals as values.', '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; + + $errors = []; + + if ( empty($this->get_option('secondary_filter_metadatum_id')) ) + $errors['secondary_filter_metadatum_id'] = __('The secondary numeric metadatum is required.','tainacan'); + + if ( empty($this->get_option('first_comparator')) ) + $errors['first_comparator'] = __('The first comparator is required.','tainacan'); + + if ( empty($this->get_option('second_comparator')) ) + $errors['second_comparator'] = __('The second comparator is required.','tainacan'); + + if ( empty($this->get_option('accept_numeric_interval')) ) + $errors['accept_numeric_interval'] = __('The filter should define if it accepts a numeric interval.','tainacan'); + + return count($errors) > 0 ? $errors : true; + } + +} + +class Numerics_Intersection_Interval_Helper { + use \Tainacan\Traits\Singleton_Instance; + + protected function init() { + add_filter( 'tainacan-api-items-tainacan-filter-numerics-intersection-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 ( + is_array($filter_arguments['label']) && + count($filter_arguments['label']) === 2 + ) { + $filter_arguments['label'] = $filter_arguments['label'][0] . ' - ' . $filter_arguments['label'][1]; + } + if ( + isset( $filter_arguments['filter'] ) && + isset( $filter_arguments['filter']['filter_type_options'] ) && + isset( $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name'] ) && + !empty( $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name'] ) + ) { + $filter_arguments['filter']['name'] = $filter_arguments['filter']['name'] . ' - ' . $filter_arguments['filter']['filter_type_options']['secondary_filter_metadatum_name']; + } + return $filter_arguments; + } +} +Numerics_Intersection_Interval_Helper::get_instance(); \ No newline at end of file diff --git a/src/views/admin/components/filter-types/tainacan-filter-item.vue b/src/views/admin/components/filter-types/tainacan-filter-item.vue index bd3f4609f..04b0e33ef 100644 --- a/src/views/admin/components/filter-types/tainacan-filter-item.vue +++ b/src/views/admin/components/filter-types/tainacan-filter-item.vue @@ -102,7 +102,8 @@ TainacanFilterDateInterval: defineAsyncComponent(() => import('./date-interval/TainacanFilterDateInterval.vue')), TainacanFilterDatesIntersection: defineAsyncComponent(() => import('./dates-intersection/TainacanFilterDatesIntersection.vue')), TainacanFilterNumericInterval: defineAsyncComponent(() => import('./numeric-interval/TainacanFilterNumericInterval.vue')), - TainacanFilterNumericListInterval: defineAsyncComponent(() => import('./numeric-list-interval/TainacanFilterNumericListInterval.vue')) + TainacanFilterNumericListInterval: defineAsyncComponent(() => import('./numeric-list-interval/TainacanFilterNumericListInterval.vue')), + TainacanFilterNumericsIntersection: defineAsyncComponent(() => import('./numerics-intersection/TainacanFilterNumericsIntersection.vue')) }, props: { filter: Object, diff --git a/src/views/tainacan-i18n.php b/src/views/tainacan-i18n.php index 4bb2101c4..ab0ebc810 100644 --- a/src/views/tainacan-i18n.php +++ b/src/views/tainacan-i18n.php @@ -789,6 +789,7 @@ return apply_filters( 'tainacan-i18n', [ 'instruction_select_geocoordinate_metadatum' => __( 'Select a geocoordinate metadatum', 'tainacan' ), 'instruction_multiple_terms_insertion' => __( 'Type or paste here a list of names using a separator to create multiple terms at once.', 'tainacan' ), 'instruction_select_second_date_to_compare' => __( 'Select the second date metadatum', 'tainacan' ), + 'instruction_select_second_numeric_to_compare' => __( 'Select the second numeric metadatum', 'tainacan' ), // Info. Other feedback to user. 'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ), From 4729bd31180515848bfcfada599388d9fb0bbb22 Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Thu, 6 Jun 2024 12:25:58 -0300 Subject: [PATCH 08/39] feat: add secondary in metaquery #887 --- .../class-tainacan-rest-items-controller.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/classes/api/endpoints/class-tainacan-rest-items-controller.php b/src/classes/api/endpoints/class-tainacan-rest-items-controller.php index d25d70d11..5d1d3982c 100644 --- a/src/classes/api/endpoints/class-tainacan-rest-items-controller.php +++ b/src/classes/api/endpoints/class-tainacan-rest-items-controller.php @@ -454,7 +454,7 @@ class REST_Items_Controller extends REST_Controller { * @return array * @throws \Exception */ - private function prepare_filters_arguments ( $args, $collection_id = false ) { + private function prepare_filters_arguments ( $args, $collection_id = false, $ignore_filter_arguments = [] ) { $filters_arguments = array(); $meta_query = isset($args['meta_query']) ? $args['meta_query'] : []; if(isset($meta_query['value'])) $meta_query = [$meta_query]; @@ -498,8 +498,7 @@ class REST_Items_Controller extends REST_Controller { } foreach($meta_query as $meta) { - - if ( !isset($meta['key']) || !isset($meta['value']) ) + if ( !isset($meta['key']) || !isset($meta['value']) || ( in_array($meta['key'], $ignore_filter_arguments) )) continue; $meta_id = $meta['key']; @@ -554,6 +553,7 @@ class REST_Items_Controller extends REST_Controller { $date_format = get_option( 'date_format' ) != false ? get_option( 'date_format' ) : 'Y-m-d'; return empty($date) == false ? mysql2date($date_format, $date) : ""; }, $meta_label); + $meta_type = 'DATE'; break; case 'item': $meta_label = array_map(function($item_id) { @@ -643,7 +643,15 @@ 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); + $metaqueries = isset($request['metaquery']) ? $request['metaquery'] : []; + $ignore_filter_arguments = array_map( + function($metaquery) { return $metaquery['key']; }, + array_filter( + $metaqueries, + function($metaquery) { return isset($metaquery['key']) && isset($metaquery['secondary']) && $metaquery['secondary'] == 'true'; } + ) + ); + $filters_args = $this->prepare_filters_arguments($args, $collection_id, $ignore_filter_arguments); if(isset($args['meta_query']) && !empty($args['meta_query']) && is_array($filters_args) && !empty($filters_args)) { foreach($filters_args as $filters_arg) { if($filters_arg['filter'] !== false) { From a8aa9bb7cba1daab8bc355f0bc8698c1008121e1 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Thu, 6 Jun 2024 14:06:52 -0300 Subject: [PATCH 09/39] Passes 'secondary' indicator to metaquery. #887. --- .../TainacanFilterDatesIntersection.vue | 3 +- .../js/store/modules/search/mutations.js | 65 ++++++++----------- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue index b43d7a002..a51506939 100644 --- a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue @@ -200,7 +200,8 @@ compare: this.filterTypeOptions.second_comparator, metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, collection_id: this.collectionId, - value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0] + value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0], + secondary: true }); } } diff --git a/src/views/admin/js/store/modules/search/mutations.js b/src/views/admin/js/store/modules/search/mutations.js index 7e0c73a2a..fe1d2baec 100644 --- a/src/views/admin/js/store/modules/search/mutations.js +++ b/src/views/admin/js/store/modules/search/mutations.js @@ -21,52 +21,39 @@ export const setAdvancedSearchQuery = (state, advancedSearchQuery) => { export const addMetaQuery = ( state, filter ) => { state.postquery.metaquery = ( ! state.postquery.metaquery || state.postquery.metaquery.length == undefined ) ? [] : state.postquery.metaquery; - let index = state.postquery.metaquery.findIndex( item => item.key === filter.metadatum_id); - if ( index >= 0 ) { - Object.assign( - state.postquery.metaquery, - { - [index]: { - key: filter.metadatum_id, - value: filter.value, - compare: filter.compare, - type: filter.type - } - } - ); - } else { - state.postquery.metaquery.push({ - key: filter.metadatum_id, - value: filter.value, - compare: filter.compare, - type: filter.type - }); + let metaquery = { + key: filter.metadatum_id, + value: filter.value } + if ( filter.compare ) + metaquery.compare = filter.compare; + if ( filter.type ) + metaquery.type = filter.type; + if ( filter.secondary ) + metaquery.secondary = filter.secondary; + + let index = state.postquery.metaquery.findIndex( item => item.key === filter.metadatum_id); + if ( index >= 0 ) + Object.assign( state.postquery.metaquery, { [index]: metaquery } ); + else + state.postquery.metaquery.push(metaquery); }; export const addTaxQuery = ( state, filter ) => { state.postquery.taxquery = ( ! state.postquery.taxquery || state.postquery.taxquery.length == undefined ) ? [] : state.postquery.taxquery; - let index = state.postquery.taxquery.findIndex( item => item.taxonomy === filter.taxonomy); - - if ( index >= 0 ) { - Object.assign( - state.postquery.taxquery, - { - [index]: { - taxonomy: filter.taxonomy, - terms: filter.terms, - compare: filter.compare - } - } - ); - } else { - state.postquery.taxquery.push({ - taxonomy: filter.taxonomy, - terms: filter.terms, - compare: filter.compare - }); + let taxquery = { + taxonomy: filter.taxonomy, + terms: filter.terms } + if ( filter.compare ) + taxquery.compare = filter.compare; + + let index = state.postquery.taxquery.findIndex( item => item.taxonomy === filter.taxonomy); + if ( index >= 0 ) + Object.assign( state.postquery.taxquery, { [index]: taxquery } ); + else + state.postquery.taxquery.push(taxquery); }; export const addFetchOnly = ( state, metadatum ) => { From 9fae42446052fc80beb10a136ce21c7d309f5c0f Mon Sep 17 00:00:00 2001 From: vnmedeiros Date: Fri, 7 Jun 2024 08:28:00 -0300 Subject: [PATCH 10/39] fix: test quantity os filters types --- tests/test-filters.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-filters.php b/tests/test-filters.php index 27517e746..65eb4a046 100644 --- a/tests/test-filters.php +++ b/tests/test-filters.php @@ -97,7 +97,7 @@ class Filters extends TAINACAN_UnitTestCase { $Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance(); $all_filter_types = $Tainacan_Filters->fetch_filter_types(); - $this->assertEquals( 11, count( $all_filter_types ) ); + $this->assertEquals( 13, count( $all_filter_types ) ); $float_filters = $Tainacan_Filters->fetch_supported_filter_types('float'); $this->assertTrue( count( $float_filters ) > 0 ); From 0ff12f3b67836a70a3139d0f94d5a37755dfd363 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Fri, 7 Jun 2024 15:57:20 -0300 Subject: [PATCH 11/39] Basic logic for intersection filters without range by now. #887. --- .../FormDatesIntersection.vue | 163 +++++++++++++++--- .../TainacanFilterDatesIntersection.vue | 53 +++--- .../class-tainacan-dates-intersection.php | 11 -- .../FormNumericsIntersection.vue | 162 ++++++++++++++--- .../TainacanFilterNumericsIntersection.vue | 46 +++-- .../class-tainacan-numerics-intersection.php | 20 --- src/views/admin/pages/lists/filters-page.vue | 2 +- src/views/tainacan-i18n.php | 3 + 8 files changed, 336 insertions(+), 124 deletions(-) diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue index a44aaa777..d9bea5a41 100644 --- a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -6,9 +6,11 @@ :message="metadataMessage">
-
+
+ +

+ {{ $i18n.get('info_intersection_explainer') }} + + + +

+
- + +

+   + {{ filter.metadatum.metadatum_name }} +

+ +
+
+ {{ $i18n.get('label_and') }} +
- + +

 {{ secondDateMetadatumName }}

+ +
-
- + +
@@ -115,7 +190,9 @@ firstComparator: String, secondComparator: String, comparatorsObject: {}, - acceptDateInterval: String + acceptDateInterval: String, + showEditFirstComparatorOptions: false, + showEditSecondComparatorOptions: false } }, watch: { @@ -132,7 +209,7 @@ this.firstComparator = this.modelValue && this.modelValue.first_comparator ? this.modelValue.first_comparator : '>='; this.secondComparator = this.modelValue && this.modelValue.second_comparator ? this.modelValue.second_comparator : '<='; this.acceptDateInterval = this.modelValue && this.modelValue.accept_date_interval ? this.modelValue.accept_date_interval : 'no'; - + this.loading = true; this.fetchMetadata(); @@ -204,4 +281,38 @@ }, } } - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue index a51506939..b46b1efeb 100644 --- a/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/TainacanFilterDatesIntersection.vue @@ -159,11 +159,16 @@ if (index >= 0) { let metadata = this.query.metaquery[ index ]; - if (metadata.value && metadata.value.length > 0) { - const dateValueInit = new Date(metadata.value[0].replace(/-/g, '/')); - this.dateInit = moment(dateValueInit, moment.ISO_8601).toDate(); - const dateValueEnd = new Date(metadata.value[1].replace(/-/g, '/')); - this.dateEnd = moment(dateValueEnd, moment.ISO_8601).toDate(); + if (metadata.value ) { + if ( Array.isArray(metadata.value) && metadata.value.length > 0 ) { + const dateValueInit = new Date(metadata.value[0].replace(/-/g, '/')); + this.dateInit = moment(dateValueInit, moment.ISO_8601).toDate(); + const dateValueEnd = new Date(metadata.value[1].replace(/-/g, '/')); + 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 { this.dateInit = null; @@ -186,23 +191,27 @@ values = [ dateInit, dateEnd ]; } - this.$emit('input', { - filter: 'intersection', - type: 'DATE', - compare: this.filterTypeOptions.first_comparator, - metadatum_id: this.metadatumId, - collection_id: this.collectionId, - value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0] - }); - this.$emit('input', { - filter: 'intersection', - type: 'DATE', - compare: this.filterTypeOptions.second_comparator, - metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, - collection_id: this.collectionId, - value: this.filterTypeOptions.accept_date_interval === 'yes' ? values : values[0], - secondary: true - }); + if ( this.filterTypeOptions.accept_date_interval !== 'yes' ) { + this.$emit('input', { + filter: 'intersection', + type: 'DATE', + compare: this.filterTypeOptions.first_comparator, + metadatum_id: this.metadatumId, + collection_id: this.collectionId, + value: values[0] + }); + this.$emit('input', { + filter: 'intersection', + type: 'DATE', + compare: this.filterTypeOptions.second_comparator, + metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, + collection_id: this.collectionId, + value: values[0], + secondary: true + }); + } else { + // Much more complicated logic to be implemented in the future. See #889 + } } } } diff --git a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php index 13ae80953..4e87802d4 100644 --- a/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php +++ b/src/views/admin/components/filter-types/dates-intersection/class-tainacan-dates-intersection.php @@ -34,17 +34,6 @@ class Dates_Intersection extends Filter_Type { -

until

-
- -
'); diff --git a/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue b/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue index bb2384fbd..45180670f 100644 --- a/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue +++ b/src/views/admin/components/filter-types/numerics-intersection/FormNumericsIntersection.vue @@ -3,9 +3,11 @@
-
+
+ +

+ {{ $i18n.get('info_intersection_explainer') }} + + + +

+
- + +

+   + {{ filter.metadatum.metadatum_name }} +

+ +
+
+ {{ $i18n.get('label_and') }} +
- + +

 {{ secondNumericMetadatumName }}

+ +
-
- + + +
@@ -204,7 +280,9 @@ firstComparator: String, secondComparator: String, comparatorsObject: {}, - acceptNumericInterval: String + acceptNumericInterval: String, + showEditFirstComparatorOptions: false, + showEditSecondComparatorOptions: false } }, watch: { @@ -295,4 +373,38 @@ }, } } - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue b/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue index 6805d6acc..5981bd661 100644 --- a/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue +++ b/src/views/admin/components/filter-types/numerics-intersection/TainacanFilterNumericsIntersection.vue @@ -94,22 +94,26 @@ let values = [ this.valueInit, this.valueEnd ]; let type = ! Number.isInteger( this.valueInit ) || ! Number.isInteger( this.valueEnd ) ? 'DECIMAL(20,3)' : 'NUMERIC'; - this.$emit('input', { - filter: 'intersection', - type: type, - compare: this.filterTypeOptions.first_comparator, - metadatum_id: this.metadatumId, - collection_id: this.collectionId, - value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0] - }); - this.$emit('input', { - filter: 'intersection', - type: type, - compare: this.filterTypeOptions.second_comparator, - metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, - collection_id: this.collectionId, - value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0] - }); + if ( this.filterTypeOptions.accept_numeric_interval !== 'yes' ) { + this.$emit('input', { + filter: 'intersection', + type: type, + compare: this.filterTypeOptions.first_comparator, + metadatum_id: this.metadatumId, + collection_id: this.collectionId, + value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0] + }); + this.$emit('input', { + filter: 'intersection', + type: type, + compare: this.filterTypeOptions.second_comparator, + metadatum_id: this.filterTypeOptions.secondary_filter_metadatum_id, + collection_id: this.collectionId, + value: this.filterTypeOptions.accept_numeric_interval === 'yes' ? values : values[0] + }); + } else { + // Much more complicated logic to be implemented in the future. See #889 + } }, updateSelectedValues(){ if ( !this.query || !this.query.metaquery || !Array.isArray( this.query.metaquery ) ) @@ -119,9 +123,13 @@ 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 ) { + if ( Array.isArray(metaquery.value) && metaquery.value.length > 1 ) { + this.valueInit = new Number(metaquery.value[0]); + this.valueEnd = new Number(metaquery.value[1]); + } else { + this.valueInit = new Number(metaquery.value); + } } } else { this.valueInit = null; diff --git a/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php b/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php index b53da5ab8..6ab929e7e 100644 --- a/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php +++ b/src/views/admin/components/filter-types/numerics-intersection/class-tainacan-numerics-intersection.php @@ -44,26 +44,6 @@ class Numerics_Intersection extends Filter_Type {

-

until

-
-

- -

-
- -
-

- -

-
'); } diff --git a/src/views/admin/pages/lists/filters-page.vue b/src/views/admin/pages/lists/filters-page.vue index 921dd650d..c19d6b871 100644 --- a/src/views/admin/pages/lists/filters-page.vue +++ b/src/views/admin/pages/lists/filters-page.vue @@ -976,7 +976,7 @@ export default { } &:not(.available-metadata-area){ - margin-right: var(--tainacan-one-column); + margin-right: 30px; flex-grow: 2; @media screen and (max-width: 769px) { diff --git a/src/views/tainacan-i18n.php b/src/views/tainacan-i18n.php index ab0ebc810..ca131e628 100644 --- a/src/views/tainacan-i18n.php +++ b/src/views/tainacan-i18n.php @@ -529,6 +529,7 @@ return apply_filters( 'tainacan-i18n', [ 'label_view_all_%s_collections' => __( 'View all %s collections', 'tainacan' ), 'label_view_collections_list' => __( 'View collections list', 'tainacan' ), 'label_comparator' => __( 'Comparator', 'tainacan' ), + 'label_comparators' => __( 'Comparators', 'tainacan' ), 'label_table_of_items' => __( 'Table of Items', 'tainacan' ), 'label_create_another_item' => __( 'Create another item', '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_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_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 */ 'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'), From 20c2a3cc1a79ad088b3f7db4af0906b7c965a860 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Sat, 8 Jun 2024 16:44:05 -0300 Subject: [PATCH 12/39] Adds intersection observer to watch map visibility in geocoordinate metadatum and prevent it from being broken in certain scenarios. --- .../geocoordinate-item-metadatum/theme.js | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/theme.js b/src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/theme.js index 7608871fc..457260b55 100644 --- a/src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/theme.js +++ b/src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/theme.js @@ -7,6 +7,7 @@ import iconUrl from 'leaflet/dist/images/marker-icon.png'; import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png'; import shadowUrl from 'leaflet/dist/images/marker-shadow.png'; +// Defines custom marker icons delete TainacanLeaflet.Icon.Default.prototype._getIconUrl; TainacanLeaflet.Icon.Default.mergeOptions({ iconRetinaUrl: iconRetinaUrl, @@ -14,6 +15,48 @@ TainacanLeaflet.Icon.Default.mergeOptions({ shadowUrl: shadowUrl }); +// Observes the visibility of the map container to resize the map when it becomes visible +const mapObserverOptions = { + root: null, // use the viewport + rootMargin: '0px', + threshold: 0.1 // 10% of the element is visible +}; + +// The mapObserver repeats part of the initialization logic to prevent the map from looking broke +// when it becomes visible after being hidden, for example inside section tabs +const mapObserver = new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + if ( + entry && + entry.target.id && + window.tainacan_leaflet_maps && + window.tainacan_leaflet_maps[entry.target.id] + ) { + const element = entry.target; + + const children = element.children ? element.children : []; + if ( !children.length ) + return; + + const coordinates = []; + for (let i = 0; i < children.length; i++) { + if ( children[i].hasAttribute('data-latitude') && children[i].hasAttribute('data-longitude') ) + coordinates.push([children[i].getAttribute('data-latitude'), children[i].getAttribute('data-longitude')]); + } + + if ( !coordinates.length ) + return; + + const maximum_zoom = element.hasAttribute('data-maximum_zoom') ? element.getAttribute('data-maximum_zoom') : 12; + + window.tainacan_leaflet_maps[element.id].invalidateSize(true); + window.tainacan_leaflet_maps[element.id].flyToBounds(coordinates, { maxZoom: maximum_zoom, animate: false }); + } + } + }); +}, mapObserverOptions); + /* Loads and instantiates map components passed to data-module="geocoordinate-item-metadatum"*/ export default (element) => { if (element && element.id) { @@ -54,7 +97,13 @@ export default (element) => { coordinates.forEach(coordinate => { TainacanLeaflet.marker(coordinate).addTo(tainacanMap); }); - + tainacanMap.flyToBounds(coordinates, { maxZoom: maximum_zoom }); + + mapObserver.observe(element); + + // Stores referenced to the leaflet instances to manipulate them via the window object inside the observer + window.tainacan_leaflet_maps = typeof window.tainacan_leaflet_maps != "undefined" ? window.tainacan_leaflet_maps : {}; + window.tainacan_leaflet_maps[element.id] = tainacanMap; } }; \ No newline at end of file From 36aaa845f6a0de3926c22367a4ed008d152addf2 Mon Sep 17 00:00:00 2001 From: mateuswetah Date: Mon, 10 Jun 2024 14:12:56 -0300 Subject: [PATCH 13/39] Small fixes to intersection filters form. #887. --- .../components/edition/filter-edition-form.vue | 13 +++++++++---- .../dates-intersection/FormDatesIntersection.vue | 2 +- .../FormNumericsIntersection.vue | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/views/admin/components/edition/filter-edition-form.vue b/src/views/admin/components/edition/filter-edition-form.vue index 959ceb074..5b1da823a 100644 --- a/src/views/admin/components/edition/filter-edition-form.vue +++ b/src/views/admin/components/edition/filter-edition-form.vue @@ -292,12 +292,16 @@ export default { } }, created() { - + this.form = this.editedFilter; this.formErrors = this.form.formErrors != undefined ? this.form.formErrors : {}; this.formErrorMessage = this.form.formErrors != undefined ? this.form.formErrorMessage : ''; this.oldForm = JSON.parse(JSON.stringify(this.originalFilter)); + + if ( this.form.metadatum == undefined && this.oldForm.metadatum != undefined ) + this.form.metadatum = this.oldForm.metadatum; + }, mounted() { // Fills hook forms with it's real values @@ -322,9 +326,11 @@ export default { 'updateFilter' ]), saveEdition(filter) { + + this.isLoading = true; + if ((filter.filter_type_object && filter.filter_type_object.form_component) || filter.edit_form == '') { - - this.isLoading = true; + for (let [key, value] of Object.entries(this.form)) { if (key === 'begin_with_filter_collapsed' || key === 'display_in_repository_level_lists') this.form[key] = (value == 'yes' || value == true) ? 'yes' : 'no'; @@ -372,7 +378,6 @@ export default { formObj['display_in_repository_level_lists'] = 'no'; this.fillExtraFormData(formObj); - this.isLoading = true; this.updateFilter({ filterId: filter.id, index: this.index, options: formObj }) .then(() => { this.form = {}; diff --git a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue index d9bea5a41..7a0aecb3e 100644 --- a/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue +++ b/src/views/admin/components/filter-types/dates-intersection/FormDatesIntersection.vue @@ -24,7 +24,7 @@ {{ $i18n.get('instruction_select_second_date_to_compare' ) }}