Skip to content
Merged
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
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);
165 changes: 70 additions & 95 deletions src/bundle/Resources/public/js/scripts/admin.search.filters.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
(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 {
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,
} = lastCreatedDateRangeNode.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');
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 lastModifiedPeriod = doc.querySelector(lastModifiedDataRange.dataset.periodSelector);
const lastModifiedDataRange = doc.querySelector(lastModifiedSelectNode.dataset.targetSelector);
const lastCreatedDataRange = doc.querySelector(lastCreatedSelectNode.dataset.targetSelector);
const lastModifiedEnd = doc.querySelector(lastModifiedDataRange.dataset.endSelector);
const lastCreatedPeriod = doc.querySelector(lastCreatedDataRange.dataset.periodSelector);
const lastCreatedEnd = doc.querySelector(lastCreatedDataRange.dataset.endSelector);

option.innerHTML = defaultText;
Expand All @@ -53,9 +62,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,27 +81,23 @@
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;
const lastModifiedPeriodValue = doc.querySelector(periodSelector).value;
const lastModifiedEndDate = doc.querySelector(endSelector).value;
if (lastModifiedSelectNode.value === 'custom_range') {
const lastModifiedStartDateValue = lastModifiedStartDate.value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick - not sure if we need this kind of variables, where you just assign property from object. :)

const lastModifiedEndDateValue = lastModifiedEndDate.value;

if (!lastModifiedPeriodValue || !lastModifiedEndDate) {
if (!lastModifiedStartDateValue || !lastModifiedEndDateValue) {
isModifiedSelected = false;
}
}

if (lastCreatedSelect.value === 'custom_range') {
const lastCreatedWrapper = lastCreatedDateRange.closest(`.${CLASS_DATE_RANGE}`);
const { periodSelector, endSelector } = lastCreatedWrapper.dataset;
const lastCreatedPeriodValue = doc.querySelector(periodSelector).value;
const lastCreatedEndDate = doc.querySelector(endSelector).value;
if (lastCreatedSelectNode.value === 'custom_range') {
const lastCreatedStartDateValue = lastCreatedStartDate.value;
const lastCreatedEndDateValue = lastCreatedEndDate.value;

if (!lastCreatedPeriodValue || !lastCreatedEndDate) {
if (!lastCreatedStartDateValue || !lastCreatedEndDateValue) {
isCreatedSelected = false;
}
}
Expand All @@ -103,20 +108,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 +134,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 +225,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 +247,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 +262,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 +307,6 @@
);
};

dateFields.forEach(initFlatPickr);
filterByContentType();

clearBtn.addEventListener('click', clearFilters, false);
Expand All @@ -362,9 +321,25 @@
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);
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