Skip to content

[TMP COMMIT] IBX-9807: Introduce date range single component #1582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: 4.6
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions dependencies.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
24 changes: 0 additions & 24 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/bundle/Resources/encore/ibexa.js.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down Expand Up @@ -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'),
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
129 changes: 42 additions & 87 deletions src/bundle/Resources/public/js/scripts/admin.search.filters.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,38 @@
(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');
const contentTypeCheckboxes = doc.querySelectorAll('.ibexa-content-type-selector__item [type="checkbox"]');
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);
Expand All @@ -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 = '';
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -103,20 +96,21 @@

applyBtn[methodName]('disabled', !isEnabled);
};
const toggleDatesSelectVisibility = (event) => {
const toggleDatesSelectVisibility = (event, select, dateRange) => {
const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector);

if (event.target.value !== 'custom_range') {
if (select.value !== 'custom_range') {
dateRange.toggleHidden(true);

dateRange.clearDates();
doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value;
doc.querySelector(datesRangeNode.dataset.endSelector).value = '';
datesRangeNode.classList.remove(CLASS_VISIBLE_DATE_RANGE);

toggleDisabledStateOnApplyBtn();

return;
}

datesRangeNode.classList.add(CLASS_VISIBLE_DATE_RANGE);
dateRange.toggleHidden(false);
};
const filterByContentType = () => {
const selectedCheckboxes = [...contentTypeCheckboxes].filter((checkbox) => checkbox.checked);
Expand All @@ -128,31 +122,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: {
Expand Down Expand Up @@ -244,21 +213,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');
Expand All @@ -281,16 +235,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.clearDates();
dateRange.toggleHidden(true);
removeSearchTag(event);
};
const clearCreator = (event) => {
Expand All @@ -302,8 +250,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;
Expand Down Expand Up @@ -347,7 +295,6 @@
);
};

dateFields.forEach(initFlatPickr);
filterByContentType();

clearBtn.addEventListener('click', clearFilters, false);
Expand All @@ -363,8 +310,16 @@
}

subtreeInput.addEventListener('change', toggleDisabledStateOnApplyBtn, false);
lastModifiedSelect.addEventListener('change', toggleDatesSelectVisibility, false);
lastCreatedSelect.addEventListener('change', toggleDatesSelectVisibility, false);
lastModifiedSelectNode.addEventListener(
'change',
(event) => toggleDatesSelectVisibility(event, lastModifiedSelectNode, lastModifiedDateRange),
false,
);
lastCreatedSelectNode.addEventListener(
'change',
(event) => toggleDatesSelectVisibility(event, lastCreatedSelectNode, lastCreatedDateRange),
false,
);
creatorInput.addEventListener('keyup', handleTyping, false);
usersList.addEventListener('click', handleSelectUser, false);
contentTypeCheckboxes.forEach((checkbox) => checkbox.addEventListener('change', filterByContentType, false));
Expand Down
Loading
Loading