From f34ab39f2c4d29cdf1b308722ba805c72e316808 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Thu, 5 Jun 2025 16:52:49 +0200 Subject: [PATCH 01/16] IBX-9807: Introduce date range single component --- .../Resources/encore/ibexa.js.config.js | 2 + .../scripts/admin.date.time.range.single.js | 12 ++ .../public/js/scripts/admin.search.filters.js | 127 +++++------------- .../public/js/scripts/admin.trash.list.js | 74 +++------- .../js/scripts/core/date.time.picker.js | 3 +- .../js/scripts/core/date.time.range.single.js | 88 ++++++++++++ .../public/scss/_date-time-range-single.scss | 11 ++ .../Resources/public/scss/_filters.scss | 20 --- .../public/scss/_trash-search-form.scss | 22 +-- src/bundle/Resources/public/scss/ibexa.scss | 1 + .../date_time_range_single.twig | 29 ++++ .../themes/admin/ui/form_fields.html.twig | 69 ++++------ .../themes/admin/ui/search/filters.html.twig | 2 - 13 files changed, 224 insertions(+), 236 deletions(-) create mode 100644 src/bundle/Resources/public/js/scripts/admin.date.time.range.single.js create mode 100644 src/bundle/Resources/public/js/scripts/core/date.time.range.single.js create mode 100644 src/bundle/Resources/public/scss/_date-time-range-single.scss create mode 100644 src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig diff --git a/src/bundle/Resources/encore/ibexa.js.config.js b/src/bundle/Resources/encore/ibexa.js.config.js index b0e571de94..bf42ec470b 100644 --- a/src/bundle/Resources/encore/ibexa.js.config.js +++ b/src/bundle/Resources/encore/ibexa.js.config.js @@ -22,6 +22,7 @@ const layout = [ path.resolve(__dirname, '../public/js/scripts/core/toggle.button.js'), path.resolve(__dirname, '../public/js/scripts/core/slug.value.input.autogenerator.js'), path.resolve(__dirname, '../public/js/scripts/core/date.time.picker.js'), + path.resolve(__dirname, '../public/js/scripts/core/date.time.range.single.js'), path.resolve(__dirname, '../public/js/scripts/core/taggify.js'), path.resolve(__dirname, '../public/js/scripts/core/suggestion.taggify.js'), path.resolve(__dirname, '../public/js/scripts/core/storage.js'), @@ -49,6 +50,7 @@ const layout = [ path.resolve(__dirname, '../public/js/scripts/admin.table.js'), path.resolve(__dirname, '../public/js/scripts/core/collapse.js'), path.resolve(__dirname, '../public/js/scripts/admin.dropdown.js'), + path.resolve(__dirname, '../public/js/scripts/admin.date.time.range.single.js'), path.resolve(__dirname, '../public/js/scripts/double.click.mark.js'), path.resolve(__dirname, '../public/js/scripts/autogenerate.identifier.js'), path.resolve(__dirname, '../public/js/scripts/admin.back.to.top.js'), diff --git a/src/bundle/Resources/public/js/scripts/admin.date.time.range.single.js b/src/bundle/Resources/public/js/scripts/admin.date.time.range.single.js new file mode 100644 index 0000000000..64dcc2774d --- /dev/null +++ b/src/bundle/Resources/public/js/scripts/admin.date.time.range.single.js @@ -0,0 +1,12 @@ +(function (global, doc, ibexa) { + const { DateTimeRangeSingle } = ibexa.core; + const containers = doc.querySelectorAll('.ibexa-date-time-range-single'); + + containers.forEach((container) => { + const dateTimeRangeSingle = new DateTimeRangeSingle({ + container, + }); + + dateTimeRangeSingle.init(); + }); +})(window, window.document, window.ibexa); diff --git a/src/bundle/Resources/public/js/scripts/admin.search.filters.js b/src/bundle/Resources/public/js/scripts/admin.search.filters.js index 293225b017..02f6dca698 100644 --- a/src/bundle/Resources/public/js/scripts/admin.search.filters.js +++ b/src/bundle/Resources/public/js/scripts/admin.search.filters.js @@ -1,22 +1,24 @@ (function (global, doc, ibexa, flatpickr, React, ReactDOM) { const { escapeHTML, escapeHTMLAttribute } = ibexa.helpers.text; const { dangerouslySetInnerHTML } = ibexa.helpers.dom; + const { getInstance } = ibexa.helpers.objectInstances; let getUsersTimeout; - const CLASS_DATE_RANGE = 'ibexa-filters__range-wrapper'; - const CLASS_VISIBLE_DATE_RANGE = 'ibexa-filters__range-wrapper--visible'; const SELECTOR_TAG = '.ibexa-tag'; const token = doc.querySelector('meta[name="CSRF-Token"]').content; const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content; const filters = doc.querySelector('.ibexa-filters'); const clearBtn = filters.querySelector('.ibexa-btn--clear'); const applyBtn = filters.querySelector('.ibexa-btn--apply'); - const dateFields = doc.querySelectorAll('.ibexa-filters__range-wrapper'); const contentTypeSelect = doc.querySelector('.ibexa-filters__item--content-type .ibexa-filters__select'); const sectionSelect = doc.querySelector('.ibexa-filters__item--section .ibexa-filters__select'); - const lastModifiedSelect = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__select'); - const lastModifiedDateRange = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__range-select'); - const lastCreatedSelect = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__select'); - const lastCreatedDateRange = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__range-select'); + const lastModifiedSelectNode = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__select'); + const lastModifiedSelect = getInstance(lastModifiedSelectNode); + const lastModifiedDateRangeNode = doc.querySelector('.ibexa-filters__item--modified .ibexa-date-time-range-single'); + const lastModifiedDateRange = getInstance(lastModifiedDateRangeNode); + const lastCreatedSelectNode = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__select'); + const lastCreatedSelect = getInstance(lastCreatedSelectNode); + const lastCreatedDateRangeNode = doc.querySelector('.ibexa-filters__item--created .ibexa-date-time-range-single'); + const lastCreatedDateRange = getInstance(lastCreatedDateRangeNode); const creatorInput = doc.querySelector('.ibexa-filters__item--creator .ibexa-input'); const searchCreatorInput = doc.querySelector('#search_creator'); const usersList = doc.querySelector('.ibexa-filters__item--creator .ibexa-filters__user-list'); @@ -24,20 +26,13 @@ const selectSubtreeBtn = doc.querySelector('.ibexa-filters__item--subtree .ibexa-tag-view-select__btn-select-path'); const subtreeInput = doc.querySelector('#search_subtree'); const showMoreBtns = doc.querySelectorAll('.ibexa-content-type-selector__show-more'); - const dateConfig = { - mode: 'range', - locale: { - rangeSeparator: ' - ', - }, - formatDate: (date) => ibexa.helpers.timezone.formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate), - }; const clearFilters = (event) => { event.preventDefault(); const option = contentTypeSelect.querySelector('option'); const defaultText = option.dataset.default; - const lastModifiedDataRange = doc.querySelector(lastModifiedSelect.dataset.targetSelector); - const lastCreatedDataRange = doc.querySelector(lastCreatedSelect.dataset.targetSelector); + const lastModifiedDataRange = doc.querySelector(lastModifiedSelectNode.dataset.targetSelector); + const lastCreatedDataRange = doc.querySelector(lastCreatedSelectNode.dataset.targetSelector); const lastModifiedPeriod = doc.querySelector(lastModifiedDataRange.dataset.periodSelector); const lastModifiedEnd = doc.querySelector(lastModifiedDataRange.dataset.endSelector); const lastCreatedPeriod = doc.querySelector(lastCreatedDataRange.dataset.periodSelector); @@ -53,9 +48,9 @@ sectionSelect[0].selected = true; } - lastModifiedSelect[0].selected = true; - lastCreatedSelect[0].selected = true; - lastModifiedSelect.querySelector('option').selected = true; + lastModifiedSelectNode[0].selected = true; + lastCreatedSelectNode[0].selected = true; + lastModifiedSelectNode.querySelector('option').selected = true; lastModifiedPeriod.value = ''; lastModifiedEnd.value = ''; lastCreatedPeriod.value = ''; @@ -72,12 +67,11 @@ const isSectionSelected = sectionSelect ? !!sectionSelect.value : false; const isCreatorSelected = !!searchCreatorInput.value; const isSubtreeSelected = !!subtreeInput.value.trim().length; - let isModifiedSelected = !!lastModifiedSelect.value; - let isCreatedSelected = !!lastCreatedSelect.value; + let isModifiedSelected = !!lastModifiedSelectNode.value; + let isCreatedSelected = !!lastCreatedSelectNode.value; - if (lastModifiedSelect.value === 'custom_range') { - const lastModifiedWrapper = lastModifiedDateRange.closest(`.${CLASS_DATE_RANGE}`); - const { periodSelector, endSelector } = lastModifiedWrapper.dataset; + if (lastModifiedSelectNode.value === 'custom_range') { + const { periodSelector, endSelector } = lastModifiedDateRangeNode.dataset; const lastModifiedPeriodValue = doc.querySelector(periodSelector).value; const lastModifiedEndDate = doc.querySelector(endSelector).value; @@ -86,9 +80,8 @@ } } - if (lastCreatedSelect.value === 'custom_range') { - const lastCreatedWrapper = lastCreatedDateRange.closest(`.${CLASS_DATE_RANGE}`); - const { periodSelector, endSelector } = lastCreatedWrapper.dataset; + if (lastCreatedSelectNode.value === 'custom_range') { + const { periodSelector, endSelector } = lastCreatedDateRangeNode.dataset; const lastCreatedPeriodValue = doc.querySelector(periodSelector).value; const lastCreatedEndDate = doc.querySelector(endSelector).value; @@ -103,20 +96,17 @@ applyBtn[methodName]('disabled', !isEnabled); }; - const toggleDatesSelectVisibility = (event) => { - const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector); - - if (event.target.value !== 'custom_range') { - doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value; - doc.querySelector(datesRangeNode.dataset.endSelector).value = ''; - datesRangeNode.classList.remove(CLASS_VISIBLE_DATE_RANGE); + const toggleDatesSelectVisibility = (select, dateRange) => { + if (select.value !== 'custom_range') { + dateRange.setDates([]); + dateRange.toggleHidden(true); toggleDisabledStateOnApplyBtn(); return; } - datesRangeNode.classList.add(CLASS_VISIBLE_DATE_RANGE); + dateRange.toggleHidden(false); }; const filterByContentType = () => { const selectedCheckboxes = [...contentTypeCheckboxes].filter((checkbox) => checkbox.checked); @@ -128,31 +118,6 @@ toggleDisabledStateOnApplyBtn(); }; - const setSelectedDateRange = (timestamps, { dates, inputField }) => { - const dateRange = inputField.closest('.ibexa-filters__range-wrapper'); - - if (dates.length === 2) { - const startDate = getUnixTimestampUTC(dates[0]); - const endDate = getUnixTimestampUTC(dates[1]); - const secondsInDay = 86400; - const days = (endDate - startDate) / secondsInDay; - - doc.querySelector(dateRange.dataset.periodSelector).value = `P0Y0M${days}D`; - doc.querySelector(dateRange.dataset.endSelector).value = endDate; - } else if (dates.length === 0) { - doc.querySelector(dateRange.dataset.periodSelector).value = ''; - doc.querySelector(dateRange.dataset.endSelector).value = ''; - } - - toggleDisabledStateOnApplyBtn(); - }; - const getUnixTimestampUTC = (dateObject) => { - let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate())); - - date = Math.floor(date.getTime() / 1000); - - return date; - }; const getUsersList = (value) => { const body = JSON.stringify({ ViewInput: { @@ -244,21 +209,6 @@ usersList.classList.add('ibexa-filters__user-list--hidden'); doc.querySelector('body').removeEventListener('click', handleClickOutsideUserList, false); }; - const initFlatPickr = (dateRangeField) => { - const { start, end } = dateRangeField.querySelector('.ibexa-filters__range-select').dataset; - const defaultDate = start && end ? [start, end] : []; - - const dateTimePickerWidget = new ibexa.core.DateTimePicker({ - container: dateRangeField, - onChange: setSelectedDateRange, - flatpickrConfig: { - ...dateConfig, - defaultDate, - }, - }); - - dateTimePickerWidget.init(); - }; const removeSearchTag = (event) => { const tag = event.currentTarget.closest(SELECTOR_TAG); const form = event.currentTarget.closest('form'); @@ -281,16 +231,10 @@ subtreeInput.value = ''; removeSearchTag(event); }; - const clearDataRange = (event, selector) => { - const dataRange = doc.querySelector(selector); - const rangeSelect = dataRange.parentNode.querySelector('.ibexa-filters__select'); - const periodInput = doc.querySelector(dataRange.dataset.periodSelector); - const endDateInput = doc.querySelector(dataRange.dataset.endSelector); - - rangeSelect[0].selected = true; - periodInput.value = ''; - endDateInput.vaue = ''; - dataRange.classList.remove(CLASS_VISIBLE_DATE_RANGE); + const clearDataRange = (event, select, dateRange) => { + select.clearCurrentSelection(); + dateRange.setDates([]); + dateRange.toggleHidden(true); removeSearchTag(event); }; const clearCreator = (event) => { @@ -302,8 +246,8 @@ subtree: (event) => clearSubtree(event), creator: (event) => clearCreator(event), 'content-types': (event) => clearContentType(event), - 'last-modified': (event) => clearDataRange(event, lastModifiedSelect.dataset.targetSelector), - 'last-created': (event) => clearDataRange(event, lastCreatedSelect.dataset.targetSelector), + 'last-modified': (event) => clearDataRange(event, lastModifiedSelect, lastModifiedDateRange), + 'last-created': (event) => clearDataRange(event, lastCreatedSelect, lastCreatedDateRange), }; const showMoreContentTypes = (event) => { const btn = event.currentTarget; @@ -347,7 +291,6 @@ ); }; - dateFields.forEach(initFlatPickr); filterByContentType(); clearBtn.addEventListener('click', clearFilters, false); @@ -363,8 +306,12 @@ } subtreeInput.addEventListener('change', toggleDisabledStateOnApplyBtn, false); - lastModifiedSelect.addEventListener('change', toggleDatesSelectVisibility, false); - lastCreatedSelect.addEventListener('change', toggleDatesSelectVisibility, false); + lastModifiedSelectNode.addEventListener( + 'change', + () => toggleDatesSelectVisibility(lastModifiedSelectNode, lastModifiedDateRange), + false, + ); + lastCreatedSelectNode.addEventListener('change', () => toggleDatesSelectVisibility(lastCreatedSelectNode, lastCreatedDateRange), false); creatorInput.addEventListener('keyup', handleTyping, false); usersList.addEventListener('click', handleSelectUser, false); contentTypeCheckboxes.forEach((checkbox) => checkbox.addEventListener('change', filterByContentType, false)); diff --git a/src/bundle/Resources/public/js/scripts/admin.trash.list.js b/src/bundle/Resources/public/js/scripts/admin.trash.list.js index dc59f3cc0e..3dc39d79a8 100644 --- a/src/bundle/Resources/public/js/scripts/admin.trash.list.js +++ b/src/bundle/Resources/public/js/scripts/admin.trash.list.js @@ -1,13 +1,14 @@ (function (global, doc, ibexa, React, ReactDOM, Translator) { const { escapeHTML, escapeHTMLAttribute } = ibexa.helpers.text; const { dangerouslySetInnerHTML } = ibexa.helpers.dom; + const { getInstance } = ibexa.helpers.objectInstances; let getUsersTimeout; const CLASS_SORTED_ASC = 'ibexa-table__sort-column--asc'; const CLASS_SORTED_DESC = 'ibexa-table__sort-column--desc'; - const CLASS_VISIBLE_DATE_RANGE = 'ibexa-trash-search-form__range-wrapper--visible'; const sortedActiveField = doc.querySelector('#trash_search_sort_field').value; const sortedActiveDirection = doc.querySelector('#trash_search_sort_direction').value; - const dateFields = doc.querySelectorAll('.ibexa-trash-search-form__range-wrapper'); + const trashedDateTimeRangeNode = doc.querySelector('.ibexa-trash-search-form__trashed-date-time-range'); + const trashedDateTimeRange = getInstance(trashedDateTimeRangeNode); const trashedTypeInput = doc.querySelector('#trash_search_trashed'); const token = doc.querySelector('meta[name="CSRF-Token"]').content; const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content; @@ -23,13 +24,6 @@ const udwContainer = doc.getElementById('react-udw'); const autoSendNodes = doc.querySelectorAll('.ibexa-trash-search-form__item--auto-send'); const errorMessage = Translator.trans(/*@Desc("Cannot fetch user list")*/ 'trash.user_list.error', {}, 'ibexa_trash_ui'); - const dateConfig = { - mode: 'range', - locale: { - rangeSeparator: ' - ', - }, - formatDate: (date) => ibexa.helpers.timezone.formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate), - }; let udwRoot = null; const closeUDW = () => udwRoot.unmount(); const onConfirm = (form, content) => { @@ -200,59 +194,14 @@ formSearch.submit(); }; const toggleDatesSelectVisibility = (event) => { - const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector); - if (event.target.value !== 'custom_range') { - doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value; - doc.querySelector(datesRangeNode.dataset.endSelector).value = ''; - datesRangeNode.classList.remove(CLASS_VISIBLE_DATE_RANGE); - formSearch.submit(); + trashedDateTimeRange.setDates([]); + trashedDateTimeRange.toggleHidden(true); return; } - datesRangeNode.classList.add(CLASS_VISIBLE_DATE_RANGE); - }; - const setSelectedDateRange = (timestamps, { dates, inputField }) => { - const dateRange = inputField.closest('.ibexa-trash-search-form__range-wrapper'); - - if (dates.length === 2) { - const startDate = getUnixTimestampUTC(dates[0]); - const endDate = getUnixTimestampUTC(dates[1]); - const secondsInDay = 86400; - const days = (endDate - startDate) / secondsInDay; - - doc.querySelector(dateRange.dataset.periodSelector).value = `P0Y0M${days}D`; - doc.querySelector(dateRange.dataset.endSelector).value = endDate; - - formSearch.submit(); - } else if (dates.length === 0) { - doc.querySelector(dateRange.dataset.periodSelector).value = ''; - doc.querySelector(dateRange.dataset.endSelector).value = ''; - - formSearch.submit(); - } - }; - const getUnixTimestampUTC = (dateObject) => { - let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate())); - date = Math.floor(date.getTime() / 1000); - - return date; - }; - const initFlatPickr = (dateRangeField) => { - const { start, end } = dateRangeField.querySelector('.ibexa-trash-search-form__range-select').dataset; - const defaultDate = start && end ? [start, end] : []; - - const dateTimePickerWidget = new ibexa.core.DateTimePicker({ - container: dateRangeField, - onChange: setSelectedDateRange, - flatpickrConfig: { - ...dateConfig, - defaultDate, - }, - }); - - dateTimePickerWidget.init(); + trashedDateTimeRange.toggleHidden(false); }; const handleAutoSubmitNodes = (event) => { event.preventDefault(); @@ -282,7 +231,16 @@ }; setSortedClass(); - dateFields.forEach(initFlatPickr); + trashedDateTimeRangeNode.addEventListener( + 'ibexa:date-time-range-single:change', + (event) => { + const { dates } = event.detail; + if (dates.length === 2 || dates.length === 0) { + formSearch.submit(); + } + }, + false, + ); autoSendNodes.forEach((node) => node.addEventListener('change', handleAutoSubmitNodes, false)); sortableColumns.forEach((column) => column.addEventListener('click', sortTrashItems, false)); trashedTypeInput.addEventListener('change', toggleDatesSelectVisibility, false); diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js index e6030c918f..ebe436f7d7 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js @@ -32,7 +32,8 @@ class DateTimePicker { ...(config.flatpickrConfig ?? {}), }; - setInstance(this.container, this); + setInstance(this.container, this); // TODO: reove in 5.0 + setInstance(this.fieldWrapper, this); } clear() { diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js new file mode 100644 index 0000000000..c9d9bf8b9e --- /dev/null +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -0,0 +1,88 @@ +import { formatShortDateTime } from '../helpers/timezone.helper'; +import { setInstance } from '../helpers/object.instances'; + +const { ibexa } = window; + +class DateTimeRangeSingle { + constructor(config) { + this.container = config.container; + this.dateTimePickerInputWrapper = this.container.querySelector('.ibexa-date-time-range-single__date-time-picker-input-wrapper'); + + const { periodSelector, endSelector } = this.container.dataset; + this.periodInput = window.document.querySelector(periodSelector); + this.endInput = window.document.querySelector(endSelector); + + const customDateConfig = config.dateConfig || {}; + this.dateConfig = { + mode: 'range', + locale: { + rangeSeparator: ' - ', + }, + formatDate: (date) => formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate), + ...customDateConfig, + }; + + this.setSelectedDateRange = this.setSelectedDateRange.bind(this); + + setInstance(this.container, this); + } + + getUnixTimestampUTC(dateObject) { + let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate())); + date = Math.floor(date.getTime() / 1000); + + return date; + } + + setDates(dates) { + if (dates.length === 2) { + const startDate = this.getUnixTimestampUTC(dates[0]); + const endDate = this.getUnixTimestampUTC(dates[1]); + const secondsInDay = 86400; + const days = (endDate - startDate) / secondsInDay; + + this.periodInput.value = `P0Y0M${days}D`; + this.endInput.value = endDate; + } else if (dates.length === 0) { + this.periodInput.value = ''; + this.endInput.value = ''; + } + } + + setSelectedDateRange(timestamps, { dates }) { + this.setDates(dates); + + this.container.dispatchEvent( + new CustomEvent('ibexa:date-time-range-single:change', { + detail: { + timestamps, + dates, + }, + }), + ); + } + + toggleHidden(isHidden) { + this.container.classList.toggle('ibexa-date-time-range-single--hidden', isHidden); + } + + init() { + const { start, end } = this.container.dataset; + const defaultDate = start && end ? [start, end] : []; + + const dateTimePickerWidget = new ibexa.core.DateTimePicker({ + container: this.dateTimePickerInputWrapper, + onChange: this.setSelectedDateRange, + flatpickrConfig: { + ...this.dateConfig, + defaultDate, + }, + }); + + dateTimePickerWidget.init(); + } +} + +ibexa?.addConfig('core.DateTimeRangeSingle', DateTimeRangeSingle); + +export { DateTimeRangeSingle as DateRangeSingle }; diff --git a/src/bundle/Resources/public/scss/_date-time-range-single.scss b/src/bundle/Resources/public/scss/_date-time-range-single.scss new file mode 100644 index 0000000000..919a8ae920 --- /dev/null +++ b/src/bundle/Resources/public/scss/_date-time-range-single.scss @@ -0,0 +1,11 @@ +.ibexa-date-time-range-single { + margin-top: calculateRem(16px); + + &--hidden { + height: 0; + width: 0; + opacity: 0; + transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; + pointer-events: none; + } +} diff --git a/src/bundle/Resources/public/scss/_filters.scss b/src/bundle/Resources/public/scss/_filters.scss index f750df9da6..c717edf5f3 100644 --- a/src/bundle/Resources/public/scss/_filters.scss +++ b/src/bundle/Resources/public/scss/_filters.scss @@ -69,26 +69,6 @@ } } - &__range-wrapper { - height: 0; - opacity: 0; - background: $ibexa-color-white; - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - pointer-events: none; - - &--visible { - height: calculateRem(40px); - opacity: 1; - pointer-events: auto; - margin-top: calculateRem(16px); - } - } - - &__range-select { - outline: none; - border-radius: $ibexa-border-radius-small; - } - &__header { display: flex; align-items: center; diff --git a/src/bundle/Resources/public/scss/_trash-search-form.scss b/src/bundle/Resources/public/scss/_trash-search-form.scss index 98ec779992..b5cae6933e 100644 --- a/src/bundle/Resources/public/scss/_trash-search-form.scss +++ b/src/bundle/Resources/public/scss/_trash-search-form.scss @@ -94,25 +94,7 @@ } } - &__range-wrapper { - width: 0; - opacity: 0; - background: $ibexa-color-white; - border: calculateRem(1px) solid $ibexa-color-white; - border-radius: calculateRem(4px); - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - pointer-events: none; - overflow: hidden; - - &--visible { - width: auto; - margin-left: calculateRem(16px); - opacity: 1; - pointer-events: auto; - } - } - - &__range-select { - outline: none; + .ibexa-date-time-range-single:not(.ibexa-date-time-range-single--hidden) { + margin-left: calculateRem(16px); } } diff --git a/src/bundle/Resources/public/scss/ibexa.scss b/src/bundle/Resources/public/scss/ibexa.scss index bb74981f5f..8e7404b4b1 100644 --- a/src/bundle/Resources/public/scss/ibexa.scss +++ b/src/bundle/Resources/public/scss/ibexa.scss @@ -117,6 +117,7 @@ @import 'object-state-group-view'; @import 'back-to-top'; @import 'date-time-picker'; +@import 'date-time-range-single'; @import 'middle-ellipsis'; @import 'user-thumbnail'; @import 'user-group-invitation'; diff --git a/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig new file mode 100644 index 0000000000..78a991ea24 --- /dev/null +++ b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig @@ -0,0 +1,29 @@ +{% import '@ibexadesign/ui/component/macros.html.twig' as html %} + +{% set attr = attr|default({})|merge({ + class: ('ibexa-date-time-range-single ' + ~ (is_hidden|default(false) ? 'ibexa-date-time-range-single--hidden ') + ~ attr.class|default(''))|trim, + 'data-period-selector': period_input_selector, + 'data-end-selector': end_input_selector, + 'data-start': start_date is defined and start_date is not null + ? start_date|date('Y-m-d') : '', + 'data-end': end_date is defined and end_date is not null + ? end_date|date('Y-m-d') : '', +}) %} + +{% set picker_wrapper_attr = picker_wrapper_attr|default({})|merge({ + class: ('ibexa-date-time-range-single__date-time-picker-input-wrapper ' + ~ picker_wrapper_attr.class|default(''))|trim, +}) %} + +
+
+ {% include '@ibexadesign/ui/component/inputs/input_date_time_picker.html.twig' with { + input_attr: { + class: 'ibexa-date-time-range-single__date-time-picker-input', + placeholder: 'search.date.range'|trans({}, 'ibexa_search')|desc('From date - to date'), + }, + } %} +
+
diff --git a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig index 9347ac5abc..750fdcd76a 100644 --- a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig @@ -326,59 +326,38 @@ {%- block _search_last_modified_select_widget -%} {{ form_widget(form) }} -
- {% include '@ibexadesign/ui/component/inputs/input_date_time_picker.html.twig' with { - input_attr: { - class: "ibexa-filters__range-select", - placeholder: 'search.date.range'|trans({}, 'ibexa_search')|desc('From date - to date'), - 'data-start': form.parent.vars.data.lastModified.start_date is defined ? form.parent.vars.data.lastModified.start_date|date("Y-m-d") : '', - 'data-end': form.parent.vars.data.lastModified.end_date is defined ? form.parent.vars.data.lastModified.end_date|date("Y-m-d") : '', - - } - } %} -
+ {% include '@ibexadesign/ui/component/date_time_range_single/date_time_range_single.twig' with { + is_hidden: form.vars.data != 'custom_range', + start_date: form.parent.vars.data.lastModified.start_date|default(null), + end_date: form.parent.vars.data.lastModified.end_date|default(null), + period_input_selector: '#' ~ form.parent.last_modified.children.date_interval.vars.id, + end_input_selector: '#' ~ form.parent.last_modified.children.end_date.vars.id, + } %} {%- endblock -%} {%- block _search_created_select_widget -%} {{ form_widget(form) }} -
- {% include '@ibexadesign/ui/component/inputs/input_date_time_picker.html.twig' with { - input_attr: { - class: "ibexa-filters__range-select", - placeholder: 'search.date.range'|trans({}, 'ibexa_search')|desc('From date - to date'), - 'data-start': form.parent.vars.data.created.start_date is defined ? form.parent.vars.data.created.start_date|date("Y-m-d") : '', - 'data-end': form.parent.vars.data.created.end_date is defined ? form.parent.vars.data.created.end_date|date("Y-m-d") : '', - - } - } %} -
+ {% include '@ibexadesign/ui/component/date_time_range_single/date_time_range_single.twig' with { + is_hidden: form.vars.data != 'custom_range', + start_date: form.parent.vars.data.created.start_date|default(null), + end_date: form.parent.vars.data.created.end_date|default(null), + period_input_selector: '#' ~ form.parent.created.children.date_interval.vars.id, + end_input_selector: '#' ~ form.parent.created.children.end_date.vars.id, + } %} {%- endblock -%} {%- block _trash_search_trashed_row -%} {{ form_row(form) }} -
- {% include '@ibexadesign/ui/component/inputs/input_date_time_picker.html.twig' with { - input_attr: { - class: "ibexa-trash-search-form__range-select", - placeholder: 'search.date.range'|trans({}, 'ibexa_search')|desc('From date - to date'), - 'data-start': form.parent.vars.data.trashedInterval.start_date is defined ? form.parent.vars.data.trashedInterval.start_date|date("Y-m-d") : '', - 'data-end': form.parent.vars.data.trashedInterval.end_date is defined ? form.parent.vars.data.trashedInterval.end_date|date("Y-m-d") : '', - - } - } %} -
+ {% include '@ibexadesign/ui/component/date_time_range_single/date_time_range_single.twig' with { + is_hidden: form.vars.data != 'custom_range', + attr: { + class: 'ibexa-trash-search-form__trashed-date-time-range', + }, + start_date: form.parent.vars.data.trashedInterval.start_date|default(null), + end_date: form.parent.vars.data.trashedInterval.end_date|default(null), + period_input_selector: '#' ~ form.parent.trashed_interval.children.date_interval.vars.id, + end_input_selector: '#' ~ form.parent.trashed_interval.children.end_date.vars.id, + } %} {%- endblock -%} {% block form_errors -%} diff --git a/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig b/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig index b306466b08..063c07add7 100644 --- a/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig @@ -41,7 +41,6 @@ {{ form_widget(form.last_modified_select, { 'attr': { 'class': 'ibexa-filters__select', - 'data-target-selector': '.ibexa-filters__range-wrapper--select-modified-range' } }) }} {{ form_errors(form.last_modified_select) }} @@ -51,7 +50,6 @@ {{ form_widget(form.created_select, { 'attr': { 'class': 'ibexa-filters__select', - 'data-target-selector': '.ibexa-filters__range-wrapper--select-created-range' } }) }} {{ form_errors(form.created_select) }} From bc48fef8858e5c9d61fc8160b83af8cbd92185cc Mon Sep 17 00:00:00 2001 From: tischsoic Date: Fri, 6 Jun 2025 09:49:52 +0200 Subject: [PATCH 02/16] adjust hidden styles --- .../Resources/public/scss/_date-time-range-single.scss | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/bundle/Resources/public/scss/_date-time-range-single.scss b/src/bundle/Resources/public/scss/_date-time-range-single.scss index 919a8ae920..bf521d2ea1 100644 --- a/src/bundle/Resources/public/scss/_date-time-range-single.scss +++ b/src/bundle/Resources/public/scss/_date-time-range-single.scss @@ -2,10 +2,6 @@ margin-top: calculateRem(16px); &--hidden { - height: 0; - width: 0; - opacity: 0; - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - pointer-events: none; + display: none; } } From 4667b8ae517dd50437aaa9289a2ceaf200eb7518 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 9 Jun 2025 13:58:53 +0200 Subject: [PATCH 03/16] fix date time range single in filters --- .../js/scripts/core/date.time.range.single.js | 10 ++++++++++ .../public/js/scripts/filters.action.btns.js | 13 +++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js index c9d9bf8b9e..e6e7583e6f 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -42,10 +42,20 @@ class DateTimeRangeSingle { const days = (endDate - startDate) / secondsInDay; this.periodInput.value = `P0Y0M${days}D`; + this.periodInput.dispatchEvent(new Event('change')); + this.periodInput.dispatchEvent(new Event('input')); + this.endInput.value = endDate; + this.endInput.dispatchEvent(new Event('change')); + this.endInput.dispatchEvent(new Event('input')); } else if (dates.length === 0) { this.periodInput.value = ''; + this.periodInput.dispatchEvent(new Event('change')); + this.periodInput.dispatchEvent(new Event('change')); + this.endInput.value = ''; + this.endInput.dispatchEvent(new Event('change')); + this.endInput.dispatchEvent(new Event('input')); } } diff --git a/src/bundle/Resources/public/js/scripts/filters.action.btns.js b/src/bundle/Resources/public/js/scripts/filters.action.btns.js index e1a82c5747..c2c06a055e 100644 --- a/src/bundle/Resources/public/js/scripts/filters.action.btns.js +++ b/src/bundle/Resources/public/js/scripts/filters.action.btns.js @@ -57,9 +57,18 @@ dateInputNodes.forEach((dateInputNode) => { if (!dateInputNode.disabled) { const datePickerNode = dateInputNode.closest('.ibexa-picker'); - const datePickerInstance = ibexa.helpers.objectInstances.getInstance(datePickerNode); + if (datePickerNode) { + const datePickerInstance = ibexa.helpers.objectInstances.getInstance(datePickerNode); - datePickerInstance.clear(); + datePickerInstance.clear(); + } + + const dateTimeRangeSingleNode = dateInputNode.closest('.ibexa-date-time-range-single'); + if (dateTimeRangeSingleNode) { + const dateTimeRangeSingleInstance = ibexa.helpers.objectInstances.getInstance(dateTimeRangeSingleNode); + + dateTimeRangeSingleInstance.setDates([]); + } } }); dropdownNodes.forEach((dropdownNode) => { From 232af77dab89e1b21133b9cc24aaa07ed0f14d3e Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 9 Jun 2025 15:47:57 +0200 Subject: [PATCH 04/16] fix clearing dates --- .../Resources/public/js/scripts/admin.search.filters.js | 4 ++-- .../Resources/public/js/scripts/admin.trash.list.js | 2 +- .../public/js/scripts/core/date.time.range.single.js | 8 ++++++-- .../Resources/public/js/scripts/filters.action.btns.js | 2 +- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.search.filters.js b/src/bundle/Resources/public/js/scripts/admin.search.filters.js index 02f6dca698..f83713b306 100644 --- a/src/bundle/Resources/public/js/scripts/admin.search.filters.js +++ b/src/bundle/Resources/public/js/scripts/admin.search.filters.js @@ -98,7 +98,7 @@ }; const toggleDatesSelectVisibility = (select, dateRange) => { if (select.value !== 'custom_range') { - dateRange.setDates([]); + dateRange.clearDates(); dateRange.toggleHidden(true); toggleDisabledStateOnApplyBtn(); @@ -233,7 +233,7 @@ }; const clearDataRange = (event, select, dateRange) => { select.clearCurrentSelection(); - dateRange.setDates([]); + dateRange.clearDates(); dateRange.toggleHidden(true); removeSearchTag(event); }; diff --git a/src/bundle/Resources/public/js/scripts/admin.trash.list.js b/src/bundle/Resources/public/js/scripts/admin.trash.list.js index 3dc39d79a8..fce966d091 100644 --- a/src/bundle/Resources/public/js/scripts/admin.trash.list.js +++ b/src/bundle/Resources/public/js/scripts/admin.trash.list.js @@ -195,7 +195,7 @@ }; const toggleDatesSelectVisibility = (event) => { if (event.target.value !== 'custom_range') { - trashedDateTimeRange.setDates([]); + trashedDateTimeRange.clearDates(); trashedDateTimeRange.toggleHidden(true); return; diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js index e6e7583e6f..6c069b6c01 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -59,6 +59,10 @@ class DateTimeRangeSingle { } } + clearDates() { + this.dateTimePickerWidget.clear(); + } + setSelectedDateRange(timestamps, { dates }) { this.setDates(dates); @@ -80,7 +84,7 @@ class DateTimeRangeSingle { const { start, end } = this.container.dataset; const defaultDate = start && end ? [start, end] : []; - const dateTimePickerWidget = new ibexa.core.DateTimePicker({ + this.dateTimePickerWidget = new ibexa.core.DateTimePicker({ container: this.dateTimePickerInputWrapper, onChange: this.setSelectedDateRange, flatpickrConfig: { @@ -89,7 +93,7 @@ class DateTimeRangeSingle { }, }); - dateTimePickerWidget.init(); + this.dateTimePickerWidget.init(); } } diff --git a/src/bundle/Resources/public/js/scripts/filters.action.btns.js b/src/bundle/Resources/public/js/scripts/filters.action.btns.js index c2c06a055e..7762c0abc6 100644 --- a/src/bundle/Resources/public/js/scripts/filters.action.btns.js +++ b/src/bundle/Resources/public/js/scripts/filters.action.btns.js @@ -67,7 +67,7 @@ if (dateTimeRangeSingleNode) { const dateTimeRangeSingleInstance = ibexa.helpers.objectInstances.getInstance(dateTimeRangeSingleNode); - dateTimeRangeSingleInstance.setDates([]); + dateTimeRangeSingleInstance.clearDates(); } } }); From 84dd0aee3877c89865aea759cf1a6e3a1b62c89c Mon Sep 17 00:00:00 2001 From: tischsoic Date: Tue, 17 Jun 2025 11:52:24 +0200 Subject: [PATCH 05/16] after review --- .../Resources/public/js/scripts/admin.trash.list.js | 1 + .../public/js/scripts/core/date.time.picker.js | 2 +- .../js/scripts/core/date.time.range.single.js | 13 +++++++------ .../public/js/scripts/filters.action.btns.js | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.trash.list.js b/src/bundle/Resources/public/js/scripts/admin.trash.list.js index fce966d091..3d45112073 100644 --- a/src/bundle/Resources/public/js/scripts/admin.trash.list.js +++ b/src/bundle/Resources/public/js/scripts/admin.trash.list.js @@ -235,6 +235,7 @@ 'ibexa:date-time-range-single:change', (event) => { const { dates } = event.detail; + if (dates.length === 2 || dates.length === 0) { formSearch.submit(); } diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js index ebe436f7d7..c05b7c936b 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js @@ -32,7 +32,7 @@ class DateTimePicker { ...(config.flatpickrConfig ?? {}), }; - setInstance(this.container, this); // TODO: reove in 5.0 + setInstance(this.container, this); // TODO: remove in 5.0 setInstance(this.fieldWrapper, this); } diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js index 6c069b6c01..f005945901 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -1,7 +1,9 @@ import { formatShortDateTime } from '../helpers/timezone.helper'; import { setInstance } from '../helpers/object.instances'; -const { ibexa } = window; +const { ibexa, document } = window; + +const SECONDS_IN_DAY = 86400; class DateTimeRangeSingle { constructor(config) { @@ -9,8 +11,8 @@ class DateTimeRangeSingle { this.dateTimePickerInputWrapper = this.container.querySelector('.ibexa-date-time-range-single__date-time-picker-input-wrapper'); const { periodSelector, endSelector } = this.container.dataset; - this.periodInput = window.document.querySelector(periodSelector); - this.endInput = window.document.querySelector(endSelector); + this.periodInput = document.querySelector(periodSelector); + this.endInput = document.querySelector(endSelector); const customDateConfig = config.dateConfig || {}; this.dateConfig = { @@ -38,8 +40,7 @@ class DateTimeRangeSingle { if (dates.length === 2) { const startDate = this.getUnixTimestampUTC(dates[0]); const endDate = this.getUnixTimestampUTC(dates[1]); - const secondsInDay = 86400; - const days = (endDate - startDate) / secondsInDay; + const days = (endDate - startDate) / SECONDS_IN_DAY; this.periodInput.value = `P0Y0M${days}D`; this.periodInput.dispatchEvent(new Event('change')); @@ -51,7 +52,7 @@ class DateTimeRangeSingle { } else if (dates.length === 0) { this.periodInput.value = ''; this.periodInput.dispatchEvent(new Event('change')); - this.periodInput.dispatchEvent(new Event('change')); + this.periodInput.dispatchEvent(new Event('input')); this.endInput.value = ''; this.endInput.dispatchEvent(new Event('change')); diff --git a/src/bundle/Resources/public/js/scripts/filters.action.btns.js b/src/bundle/Resources/public/js/scripts/filters.action.btns.js index 7762c0abc6..8a4e92dec3 100644 --- a/src/bundle/Resources/public/js/scripts/filters.action.btns.js +++ b/src/bundle/Resources/public/js/scripts/filters.action.btns.js @@ -64,6 +64,7 @@ } const dateTimeRangeSingleNode = dateInputNode.closest('.ibexa-date-time-range-single'); + if (dateTimeRangeSingleNode) { const dateTimeRangeSingleInstance = ibexa.helpers.objectInstances.getInstance(dateTimeRangeSingleNode); From be56a62cf00bd8570e1fc6657aa8e57e2b752cc3 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Wed, 18 Jun 2025 10:33:24 +0200 Subject: [PATCH 06/16] remove empty spaces --- src/bundle/Resources/public/js/scripts/filters.action.btns.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bundle/Resources/public/js/scripts/filters.action.btns.js b/src/bundle/Resources/public/js/scripts/filters.action.btns.js index 8a4e92dec3..6b0b7d9ac1 100644 --- a/src/bundle/Resources/public/js/scripts/filters.action.btns.js +++ b/src/bundle/Resources/public/js/scripts/filters.action.btns.js @@ -64,7 +64,7 @@ } const dateTimeRangeSingleNode = dateInputNode.closest('.ibexa-date-time-range-single'); - + if (dateTimeRangeSingleNode) { const dateTimeRangeSingleInstance = ibexa.helpers.objectInstances.getInstance(dateTimeRangeSingleNode); From 488353b18247421f448069c57e5ea2192ab9afd2 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Wed, 25 Jun 2025 09:35:44 +0200 Subject: [PATCH 07/16] after QA --- .../public/js/scripts/admin.search.filters.js | 16 ++++++++++++---- .../public/js/scripts/admin.trash.list.js | 10 ++++++++-- .../views/themes/admin/trash/list.html.twig | 2 +- .../views/themes/admin/ui/form_fields.html.twig | 6 ++++++ .../themes/admin/ui/search/filters.html.twig | 2 ++ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.search.filters.js b/src/bundle/Resources/public/js/scripts/admin.search.filters.js index f83713b306..bf15dcea96 100644 --- a/src/bundle/Resources/public/js/scripts/admin.search.filters.js +++ b/src/bundle/Resources/public/js/scripts/admin.search.filters.js @@ -96,11 +96,15 @@ applyBtn[methodName]('disabled', !isEnabled); }; - const toggleDatesSelectVisibility = (select, dateRange) => { + const toggleDatesSelectVisibility = (event, select, dateRange) => { + const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector); + if (select.value !== 'custom_range') { - dateRange.clearDates(); dateRange.toggleHidden(true); + dateRange.clearDates(); + doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value; + toggleDisabledStateOnApplyBtn(); return; @@ -308,10 +312,14 @@ subtreeInput.addEventListener('change', toggleDisabledStateOnApplyBtn, false); lastModifiedSelectNode.addEventListener( 'change', - () => toggleDatesSelectVisibility(lastModifiedSelectNode, lastModifiedDateRange), + (event) => toggleDatesSelectVisibility(event, lastModifiedSelectNode, lastModifiedDateRange), + false, + ); + lastCreatedSelectNode.addEventListener( + 'change', + (event) => toggleDatesSelectVisibility(event, lastCreatedSelectNode, lastCreatedDateRange), false, ); - lastCreatedSelectNode.addEventListener('change', () => toggleDatesSelectVisibility(lastCreatedSelectNode, lastCreatedDateRange), false); creatorInput.addEventListener('keyup', handleTyping, false); usersList.addEventListener('click', handleSelectUser, false); contentTypeCheckboxes.forEach((checkbox) => checkbox.addEventListener('change', filterByContentType, false)); diff --git a/src/bundle/Resources/public/js/scripts/admin.trash.list.js b/src/bundle/Resources/public/js/scripts/admin.trash.list.js index 3d45112073..0329da07f0 100644 --- a/src/bundle/Resources/public/js/scripts/admin.trash.list.js +++ b/src/bundle/Resources/public/js/scripts/admin.trash.list.js @@ -194,10 +194,16 @@ formSearch.submit(); }; const toggleDatesSelectVisibility = (event) => { + const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector); + if (event.target.value !== 'custom_range') { - trashedDateTimeRange.clearDates(); trashedDateTimeRange.toggleHidden(true); + trashedDateTimeRange.clearDates(); + doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value; + + formSearch.submit(); + return; } @@ -207,7 +213,7 @@ event.preventDefault(); if (event.target.value !== 'custom_range') { - formSearch.submit(); + // formSearch.submit(); } }; const setSortedClass = () => { diff --git a/src/bundle/Resources/views/themes/admin/trash/list.html.twig b/src/bundle/Resources/views/themes/admin/trash/list.html.twig index b74857a087..87a055aeb6 100644 --- a/src/bundle/Resources/views/themes/admin/trash/list.html.twig +++ b/src/bundle/Resources/views/themes/admin/trash/list.html.twig @@ -61,7 +61,7 @@ 'attr': {'class': 'ibexa-trash-search-form__item ibexa-trash-search-form__item--auto-send'} }), form_row(form_search.trashed, { - 'attr': {'data-target-selector': '.ibexa-trash-search-form__range-wrapper--select-trashed-range'} + attr: { 'data-target-selector': '.ibexa-trash-search-form__trashed-date-time-range' }, }), ] %} diff --git a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig index 750fdcd76a..3135445176 100644 --- a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig @@ -328,6 +328,9 @@ {{ form_widget(form) }} {% include '@ibexadesign/ui/component/date_time_range_single/date_time_range_single.twig' with { is_hidden: form.vars.data != 'custom_range', + attr: { + class: 'ibexa-trash-search-form__last-modified-date-time-range', + }, start_date: form.parent.vars.data.lastModified.start_date|default(null), end_date: form.parent.vars.data.lastModified.end_date|default(null), period_input_selector: '#' ~ form.parent.last_modified.children.date_interval.vars.id, @@ -339,6 +342,9 @@ {{ form_widget(form) }} {% include '@ibexadesign/ui/component/date_time_range_single/date_time_range_single.twig' with { is_hidden: form.vars.data != 'custom_range', + attr: { + class: 'ibexa-trash-search-form__created-date-time-range', + }, start_date: form.parent.vars.data.created.start_date|default(null), end_date: form.parent.vars.data.created.end_date|default(null), period_input_selector: '#' ~ form.parent.created.children.date_interval.vars.id, diff --git a/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig b/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig index 063c07add7..e62c5a670c 100644 --- a/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/search/filters.html.twig @@ -41,6 +41,7 @@ {{ form_widget(form.last_modified_select, { 'attr': { 'class': 'ibexa-filters__select', + 'data-target-selector': '.ibexa-trash-search-form__last-modified-date-time-range', } }) }} {{ form_errors(form.last_modified_select) }} @@ -50,6 +51,7 @@ {{ form_widget(form.created_select, { 'attr': { 'class': 'ibexa-filters__select', + 'data-target-selector': '.ibexa-trash-search-form__created-date-time-range', } }) }} {{ form_errors(form.created_select) }} From 50655fe3647b23e08f2eaff10cf3245053b39504 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Wed, 25 Jun 2025 13:06:52 +0200 Subject: [PATCH 08/16] fix time in date.time.range.single --- .../public/js/scripts/core/date.time.range.single.js | 9 +++------ .../date_time_range_single/date_time_range_single.twig | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js index f005945901..daafc2435a 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -20,7 +20,7 @@ class DateTimeRangeSingle { locale: { rangeSeparator: ' - ', }, - formatDate: (date) => formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate), + formatDate: (date) => formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDateTime), ...customDateConfig, }; @@ -30,17 +30,14 @@ class DateTimeRangeSingle { } getUnixTimestampUTC(dateObject) { - let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate())); - date = Math.floor(date.getTime() / 1000); - - return date; + return Math.floor(dateObject.getTime() / 1000); } setDates(dates) { if (dates.length === 2) { const startDate = this.getUnixTimestampUTC(dates[0]); const endDate = this.getUnixTimestampUTC(dates[1]); - const days = (endDate - startDate) / SECONDS_IN_DAY; + const days = Math.floor((endDate - startDate) / SECONDS_IN_DAY); this.periodInput.value = `P0Y0M${days}D`; this.periodInput.dispatchEvent(new Event('change')); diff --git a/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig index 78a991ea24..a3d6f0e1a9 100644 --- a/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig +++ b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig @@ -7,9 +7,9 @@ 'data-period-selector': period_input_selector, 'data-end-selector': end_input_selector, 'data-start': start_date is defined and start_date is not null - ? start_date|date('Y-m-d') : '', + ? start_date|date('Y-m-d H:i:s') : '', 'data-end': end_date is defined and end_date is not null - ? end_date|date('Y-m-d') : '', + ? end_date|date('Y-m-d H:i:s') : '', }) %} {% set picker_wrapper_attr = picker_wrapper_attr|default({})|merge({ From c2933628a11ed08b9de6cff74a52e5e2f1b3a5bf Mon Sep 17 00:00:00 2001 From: konradoboza Date: Wed, 25 Jun 2025 13:58:57 +0200 Subject: [PATCH 09/16] removed arbitrary time setting --- src/lib/Form/DataTransformer/DateIntervalTransformer.php | 5 ++--- src/lib/Form/Type/Date/DateIntervalType.php | 4 ++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/Form/DataTransformer/DateIntervalTransformer.php b/src/lib/Form/DataTransformer/DateIntervalTransformer.php index d04f623aad..1e07c68e30 100644 --- a/src/lib/Form/DataTransformer/DateIntervalTransformer.php +++ b/src/lib/Form/DataTransformer/DateIntervalTransformer.php @@ -56,12 +56,11 @@ public function reverseTransform($value) $date->setTimestamp($value['end_date']); } - $date->setTime(23, 59, 59); $endDate = $date->getTimestamp(); $interval = new \DateInterval($value['date_interval']); $date->sub($interval); - $date->setTime(00, 00, 00); - $startDate = $date->getTimestamp(); + + $startDate = $value['start_date'] ?? $date->getTimestamp(); return ['start_date' => $startDate, 'end_date' => $endDate]; } diff --git a/src/lib/Form/Type/Date/DateIntervalType.php b/src/lib/Form/Type/Date/DateIntervalType.php index 6f7fd8dd4c..2ab185260f 100644 --- a/src/lib/Form/Type/Date/DateIntervalType.php +++ b/src/lib/Form/Type/Date/DateIntervalType.php @@ -24,6 +24,10 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'widget' => 'single_text', 'required' => false, ]) + ->add('start_date', IntegerType::class, [ + 'attr' => ['hidden' => true], + 'required' => false, + ]) ->add('end_date', IntegerType::class, [ 'attr' => ['hidden' => true], 'required' => false, From a007dd52b903f3e83811d1aaabbc17143294e809 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Wed, 25 Jun 2025 14:06:34 +0200 Subject: [PATCH 10/16] add start_date support in js --- .../js/scripts/core/date.time.range.single.js | 18 ++++++++++-------- .../date_time_range_single.twig | 1 + .../themes/admin/ui/form_fields.html.twig | 3 +++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js index daafc2435a..24efcb01fc 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.range.single.js @@ -3,15 +3,14 @@ import { setInstance } from '../helpers/object.instances'; const { ibexa, document } = window; -const SECONDS_IN_DAY = 86400; - class DateTimeRangeSingle { constructor(config) { this.container = config.container; this.dateTimePickerInputWrapper = this.container.querySelector('.ibexa-date-time-range-single__date-time-picker-input-wrapper'); - const { periodSelector, endSelector } = this.container.dataset; + const { periodSelector, startSelector, endSelector } = this.container.dataset; this.periodInput = document.querySelector(periodSelector); + this.startInput = document.querySelector(startSelector); this.endInput = document.querySelector(endSelector); const customDateConfig = config.dateConfig || {}; @@ -37,19 +36,22 @@ class DateTimeRangeSingle { if (dates.length === 2) { const startDate = this.getUnixTimestampUTC(dates[0]); const endDate = this.getUnixTimestampUTC(dates[1]); - const days = Math.floor((endDate - startDate) / SECONDS_IN_DAY); - this.periodInput.value = `P0Y0M${days}D`; + this.periodInput.value = ''; this.periodInput.dispatchEvent(new Event('change')); this.periodInput.dispatchEvent(new Event('input')); + this.startInput.value = startDate; + this.startInput.dispatchEvent(new Event('change')); + this.startInput.dispatchEvent(new Event('input')); + this.endInput.value = endDate; this.endInput.dispatchEvent(new Event('change')); this.endInput.dispatchEvent(new Event('input')); } else if (dates.length === 0) { - this.periodInput.value = ''; - this.periodInput.dispatchEvent(new Event('change')); - this.periodInput.dispatchEvent(new Event('input')); + this.startInput.value = ''; + this.startInput.dispatchEvent(new Event('change')); + this.startInput.dispatchEvent(new Event('input')); this.endInput.value = ''; this.endInput.dispatchEvent(new Event('change')); diff --git a/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig index a3d6f0e1a9..ceb8e28520 100644 --- a/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig +++ b/src/bundle/Resources/views/themes/admin/ui/component/date_time_range_single/date_time_range_single.twig @@ -5,6 +5,7 @@ ~ (is_hidden|default(false) ? 'ibexa-date-time-range-single--hidden ') ~ attr.class|default(''))|trim, 'data-period-selector': period_input_selector, + 'data-start-selector': start_input_selector, 'data-end-selector': end_input_selector, 'data-start': start_date is defined and start_date is not null ? start_date|date('Y-m-d H:i:s') : '', diff --git a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig index 3135445176..2f05ac57ce 100644 --- a/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/form_fields.html.twig @@ -334,6 +334,7 @@ start_date: form.parent.vars.data.lastModified.start_date|default(null), end_date: form.parent.vars.data.lastModified.end_date|default(null), period_input_selector: '#' ~ form.parent.last_modified.children.date_interval.vars.id, + start_input_selector: '#' ~ form.parent.last_modified.children.start_date.vars.id, end_input_selector: '#' ~ form.parent.last_modified.children.end_date.vars.id, } %} {%- endblock -%} @@ -348,6 +349,7 @@ start_date: form.parent.vars.data.created.start_date|default(null), end_date: form.parent.vars.data.created.end_date|default(null), period_input_selector: '#' ~ form.parent.created.children.date_interval.vars.id, + start_input_selector: '#' ~ form.parent.created.children.start_date.vars.id, end_input_selector: '#' ~ form.parent.created.children.end_date.vars.id, } %} {%- endblock -%} @@ -362,6 +364,7 @@ start_date: form.parent.vars.data.trashedInterval.start_date|default(null), end_date: form.parent.vars.data.trashedInterval.end_date|default(null), period_input_selector: '#' ~ form.parent.trashed_interval.children.date_interval.vars.id, + start_input_selector: '#' ~ form.parent.trashed_interval.children.start_date.vars.id, end_input_selector: '#' ~ form.parent.trashed_interval.children.end_date.vars.id, } %} {%- endblock -%} From 09d6f992cb7d258671f95e290810f492c6836b4d Mon Sep 17 00:00:00 2001 From: konradoboza Date: Wed, 25 Jun 2025 15:31:55 +0200 Subject: [PATCH 11/16] fixed data manipulation --- phpstan-baseline.neon | 24 ---------- .../DateIntervalTransformer.php | 45 ++++++++++--------- 2 files changed, 25 insertions(+), 44 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4a49247916..7f92b0f688 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6702,36 +6702,12 @@ parameters: count: 1 path: src/lib/Form/DataTransformer/DateIntervalToArrayTransformer.php - - - message: '#^Call to function array_key_exists\(\) with ''date_interval'' and non\-empty\-array will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: src/lib/Form/DataTransformer/DateIntervalTransformer.php - - - - message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: src/lib/Form/DataTransformer/DateIntervalTransformer.php - - message: '#^Class Ibexa\\AdminUi\\Form\\DataTransformer\\DateIntervalTransformer implements generic interface Symfony\\Component\\Form\\DataTransformerInterface but does not specify its types\: T, R$#' identifier: missingType.generics count: 1 path: src/lib/Form/DataTransformer/DateIntervalTransformer.php - - - message: '#^Method Ibexa\\AdminUi\\Form\\DataTransformer\\DateIntervalTransformer\:\:reverseTransform\(\) has parameter \$value with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: src/lib/Form/DataTransformer/DateIntervalTransformer.php - - - - message: '#^Method Ibexa\\AdminUi\\Form\\DataTransformer\\DateIntervalTransformer\:\:reverseTransform\(\) return type has no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: src/lib/Form/DataTransformer/DateIntervalTransformer.php - - message: '#^Method Ibexa\\AdminUi\\Form\\DataTransformer\\DateIntervalTransformer\:\:transform\(\) has Symfony\\Component\\Form\\Exception\\TransformationFailedException in PHPDoc @throws tag but it''s not thrown\.$#' identifier: throws.unusedType diff --git a/src/lib/Form/DataTransformer/DateIntervalTransformer.php b/src/lib/Form/DataTransformer/DateIntervalTransformer.php index 1e07c68e30..623ab2de7d 100644 --- a/src/lib/Form/DataTransformer/DateIntervalTransformer.php +++ b/src/lib/Form/DataTransformer/DateIntervalTransformer.php @@ -8,6 +8,8 @@ namespace Ibexa\AdminUi\Form\DataTransformer; +use DateInterval; +use DateTime; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Exception\TransformationFailedException; @@ -29,40 +31,43 @@ public function transform($value) } /** - * @param array|null $value - * - * @return array|null + * @param array|null $value * - * @throws \Exception - * @throws \Symfony\Component\Form\Exception\TransformationFailedException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\UnauthorizedException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + * @return array */ - public function reverseTransform($value) + public function reverseTransform($value): array { - if (null === $value || !is_array($value) || empty($value['date_interval'])) { + if (!is_array($value)) { return []; } - if (!array_key_exists('date_interval', $value) || !array_key_exists('end_date', $value)) { + if ( + !array_key_exists('date_interval', $value) + || !array_key_exists('start_date', $value) + || !array_key_exists('end_date', $value) + ) { throw new TransformationFailedException( - "Invalid data. Value array is missing 'date_interval' and/or 'end_date' keys" + "Invalid data. On of the array keys is missing 'date_interval', 'start_date' or 'end_date'" ); } - $date = new \DateTime(); + $startDateTimestamp = $value['start_date'] ?? null; + $endDateTimestamp = $value['end_date'] ?? null; - if ($value['end_date']) { - $date->setTimestamp($value['end_date']); - } + $dateInterval = $value['date_interval']; + if (!empty($dateInterval)) { + $interval = new DateInterval($dateInterval); + + $date = new DateTime(); + $endDateTimestamp = $date->getTimestamp(); - $endDate = $date->getTimestamp(); - $interval = new \DateInterval($value['date_interval']); - $date->sub($interval); + $date->setTimestamp($endDateTimestamp); + $date->sub($interval); - $startDate = $value['start_date'] ?? $date->getTimestamp(); + $startDateTimestamp = $date->getTimestamp(); + } - return ['start_date' => $startDate, 'end_date' => $endDate]; + return ['start_date' => $startDateTimestamp, 'end_date' => $endDateTimestamp]; } } From 112b30460b3b3c760fed54ee38e24e0df7ac95fb Mon Sep 17 00:00:00 2001 From: tischsoic Date: Wed, 25 Jun 2025 15:51:55 +0200 Subject: [PATCH 12/16] uncomment form submit --- src/bundle/Resources/public/js/scripts/admin.trash.list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.trash.list.js b/src/bundle/Resources/public/js/scripts/admin.trash.list.js index 0329da07f0..0f37b02431 100644 --- a/src/bundle/Resources/public/js/scripts/admin.trash.list.js +++ b/src/bundle/Resources/public/js/scripts/admin.trash.list.js @@ -213,7 +213,7 @@ event.preventDefault(); if (event.target.value !== 'custom_range') { - // formSearch.submit(); + formSearch.submit(); } }; const setSortedClass = () => { From 0334cbfe382654983a2c6991d9b717f12c22a528 Mon Sep 17 00:00:00 2001 From: konradoboza Date: Thu, 26 Jun 2025 09:30:25 +0200 Subject: [PATCH 13/16] [tmp] dependency to ibexa/search --- dependencies.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dependencies.json diff --git a/dependencies.json b/dependencies.json new file mode 100644 index 0000000000..aaa643e4ee --- /dev/null +++ b/dependencies.json @@ -0,0 +1,11 @@ +{ + "recipesEndpoint": "", + "packages": [ + { + "requirement": "dev-ibx-9807-adjusted-date-range-filter as 4.6.x-dev", + "repositoryUrl": "https://github.com/ibexa/search", + "package": "ibexa/search", + "shouldBeAddedAsVCS": true + } + ] +} From 750b5ef964e4cb32aa9a01f868bf13aa11183a7f Mon Sep 17 00:00:00 2001 From: konradoboza Date: Fri, 27 Jun 2025 07:21:32 +0200 Subject: [PATCH 14/16] fix after QA --- src/lib/QueryType/TrashSearchQueryType.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/QueryType/TrashSearchQueryType.php b/src/lib/QueryType/TrashSearchQueryType.php index a32dc021a2..95cbfe6296 100644 --- a/src/lib/QueryType/TrashSearchQueryType.php +++ b/src/lib/QueryType/TrashSearchQueryType.php @@ -70,9 +70,12 @@ protected function addCriteria(TrashSearchData $searchData, Query $query): void $criteria[] = new Criterion\ContentTypeId([$searchData->getContentType()->id]); } - if (!empty($searchData->getTrashedInterval())) { - $trashedInterval = $searchData->getTrashedInterval(); - + $trashedInterval = $searchData->getTrashedInterval(); + if ( + !empty($trashedInterval) + && $trashedInterval['start_date'] !== null + && $trashedInterval['end_date'] !== null + ) { $criteria[] = new Criterion\DateMetadata( Criterion\DateMetadata::TRASHED, Criterion\Operator::BETWEEN, From 44da23facbceff9f252e022e968a9f16de9240a5 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 30 Jun 2025 14:11:49 +0200 Subject: [PATCH 15/16] fix Apply btn refresh --- .../public/js/scripts/admin.search.filters.js | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.search.filters.js b/src/bundle/Resources/public/js/scripts/admin.search.filters.js index bf15dcea96..3f00eef55a 100644 --- a/src/bundle/Resources/public/js/scripts/admin.search.filters.js +++ b/src/bundle/Resources/public/js/scripts/admin.search.filters.js @@ -15,10 +15,26 @@ const lastModifiedSelect = getInstance(lastModifiedSelectNode); const lastModifiedDateRangeNode = doc.querySelector('.ibexa-filters__item--modified .ibexa-date-time-range-single'); const lastModifiedDateRange = getInstance(lastModifiedDateRangeNode); + const { + periodSelector: lastModifiedPeriodSelector, + startSelector: lastModifiedStartSelector, + endSelector: lastModifiedEndSelector, + } = lastModifiedDateRangeNode.dataset; + const lastModifiedPeriod = doc.querySelector(lastModifiedPeriodSelector); + const lastModifiedStartDate = doc.querySelector(lastModifiedStartSelector); + const lastModifiedEndDate = doc.querySelector(lastModifiedEndSelector); const lastCreatedSelectNode = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__select'); const lastCreatedSelect = getInstance(lastCreatedSelectNode); const lastCreatedDateRangeNode = doc.querySelector('.ibexa-filters__item--created .ibexa-date-time-range-single'); const lastCreatedDateRange = getInstance(lastCreatedDateRangeNode); + const { + periodSelector: lastCreatedPeriodSelector, + startSelector: lastCreatedStartDateSelector, + endSelector: lastCreatedEndDateSelector, + } = lastModifiedDateRangeNode.dataset; + const lastCreatedPeriod = doc.querySelector(lastCreatedPeriodSelector); + const lastCreatedStartDate = doc.querySelector(lastCreatedStartDateSelector); + const lastCreatedEndDate = doc.querySelector(lastCreatedEndDateSelector); const creatorInput = doc.querySelector('.ibexa-filters__item--creator .ibexa-input'); const searchCreatorInput = doc.querySelector('#search_creator'); const usersList = doc.querySelector('.ibexa-filters__item--creator .ibexa-filters__user-list'); @@ -62,6 +78,7 @@ event.target.closest('form').submit(); }; const toggleDisabledStateOnApplyBtn = () => { + console.log('toggleDisabledStateOnApplyBtn'); const contentTypeOption = contentTypeSelect.querySelector('option'); const isContentTypeSelected = contentTypeOption.innerHTML !== contentTypeOption.dataset.default; const isSectionSelected = sectionSelect ? !!sectionSelect.value : false; @@ -71,21 +88,19 @@ let isCreatedSelected = !!lastCreatedSelectNode.value; if (lastModifiedSelectNode.value === 'custom_range') { - const { periodSelector, endSelector } = lastModifiedDateRangeNode.dataset; - const lastModifiedPeriodValue = doc.querySelector(periodSelector).value; - const lastModifiedEndDate = doc.querySelector(endSelector).value; + const lastModifiedStartDateValue = lastModifiedStartDate.value; + const lastModifiedEndDateValue = lastModifiedEndDate.value; - if (!lastModifiedPeriodValue || !lastModifiedEndDate) { + if (!lastModifiedStartDateValue || !lastModifiedEndDateValue) { isModifiedSelected = false; } } if (lastCreatedSelectNode.value === 'custom_range') { - const { periodSelector, endSelector } = lastCreatedDateRangeNode.dataset; - const lastCreatedPeriodValue = doc.querySelector(periodSelector).value; - const lastCreatedEndDate = doc.querySelector(endSelector).value; + const lastCreatedStartDateValue = lastCreatedStartDate.value; + const lastCreatedEndDateValue = lastCreatedEndDate.value; - if (!lastCreatedPeriodValue || !lastCreatedEndDate) { + if (!lastCreatedStartDateValue || !lastCreatedEndDateValue) { isCreatedSelected = false; } } @@ -309,6 +324,14 @@ tagBtns.forEach((btn) => btn.addEventListener('click', clearSearchTagBtnMethods[tagType], false)); } + lastModifiedPeriod.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + lastModifiedStartDate.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + lastModifiedEndDate.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + + lastCreatedPeriod.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + lastCreatedStartDate.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + lastCreatedEndDate.addEventListener('change', toggleDisabledStateOnApplyBtn, false); + subtreeInput.addEventListener('change', toggleDisabledStateOnApplyBtn, false); lastModifiedSelectNode.addEventListener( 'change', From c58972147625839694cc0806176fd28d2b233d3a Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 30 Jun 2025 14:21:18 +0200 Subject: [PATCH 16/16] fix tags --- .../admin/ui/search/criteria_tags.html.twig | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/bundle/Resources/views/themes/admin/ui/search/criteria_tags.html.twig b/src/bundle/Resources/views/themes/admin/ui/search/criteria_tags.html.twig index 6da01b66a8..4bf8b8dd65 100644 --- a/src/bundle/Resources/views/themes/admin/ui/search/criteria_tags.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/search/criteria_tags.html.twig @@ -38,9 +38,13 @@ }) }} {% endif %} - {% if form.vars.value.lastModified is not empty %} - {% set start_date = form.vars.value.lastModified.start_date|ibexa_short_date %} - {% set end_date = form.vars.value.lastModified.end_date|ibexa_short_date %} + {% set last_modified = form.vars.value.lastModified %} + {% if last_modified is not empty + and last_modified.start_date is not null + and last_modified.end_date is not null + %} + {% set start_date = last_modified.start_date|ibexa_short_datetime %} + {% set end_date = last_modified.end_date|ibexa_short_datetime %} {{ include('@ibexadesign/ui/search_tag.html.twig', { 'content': "#{'search.last.modified'|trans|desc('Last modified')}: #{start_date} - #{end_date}", @@ -48,9 +52,13 @@ }) }} {% endif %} - {% if form.vars.value.created is not empty %} - {% set start_date = form.vars.value.created.start_date|ibexa_short_date %} - {% set end_date = form.vars.value.created.end_date|ibexa_short_date %} + {% set created = form.vars.value.created %} + {% if created is not empty + and created.start_date is not null + and created.end_date is not null + %} + {% set start_date = form.vars.value.created.start_date|ibexa_short_datetime %} + {% set end_date = form.vars.value.created.end_date|ibexa_short_datetime %} {{ include('@ibexadesign/ui/search_tag.html.twig', { 'content': "#{'search.created'|trans|desc('Created')}: #{start_date} - #{end_date}",