Skip to content

Commit 5caecd9

Browse files
committed
IBX-9807: Introduce date range single component
1 parent 72a64d9 commit 5caecd9

File tree

13 files changed

+224
-236
lines changed

13 files changed

+224
-236
lines changed

src/bundle/Resources/encore/ibexa.js.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const layout = [
2222
path.resolve(__dirname, '../public/js/scripts/core/toggle.button.js'),
2323
path.resolve(__dirname, '../public/js/scripts/core/slug.value.input.autogenerator.js'),
2424
path.resolve(__dirname, '../public/js/scripts/core/date.time.picker.js'),
25+
path.resolve(__dirname, '../public/js/scripts/core/date.time.range.single.js'),
2526
path.resolve(__dirname, '../public/js/scripts/core/taggify.js'),
2627
path.resolve(__dirname, '../public/js/scripts/core/suggestion.taggify.js'),
2728
path.resolve(__dirname, '../public/js/scripts/core/storage.js'),
@@ -49,6 +50,7 @@ const layout = [
4950
path.resolve(__dirname, '../public/js/scripts/admin.table.js'),
5051
path.resolve(__dirname, '../public/js/scripts/core/collapse.js'),
5152
path.resolve(__dirname, '../public/js/scripts/admin.dropdown.js'),
53+
path.resolve(__dirname, '../public/js/scripts/admin.date.time.range.single.js'),
5254
path.resolve(__dirname, '../public/js/scripts/double.click.mark.js'),
5355
path.resolve(__dirname, '../public/js/scripts/autogenerate.identifier.js'),
5456
path.resolve(__dirname, '../public/js/scripts/admin.back.to.top.js'),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(function (global, doc, ibexa) {
2+
const { DateTimeRangeSingle } = ibexa.core;
3+
const containers = doc.querySelectorAll('.ibexa-date-time-range-single');
4+
5+
containers.forEach((container) => {
6+
const dateTimeRangeSingle = new DateTimeRangeSingle({
7+
container,
8+
});
9+
10+
dateTimeRangeSingle.init();
11+
});
12+
})(window, window.document, window.ibexa);

src/bundle/Resources/public/js/scripts/admin.search.filters.js

Lines changed: 37 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,38 @@
11
(function (global, doc, ibexa, flatpickr, React, ReactDOM) {
22
const { escapeHTML, escapeHTMLAttribute } = ibexa.helpers.text;
33
const { dangerouslySetInnerHTML } = ibexa.helpers.dom;
4+
const { getInstance } = ibexa.helpers.objectInstances;
45
let getUsersTimeout;
5-
const CLASS_DATE_RANGE = 'ibexa-filters__range-wrapper';
6-
const CLASS_VISIBLE_DATE_RANGE = 'ibexa-filters__range-wrapper--visible';
76
const SELECTOR_TAG = '.ibexa-tag';
87
const token = doc.querySelector('meta[name="CSRF-Token"]').content;
98
const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content;
109
const filters = doc.querySelector('.ibexa-filters');
1110
const clearBtn = filters.querySelector('.ibexa-btn--clear');
1211
const applyBtn = filters.querySelector('.ibexa-btn--apply');
13-
const dateFields = doc.querySelectorAll('.ibexa-filters__range-wrapper');
1412
const contentTypeSelect = doc.querySelector('.ibexa-filters__item--content-type .ibexa-filters__select');
1513
const sectionSelect = doc.querySelector('.ibexa-filters__item--section .ibexa-filters__select');
16-
const lastModifiedSelect = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__select');
17-
const lastModifiedDateRange = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__range-select');
18-
const lastCreatedSelect = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__select');
19-
const lastCreatedDateRange = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__range-select');
14+
const lastModifiedSelectNode = doc.querySelector('.ibexa-filters__item--modified .ibexa-filters__select');
15+
const lastModifiedSelect = getInstance(lastModifiedSelectNode);
16+
const lastModifiedDateRangeNode = doc.querySelector('.ibexa-filters__item--modified .ibexa-date-time-range-single');
17+
const lastModifiedDateRange = getInstance(lastModifiedDateRangeNode);
18+
const lastCreatedSelectNode = doc.querySelector('.ibexa-filters__item--created .ibexa-filters__select');
19+
const lastCreatedSelect = getInstance(lastCreatedSelectNode);
20+
const lastCreatedDateRangeNode = doc.querySelector('.ibexa-filters__item--created .ibexa-date-time-range-single');
21+
const lastCreatedDateRange = getInstance(lastCreatedDateRangeNode);
2022
const creatorInput = doc.querySelector('.ibexa-filters__item--creator .ibexa-input');
2123
const searchCreatorInput = doc.querySelector('#search_creator');
2224
const usersList = doc.querySelector('.ibexa-filters__item--creator .ibexa-filters__user-list');
2325
const contentTypeCheckboxes = doc.querySelectorAll('.ibexa-content-type-selector__item [type="checkbox"]');
2426
const selectSubtreeBtn = doc.querySelector('.ibexa-filters__item--subtree .ibexa-tag-view-select__btn-select-path');
2527
const subtreeInput = doc.querySelector('#search_subtree');
2628
const showMoreBtns = doc.querySelectorAll('.ibexa-content-type-selector__show-more');
27-
const dateConfig = {
28-
mode: 'range',
29-
locale: {
30-
rangeSeparator: ' - ',
31-
},
32-
formatDate: (date) => ibexa.helpers.timezone.formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate),
33-
};
3429
const clearFilters = (event) => {
3530
event.preventDefault();
3631

3732
const option = contentTypeSelect.querySelector('option');
3833
const defaultText = option.dataset.default;
39-
const lastModifiedDataRange = doc.querySelector(lastModifiedSelect.dataset.targetSelector);
40-
const lastCreatedDataRange = doc.querySelector(lastCreatedSelect.dataset.targetSelector);
34+
const lastModifiedDataRange = doc.querySelector(lastModifiedSelectNode.dataset.targetSelector);
35+
const lastCreatedDataRange = doc.querySelector(lastCreatedSelectNode.dataset.targetSelector);
4136
const lastModifiedPeriod = doc.querySelector(lastModifiedDataRange.dataset.periodSelector);
4237
const lastModifiedEnd = doc.querySelector(lastModifiedDataRange.dataset.endSelector);
4338
const lastCreatedPeriod = doc.querySelector(lastCreatedDataRange.dataset.periodSelector);
@@ -53,9 +48,9 @@
5348
sectionSelect[0].selected = true;
5449
}
5550

56-
lastModifiedSelect[0].selected = true;
57-
lastCreatedSelect[0].selected = true;
58-
lastModifiedSelect.querySelector('option').selected = true;
51+
lastModifiedSelectNode[0].selected = true;
52+
lastCreatedSelectNode[0].selected = true;
53+
lastModifiedSelectNode.querySelector('option').selected = true;
5954
lastModifiedPeriod.value = '';
6055
lastModifiedEnd.value = '';
6156
lastCreatedPeriod.value = '';
@@ -72,12 +67,11 @@
7267
const isSectionSelected = sectionSelect ? !!sectionSelect.value : false;
7368
const isCreatorSelected = !!searchCreatorInput.value;
7469
const isSubtreeSelected = !!subtreeInput.value.trim().length;
75-
let isModifiedSelected = !!lastModifiedSelect.value;
76-
let isCreatedSelected = !!lastCreatedSelect.value;
70+
let isModifiedSelected = !!lastModifiedSelectNode.value;
71+
let isCreatedSelected = !!lastCreatedSelectNode.value;
7772

78-
if (lastModifiedSelect.value === 'custom_range') {
79-
const lastModifiedWrapper = lastModifiedDateRange.closest(`.${CLASS_DATE_RANGE}`);
80-
const { periodSelector, endSelector } = lastModifiedWrapper.dataset;
73+
if (lastModifiedSelectNode.value === 'custom_range') {
74+
const { periodSelector, endSelector } = lastModifiedDateRangeNode.dataset;
8175
const lastModifiedPeriodValue = doc.querySelector(periodSelector).value;
8276
const lastModifiedEndDate = doc.querySelector(endSelector).value;
8377

@@ -86,9 +80,8 @@
8680
}
8781
}
8882

89-
if (lastCreatedSelect.value === 'custom_range') {
90-
const lastCreatedWrapper = lastCreatedDateRange.closest(`.${CLASS_DATE_RANGE}`);
91-
const { periodSelector, endSelector } = lastCreatedWrapper.dataset;
83+
if (lastCreatedSelectNode.value === 'custom_range') {
84+
const { periodSelector, endSelector } = lastCreatedDateRangeNode.dataset;
9285
const lastCreatedPeriodValue = doc.querySelector(periodSelector).value;
9386
const lastCreatedEndDate = doc.querySelector(endSelector).value;
9487

@@ -103,20 +96,17 @@
10396

10497
applyBtn[methodName]('disabled', !isEnabled);
10598
};
106-
const toggleDatesSelectVisibility = (event) => {
107-
const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector);
108-
109-
if (event.target.value !== 'custom_range') {
110-
doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value;
111-
doc.querySelector(datesRangeNode.dataset.endSelector).value = '';
112-
datesRangeNode.classList.remove(CLASS_VISIBLE_DATE_RANGE);
99+
const toggleDatesSelectVisibility = (select, dateRange) => {
100+
if (select.value !== 'custom_range') {
101+
dateRange.setDates([]);
102+
dateRange.toggleHidden(true);
113103

114104
toggleDisabledStateOnApplyBtn();
115105

116106
return;
117107
}
118108

119-
datesRangeNode.classList.add(CLASS_VISIBLE_DATE_RANGE);
109+
dateRange.toggleHidden(false);
120110
};
121111
const filterByContentType = () => {
122112
const selectedCheckboxes = [...contentTypeCheckboxes].filter((checkbox) => checkbox.checked);
@@ -128,31 +118,6 @@
128118

129119
toggleDisabledStateOnApplyBtn();
130120
};
131-
const setSelectedDateRange = (timestamps, { dates, inputField }) => {
132-
const dateRange = inputField.closest('.ibexa-filters__range-wrapper');
133-
134-
if (dates.length === 2) {
135-
const startDate = getUnixTimestampUTC(dates[0]);
136-
const endDate = getUnixTimestampUTC(dates[1]);
137-
const secondsInDay = 86400;
138-
const days = (endDate - startDate) / secondsInDay;
139-
140-
doc.querySelector(dateRange.dataset.periodSelector).value = `P0Y0M${days}D`;
141-
doc.querySelector(dateRange.dataset.endSelector).value = endDate;
142-
} else if (dates.length === 0) {
143-
doc.querySelector(dateRange.dataset.periodSelector).value = '';
144-
doc.querySelector(dateRange.dataset.endSelector).value = '';
145-
}
146-
147-
toggleDisabledStateOnApplyBtn();
148-
};
149-
const getUnixTimestampUTC = (dateObject) => {
150-
let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate()));
151-
152-
date = Math.floor(date.getTime() / 1000);
153-
154-
return date;
155-
};
156121
const getUsersList = (value) => {
157122
const body = JSON.stringify({
158123
ViewInput: {
@@ -244,21 +209,6 @@
244209
usersList.classList.add('ibexa-filters__user-list--hidden');
245210
doc.querySelector('body').removeEventListener('click', handleClickOutsideUserList, false);
246211
};
247-
const initFlatPickr = (dateRangeField) => {
248-
const { start, end } = dateRangeField.querySelector('.ibexa-filters__range-select').dataset;
249-
const defaultDate = start && end ? [start, end] : [];
250-
251-
const dateTimePickerWidget = new ibexa.core.DateTimePicker({
252-
container: dateRangeField,
253-
onChange: setSelectedDateRange,
254-
flatpickrConfig: {
255-
...dateConfig,
256-
defaultDate,
257-
},
258-
});
259-
260-
dateTimePickerWidget.init();
261-
};
262212
const removeSearchTag = (event) => {
263213
const tag = event.currentTarget.closest(SELECTOR_TAG);
264214
const form = event.currentTarget.closest('form');
@@ -281,16 +231,10 @@
281231
subtreeInput.value = '';
282232
removeSearchTag(event);
283233
};
284-
const clearDataRange = (event, selector) => {
285-
const dataRange = doc.querySelector(selector);
286-
const rangeSelect = dataRange.parentNode.querySelector('.ibexa-filters__select');
287-
const periodInput = doc.querySelector(dataRange.dataset.periodSelector);
288-
const endDateInput = doc.querySelector(dataRange.dataset.endSelector);
289-
290-
rangeSelect[0].selected = true;
291-
periodInput.value = '';
292-
endDateInput.vaue = '';
293-
dataRange.classList.remove(CLASS_VISIBLE_DATE_RANGE);
234+
const clearDataRange = (event, select, dateRange) => {
235+
select.clearCurrentSelection();
236+
dateRange.setDates([]);
237+
dateRange.toggleHidden(true);
294238
removeSearchTag(event);
295239
};
296240
const clearCreator = (event) => {
@@ -302,8 +246,8 @@
302246
subtree: (event) => clearSubtree(event),
303247
creator: (event) => clearCreator(event),
304248
'content-types': (event) => clearContentType(event),
305-
'last-modified': (event) => clearDataRange(event, lastModifiedSelect.dataset.targetSelector),
306-
'last-created': (event) => clearDataRange(event, lastCreatedSelect.dataset.targetSelector),
249+
'last-modified': (event) => clearDataRange(event, lastModifiedSelect, lastModifiedDateRange),
250+
'last-created': (event) => clearDataRange(event, lastCreatedSelect, lastCreatedDateRange),
307251
};
308252
const showMoreContentTypes = (event) => {
309253
const btn = event.currentTarget;
@@ -347,7 +291,6 @@
347291
);
348292
};
349293

350-
dateFields.forEach(initFlatPickr);
351294
filterByContentType();
352295

353296
clearBtn.addEventListener('click', clearFilters, false);
@@ -363,8 +306,12 @@
363306
}
364307

365308
subtreeInput.addEventListener('change', toggleDisabledStateOnApplyBtn, false);
366-
lastModifiedSelect.addEventListener('change', toggleDatesSelectVisibility, false);
367-
lastCreatedSelect.addEventListener('change', toggleDatesSelectVisibility, false);
309+
lastModifiedSelectNode.addEventListener(
310+
'change',
311+
() => toggleDatesSelectVisibility(lastModifiedSelectNode, lastModifiedDateRange),
312+
false,
313+
);
314+
lastCreatedSelectNode.addEventListener('change', () => toggleDatesSelectVisibility(lastCreatedSelectNode, lastCreatedDateRange), false);
368315
creatorInput.addEventListener('keyup', handleTyping, false);
369316
usersList.addEventListener('click', handleSelectUser, false);
370317
contentTypeCheckboxes.forEach((checkbox) => checkbox.addEventListener('change', filterByContentType, false));

src/bundle/Resources/public/js/scripts/admin.trash.list.js

Lines changed: 16 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
(function (global, doc, ibexa, React, ReactDOM, Translator) {
22
const { escapeHTML, escapeHTMLAttribute } = ibexa.helpers.text;
33
const { dangerouslySetInnerHTML } = ibexa.helpers.dom;
4+
const { getInstance } = ibexa.helpers.objectInstances;
45
let getUsersTimeout;
56
const CLASS_SORTED_ASC = 'ibexa-table__sort-column--asc';
67
const CLASS_SORTED_DESC = 'ibexa-table__sort-column--desc';
7-
const CLASS_VISIBLE_DATE_RANGE = 'ibexa-trash-search-form__range-wrapper--visible';
88
const sortedActiveField = doc.querySelector('#trash_search_sort_field').value;
99
const sortedActiveDirection = doc.querySelector('#trash_search_sort_direction').value;
10-
const dateFields = doc.querySelectorAll('.ibexa-trash-search-form__range-wrapper');
10+
const trashedDateTimeRangeNode = doc.querySelector('.ibexa-trash-search-form__trashed-date-time-range');
11+
const trashedDateTimeRange = getInstance(trashedDateTimeRangeNode);
1112
const trashedTypeInput = doc.querySelector('#trash_search_trashed');
1213
const token = doc.querySelector('meta[name="CSRF-Token"]').content;
1314
const siteaccess = doc.querySelector('meta[name="SiteAccess"]').content;
@@ -23,13 +24,6 @@
2324
const udwContainer = doc.getElementById('react-udw');
2425
const autoSendNodes = doc.querySelectorAll('.ibexa-trash-search-form__item--auto-send');
2526
const errorMessage = Translator.trans(/*@Desc("Cannot fetch user list")*/ 'trash.user_list.error', {}, 'ibexa_trash_ui');
26-
const dateConfig = {
27-
mode: 'range',
28-
locale: {
29-
rangeSeparator: ' - ',
30-
},
31-
formatDate: (date) => ibexa.helpers.timezone.formatShortDateTime(date, null, ibexa.adminUiConfig.dateFormat.shortDate),
32-
};
3327
let udwRoot = null;
3428
const closeUDW = () => udwRoot.unmount();
3529
const onConfirm = (form, content) => {
@@ -200,59 +194,14 @@
200194
formSearch.submit();
201195
};
202196
const toggleDatesSelectVisibility = (event) => {
203-
const datesRangeNode = doc.querySelector(event.target.dataset.targetSelector);
204-
205197
if (event.target.value !== 'custom_range') {
206-
doc.querySelector(datesRangeNode.dataset.periodSelector).value = event.target.value;
207-
doc.querySelector(datesRangeNode.dataset.endSelector).value = '';
208-
datesRangeNode.classList.remove(CLASS_VISIBLE_DATE_RANGE);
209-
formSearch.submit();
198+
trashedDateTimeRange.setDates([]);
199+
trashedDateTimeRange.toggleHidden(true);
210200

211201
return;
212202
}
213203

214-
datesRangeNode.classList.add(CLASS_VISIBLE_DATE_RANGE);
215-
};
216-
const setSelectedDateRange = (timestamps, { dates, inputField }) => {
217-
const dateRange = inputField.closest('.ibexa-trash-search-form__range-wrapper');
218-
219-
if (dates.length === 2) {
220-
const startDate = getUnixTimestampUTC(dates[0]);
221-
const endDate = getUnixTimestampUTC(dates[1]);
222-
const secondsInDay = 86400;
223-
const days = (endDate - startDate) / secondsInDay;
224-
225-
doc.querySelector(dateRange.dataset.periodSelector).value = `P0Y0M${days}D`;
226-
doc.querySelector(dateRange.dataset.endSelector).value = endDate;
227-
228-
formSearch.submit();
229-
} else if (dates.length === 0) {
230-
doc.querySelector(dateRange.dataset.periodSelector).value = '';
231-
doc.querySelector(dateRange.dataset.endSelector).value = '';
232-
233-
formSearch.submit();
234-
}
235-
};
236-
const getUnixTimestampUTC = (dateObject) => {
237-
let date = new Date(Date.UTC(dateObject.getFullYear(), dateObject.getMonth(), dateObject.getDate()));
238-
date = Math.floor(date.getTime() / 1000);
239-
240-
return date;
241-
};
242-
const initFlatPickr = (dateRangeField) => {
243-
const { start, end } = dateRangeField.querySelector('.ibexa-trash-search-form__range-select').dataset;
244-
const defaultDate = start && end ? [start, end] : [];
245-
246-
const dateTimePickerWidget = new ibexa.core.DateTimePicker({
247-
container: dateRangeField,
248-
onChange: setSelectedDateRange,
249-
flatpickrConfig: {
250-
...dateConfig,
251-
defaultDate,
252-
},
253-
});
254-
255-
dateTimePickerWidget.init();
204+
trashedDateTimeRange.toggleHidden(false);
256205
};
257206
const handleAutoSubmitNodes = (event) => {
258207
event.preventDefault();
@@ -282,7 +231,16 @@
282231
};
283232

284233
setSortedClass();
285-
dateFields.forEach(initFlatPickr);
234+
trashedDateTimeRangeNode.addEventListener(
235+
'ibexa:date-time-range-single:change',
236+
(event) => {
237+
const { dates } = event.detail;
238+
if (dates.length === 2 || dates.length === 0) {
239+
formSearch.submit();
240+
}
241+
},
242+
false,
243+
);
286244
autoSendNodes.forEach((node) => node.addEventListener('change', handleAutoSubmitNodes, false));
287245
sortableColumns.forEach((column) => column.addEventListener('click', sortTrashItems, false));
288246
trashedTypeInput.addEventListener('change', toggleDatesSelectVisibility, false);

src/bundle/Resources/public/js/scripts/core/date.time.picker.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class DateTimePicker {
3232
...(config.flatpickrConfig ?? {}),
3333
};
3434

35-
setInstance(this.container, this);
35+
setInstance(this.container, this); // TODO: reove in 5.0
36+
setInstance(this.fieldWrapper, this);
3637
}
3738

3839
clear() {

0 commit comments

Comments
 (0)