mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 14:45:56 +08:00
Merge branch 'develop' into features/inventory-item-card-edit
This commit is contained in:
commit
cc8b993430
|
@ -731,6 +731,7 @@ DEPENDENCIES
|
|||
fastimage
|
||||
figaro
|
||||
graphviz
|
||||
grover
|
||||
httparty (~> 0.21.0)
|
||||
i18n-js (~> 3.6)
|
||||
image_processing
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
// Add and show modal
|
||||
$(experimentWrapper).append($.parseHTML(result.html));
|
||||
$(newMyModuleModal).modal('show');
|
||||
window.initDateTimePickerComponent(`#date-time-picker-my-module`);
|
||||
$(newMyModuleModal).find("input[type='text']").focus();
|
||||
|
||||
// Remove modal when it gets closed
|
||||
|
|
|
@ -141,43 +141,32 @@ var ExperimnetTable = {
|
|||
let dateText = $(element).closest('.date-text');
|
||||
let clearDate = $(element).closest('.datetime-container').find('.clear-date');
|
||||
|
||||
$(element).on('dp.change', function() {
|
||||
$.ajax({
|
||||
url: dueDateContainer.data('update-url'),
|
||||
type: 'PATCH',
|
||||
dataType: 'json',
|
||||
data: { my_module: { due_date: $(element).val() } },
|
||||
success: function(result) {
|
||||
dueDateContainer.find('#dueDateLabelContainer').html(result.table_due_date_label.html);
|
||||
dateText.data('due-status', result.table_due_date_label.due_status);
|
||||
$(`#calendarDueDateContainer${row.id}`).parent().on('dp:ready', () => {
|
||||
$(element).data('dateTimePicker').onChange = () => {
|
||||
$.ajax({
|
||||
url: dueDateContainer.data('update-url'),
|
||||
type: 'PATCH',
|
||||
dataType: 'json',
|
||||
data: { my_module: { due_date: $(element).val() } },
|
||||
success: function(result) {
|
||||
dueDateContainer.find('#dueDateLabelContainer').html(result.table_due_date_label.html);
|
||||
dateText.data('due-status', result.table_due_date_label.due_status);
|
||||
|
||||
if ($(result.table_due_date_label.html).data('due-date')) {
|
||||
clearDate.addClass('open');
|
||||
if ($(result.table_due_date_label.html).data('due-date')) {
|
||||
clearDate.removeClass('tw-hidden');
|
||||
} else {
|
||||
clearDate.addClass('tw-hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearDate.on('click', () => {
|
||||
$(element).data('dateTimePicker').clearDate();
|
||||
});
|
||||
});
|
||||
|
||||
$(element).on('dp.hide', function() {
|
||||
dateText.attr('data-original-title', dateText.data('due-status'));
|
||||
clearDate.removeClass('open');
|
||||
});
|
||||
|
||||
$(element).on('dp.show', function() {
|
||||
var datePicker = $('.bootstrap-datetimepicker-widget.dropdown-menu')[0];
|
||||
|
||||
// show full datepicker menu for due date
|
||||
if (datePicker.getBoundingClientRect().bottom > window.innerHeight) {
|
||||
datePicker.scrollIntoView(false);
|
||||
} else if (datePicker.getBoundingClientRect().top < 0) {
|
||||
datePicker.scrollIntoView();
|
||||
}
|
||||
|
||||
dateText.attr('data-original-title', '').tooltip('hide');
|
||||
if (dueDateContainer.find('.due-date-label').data('due-date')) {
|
||||
clearDate.addClass('open');
|
||||
}
|
||||
});
|
||||
window.initDateTimePickerComponent(`#calendarDueDateContainer${row.id}`);
|
||||
});
|
||||
},
|
||||
initMyModuleActions: function() {
|
||||
|
@ -505,9 +494,9 @@ var ExperimnetTable = {
|
|||
}
|
||||
},
|
||||
selectDate: function($field) {
|
||||
var datePicker = $field.data('DateTimePicker');
|
||||
if (datePicker && datePicker.date()) {
|
||||
return datePicker.date()._d.toUTCString();
|
||||
var datePicker = $field.data('dateTimePicker');
|
||||
if (datePicker && datePicker.date) {
|
||||
return datePicker.date.toString();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
@ -748,9 +737,7 @@ ExperimnetTable.filters.push({
|
|||
},
|
||||
active: (value) => { return value; },
|
||||
clearFilter: ($container) => {
|
||||
if ($('.due-date-filter .from-date', $container).data('DateTimePicker')) {
|
||||
$('.due-date-filter .from-date', $container).data('DateTimePicker').clear();
|
||||
}
|
||||
$('.due-date-filter .from-date', $container).data('dateTimePicker')?.clearDate();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -763,9 +750,7 @@ ExperimnetTable.filters.push({
|
|||
},
|
||||
active: (value) => { return value; },
|
||||
clearFilter: ($container) => {
|
||||
if ($('.due-date-filter .to-date', $container).data('DateTimePicker')) {
|
||||
$('.due-date-filter .to-date', $container).data('DateTimePicker').clear();
|
||||
}
|
||||
$('.due-date-filter .to-date', $container).data('dateTimePicker')?.clearDate();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -778,9 +763,7 @@ ExperimnetTable.filters.push({
|
|||
},
|
||||
active: (value) => { return value; },
|
||||
clearFilter: ($container) => {
|
||||
if ($('.archived-on-filter .from-date', $container).data('DateTimePicker')) {
|
||||
$('.archived-on-filter .from-date', $container).data('DateTimePicker').clear();
|
||||
}
|
||||
$('.archived-on-filter .from-date', $container).data('dateTimePicker')?.clearDate();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -793,9 +776,7 @@ ExperimnetTable.filters.push({
|
|||
},
|
||||
active: (value) => { return value; },
|
||||
clearFilter: ($container) => {
|
||||
if ($('.archived-on-filter .to-date', $container).data('DateTimePicker')) {
|
||||
$('.archived-on-filter .to-date', $container).data('DateTimePicker').clear();
|
||||
}
|
||||
$('.archived-on-filter .to-date', $container).data('dateTimePicker')?.clearDate();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -26,13 +26,13 @@ var globalActivities = (function() {
|
|||
};
|
||||
|
||||
function GlobalActivitiesFiltersGetDates() {
|
||||
var fromDate = $('#calendar-from-date').data('DateTimePicker').date();
|
||||
var toDate = $('#calendar-to-date').data('DateTimePicker').date();
|
||||
var fromDate = $('#calendar-from-date').data('dateTimePicker').$refs.vueDateTime.datetime;
|
||||
var toDate = $('#calendar-to-date').data('dateTimePicker').$refs.vueDateTime.datetime;
|
||||
if (fromDate) {
|
||||
fromDate = fromDate._d.date_to_string();
|
||||
fromDate = fromDate.date_to_string();
|
||||
}
|
||||
if (toDate) {
|
||||
toDate = toDate._d.date_to_string();
|
||||
toDate = toDate.date_to_string();
|
||||
}
|
||||
return { from: fromDate, to: toDate };
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ var globalActivities = (function() {
|
|||
|
||||
$('.date-selector .date.clear').click(() => {
|
||||
updateRunning = true;
|
||||
$('#calendar-from-date').data('DateTimePicker').clear();
|
||||
$('#calendar-to-date').data('DateTimePicker').clear();
|
||||
$('#calendar-from-date').data('dateTimePicker').clearDate();
|
||||
$('#calendar-to-date').data('dateTimePicker').clearDate();
|
||||
$('.ga-side .date-selector.filter-block')[0].dataset.periodSelect = '';
|
||||
resetHotButtonsBackgroundColor();
|
||||
updateRunning = false;
|
||||
|
@ -205,8 +205,8 @@ var globalActivities = (function() {
|
|||
var selectorsCount = $(projectFilter).length === 1 ? clearSelectors.length - 1 : 1;
|
||||
updateRunning = true;
|
||||
|
||||
$('#calendar-from-date').data('DateTimePicker').clear();
|
||||
$('#calendar-to-date').data('DateTimePicker').clear();
|
||||
$('#calendar-from-date').data('dateTimePicker').clearDate();
|
||||
$('#calendar-to-date').data('dateTimePicker').clearDate();
|
||||
$('.ga-side .date-selector.filter-block')[0].dataset.periodSelect = '';
|
||||
|
||||
|
||||
|
@ -331,27 +331,18 @@ var globalActivities = (function() {
|
|||
});
|
||||
});
|
||||
|
||||
$('#calendar-to-date').on('dp.change', function(e) {
|
||||
var dateContainer = $('.ga-side .date-selector.filter-block');
|
||||
if (!updateRunning) {
|
||||
$('#calendar-from-date').data('DateTimePicker').minDate(e.date);
|
||||
dateContainer[0].dataset.periodSelect = $('#calendar-to-date').val() + ' - ' + $('#calendar-from-date').val();
|
||||
GlobalActivitiesUpdateTopPaneTags();
|
||||
reloadActivities();
|
||||
toggleClearButtons();
|
||||
resetHotButtonsBackgroundColor();
|
||||
}
|
||||
});
|
||||
|
||||
$('#calendar-from-date').on('dp.change', function(e) {
|
||||
var dateContainer = $('.ga-side .date-selector.filter-block');
|
||||
if (!updateRunning) {
|
||||
$('#calendar-to-date').data('DateTimePicker').maxDate(e.date);
|
||||
dateContainer[0].dataset.periodSelect = $('#calendar-to-date').val() + ' - ' + $('#calendar-from-date').val();
|
||||
GlobalActivitiesUpdateTopPaneTags();
|
||||
reloadActivities();
|
||||
toggleClearButtons();
|
||||
resetHotButtonsBackgroundColor();
|
||||
$('.datetime-picker-container').on('dp:ready', function() {
|
||||
$(this).find('.calendar-input').data('dateTimePicker').onChange = () => {
|
||||
let dateContainer = $('.ga-side .date-selector.filter-block');
|
||||
if (!updateRunning) {
|
||||
let toDate = $('#calendar-to-date').data('dateTimePicker').$refs.vueDateTime.datetime;
|
||||
let fromDate = $('#calendar-from-date').data('dateTimePicker').$refs.vueDateTime.datetime;
|
||||
dateContainer[0].dataset.periodSelect = (toDate ? toDate?.date_to_string() : '') + ' - ' + (fromDate ? fromDate.date_to_string() : '');
|
||||
GlobalActivitiesUpdateTopPaneTags();
|
||||
reloadActivities();
|
||||
toggleClearButtons();
|
||||
resetHotButtonsBackgroundColor();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -362,8 +353,8 @@ var globalActivities = (function() {
|
|||
$('.date-selector .hot-button').click(function() {
|
||||
var selectPeriod = this.dataset.period;
|
||||
var dateContainer = $('.ga-side .date-selector.filter-block');
|
||||
var fromDate = $('#calendar-from-date').data('DateTimePicker');
|
||||
var toDate = $('#calendar-to-date').data('DateTimePicker');
|
||||
var fromDate = $('#calendar-from-date').data('dateTimePicker');
|
||||
var toDate = $('#calendar-to-date').data('dateTimePicker');
|
||||
var today = new Date();
|
||||
var yesterday = new Date(new Date().setDate(today.getDate() - 1));
|
||||
var weekDay = today.getDay();
|
||||
|
@ -375,26 +366,24 @@ var globalActivities = (function() {
|
|||
var lastMonthEnd = new Date(new Date().setDate(firstDay.getDate() - 1));
|
||||
var lastMonthStart = new Date(lastMonthEnd.getFullYear(), lastMonthEnd.getMonth(), 1);
|
||||
updateRunning = true;
|
||||
fromDate.minDate(new Date(1900, 1, 1));
|
||||
toDate.maxDate(new Date(3000, 1, 1));
|
||||
if (selectPeriod === 'today') {
|
||||
fromDate.date(today);
|
||||
toDate.date(today);
|
||||
fromDate.$refs.vueDateTime.datetime = today;
|
||||
toDate.$refs.vueDateTime.datetime = today;
|
||||
} else if (selectPeriod === 'yesterday') {
|
||||
fromDate.date(yesterday);
|
||||
toDate.date(yesterday);
|
||||
fromDate.$refs.vueDateTime.datetime = yesterday;
|
||||
toDate.$refs.vueDateTime.datetime = yesterday;
|
||||
} else if (selectPeriod === 'this_week') {
|
||||
fromDate.date(today);
|
||||
toDate.date(monday);
|
||||
fromDate.$refs.vueDateTime.datetime = today;
|
||||
toDate.$refs.vueDateTime.datetime = monday;
|
||||
} else if (selectPeriod === 'last_week') {
|
||||
fromDate.date(lastWeekEnd);
|
||||
toDate.date(lastWeekStart);
|
||||
fromDate.$refs.vueDateTime.datetime = lastWeekEnd;
|
||||
toDate.$refs.vueDateTime.datetime = lastWeekStart;
|
||||
} else if (selectPeriod === 'this_month') {
|
||||
fromDate.date(today);
|
||||
toDate.date(firstDay);
|
||||
fromDate.$refs.vueDateTime.datetime = today;
|
||||
toDate.$refs.vueDateTime.datetime = firstDay;
|
||||
} else if (selectPeriod === 'last_month') {
|
||||
fromDate.date(lastMonthEnd);
|
||||
toDate.date(lastMonthStart);
|
||||
fromDate.$refs.vueDateTime.datetime = lastMonthEnd;
|
||||
toDate.$refs.vueDateTime.datetime = lastMonthStart;
|
||||
}
|
||||
updateRunning = false;
|
||||
dateContainer[0].dataset.periodSelect = this.innerHTML;
|
||||
|
|
|
@ -56,9 +56,12 @@
|
|||
|
||||
// Bind ajax for editing due dates
|
||||
function initStartDatePicker() {
|
||||
$('#calendarStartDate').on('dp.change', function() {
|
||||
updateStartDate();
|
||||
$('.datetime-picker-container#start-date').on('dp:ready', () => {
|
||||
$('#calendarStartDate').data('dateTimePicker').onChange = () => {
|
||||
updateStartDate();
|
||||
};
|
||||
});
|
||||
window.initDateTimePickerComponent('#calendarStartDateContainer');
|
||||
}
|
||||
|
||||
function updateDueDate() {
|
||||
|
@ -82,9 +85,12 @@
|
|||
|
||||
// Bind ajax for editing due dates
|
||||
function initDueDatePicker() {
|
||||
$('#calendarDueDate').on('dp.change', function() {
|
||||
updateDueDate();
|
||||
$('.datetime-picker-container#due-date').on('dp:ready', () => {
|
||||
$('#calendarDueDate').data('dateTimePicker').onChange = () => {
|
||||
updateDueDate();
|
||||
};
|
||||
});
|
||||
window.initDateTimePickerComponent('#calendarDueDateContainer');
|
||||
}
|
||||
|
||||
function initTagsSelector() {
|
||||
|
|
|
@ -763,6 +763,8 @@ function bindEditDueDateAjax() {
|
|||
editDueDateModalBody.html(data.html);
|
||||
editDueDateModalTitle.text(data.title);
|
||||
|
||||
window.initDateTimePickerComponent('#date-time-picker');
|
||||
|
||||
// Add listener to form inside modal
|
||||
editDueDateModalBody.find("form")
|
||||
.on("ajax:success", function(ev2, data2, status2) {
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
var ProjectsIndex = (function() {
|
||||
var projectsWrapper = '#projectsWrapper';
|
||||
var toolbarWrapper = '#toolbarWrapper';
|
||||
var cardsWrapper = '#cardsWrapper';
|
||||
var editProjectModal = '#edit-modal';
|
||||
var moveToModal = '#move-to-modal';
|
||||
|
@ -448,22 +447,13 @@ var ProjectsIndex = (function() {
|
|||
data: { ...requestParams, ...{ page: 1 } },
|
||||
success: function(data) {
|
||||
$(projectsWrapper).find('.projects-title').html(data.title_html);
|
||||
$(toolbarWrapper).html(data.toolbar_html);
|
||||
initProjectsViewModeSwitch();
|
||||
|
||||
initCardData(viewContainer, data);
|
||||
|
||||
selectedProjects.length = 0;
|
||||
selectedProjectFolders.length = 0;
|
||||
|
||||
updateProjectsToolbar();
|
||||
initProjectsFilters();
|
||||
initSorting();
|
||||
|
||||
// set current sort item
|
||||
if (projectsCurrentSort) {
|
||||
$('#sortMenuDropdown a').removeClass('selected');
|
||||
$(`#sortMenuDropdown a[data-sort="${projectsCurrentSort}"]`).addClass('selected');
|
||||
}
|
||||
|
||||
if (data.filtered) {
|
||||
$(projectsWrapper).find('.project-list-end-placeholder').remove();
|
||||
|
@ -546,11 +536,9 @@ var ProjectsIndex = (function() {
|
|||
}
|
||||
|
||||
function selectDate($field) {
|
||||
var datePicker = $field.data('DateTimePicker');
|
||||
if (datePicker && datePicker.date()) {
|
||||
return datePicker.date()._d.toUTCString();
|
||||
} else if ($field.val()) {
|
||||
return moment($field.val(), $field.data('dateFormat'))._d.toUTCString();
|
||||
let datePicker = $field.data('dateTimePicker');
|
||||
if (datePicker && datePicker.date) {
|
||||
return datePicker.date.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -576,32 +564,6 @@ var ProjectsIndex = (function() {
|
|||
projectsViewSearch = $textFilter.val();
|
||||
}
|
||||
|
||||
function saveCurrentFilters() {
|
||||
getFilterValues();
|
||||
|
||||
currentFilters = {
|
||||
createdOnFromFilter: $createdOnFromFilter.val(),
|
||||
createdOnToFilter: $createdOnToFilter.val(),
|
||||
membersFilter: membersFilter,
|
||||
lookInsideFolders: lookInsideFolders,
|
||||
archivedOnFromFilter: $archivedOnFromFilter.val(),
|
||||
archivedOnToFilter: $archivedOnToFilter.val(),
|
||||
projectsViewSearch: projectsViewSearch
|
||||
};
|
||||
}
|
||||
|
||||
function loadCurrentFilters() {
|
||||
if (!currentFilters) return;
|
||||
|
||||
$createdOnFromFilter.val(currentFilters.createdOnFromFilter);
|
||||
$createdOnToFilter.val(currentFilters.createdOnToFilter);
|
||||
$foldersCB.attr('checked', !!currentFilters.lookInsideFolders);
|
||||
dropdownSelector.setData($('.members-filter'), currentFilters.membersFilter);
|
||||
$archivedOnFromFilter.val(currentFilters.archivedOnFromFilter);
|
||||
$archivedOnToFilter.val(currentFilters.archivedOnToFilter);
|
||||
$textFilter.val(currentFilters.projectsViewSearch);
|
||||
}
|
||||
|
||||
function filtersEnabled() {
|
||||
getFilterValues();
|
||||
|
||||
|
@ -640,7 +602,6 @@ var ProjectsIndex = (function() {
|
|||
});
|
||||
|
||||
$filterDropdown.on('filter:apply', function() {
|
||||
saveCurrentFilters();
|
||||
appliedFiltersMark();
|
||||
loadCardsView();
|
||||
});
|
||||
|
@ -650,12 +611,11 @@ var ProjectsIndex = (function() {
|
|||
currentFilters = null;
|
||||
|
||||
dropdownSelector.clearData($membersFilter);
|
||||
$createdOnFromFilter.val('');
|
||||
$createdOnToFilter.val('');
|
||||
$createdOnFromFilter.val('');
|
||||
$createdOnToFilter.val('');
|
||||
$archivedOnFromFilter.val('');
|
||||
$archivedOnToFilter.val('');
|
||||
|
||||
$createdOnFromFilter.data('dateTimePicker').clearDate();
|
||||
$createdOnToFilter.data('dateTimePicker').clearDate();
|
||||
$archivedOnFromFilter.data('dateTimePicker').clearDate();
|
||||
$archivedOnToFilter.data('dateTimePicker').clearDate();
|
||||
$foldersCB.prop('checked', false);
|
||||
$textFilter.val('');
|
||||
});
|
||||
|
@ -668,7 +628,6 @@ var ProjectsIndex = (function() {
|
|||
$('#folderSearchInfo').hide();
|
||||
});
|
||||
|
||||
loadCurrentFilters();
|
||||
appliedFiltersMark();
|
||||
}
|
||||
|
||||
|
@ -710,10 +669,12 @@ var ProjectsIndex = (function() {
|
|||
initArchiveRestoreToolbarButtons();
|
||||
initEditButton();
|
||||
initMoveButton();
|
||||
initProjectsViewModeSwitch();
|
||||
initSelectAllCheckbox();
|
||||
initArchiveRestoreButton();
|
||||
loadCardsView();
|
||||
initProjectsViewModeSwitch();
|
||||
initProjectsFilters();
|
||||
initSorting();
|
||||
AsyncDropdown.init($(projectsWrapper));
|
||||
|
||||
$(projectsWrapper).on('click', '.folder-card-selector', function() {
|
||||
|
|
|
@ -132,9 +132,9 @@
|
|||
}
|
||||
|
||||
function selectDate($field) {
|
||||
var datePicker = $field.data('DateTimePicker');
|
||||
if (datePicker && datePicker.date()) {
|
||||
return datePicker.date()._d.toUTCString();
|
||||
let datePicker = $field.data('dateTimePicker');
|
||||
if (datePicker && datePicker.date) {
|
||||
return datePicker.date.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -186,12 +186,12 @@
|
|||
// Clear filters
|
||||
$filterDropdown.on('filter:clear', function() {
|
||||
$(this).find('input').val('');
|
||||
if ($startedOnFromFilter.data('DateTimePicker')) $startedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($startedOnToFilter.data('DateTimePicker')) $startedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnFromFilter.data('DateTimePicker')) $modifiedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnToFilter.data('DateTimePicker')) $modifiedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnFromFilter.data('DateTimePicker')) $archivedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnToFilter.data('DateTimePicker')) $archivedOnToFilter.data('DateTimePicker').clear();
|
||||
$startedOnFromFilter.data('dateTimePicker').clearDate();
|
||||
$startedOnToFilter.data('dateTimePicker').clearDate();
|
||||
$modifiedOnFromFilter.data('dateTimePicker').clearDate();
|
||||
$modifiedOnToFilter.data('dateTimePicker').clearDate();
|
||||
$archivedOnFromFilter.data('dateTimePicker').clearDate();
|
||||
$archivedOnToFilter.data('dateTimePicker').clearDate();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ var ProtocolsIndex = (function() {
|
|||
}
|
||||
|
||||
function selectDate($field) {
|
||||
var datePicker = $field.data('DateTimePicker');
|
||||
if (datePicker && datePicker.date()) {
|
||||
return datePicker.date()._d.toUTCString();
|
||||
var datePicker = $field.data('dateTimePicker');
|
||||
if (datePicker && datePicker.date) {
|
||||
return datePicker.date.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -129,12 +129,12 @@ var ProtocolsIndex = (function() {
|
|||
dropdownSelector.clearData($accessByFilter);
|
||||
|
||||
$(this).find('input').val('');
|
||||
if ($publishedOnFromFilter.data('DateTimePicker')) $publishedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($publishedOnToFilter.data('DateTimePicker')) $publishedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnFromFilter.data('DateTimePicker')) $modifiedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnToFilter.data('DateTimePicker')) $modifiedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnFromFilter.data('DateTimePicker')) $archivedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnToFilter.data('DateTimePicker')) $archivedOnToFilter.data('DateTimePicker').clear();
|
||||
$publishedOnFromFilter.data('dateTimePicker')?.clearDate();
|
||||
$publishedOnToFilter.data('dateTimePicker')?.clearDate();
|
||||
$modifiedOnFromFilter.data('dateTimePicker')?.clearDate();
|
||||
$modifiedOnToFilter.data('dateTimePicker')?.clearDate();
|
||||
$archivedOnFromFilter.data('dateTimePicker')?.clearDate();
|
||||
$archivedOnToFilter.data('dateTimePicker')?.clearDate();
|
||||
$hasDraft.prop('checked', false);
|
||||
$textFilter.val('');
|
||||
});
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
}],
|
||||
fnInitComplete: function(e) {
|
||||
initActionToolbar();
|
||||
|
||||
window.actionToolbarComponent.setReloadCallback(() =>
|
||||
initRepositoriesDataTable('#repositoriesList', archived));
|
||||
window.actionToolbarComponent.setBottomOffset(68);
|
||||
|
|
|
@ -2,316 +2,90 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
|
||||
var DateTimeHelper = (function() {
|
||||
function isValidTimeStr(timeStr) {
|
||||
return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(timeStr);
|
||||
}
|
||||
|
||||
function isValidDate(date) {
|
||||
return (date instanceof Date) && !isNaN(date.getTime());
|
||||
}
|
||||
|
||||
function addLeadingZero(value) {
|
||||
return ('0' + value).slice(-2);
|
||||
}
|
||||
|
||||
function setDateTimePickerOpeningDirection(event) {
|
||||
const element = $(event.target);
|
||||
const dateTimePickerWidget = $('.bootstrap-datetimepicker-widget');
|
||||
|
||||
const windowHeight = element.closest('table').offset().top;
|
||||
const inputTop = element.offset().top;
|
||||
const pickerHeight = $('.bootstrap-datetimepicker-widget').outerHeight();
|
||||
|
||||
if (inputTop - windowHeight > pickerHeight) {
|
||||
dateTimePickerWidget.addClass('top')
|
||||
.removeClass('bottom')
|
||||
.css({
|
||||
top: 'auto',
|
||||
bottom: '36px',
|
||||
});
|
||||
} else {
|
||||
dateTimePickerWidget.addClass('bottom')
|
||||
.removeClass('top')
|
||||
.css({
|
||||
top: '36px',
|
||||
bottom: 'auto',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function recalcTimestamp(date, timeStr) {
|
||||
if (!isValidTimeStr(timeStr)) {
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
return date;
|
||||
}
|
||||
|
||||
date.setHours(timeStr.split(':')[0]);
|
||||
date.setMinutes(timeStr.split(':')[1]);
|
||||
return date;
|
||||
}
|
||||
|
||||
function stringDateTimeFormat(date, format) {
|
||||
let y = date.getFullYear();
|
||||
let m = addLeadingZero(date.getMonth() + 1);
|
||||
let d = addLeadingZero(date.getDate());
|
||||
let hours = addLeadingZero(date.getHours());
|
||||
let mins = addLeadingZero(date.getMinutes());
|
||||
|
||||
if (format === 'dateonly') {
|
||||
return `${y}/${m}/${d}`;
|
||||
}
|
||||
return `${y}/${m}/${d} ${hours}:${mins}`;
|
||||
}
|
||||
|
||||
function insertHiddenField($container) {
|
||||
let formId = $container.data('form-id');
|
||||
let columnId = $container.data('column-id');
|
||||
let dateStr = $container.find('input.date-part').data('selected-date');
|
||||
let timeStr = $container.find('input.time-part').val();
|
||||
let columnType = $container.data('type');
|
||||
let date = new Date(dateStr);
|
||||
let value = '';
|
||||
let hiddenField;
|
||||
|
||||
if (isValidDate(date) && isValidTimeStr(timeStr)) {
|
||||
value = stringDateTimeFormat(recalcTimestamp(date, timeStr), 'full');
|
||||
}
|
||||
|
||||
hiddenField = `
|
||||
<input class="repository-cell-value"
|
||||
type="hidden"
|
||||
form="${formId}"
|
||||
name="repository_cells[${columnId}]"
|
||||
value="${value}"
|
||||
data-type="${columnType}"/>`;
|
||||
|
||||
$container.find('input.repository-cell-value').remove();
|
||||
$container.prepend(hiddenField);
|
||||
}
|
||||
|
||||
|
||||
function insertRangeHiddenField($container) {
|
||||
let formId = $container.data('form-id');
|
||||
let columnId = $container.data('column-id');
|
||||
let columnType = $container.data('type');
|
||||
let $startContainer = $container.find('.start-time');
|
||||
let $endContainer = $container.find('.end-time');
|
||||
let startDate = new Date($startContainer.find('input.date-part').data('selected-date'));
|
||||
let startTimeStr = $startContainer.find('input.time-part').val();
|
||||
let endDate = new Date($endContainer.find('input.date-part').data('selected-date'));
|
||||
let endTimeStr = $endContainer.find('input.time-part').val();
|
||||
let hiddenField;
|
||||
let value = '';
|
||||
|
||||
if (isValidDate(startDate)
|
||||
&& isValidTimeStr(startTimeStr)
|
||||
&& isValidDate(endDate)
|
||||
&& isValidTimeStr(endTimeStr)) {
|
||||
let start = stringDateTimeFormat(recalcTimestamp(startDate, startTimeStr), 'full');
|
||||
let end = stringDateTimeFormat(recalcTimestamp(endDate, endTimeStr), 'full');
|
||||
value = JSON.stringify({ start_time: start, end_time: end });
|
||||
}
|
||||
|
||||
hiddenField = `
|
||||
<input class="repository-cell-value"
|
||||
type="hidden"
|
||||
form="${formId}"
|
||||
name="repository_cells[${columnId}]"
|
||||
value='${value}'
|
||||
data-type="${columnType}"/>`;
|
||||
|
||||
$container.find('input.repository-cell-value').remove();
|
||||
$container.prepend(hiddenField);
|
||||
}
|
||||
|
||||
function initChangeEvents($cell) {
|
||||
$cell.find('input.time-part').on('change', function() {
|
||||
let $input = $(this);
|
||||
let $container = $input.closest('.datetime-container');
|
||||
|
||||
if ($container.hasClass('range-type')) {
|
||||
insertRangeHiddenField($container);
|
||||
} else {
|
||||
insertHiddenField($container);
|
||||
}
|
||||
});
|
||||
|
||||
$cell.find('input.date-part').on('dp.change', function(e) {
|
||||
let $input = $(this);
|
||||
let date = e.date._d;
|
||||
let $container = $input.closest('.datetime-container');
|
||||
|
||||
if (date !== undefined) {
|
||||
$input.data('selected-date', stringDateTimeFormat(date, 'dateonly'));
|
||||
} else {
|
||||
$input.data('selected-date', '');
|
||||
}
|
||||
|
||||
if ($container.hasClass('range-type')) {
|
||||
insertRangeHiddenField($container);
|
||||
} else {
|
||||
insertHiddenField($container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function dateInputField(value, dateDataValue) {
|
||||
return `
|
||||
<div class="sci-input-container date-container right-icon">
|
||||
<input class="calendar-input date-part sci-input-field"
|
||||
type="datetime"
|
||||
placeholder="${formatJS}"
|
||||
data-datetime-part="date"
|
||||
data-selected-date="${dateDataValue}"
|
||||
value='${value}'/>
|
||||
<i class="sn-icon sn-icon-calendar"></i>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function timeInputField(value) {
|
||||
return `
|
||||
<div class="sci-input-container time-container right-icon">
|
||||
<input class="time-part sci-input-field"
|
||||
type="text"
|
||||
data-mask-type="time"
|
||||
value='${value}'
|
||||
placeholder="HH:mm"/>
|
||||
<i class="sn-icon sn-icon-created"></i>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function getDateOrDefault($span, mode) {
|
||||
let dateStr = $span.data('date');
|
||||
let date;
|
||||
if (mode === 'timeonly') {
|
||||
// Set default date if no data in span
|
||||
date = new Date(dateStr);
|
||||
if (isValidDate(date)) {
|
||||
dateStr = stringDateTimeFormat(new Date(date), 'dateonly');
|
||||
} else {
|
||||
dateStr = stringDateTimeFormat(new Date(), 'dateonly');
|
||||
}
|
||||
}
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
function getTimeOrDefault($span, mode) {
|
||||
let timeStr = $span.data('time');
|
||||
|
||||
if ((mode === 'dateonly') && (!isValidTimeStr(timeStr))) {
|
||||
timeStr = '00:00';
|
||||
}
|
||||
return timeStr;
|
||||
}
|
||||
|
||||
function initCurrentTimeSelector($cell) {
|
||||
$cell.find('.time-container .fa-clock').click(function() {
|
||||
var inputField = $(this).prev();
|
||||
var d = new Date();
|
||||
var h = addLeadingZero(d.getHours());
|
||||
var m = addLeadingZero(d.getMinutes());
|
||||
inputField.val(h + ':' + m).change();
|
||||
});
|
||||
function placeholder(mode) {
|
||||
if (mode === 'date') return formatJS;
|
||||
if (mode === 'time') return 'HH:mm';
|
||||
return `${formatJS} HH:mm`;
|
||||
}
|
||||
|
||||
function initDateTimeEditMode(formId, columnId, $cell, mode, columnType) {
|
||||
let $span = $cell.find('span').first();
|
||||
let date = $span.data('date');
|
||||
let dateDataValue = getDateOrDefault($span, mode);
|
||||
let time = getTimeOrDefault($span, mode);
|
||||
let datetime = $span.data('datetime');
|
||||
let inputFields = `
|
||||
<div class="form-group datetime-container ${mode}"
|
||||
data-form-id="${formId}"
|
||||
data-column-id="${columnId}"
|
||||
const $span = $cell.find('span').first();
|
||||
const dateTime = $span.data('datetime') || '';
|
||||
const inputFields = `
|
||||
<div class="datetime-container">
|
||||
<div id="datetimePickerContainer${formId}${columnId}"
|
||||
class="date-container ${mode} vue-date-time-picker-filter min-w-[160px]">
|
||||
<input ref="input"
|
||||
data-type="${columnType}"
|
||||
data-current-datetime="${datetime}">
|
||||
${dateInputField(date, dateDataValue)}
|
||||
${timeInputField(time)}
|
||||
</div>
|
||||
`;
|
||||
data-simple-format="true"
|
||||
form="${formId}"
|
||||
name="repository_cells[${columnId}]"
|
||||
class="datetime" type="hidden"
|
||||
data-default="${dateTime}"
|
||||
v-model="date"
|
||||
id="datetimePicker${formId}${columnId}" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate"
|
||||
:teleport="false"
|
||||
:clearable="true"
|
||||
ref="vueDateTime" @change="updateDate" mode="${mode}"
|
||||
placeholder="${placeholder(mode)}"></date-time-picker>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
$cell.html(inputFields);
|
||||
initCurrentTimeSelector($cell);
|
||||
|
||||
Inputmask('datetime', {
|
||||
inputFormat: 'HH:MM',
|
||||
placeholder: 'HH:mm',
|
||||
clearIncomplete: true,
|
||||
showMaskOnHover: true,
|
||||
hourFormat: 24
|
||||
}).mask($cell.find('input[data-mask-type="time"]'));
|
||||
|
||||
$cell.find('.calendar-input')
|
||||
.datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS })
|
||||
.on('dp.show', (e) => {
|
||||
setDateTimePickerOpeningDirection(e);
|
||||
});
|
||||
initChangeEvents($cell);
|
||||
window.initDateTimePickerComponent(`#datetimePickerContainer${formId}${columnId}`);
|
||||
}
|
||||
|
||||
function initDateTimeRangeEditMode(formId, columnId, $cell, mode, columnType) {
|
||||
let $startSpan = $cell.find('span').first();
|
||||
let startDate = $startSpan.data('date');
|
||||
let startTime = getTimeOrDefault($startSpan, mode);
|
||||
let startDatetime = getDateOrDefault($startSpan, mode);
|
||||
let startDateDataValue = getDateOrDefault($startSpan, mode);
|
||||
let $endSpan = $cell.find('span').last();
|
||||
let endDate = $endSpan.data('date');
|
||||
let endTime = getTimeOrDefault($endSpan, mode);
|
||||
let endDatetime = getDateOrDefault($endSpan, mode);
|
||||
let endDateDataValue = getDateOrDefault($endSpan, mode);
|
||||
const $startSpan = $cell.find('span').first();
|
||||
const startDateTime = $startSpan.data('datetime') || '';
|
||||
const $endSpan = $cell.find('span').last();
|
||||
const endDateTime = $endSpan.data('datetime') || '';
|
||||
|
||||
let inputFields = `
|
||||
<div class="form-group datetime-container range-type ${mode}"
|
||||
data-form-id="${formId}"
|
||||
data-column-id="${columnId}"
|
||||
data-type="${columnType}"
|
||||
>
|
||||
<div class="start-time ${mode}"
|
||||
data-current-datetime="${startDatetime}">
|
||||
${dateInputField(startDate, startDatetime)}
|
||||
${timeInputField(startTime)}
|
||||
</div>
|
||||
<div class="separator">—</div>
|
||||
<div class="end-time ${mode}"
|
||||
data-current-datetime="${endDatetime}">
|
||||
${dateInputField(endDate, endDatetime)}
|
||||
${timeInputField(endTime)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const inputFields = `
|
||||
<div class="datetime-container range-type ${mode}">
|
||||
<input type="hidden" form="${formId}" class="column-range" name="repository_cells[${columnId}]"
|
||||
value='${JSON.stringify({ start_time: startDateTime, end_time: endDateTime })}'>
|
||||
<div id="datetimeStartPickerComtainer${formId}${columnId}"
|
||||
class="date-container ${mode} vue-date-time-picker-filter min-w-[160px]">
|
||||
<input ref="input"
|
||||
data-type="${columnType}"
|
||||
data-simple-format="true"
|
||||
form="${formId}"
|
||||
class="datetime start" type="hidden"
|
||||
data-default="${startDateTime}"
|
||||
v-model="date"
|
||||
id="datetimeStartPicker${formId}${columnId}" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate"
|
||||
:teleport="false"
|
||||
:clearable="true"
|
||||
ref="vueDateTime" @change="updateDate"
|
||||
mode="${mode}" placeholder="${placeholder(mode)}"></date-time-picker>
|
||||
</div>
|
||||
<div class="separator">—</div>
|
||||
<div id="datetimeEndPickerComtainer${formId}${columnId}"
|
||||
class="date-container ${mode} vue-date-time-picker-filter min-w-[160px]">
|
||||
<input ref="input"
|
||||
data-type="${columnType}"
|
||||
data-simple-format="true"
|
||||
form="${formId}"
|
||||
class="datetime end" type="hidden"
|
||||
data-default="${endDateTime}"
|
||||
v-model="date"
|
||||
id="datetimeEndPicker${formId}${columnId}" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate"
|
||||
:teleport="false"
|
||||
:clearable="true"
|
||||
ref="vueDateTime" @change="updateDate" mode="${mode}"
|
||||
placeholder="${placeholder(mode)}"></date-time-picker>
|
||||
</div>
|
||||
</div>`;
|
||||
$cell.html(inputFields);
|
||||
initCurrentTimeSelector($cell);
|
||||
|
||||
Inputmask('datetime', {
|
||||
inputFormat: 'HH:MM',
|
||||
placeholder: 'HH:mm',
|
||||
clearIncomplete: true,
|
||||
showMaskOnHover: true,
|
||||
hourFormat: 24
|
||||
}).mask($cell.find('input[data-mask-type="time"]'));
|
||||
|
||||
let $cal1 = $cell.find('.calendar-input').first().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||
let $cal2 = $cell.find('.calendar-input').last().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
|
||||
|
||||
$cal1.on('dp.change', function(e) {
|
||||
$cal2.data('DateTimePicker').minDate(e.date);
|
||||
}).on('dp.show', (e) => {
|
||||
setDateTimePickerOpeningDirection(e);
|
||||
});
|
||||
$cal2.on('dp.change', function(e) {
|
||||
$cal1.data('DateTimePicker').maxDate(e.date);
|
||||
}).on('dp.show', (e) => {
|
||||
setDateTimePickerOpeningDirection(e);
|
||||
});
|
||||
|
||||
initChangeEvents($cell);
|
||||
window.initDateTimePickerComponent(`#datetimeStartPickerComtainer${formId}${columnId}`);
|
||||
window.initDateTimePickerComponent(`#datetimeEndPickerComtainer${formId}${columnId}`);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -75,37 +75,37 @@ $.fn.dataTable.render.editRepositoryStatusValue = function(formId, columnId, cel
|
|||
$.fn.dataTable.render.editRepositoryDateTimeValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, '', 'RepositoryDateTimeValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'datetime', 'RepositoryDateTimeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'dateonly', 'RepositoryDateValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'date', 'RepositoryDateValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryTimeValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'timeonly', 'RepositoryTimeValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'time', 'RepositoryTimeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateTimeRangeValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, '', 'RepositoryDateTimeRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'datetime', 'RepositoryDateTimeRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryDateRangeValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'dateonly', 'RepositoryDateRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'date', 'RepositoryDateRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryTimeRangeValue = function(formId, columnId, cell) {
|
||||
let $cell = $(cell.node());
|
||||
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'timeonly', 'RepositoryTimeRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'time', 'RepositoryTimeRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.editRepositoryChecklistValue = function(formId, columnId, cell) {
|
||||
|
|
|
@ -78,27 +78,27 @@ $.fn.dataTable.render.newRepositoryNumberValue = function(formId, columnId, $cel
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateTimeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, '', 'RepositoryDateTimeValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'datetime', 'RepositoryDateTimeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryTimeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'timeonly', 'RepositoryTimeValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'time', 'RepositoryTimeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'dateonly', 'RepositoryDateValue');
|
||||
DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, 'date', 'RepositoryDateValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateTimeRangeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, '', 'RepositoryDateTimeRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'datetime', 'RepositoryDateTimeRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryDateRangeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'dateonly', 'RepositoryDateRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'date', 'RepositoryDateRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryTimeRangeValue = function(formId, columnId, $cell) {
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'timeonly', 'RepositoryTimeRangeValue');
|
||||
DateTimeHelper.initDateTimeRangeEditMode(formId, columnId, $cell, 'time', 'RepositoryTimeRangeValue');
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.newRepositoryStockValue = function() {
|
||||
|
|
|
@ -791,6 +791,7 @@ var RepositoryDatatable = (function(global) {
|
|||
fnInitComplete: function() {
|
||||
window.initActionToolbar();
|
||||
window.actionToolbarComponent.setBottomOffset(68);
|
||||
|
||||
initHeaderTooltip();
|
||||
disableCheckboxToggleOnCheckboxPreview();
|
||||
|
||||
|
|
|
@ -76,18 +76,7 @@ $.fn.dataTable.render.RepositoryNumberValueValidator = function($input) {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateTimeValueValidator = function($input) {
|
||||
let $container = $input.parents('.datetime-container');
|
||||
let $date = $container.find('input.date-part');
|
||||
let $time = $container.find('input.time-part');
|
||||
|
||||
if (($date.val() === '') === ($time.val() === '')) {
|
||||
return true;
|
||||
}
|
||||
$container.find('.date-container')
|
||||
.addClass('error')
|
||||
.attr('data-error-text', I18n.t('repositories.table.date_time.errors.set_all_or_none'));
|
||||
$container.find('.time-container').addClass('error');
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateValueValidator = function() {
|
||||
|
@ -99,11 +88,10 @@ $.fn.dataTable.render.RepositoryTimeValueValidator = function() {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateTimeRangeValueValidator = function($input) {
|
||||
let $container = $input.parents('.datetime-container');
|
||||
let $dateS = $container.find('.start-time input.date-part');
|
||||
let $timeS = $container.find('.start-time input.time-part');
|
||||
let $dateE = $container.find('.end-time input.date-part');
|
||||
let $timeE = $container.find('.end-time input.time-part');
|
||||
const $container = $input.parents('.datetime-container');
|
||||
const $dateS = $container.find('.datetime.start');
|
||||
const $dateE = $container.find('.datetime.end');
|
||||
const $submitField = $container.find('.column-range');
|
||||
let isValid = true;
|
||||
let errorMessage;
|
||||
let startTime;
|
||||
|
@ -111,14 +99,12 @@ $.fn.dataTable.render.RepositoryDateTimeRangeValueValidator = function($input) {
|
|||
let a = [];
|
||||
|
||||
if ($input.val()) {
|
||||
startTime = new Date(JSON.parse($input.val()).start_time);
|
||||
endTime = new Date(JSON.parse($input.val()).end_time);
|
||||
startTime = new Date($dateS.val());
|
||||
endTime = new Date($dateE.val());
|
||||
}
|
||||
|
||||
a.push($dateS.val() === '');
|
||||
a.push($timeS.val() === '');
|
||||
a.push($dateE.val() === '');
|
||||
a.push($timeE.val() === '');
|
||||
|
||||
if (a.filter((v, i, arr) => arr.indexOf(v) === i).length > 1) {
|
||||
isValid = false;
|
||||
|
@ -129,26 +115,35 @@ $.fn.dataTable.render.RepositoryDateTimeRangeValueValidator = function($input) {
|
|||
}
|
||||
|
||||
if (isValid) {
|
||||
const oldValue = $submitField.val();
|
||||
let newValue;
|
||||
if ($dateS.val() && $dateE.val()) {
|
||||
newValue = JSON.stringify({ start_time: $dateS.val(), end_time: $dateE.val() });
|
||||
}
|
||||
if (oldValue !== newValue) {
|
||||
$submitField.val(newValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$container.find('.date-container').addClass('error');
|
||||
$container.find('.time-container').addClass('error');
|
||||
$container.find('.date-container').first().attr('data-error-text', errorMessage);
|
||||
return false;
|
||||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryDateRangeValueValidator = function($input) {
|
||||
let $container = $input.parents('.datetime-container');
|
||||
let $dateS = $container.find('.start-time input.date-part');
|
||||
let $dateE = $container.find('.end-time input.date-part');
|
||||
const $container = $input.parents('.datetime-container');
|
||||
const $dateS = $container.find('.datetime.start');
|
||||
const $dateE = $container.find('.datetime.end');
|
||||
const $submitField = $container.find('.column-range');
|
||||
let isValid = true;
|
||||
let errorMessage;
|
||||
let endTime;
|
||||
let startTime;
|
||||
let endTime;
|
||||
|
||||
if ($input.val()) {
|
||||
startTime = new Date(JSON.parse($input.val()).start_time);
|
||||
endTime = new Date(JSON.parse($input.val()).end_time);
|
||||
startTime = new Date($dateS.val());
|
||||
endTime = new Date($dateE.val());
|
||||
}
|
||||
|
||||
if (($dateS.val() === '') !== ($dateE.val() === '')) {
|
||||
|
@ -160,6 +155,14 @@ $.fn.dataTable.render.RepositoryDateRangeValueValidator = function($input) {
|
|||
}
|
||||
|
||||
if (isValid) {
|
||||
const oldValue = $submitField.val();
|
||||
let newValue;
|
||||
if ($dateS.val() && $dateE.val()) {
|
||||
newValue = JSON.stringify({ start_time: $dateS.val(), end_time: $dateE.val() });
|
||||
}
|
||||
if (oldValue !== newValue) {
|
||||
$submitField.val(newValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -169,24 +172,40 @@ $.fn.dataTable.render.RepositoryDateRangeValueValidator = function($input) {
|
|||
};
|
||||
|
||||
$.fn.dataTable.render.RepositoryTimeRangeValueValidator = function($input) {
|
||||
let $container = $input.parents('.datetime-container');
|
||||
let $timeS = $container.find('.start-time input.time-part');
|
||||
let $timeE = $container.find('.end-time input.time-part');
|
||||
const $container = $input.parents('.datetime-container');
|
||||
const $dateS = $container.find('.datetime.start');
|
||||
const $dateE = $container.find('.datetime.end');
|
||||
const $submitField = $container.find('.column-range');
|
||||
let isValid = true;
|
||||
let errorMessage;
|
||||
let startTime;
|
||||
let endTime;
|
||||
|
||||
if (($timeS.val() === '') !== ($timeE.val() === '')) {
|
||||
if ($input.val()) {
|
||||
startTime = new Date($dateS.val());
|
||||
endTime = new Date($dateE.val());
|
||||
}
|
||||
|
||||
if (($dateS.val() === '') !== ($dateE.val() === '')) {
|
||||
isValid = false;
|
||||
errorMessage = I18n.t('repositories.table.date_time.errors.set_all_or_none');
|
||||
} else if ($timeS.val() > $timeE.val()) {
|
||||
} else if (endTime < startTime) {
|
||||
isValid = false;
|
||||
errorMessage = I18n.t('repositories.table.date_time.errors.not_valid_range');
|
||||
}
|
||||
if (isValid) {
|
||||
const oldValue = $submitField.val();
|
||||
let newValue;
|
||||
if ($dateS.val() && $dateE.val()) {
|
||||
newValue = JSON.stringify({ start_time: $dateS.val(), end_time: $dateE.val() });
|
||||
}
|
||||
if (oldValue !== newValue) {
|
||||
$submitField.val(newValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
$container.find('.time-container').addClass('error');
|
||||
$container.find('.time-container').first().attr('data-error-text', errorMessage);
|
||||
$container.find('.date-container').addClass('error');
|
||||
$container.find('.date-container').first().attr('data-error-text', errorMessage);
|
||||
return false;
|
||||
};
|
||||
|
|
|
@ -54,6 +54,11 @@
|
|||
|
||||
$(document).on('mousedown', '[data-toggle="clear-date-time-picker"]', function() {
|
||||
let dt = $(`#${$(this).data('target')}`);
|
||||
if (dt.data('dateTimePicker')) {
|
||||
dt.data('dateTimePicker').clearDate();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dt.data('DateTimePicker')) dt.datetimepicker({ useCurrent: false });
|
||||
dt.data('DateTimePicker').clear();
|
||||
dt.val('');
|
||||
|
|
|
@ -131,6 +131,14 @@ var filterDropdown = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function initDateTimePickerComponent() {
|
||||
const dateTimePickers = document.querySelectorAll('.vue-date-time-picker-filter');
|
||||
dateTimePickers.forEach((dateTimePicker) => {
|
||||
$((`#${dateTimePicker.id}`)).removeClass('vue-date-time-picker-filter');
|
||||
window.initDateTimePickerComponent(`#${dateTimePicker.id}`);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function(filtersEnabledFunction) {
|
||||
$filterContainer = $('.filter-container');
|
||||
|
@ -138,6 +146,7 @@ var filterDropdown = (function() {
|
|||
preventDropdownClose();
|
||||
initApplyButton();
|
||||
initCloseButton();
|
||||
initDateTimePickerComponent();
|
||||
initSearchField(filtersEnabledFunction);
|
||||
this.toggleFilterMark($filterContainer, filtersEnabled)
|
||||
return $filterContainer;
|
||||
|
|
|
@ -467,21 +467,17 @@
|
|||
.clear-date {
|
||||
cursor: pointer;
|
||||
left: calc(100% - 16px);
|
||||
position: absolute;
|
||||
margin-left: auto;
|
||||
opacity: 0;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
width: 16px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
&.open {
|
||||
visibility: visible;
|
||||
}
|
||||
&:hover .clear-date {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.date-text {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
.alert-yellow {
|
||||
color: $brand-warning;
|
||||
margin-left: 4px;
|
||||
|
@ -497,7 +493,7 @@
|
|||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: calc(100% - 16px);
|
||||
width: calc(100% - 24px);
|
||||
|
||||
.calendar-due-date {
|
||||
opacity: 0;
|
||||
|
|
|
@ -248,6 +248,10 @@
|
|||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
.dp__input_wrap {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#calendarDueDate {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
.sci--layout-navigation-navigator {
|
||||
.handle-mr {
|
||||
display: block !important;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
right: -2px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
||||
.menu-item:not(.active):hover {
|
||||
background-color: var(--sn-super-light-grey);
|
||||
|
||||
|
|
|
@ -494,7 +494,7 @@
|
|||
}
|
||||
|
||||
.repository-edit-overlay--pagination {
|
||||
bottom: 0;
|
||||
bottom: .5rem;
|
||||
height: 5em;
|
||||
line-height: 5em;
|
||||
padding: .5em;
|
||||
|
|
|
@ -349,7 +349,28 @@
|
|||
}
|
||||
|
||||
.date-container {
|
||||
width: 160px;
|
||||
&.datetime {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
&.time {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
&.date {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
&.error {
|
||||
&::after {
|
||||
color: $brand-danger;
|
||||
content: attr(data-error-text);
|
||||
font-size: 12px;
|
||||
margin-top: -4px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.time-container {
|
||||
|
|
|
@ -1,5 +1,202 @@
|
|||
// scss-lint:disable SelectorDepth NestingDepth
|
||||
|
||||
.dp--menu-wrapper {
|
||||
font-weight: normal;
|
||||
|
||||
.dp__menu,
|
||||
&.dp__menu {
|
||||
border: 0;
|
||||
box-shadow: 0px 4px 16px rgba(35, 31, 32, 0.15)
|
||||
}
|
||||
|
||||
.dp__action_buttons {
|
||||
flex: 1;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.dp__active_date {
|
||||
background-color: var(--sn-science-blue);
|
||||
}
|
||||
|
||||
.dp__calendar_header_separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dp__month_year_wrap {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dp__month_year_row {
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.dp__menu_inner {
|
||||
margin: 0 1rem;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.dp__time_picker_overlay_container {
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
|
||||
.dp__button_bottom {
|
||||
background-color: var(--sn-white);
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
.dp--tp-wrap {
|
||||
border-top: 1px solid var(--sn-light-grey);
|
||||
padding: .5rem 1rem;
|
||||
|
||||
.dp__time_display {
|
||||
margin: .5rem 0;
|
||||
}
|
||||
|
||||
.dp__button_bottom {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dp__action_cancel {
|
||||
color: var(--sn-blue);
|
||||
}
|
||||
|
||||
.dp__action_button {
|
||||
margin-inline-start: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dp__inner_nav {
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
.dp__tp_inline_btn_bar {
|
||||
height: 2px;
|
||||
}
|
||||
|
||||
.dp__calendar_item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dp__btn:hover {
|
||||
.dp__tp_inline_btn_bar {
|
||||
background-color: var(--sn-science-blue);
|
||||
}
|
||||
}
|
||||
|
||||
.dp__overlay_container {
|
||||
padding-bottom: .5rem;
|
||||
}
|
||||
|
||||
.dp--arrow-btn-nav {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
width: 40px;
|
||||
|
||||
.dp__inner_nav {
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dp__input_wrap {
|
||||
.dp__input_icon {
|
||||
height: 1.5rem;
|
||||
left: .5rem;
|
||||
}
|
||||
|
||||
.dp__input {
|
||||
height: 2.25rem;
|
||||
line-height: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.dp__main.only-time {
|
||||
.dp--tp-wrap {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.dp__overlay_container {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dp__theme_light {
|
||||
--dp-background-color: var(--sn-white);
|
||||
--dp-text-color: var(--sn-black);
|
||||
--dp-hover-color: var(--sn-super-light-grey);
|
||||
--dp-hover-text-color: #212121;
|
||||
--dp-hover-icon-color: #959595;
|
||||
--dp-primary-color: var(--sn-blue);
|
||||
--dp-primary-disabled-color: var(--sn-super-light-blue);
|
||||
--dp-primary-text-color: var(--sn-white);
|
||||
--dp-secondary-color: var(--sn-grey);
|
||||
--dp-border-color: var(--sn-light-grey);
|
||||
--dp-menu-border-color: var(--sn-light-grey);
|
||||
--dp-border-color-hover: var(--sn-light-grey);
|
||||
--dp-disabled-color: var(--sn-super-light-grey);
|
||||
--dp-scroll-bar-background: var(--sn-white);
|
||||
--dp-scroll-bar-color: var(--sn-grey);
|
||||
--dp-success-color: var(--sn-blue);
|
||||
--dp-success-color-disabled: var(--sn-super-light-blue);
|
||||
--dp-icon-color: var(--sn-black);
|
||||
--dp-danger-color: var(--sn-delete-red);
|
||||
--dp-marker-color: var(--sn-delete-red-disabled);
|
||||
--dp-tooltip-color: var(--sn-super-light-grey);
|
||||
--dp-disabled-color-text: var(--sn-grey);
|
||||
--dp-highlight-color: var(--sn-super-light-grey);
|
||||
--dp-range-between-dates-background-color: var(--dp-hover-color, var(--sn-super-light-grey));
|
||||
--dp-range-between-dates-text-color: var(--dp-hover-text-color, var(--sn-black));
|
||||
--dp-range-between-border-color: var(--dp-hover-color, var(--sn-super-light-grey));
|
||||
}
|
||||
|
||||
:root {
|
||||
/*General*/
|
||||
--dp-font-family: inherit; /*Font family*/
|
||||
--dp-border-radius: .25rem; /*Configurable border-radius*/
|
||||
--dp-cell-border-radius: .25rem; /*Specific border radius for the calendar cell*/
|
||||
--dp-common-transition: all 0.1s ease-in; /*Generic transition applied on buttons and calendar cells*/
|
||||
|
||||
/*Sizing*/
|
||||
--dp-button-height: 2.5rem; /*Size for buttons in overlays*/
|
||||
--dp-month-year-row-height: 2.5rem; /*Height of the month-year select row*/
|
||||
--dp-month-year-row-button-size: 2.5rem; /*Specific height for the next/previous buttons*/
|
||||
--dp-button-icon-height: 1.5rem; /*Icon sizing in buttons*/
|
||||
--dp-cell-size: 1.875rem; /*Width and height of calendar cell*/
|
||||
--dp-cell-padding: 0rem; /*Padding in the cell*/
|
||||
--dp-common-padding: 1rem; /*Common padding used*/
|
||||
--dp-input-padding: .3em 2rem .3rem 1rem; /*Padding in the input*/
|
||||
--dp-menu-min-width: 276px; /*Adjust the min width of the menu*/
|
||||
--dp-action-row-padding: 0 1rem 1rem; /*Adjust padding for the action row*/
|
||||
--dp-action-buttons-padding: 0 .625rem; /*Adjust padding for the action buttons in action row*/
|
||||
--dp-action-button-height: 1.875rem; /*Adjust height for the action buttons in action row*/
|
||||
--dp-row-margin: 2px 0; /*Adjust the spacing between rows in the calendar*/
|
||||
--dp-calendar-header-cell-padding: .5rem; /*Adjust padding in calendar header cells*/
|
||||
--dp-two-calendars-spacing: .75rem; /*Space between multiple calendars*/
|
||||
--dp-overlay-col-padding: .25rem; /*Padding in the overlay column*/
|
||||
--dp-time-inc-dec-button-size: 1.5rem; /*Sizing for arrow buttons in the time picker*/
|
||||
--dp-menu-padding: 1rem; /*Menu padding*/
|
||||
--dp-input-icon-padding: 2rem; /*Padding on the left side of the input if icon is present*/
|
||||
|
||||
/*Font sizes*/
|
||||
--dp-font-size: .875rem; /*Default font-size*/
|
||||
--dp-preview-font-size: .75rem; /*Font size of the date preview in the action row*/
|
||||
--dp-time-font-size: 1.875rem; /*Font size in the time picker*/
|
||||
|
||||
/*Transitions*/
|
||||
--dp-animation-duration: 0.1s; /*Transition duration*/
|
||||
--dp-menu-appear-transition-timing: cubic-bezier(.4, 0, 1, 1); /*Timing on menu appear animation*/
|
||||
--dp-transition-timing: ease-out; /*Timing on slide animations*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Legacy
|
||||
|
||||
.bootstrap-datetimepicker-widget {
|
||||
.glyphicon-calendar {
|
||||
margin: 0;
|
||||
|
|
|
@ -79,11 +79,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.datetime-picker-container {
|
||||
display: inline-block;
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.connect-line {
|
||||
display: inline-block;
|
||||
margin: 0 11px;
|
||||
|
|
|
@ -475,11 +475,11 @@ class MyModulesController < ApplicationController
|
|||
|
||||
if permitted_params[:started_on].present?
|
||||
permitted_params[:started_on] =
|
||||
Time.zone.strptime(permitted_params[:started_on], I18n.backend.date_format.dup.gsub(/%-/, '%') + ' %H:%M')
|
||||
Time.zone.strptime(permitted_params[:started_on], '%Y/%m/%d %H:%M')
|
||||
end
|
||||
if permitted_params[:due_date].present?
|
||||
permitted_params[:due_date] =
|
||||
Time.zone.strptime(permitted_params[:due_date], I18n.backend.date_format.dup.gsub(/%-/, '%') + ' %H:%M')
|
||||
Time.zone.strptime(permitted_params[:due_date], '%Y/%m/%d %H:%M')
|
||||
end
|
||||
|
||||
permitted_params
|
||||
|
|
|
@ -69,7 +69,6 @@ class ProjectsController < ApplicationController
|
|||
projects_cards_url: projects_cards_url,
|
||||
title_html: title_html,
|
||||
next_page: cards.next_page,
|
||||
toolbar_html: render_to_string(partial: 'projects/index/toolbar'),
|
||||
cards_html: render_to_string(
|
||||
partial: 'projects/index/team_projects',
|
||||
locals: { cards: cards, view_mode: params[:view_mode] }
|
||||
|
|
|
@ -94,10 +94,28 @@ module SciFormHelper
|
|||
js_format
|
||||
end
|
||||
|
||||
def datetime_picker_format_date_only_vue
|
||||
js_format = I18n.backend.date_format.dup
|
||||
js_format.gsub!(/%-d/, 'd')
|
||||
js_format.gsub!(/%d/, 'dd')
|
||||
js_format.gsub!(/%-m/, 'M')
|
||||
js_format.gsub!(/%m/, 'MM')
|
||||
js_format.gsub!(/%b/, 'MMM')
|
||||
js_format.gsub!(/%B/, 'MMMM')
|
||||
js_format.gsub!('%Y', 'yyyy')
|
||||
js_format
|
||||
end
|
||||
|
||||
# Returns date and time format string for Bootstrap DateTimePicker
|
||||
def datetime_picker_format_full
|
||||
js_format = datetime_picker_format_date_only
|
||||
js_format << ' HH:mm'
|
||||
js_format
|
||||
end
|
||||
|
||||
def datetime_picker_format_full_vue
|
||||
js_format = datetime_picker_format_date_only_vue
|
||||
js_format << ' HH:mm'
|
||||
js_format
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,8 @@ require('jquery-ui/ui/effects/effect-slide');
|
|||
require('hammerjs');
|
||||
import 'bootstrap';
|
||||
require('bootstrap-select/js/bootstrap-select');
|
||||
import '@vuepic/vue-datepicker/dist/main.css';
|
||||
import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css'
|
||||
|
||||
window.bwipjs = require('bwip-js');
|
||||
window.Decimal = require('decimal.js');
|
||||
|
|
|
@ -1 +1 @@
|
|||
@import "bootstrap-select/sass/bootstrap-select"
|
||||
@import "bootstrap-select/sass/bootstrap-select";
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
/* global notTurbolinksPreview */
|
||||
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import ActionToolbar from '../../vue/components/action_toolbar.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
window.initActionToolbar = () => {
|
||||
if (window.actionToolbarComponent) return;
|
||||
|
||||
if (notTurbolinksPreview()) {
|
||||
new Vue({
|
||||
el: '#actionToolbar',
|
||||
components: {
|
||||
ActionToolbar
|
||||
}
|
||||
const app = createApp({});
|
||||
app.component('ActionToolbar', ActionToolbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#actionToolbar', () => {
|
||||
window.actionToolbarComponent = null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,14 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import AssignItemsToTaskModalContainer from '../../vue/assign_items_to_tasks_modal/container.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css';
|
||||
import AssignItemsToTaskModalContainer from '../../vue/assign_items_to_tasks_modal/container.vue';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
function initAssignItemsToTaskModalComponent() {
|
||||
const container = $('.assign-items-to-task-modal-container');
|
||||
if (container.length) {
|
||||
window.AssignItemsToTaskModalComponentContainer = new Vue({
|
||||
el: '.assign-items-to-task-modal-container',
|
||||
name: 'AssignItemsToTaskModalComponent',
|
||||
components: {
|
||||
'assign-items-to-task-modal-container': AssignItemsToTaskModalContainer
|
||||
},
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
visibility: false,
|
||||
|
@ -39,6 +31,10 @@ function initAssignItemsToTaskModalComponent() {
|
|||
}
|
||||
}
|
||||
});
|
||||
app.component('AssignItemsToTaskModalContainer', AssignItemsToTaskModalContainer);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
window.AssignItemsToTaskModalComponentContainer = mountWithTurbolinks(app, '.assign-items-to-task-modal-container');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// Use this to register outside-click directive on a Vue component
|
||||
// eslint-disable-next-line max-len
|
||||
// eg v-click-outside="{handler: 'handlerToTrigger', exclude: [refs to ignore on click (eg 'searchInput', 'searchInputBtn')]}"
|
||||
// eslint-enable-next-line max-len
|
||||
|
||||
export default {
|
||||
bind(el, binding, vnode) {
|
||||
el._vueClickOutside_ = (e) => {
|
||||
let clickedOnExcludedEl = false;
|
||||
const { exclude } = binding.value;
|
||||
exclude.forEach(refName => {
|
||||
if (!clickedOnExcludedEl) {
|
||||
const excludedEl = vnode.context.$refs[refName];
|
||||
if (!excludedEl) return;
|
||||
|
||||
clickedOnExcludedEl = (excludedEl._isVue ? excludedEl.$el : excludedEl).contains(e.target);
|
||||
}
|
||||
});
|
||||
|
||||
if (!el.contains(e.target) && !clickedOnExcludedEl) {
|
||||
const { handler } = binding.value;
|
||||
vnode.context[handler]();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', el._vueClickOutside_);
|
||||
document.addEventListener('touchstart', el._vueClickOutside_);
|
||||
},
|
||||
unbind(el) {
|
||||
document.removeEventListener('click', el._vueClickOutside_);
|
||||
document.removeEventListener('touchstart', el._vueClickOutside_);
|
||||
el._vueClickOutside_ = null;
|
||||
}
|
||||
};
|
|
@ -1,21 +1,15 @@
|
|||
/* global notTurbolinksPreview */
|
||||
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import ExportStockConsumptionModal from '../../vue/repository_row/export_stock_consumption_modal.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
window.initExportStockConsumptionModal = () => {
|
||||
if (window.exportStockConsumptionModalComponent) return;
|
||||
|
||||
if (notTurbolinksPreview()) {
|
||||
new Vue({
|
||||
el: '#exportStockConsumtionModal',
|
||||
components: {
|
||||
ExportStockConsumptionModal,
|
||||
},
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('ExportStockConsumptionModal', ExportStockConsumptionModal);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#exportStockConsumtionModal');
|
||||
}
|
||||
};
|
||||
|
|
15
app/javascript/packs/vue/helpers/turbolinks.js
Normal file
15
app/javascript/packs/vue/helpers/turbolinks.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
function mountWithTurbolinks(app, target, callback = null) {
|
||||
const originalHtml = document.querySelector(target).innerHTML;
|
||||
|
||||
document.addEventListener('turbolinks:before-cache', () => {
|
||||
app.unmount();
|
||||
if (document.querySelector(target)) {
|
||||
document.querySelector(target).innerHTML = originalHtml;
|
||||
}
|
||||
if (callback) callback();
|
||||
}, { once: true });
|
||||
|
||||
return app.mount(target);
|
||||
}
|
||||
|
||||
export { mountWithTurbolinks };
|
|
@ -1,17 +1,9 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import LabelTemplateContainer from '../../vue/label_template/container.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
window.initLabelTemplateComponent = () => {
|
||||
|
||||
new Vue({
|
||||
el: '#labelTemplateContainer',
|
||||
components: {
|
||||
'label-template-container': LabelTemplateContainer
|
||||
},
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
labelTemplateUrl: $('#labelTemplateContainer').data('label-template-url'),
|
||||
|
@ -21,6 +13,9 @@ window.initLabelTemplateComponent = () => {
|
|||
};
|
||||
}
|
||||
});
|
||||
app.component('LabelTemplateContainer', LabelTemplateContainer);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#labelTemplateContainer');
|
||||
};
|
||||
|
||||
initLabelTemplateComponent();
|
||||
|
|
79
app/javascript/packs/vue/legacy/datetime_picker.js
Normal file
79
app/javascript/packs/vue/legacy/datetime_picker.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import DateTimePicker from '../../../vue/shared/date_time_picker.vue';
|
||||
import { mountWithTurbolinks } from '../helpers/turbolinks.js';
|
||||
/*
|
||||
<div id="date-time-picker" class="vue-date-time-picker">
|
||||
<input ref="input" type="hidden" v-model="date" id="legacy-id" data-default="" />
|
||||
<date-time-picker ref="vueDateTime" @change="updateDate" :mode="date"></date-time-picker>
|
||||
</div>
|
||||
*/
|
||||
|
||||
window.initDateTimePickerComponent = (id) => {
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
date: null,
|
||||
onChange: null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.input.dataset.default) {
|
||||
const defaultDate = new Date(this.$refs.input.dataset.default.replace(/([^!\s])-/g, '$1/')); // Safari fix
|
||||
this.date = this.formatDate(defaultDate);
|
||||
this.$refs.vueDateTime.manualUpdate = true;
|
||||
this.$refs.vueDateTime.datetime = defaultDate;
|
||||
} else if (this.date) {
|
||||
this.$refs.vueDateTime.manualUpdate = true;
|
||||
this.$refs.vueDateTime.datetime = new Date(this.date);
|
||||
}
|
||||
|
||||
$(this.$refs.input).data('dateTimePicker', this);
|
||||
$(this.$el.parentElement).parent().trigger('dp:ready');
|
||||
},
|
||||
methods: {
|
||||
formatDate(date) {
|
||||
if (this.$refs.input.dataset.simpleFormat) {
|
||||
const y = date.getFullYear();
|
||||
const m = date.getMonth() + 1;
|
||||
const d = date.getDate();
|
||||
const hours = date.getHours();
|
||||
const mins = date.getMinutes();
|
||||
return `${y}/${m}/${d} ${hours}:${mins}`;
|
||||
}
|
||||
return date.toISOString();
|
||||
},
|
||||
updateDate(date) {
|
||||
this.date = this.formatDate(date);
|
||||
this.$nextTick(() => {
|
||||
if (this.onChange) this.onChange(date);
|
||||
});
|
||||
|
||||
},
|
||||
setDate(date) {
|
||||
this.date = this.formatDate(date);
|
||||
this.$refs.vueDateTime.manualUpdate = true;
|
||||
this.$refs.vueDateTime.datetime = date;
|
||||
this.$nextTick(() => {
|
||||
if (this.onChange) this.onChange(date);
|
||||
});
|
||||
},
|
||||
clearDate() {
|
||||
this.date = null;
|
||||
this.$refs.vueDateTime.datetime = null;
|
||||
this.$nextTick(() => {
|
||||
if (this.onChange) this.onChange(null);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
app.component('DateTimePicker', DateTimePicker);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, id);
|
||||
};
|
||||
|
||||
document.addEventListener('turbolinks:load', () => {
|
||||
const dateTimePickers = document.querySelectorAll('.vue-date-time-picker');
|
||||
dateTimePickers.forEach((dateTimePicker) => {
|
||||
window.initDateTimePickerComponent(`#${dateTimePicker.id}`);
|
||||
});
|
||||
})
|
|
@ -1,17 +1,13 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css';
|
||||
import Breadcrumbs from '../../../vue/navigation/breadcrumbs/breadcrumbs.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
import { mountWithTurbolinks } from '../helpers/turbolinks.js';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
window.breadcrumbsComponent = new Vue({
|
||||
el: '#breadcrumbs',
|
||||
name: 'BreadcrumbsContainer',
|
||||
components: {
|
||||
breadcrumbs: Breadcrumbs
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('Breadcrumbs', Breadcrumbs);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
window.breadcrumbsComponent = mountWithTurbolinks(app, '#breadcrumbs');
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css';
|
||||
import NavigatorContainer from '../../../vue/navigation/navigator.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
function addNavigationNavigatorContainer() {
|
||||
let navigator = new Vue({
|
||||
el: '#sciNavigationNavigatorContainer',
|
||||
components: {
|
||||
'navigator-container': NavigatorContainer
|
||||
},
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
reloadCurrentLevel: false,
|
||||
|
@ -53,8 +44,10 @@ function addNavigationNavigatorContainer() {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.navigatorContainer = navigator
|
||||
app.component('NavigatorContainer', NavigatorContainer);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
window.navigatorContainer = app.mount('#sciNavigationNavigatorContainer');
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css';
|
||||
import TopMenuContainer from '../../../vue/navigation/top_menu.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
import outsideClick from '../directives/outside_click';
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.directive('click-outside', outsideClick);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
function addNavigationTopMenuContainer() {
|
||||
new Vue({
|
||||
el: '#sciNavigationTopMenuContainer',
|
||||
components: {
|
||||
'top-menu-container': TopMenuContainer
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('TopMenuContainer', TopMenuContainer);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.mount('#sciNavigationTopMenuContainer');
|
||||
}
|
||||
|
||||
if (document.readyState !== 'loading') {
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import OpenVectorEditor from '../../vue/ove/OpenVectorEditor.vue';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
new Vue({
|
||||
el: '#open-vector-editor',
|
||||
components: { OpenVectorEditor }
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('OpenVectorEditor', OpenVectorEditor);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#open-vector-editor');
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
/* global HelperModule */
|
||||
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import ProtocolContainer from '../../vue/protocol/container.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import outsideClick from './directives/outside_click';
|
||||
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.directive('click-outside', outsideClick);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
Vue.prototype.inlineEditing = window.inlineEditing;
|
||||
Vue.prototype.ActiveStoragePreviews = window.ActiveStoragePreviews;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
window.initProtocolComponent = () => {
|
||||
Vue.prototype.dateFormat = $('#protocolContainer').data('date-format');
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
protocolUrl: $('#protocolContainer').data('protocol-url'),
|
||||
};
|
||||
},
|
||||
});
|
||||
app.component('ProtocolContainer', ProtocolContainer);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.config.globalProperties.inlineEditing = window.inlineEditing;
|
||||
app.config.globalProperties.ActiveStoragePreviews = window.ActiveStoragePreviews;
|
||||
app.config.globalProperties.dateFormat = $('#protocolContainer').data('date-format');
|
||||
mountWithTurbolinks(app, '#protocolContainer');
|
||||
|
||||
$('.protocols-show').on('click', '#protocol-versions-modal .delete-draft', (e) => {
|
||||
const url = e.currentTarget.dataset.url;
|
||||
|
@ -28,18 +32,6 @@ window.initProtocolComponent = () => {
|
|||
$('#deleteDraftModal form').on('ajax:error', function(_ev, data) {
|
||||
HelperModule.flashAlertMsg(data.responseJSON.message, 'danger');
|
||||
});
|
||||
|
||||
new Vue({
|
||||
el: '#protocolContainer',
|
||||
components: {
|
||||
'protocol-container': ProtocolContainer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
protocolUrl: $('#protocolContainer').data('protocol-url')
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
initProtocolComponent();
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import ProtocolFileImportModal from '../../vue/protocol_import/file_import_modal.vue';
|
||||
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
window.initProtocolFileImportModalComponent = () => {
|
||||
new Vue({
|
||||
el: '#protocolFileImportModal',
|
||||
components: {
|
||||
'protocol-file-import-modal': ProtocolFileImportModal
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('ProtocolFileImportModal', ProtocolFileImportModal);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#protocolFileImportModal');
|
||||
};
|
||||
|
||||
initProtocolFileImportModalComponent();
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
/* global I18n */
|
||||
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import FilterContainer from '../../vue/repository_filter/container.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
const DEFAULT_FILTERS = [
|
||||
{
|
||||
|
@ -62,7 +59,6 @@ const DEFAULT_FILTERS = [
|
|||
|
||||
window.repositoryFilterObject = null;
|
||||
window.initRepositoryFilter = () => {
|
||||
Vue.prototype.dateFormat = $('#filterContainer').data('date-format')
|
||||
const defaultColumns = [
|
||||
{ id: 'assigned', name: I18n.t('repositories.table.assigned_tasks'), data_type: 'RepositoryMyModuleValue' },
|
||||
{ id: 'row_id', name: I18n.t('repositories.table.id'), data_type: 'RepositoryTextValue' },
|
||||
|
@ -73,8 +69,7 @@ window.initRepositoryFilter = () => {
|
|||
{ id: 'archived_on', name: I18n.t('repositories.table.archived_on'), data_type: 'RepositoryDateTimeValue' }
|
||||
];
|
||||
const defFilters = JSON.parse(JSON.stringify(DEFAULT_FILTERS));
|
||||
const repositoryFilterContainer = new Vue({
|
||||
el: '#filterContainer',
|
||||
const app = createApp({
|
||||
data: () => ({
|
||||
filters: [],
|
||||
defaultFilters: DEFAULT_FILTERS,
|
||||
|
@ -86,10 +81,19 @@ window.initRepositoryFilter = () => {
|
|||
}),
|
||||
created() {
|
||||
this.dataTableElement = $($('#filterContainer').data('datatable-id'));
|
||||
},
|
||||
|
||||
components: {
|
||||
'filter-container': FilterContainer
|
||||
$.get($('#filterContainer').data('my-modules-url'), (data) => {
|
||||
this.my_modules = data.data;
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('columns-url'), (data) => {
|
||||
const combinedColumns = data.response.concat(defaultColumns);
|
||||
this.columns = combinedColumns.sort((a, b) => a.name > b.name ? 1 : -1);
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('saved-filters-url'), (data) => {
|
||||
this.savedFilters = data.data;
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
filtersJSON() {
|
||||
|
@ -144,19 +148,10 @@ window.initRepositoryFilter = () => {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('my-modules-url'), (data) => {
|
||||
repositoryFilterContainer.my_modules = data.data;
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('columns-url'), (data) => {
|
||||
const combinedColumns = data.response.concat(defaultColumns);
|
||||
repositoryFilterContainer.columns = combinedColumns.sort((a, b) => a.name > b.name ? 1 : -1);
|
||||
});
|
||||
|
||||
$.get($('#filterContainer').data('saved-filters-url'), (data) => {
|
||||
repositoryFilterContainer.savedFilters = data.data;
|
||||
});
|
||||
app.component('FilterContainer', FilterContainer);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.config.globalProperties.dateFormat = $('#filterContainer').data('date-format');
|
||||
window.repositoryFilterObject = mountWithTurbolinks(app, '#filterContainer');
|
||||
|
||||
$('#filterContainer').on('click', (e) => {
|
||||
$('#filterContainer .dropdown-selector-container').removeClass('open')
|
||||
|
@ -166,6 +161,4 @@ window.initRepositoryFilter = () => {
|
|||
$('#filtersDropdownButton').on('show.bs.dropdown', () => {
|
||||
$('#filtersColumnsDropdown, #savedFiltersContainer').removeClass('open');
|
||||
});
|
||||
|
||||
window.repositoryFilterObject = repositoryFilterContainer;
|
||||
};
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/* global notTurbolinksPreview */
|
||||
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import RepositoryItemSidebar from '../../vue/repository_item_sidebar/RepositoryItemSidebar.vue';
|
||||
import outsideClick from './directives/outside_click';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.directive('click-outside', outsideClick);
|
||||
|
@ -13,12 +15,10 @@ Vue.use(PerfectScrollbar);
|
|||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
function initRepositoryItemSidebar() {
|
||||
new Vue({
|
||||
el: '#repositoryItemSidebar',
|
||||
components: {
|
||||
RepositoryItemSidebar
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('RepositoryItemSidebar', RepositoryItemSidebar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#repositoryItemSidebar');
|
||||
}
|
||||
|
||||
initRepositoryItemSidebar();
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import PrintModalContainer from '../../vue/repository_print_modal/container.vue';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
function initPrintModalComponent() {
|
||||
const container = $('.print-label-modal-container');
|
||||
if (container.length) {
|
||||
window.PrintModalComponent = new Vue({
|
||||
el: '.print-label-modal-container',
|
||||
name: 'PrintModalComponent',
|
||||
components: {
|
||||
'print-modal-container': PrintModalContainer
|
||||
},
|
||||
const app = createApp({
|
||||
data() {
|
||||
return {
|
||||
showModal: false,
|
||||
|
@ -36,6 +28,9 @@ function initPrintModalComponent() {
|
|||
}
|
||||
}
|
||||
});
|
||||
app.component('PrintModalContainer', PrintModalContainer);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '.print-label-modal-container');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import RepositorySearchContainer from '../../vue/repository_search/container.vue';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
window.initRepositorySearch = () => {
|
||||
window.RepositorySearchComponent = new Vue({
|
||||
el: '#inventorySearchComponent',
|
||||
name: 'RepositorySearchComponent',
|
||||
components: {
|
||||
'repository_search_container': RepositorySearchContainer
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('RepositorySearchContainer', RepositorySearchContainer);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
mountWithTurbolinks(app, '#inventorySearchComponent');
|
||||
}
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import Results from '../../vue/results/results.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import outsideClick from './directives/outside_click';
|
||||
import { mountWithTurbolinks } from './helpers/turbolinks.js';
|
||||
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.directive('click-outside', outsideClick);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
Vue.prototype.ActiveStoragePreviews = window.ActiveStoragePreviews;
|
||||
|
||||
new Vue({
|
||||
el: '#results',
|
||||
components: {
|
||||
Results
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('Results', Results);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.config.globalProperties.ActiveStoragePreviews = window.ActiveStoragePreviews;
|
||||
mountWithTurbolinks(app, '#results');
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
import Vue from 'vue/dist/vue.esm';
|
||||
import PerfectScrollbar from 'vue3-perfect-scrollbar';
|
||||
import { createApp } from 'vue/dist/vue.esm-bundler.js';
|
||||
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css';
|
||||
import ShareLinkContainer from '../../vue/shareable_links/container.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css';
|
||||
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
|
||||
function initShareTaskContainer() {
|
||||
new Vue({
|
||||
el: '.share-task-container',
|
||||
components: {
|
||||
'share-task-container': ShareLinkContainer
|
||||
}
|
||||
});
|
||||
const app = createApp({});
|
||||
app.component('ShareLinkContainer', ShareLinkContainer);
|
||||
app.use(PerfectScrollbar);
|
||||
app.config.globalProperties.i18n = window.I18n;
|
||||
app.mount('.share-task-container');
|
||||
}
|
||||
|
||||
initShareTaskContainer();
|
||||
|
|
|
@ -184,7 +184,7 @@ export default {
|
|||
this.$emit("close");
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
delete window.AssignItemsToTaskModalComponent;
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
this.$nextTick(this.setWidth);
|
||||
window.addEventListener('scroll', this.setLeftOffset);
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
delete window.actionToolbarComponent;
|
||||
window.removeEventListener('scroll', this.setLeftOffset);
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ export default {
|
|||
mounted() {
|
||||
this.observeChanges();
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ export default {
|
|||
this.handleTinyMCEOpened(e.detail.target);
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (this.resizeObserver) {
|
||||
this.resizeObserver.disconnect();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { PerfectScrollbar } from 'vue2-perfect-scrollbar';
|
||||
import { PerfectScrollbar } from 'vue3-perfect-scrollbar';
|
||||
|
||||
export default {
|
||||
name: "BreadcrumbsDropdown",
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<template>
|
||||
<vue-resizable
|
||||
<Vue3DraggableResizable
|
||||
:initW="getNavigatorWidth()"
|
||||
ref="vueResizable"
|
||||
:max-width="400"
|
||||
:min-width="208"
|
||||
width="auto"
|
||||
height="100%"
|
||||
class="!h-full"
|
||||
:active="['r']"
|
||||
@resize:start="onResizeStart"
|
||||
@resize:move="onResizeMove"
|
||||
@resize:end="onResizeEnd"
|
||||
:minW="208"
|
||||
:disabledH="true"
|
||||
:handles="['mr']"
|
||||
:resizable="true"
|
||||
:draggable="false"
|
||||
class="max-w-[400px] !h-full"
|
||||
@resize-start="onResizeStart"
|
||||
@resizing="onResizeMove"
|
||||
@resize-end="onResizeEnd"
|
||||
>
|
||||
<div class="ml-4 h-full border rounded relative bg-sn-white flex flex-col right-0 absolute navigator-container">
|
||||
<div class="ml-4 h-full w-full border rounded bg-sn-white flex flex-col right-0 absolute navigator-container">
|
||||
<div class="px-3 py-2.5 flex items-center relative leading-4">
|
||||
<i class="sn-icon sn-icon-navigator"></i>
|
||||
<div class="font-bold text-base pl-3">
|
||||
|
@ -31,20 +32,20 @@
|
|||
:archived="archived" />
|
||||
</perfect-scrollbar>
|
||||
</div>
|
||||
</vue-resizable>
|
||||
</Vue3DraggableResizable>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import NavigatorItem from './navigator_item.vue'
|
||||
import VueResizable from 'vue-resizable'
|
||||
import axios from '../../packs/custom_axios.js';
|
||||
import Vue3DraggableResizable from 'vue3-draggable-resizable'
|
||||
|
||||
export default {
|
||||
name : 'NavigatorContainer',
|
||||
components: {
|
||||
NavigatorItem,
|
||||
VueResizable
|
||||
Vue3DraggableResizable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -54,7 +55,7 @@ export default {
|
|||
navigatorYScroll: 0,
|
||||
navigatorXScroll: 0,
|
||||
currentItemId: null,
|
||||
archived: null
|
||||
archived: null,
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
@ -128,10 +129,11 @@ export default {
|
|||
},
|
||||
getNavigatorWidth() {
|
||||
const computedStyle = getComputedStyle(document.documentElement);
|
||||
return computedStyle.getPropertyValue('--navigator-navigation-width').trim();
|
||||
return parseInt(computedStyle.getPropertyValue('--navigator-navigation-width').trim());
|
||||
},
|
||||
onResizeMove(event) {
|
||||
document.documentElement.style.setProperty('--navigator-navigation-width', event.width + 'px');
|
||||
if (event.w > 400) event.w = 400;
|
||||
document.documentElement.style.setProperty('--navigator-navigation-width', event.w + 'px');
|
||||
},
|
||||
onResizeStart() {
|
||||
document.body.style.cursor = 'url(/images/icon_small/Resize.svg) 0 0, auto';
|
||||
|
@ -139,10 +141,11 @@ export default {
|
|||
$('.sci--layout').addClass('!transition-none');
|
||||
},
|
||||
onResizeEnd(event) {
|
||||
if (event.w > 400) event.w = 400;
|
||||
document.body.style.cursor = 'default';
|
||||
$('.sci--layout-navigation-navigator').removeClass('!transition-none');
|
||||
$('.sci--layout').removeClass('!transition-none');
|
||||
this.changeNavigatorState(event.width)
|
||||
this.changeNavigatorState(event.w)
|
||||
},
|
||||
async changeNavigatorState(newWidth) {
|
||||
try {
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
// Track name update in user profile settings
|
||||
$(document).on('inlineEditing::updated', '.inline-editing-container[data-field-to-update="full_name"]', this.fetchData);
|
||||
},
|
||||
beforeDestroy: function(){
|
||||
beforeUnmount: function(){
|
||||
clearTimeout(this.unseenNotificationsTimeout);
|
||||
},
|
||||
computed: {
|
||||
|
|
|
@ -286,7 +286,7 @@
|
|||
})
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
if (!this.inRepository) {
|
||||
window.removeEventListener('scroll', this.initStackableHeaders, false);
|
||||
}
|
||||
|
|
|
@ -429,6 +429,9 @@
|
|||
},
|
||||
updateElement(element, skipRequest=false, callback) {
|
||||
let index = this.elements.findIndex((e) => e.id === element.id);
|
||||
|
||||
if (!this.elements[index]) return;
|
||||
|
||||
this.elements[index].isNew = false;
|
||||
|
||||
if (skipRequest) {
|
||||
|
|
|
@ -88,8 +88,6 @@
|
|||
$.get(`/jobs/${this.jobId}/status`, (data) => {
|
||||
let status = data.status;
|
||||
|
||||
console.log(data)
|
||||
|
||||
switch (status) {
|
||||
case 'pending':
|
||||
break;
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
@dropdown:changed="updateOperator" />
|
||||
</div>
|
||||
<div class="filter-datepicker-input">
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :onlyDate="true" :defaultValue="date || fallbackDate()" />
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :mode="'date'" :defaultValue="date || fallbackDate()" />
|
||||
</div>
|
||||
<span class="between-delimiter">—</span>
|
||||
<div class="filter-datepicker-to-input">
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`DatePickerTo${filter.id}`" :onlyDate="true" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`DatePickerTo${filter.id}`" :mode="'date'" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -22,7 +22,7 @@
|
|||
import FilterMixin from '../mixins/filter.js'
|
||||
import RangeDateTimeFilterMixin from '../mixins/filters/range_date_time_filter.js'
|
||||
import DropdownSelector from '../../shared/dropdown_selector.vue'
|
||||
import DateTimePicker from '../../shared/date_picker.vue'
|
||||
import DateTimePicker from '../../shared/date_time_picker.vue'
|
||||
|
||||
export default {
|
||||
name: 'RepositoryDateRangeValue',
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<template v-if="!isPreset">
|
||||
<div class="datetime-filter-attributes">
|
||||
<div class="filter-datepicker-input">
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :defaultValue="null" />
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :defaultValue="date" />
|
||||
</div>
|
||||
<div class="between-delimiter vertical" v-if="operator == 'between'"></div>
|
||||
<div class="filter-datepicker-to-input">
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
</div>
|
||||
<template v-if="!isPreset">
|
||||
<div class="filter-datepicker-input">
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :onlyDate="true" :defaultValue="date || fallbackDate()" />
|
||||
<DateTimePicker @change="updateDate" :selectorId="`DatePicker${filter.id}`" :mode="'date'" :defaultValue="date || fallbackDate()" />
|
||||
</div>
|
||||
<span class="between-delimiter" v-if="operator == 'between'">—</span>
|
||||
<div class="filter-datepicker-to-input" v-if="operator == 'between'">
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`DatePickerTo${filter.id}`" :onlyDate="true" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`DatePickerTo${filter.id}`" :mode="'date'" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -24,7 +24,7 @@
|
|||
import FilterMixin from '../mixins/filter.js'
|
||||
import DateTimeFilterMixin from '../mixins/filters/date_time_filter.js'
|
||||
import DropdownSelector from '../../shared/dropdown_selector.vue'
|
||||
import DateTimePicker from '../../shared/date_picker.vue'
|
||||
import DateTimePicker from '../../shared/date_time_picker.vue'
|
||||
|
||||
export default {
|
||||
name: 'RepositoryDateValue',
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
@dropdown:changed="updateOperator" />
|
||||
</div>
|
||||
<div class="filter-datepicker-input">
|
||||
<DateTimePicker @change="updateDate" :selectorId="`TimePicker${filter.id}`" :timeOnly="true" :defaultValue="date || fallbackDate()" />
|
||||
<DateTimePicker @change="updateDate" :selectorId="`TimePicker${filter.id}`" :mode="'time'" :defaultValue="date || fallbackDate()" />
|
||||
</div>
|
||||
<span class="between-delimiter">—</span>
|
||||
<div class="filter-datepicker-to-input">
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`TimePickerTo${filter.id}`" :timeOnly="true" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`TimePickerTo${filter.id}`" :mode="'time'" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
</div>
|
||||
<template v-if="!isPreset">
|
||||
<div class="filter-datepicker-input">
|
||||
<DateTimePicker @change="updateDate" :selectorId="`TimePicker${filter.id}`" :timeOnly="true" :defaultValue="date || fallbackDate()" />
|
||||
<DateTimePicker @change="updateDate" :selectorId="`TimePicker${filter.id}`" :mode="'time'" :defaultValue="date || fallbackDate()" />
|
||||
</div>
|
||||
<span class="between-delimiter" v-if="operator == 'between'">—</span>
|
||||
<div class="filter-datepicker-to-input" v-if="operator == 'between'">
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`TimePickerTo${filter.id}`" :timeOnly="true" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
<DateTimePicker @change="updateDateTo" :selectorId="`TimePickerTo${filter.id}`" :mode="'time'" :defaultValue="dateTo || fallbackDate(7 * 24 * 60 * 60)" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -263,7 +263,7 @@ export default {
|
|||
document.addEventListener('mousedown', this.handleOutsideClick);
|
||||
this.inRepository = $('.assign-items-to-task-modal-container').length > 0;
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
delete window.repositoryItemSidebarComponent;
|
||||
document.removeEventListener('mousedown', this.handleOutsideClick);
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div ref="modal"
|
||||
class="modal fade"
|
||||
class="modal fade"
|
||||
id="exportStockConsumptionModal"
|
||||
tabindex="-1"
|
||||
role="dialog"
|
||||
|
@ -22,7 +22,7 @@
|
|||
<button type='button' class='btn btn-secondary' data-dismiss='modal' id='close-modal-export-stock-consumption'>
|
||||
{{ i18n.t('general.cancel') }}
|
||||
</button>
|
||||
|
||||
|
||||
<button class="btn btn-success" id="export-stock-consumption" @click="exportConsumption">
|
||||
{{ i18n.t('zip_export.consumption_generate') }}
|
||||
</button>
|
||||
|
@ -47,7 +47,7 @@
|
|||
created() {
|
||||
window.exportStockConsumptionModalComponent = this;
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
delete window.exportStockConsumptionModalComponent;
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
class="flex items-center mr-3 flex-nowrap relative"
|
||||
v-click-outside="{handler: 'closeSearchInputs', exclude: ['searchInput', 'searchInputBtn', 'barcodeSearchInput', 'barcodeSearchInputBtn']}"
|
||||
<div
|
||||
class="flex items-center mr-3 flex-nowrap relative"
|
||||
v-click-outside="closeSearchInputs"
|
||||
>
|
||||
<button :class="{hidden: searchOpened}" ref='searchInputBtn' class="btn btn-light btn-black icon-btn" :title="i18n.t('repositories.show.search_button_tooltip')" @click="openSearch">
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
|
@ -35,7 +35,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import outsideClick from '../../packs/vue/directives/outside_click';
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
|
||||
export default {
|
||||
name: 'RepositorySearchContainer',
|
||||
directives: {
|
||||
|
@ -49,6 +50,9 @@ export default {
|
|||
value: ''
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
'click-outside': vOnClickOutside
|
||||
},
|
||||
watch: {
|
||||
barcodeValue() {
|
||||
this.updateRepositoySearch();
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
this.loadResults();
|
||||
this.initStackableHeaders();
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('scroll', this.loadResults, false);
|
||||
window.removeEventListener('scroll', this.initStackableHeaders, false);
|
||||
},
|
||||
|
|
|
@ -38,26 +38,27 @@
|
|||
:chosenClass="'checklist-item-chosen'"
|
||||
:forceFallback="true"
|
||||
:handle="'.element-grip'"
|
||||
item-key="id"
|
||||
:disabled="editingItem || checklistItems.length < 2 || !element.attributes.orderable.urls.reorder_url"
|
||||
@start="startReorder"
|
||||
@end="endReorder"
|
||||
>
|
||||
<ChecklistItem
|
||||
v-for="checklistItem in orderedChecklistItems"
|
||||
:key="checklistItem.id"
|
||||
:checklistItem="checklistItem"
|
||||
:locked="locked"
|
||||
:reordering="reordering"
|
||||
:reorderChecklistItemUrl="element.attributes.orderable.urls.reorder_url"
|
||||
:inRepository="inRepository"
|
||||
:draggable="checklistItems.length > 1"
|
||||
@editStart="editingItem = true"
|
||||
@editEnd="editingItem = false"
|
||||
@update="saveItem"
|
||||
@toggle="saveItemChecked"
|
||||
@removeItem="removeItem"
|
||||
@component:delete="removeItem"
|
||||
/>
|
||||
<template #item="{element}">
|
||||
<ChecklistItem
|
||||
:checklistItem="element"
|
||||
:locked="locked"
|
||||
:reordering="reordering"
|
||||
:reorderChecklistItemUrl="this.element.attributes.orderable.urls.reorder_url"
|
||||
:inRepository="inRepository"
|
||||
:draggable="checklistItems.length > 1"
|
||||
@editStart="editingItem = true"
|
||||
@editEnd="editingItem = false"
|
||||
@update="saveItem"
|
||||
@toggle="saveItemChecked"
|
||||
@removeItem="removeItem"
|
||||
@component:delete="removeItem"
|
||||
/>
|
||||
</template>
|
||||
</Draggable>
|
||||
<div v-if="element.attributes.orderable.urls.create_item_url && !addingNewItem"
|
||||
class="flex items-center gap-1 text-sn-blue cursor-pointer mb-2 mt-1 "
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="content__checklist-item">
|
||||
<div class="checklist-item-header flex rounded pl-10 ml-[-2.325rem] items-center relative w-full group/checklist-item-header" :class="{ 'locked': locked || editingText, 'editing-name': editingText }">
|
||||
<div class="content__checklist-item pl-10 ml-[-2.325rem]">
|
||||
<div class="checklist-item-header flex rounded items-center relative w-full group/checklist-item-header" :class="{ 'locked': locked || editingText, 'editing-name': editingText }">
|
||||
<div v-if="reorderChecklistItemUrl"
|
||||
class="absolute h-6 cursor-grab justify-center left-0 top-0.5 px-2 tw-hidden text-sn-grey element-grip step-element-grip--draggable"
|
||||
class="absolute h-6 cursor-grab justify-center left-[-2.325rem] top-0.5 px-2 tw-hidden text-sn-grey element-grip step-element-grip--draggable"
|
||||
:class="{ 'group-hover/checklist-item-header:flex': (!locked && !editingText && draggable) }"
|
||||
>
|
||||
<i class="sn-icon sn-icon-drag"></i>
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
created() {
|
||||
window.addEventListener('beforeunload', this.showSaveWarning);
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('beforeunload', this.showSaveWarning);
|
||||
},
|
||||
updated() {
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
<template>
|
||||
<div v-if="!standAlone" class="datepicker sci-input-container right-icon">
|
||||
<input
|
||||
@change="update"
|
||||
type="datetime"
|
||||
class="form-control calendar-input sci-input-field"
|
||||
:id="this.selectorId"
|
||||
:placeholder="placeholder || 'dd/mm/yyyy'"
|
||||
/>
|
||||
<i class="sn-icon sn-icon-calendar"></i>
|
||||
</div>
|
||||
<div :class="className" v-else>
|
||||
<input
|
||||
@input="update"
|
||||
type="datetime"
|
||||
class='inline-block m-0 p-0 w-full border-none shadow-none outline-none'
|
||||
:id="this.selectorId"
|
||||
:placeholder="placeholder || 'dd/mm/yyyy'"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '../../../../vendor/assets/javascripts/bootstrap-datetimepicker';
|
||||
|
||||
export default {
|
||||
name: 'DatePicker',
|
||||
props: {
|
||||
placeholder: { type: String },
|
||||
selectorId: { type: String, required: true },
|
||||
useCurrent: { type: Boolean, default: true },
|
||||
defaultValue: { type: Date, default: null },
|
||||
standAlone: { type: Boolean, default: false, required: false },
|
||||
className: { type: String, default: '' },
|
||||
disabled: { type: Boolean, default: false }
|
||||
},
|
||||
mounted() {
|
||||
$("#" + this.selectorId).datetimepicker(
|
||||
{
|
||||
useCurrent: this.useCurrent,
|
||||
ignoreReadonly: this.ignoreReadOnly,
|
||||
locale: this.i18n.locale,
|
||||
format: $('body').data('datetime-picker-format'),
|
||||
date: this.defaultValue
|
||||
}
|
||||
);
|
||||
$("#" + this.selectorId).on('dp.change', (e) => this.update(e.date))
|
||||
if (this.isValidDate(this.defaultValue)) this.update(moment(this.defaultValue));
|
||||
},
|
||||
methods: {
|
||||
update(value) {
|
||||
this.$emit('change', (value?._isAMomentObject) ? value.toDate() : '');
|
||||
},
|
||||
isValidDate(date) {
|
||||
return (date instanceof Date) && !isNaN(date.getTime());
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,36 +1,60 @@
|
|||
<template>
|
||||
<div class="date-time-picker" :class="{ 'grow': !standAlone, 'flex': standAlone}">
|
||||
<DatePicker v-if="!timeOnly"
|
||||
@change="updateDate"
|
||||
:placeholder="placeholder"
|
||||
:selectorId="`${this.selectorId}_Date`"
|
||||
:defaultValue="defaultValue"
|
||||
:standAlone="standAlone"
|
||||
:className="dateClassName"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<TimePicker v-if="!dateOnly"
|
||||
@change="updateTime"
|
||||
:placeholder="placeholder"
|
||||
:selectorId="`${this.selectorId}_Time`"
|
||||
:defaultValue="getTime(defaultValue)"
|
||||
:standAlone="standAlone"
|
||||
:className="timeClassName"
|
||||
:disabled="disabled"
|
||||
/>
|
||||
<div class="date-time-picker grow">
|
||||
<VueDatePicker
|
||||
:class="{
|
||||
'only-time': mode == 'time',
|
||||
}"
|
||||
v-model="compDatetime"
|
||||
:teleport="teleport"
|
||||
:text-input="true"
|
||||
:no-today="true"
|
||||
:clearable="clearable"
|
||||
:format="format"
|
||||
:month-change-on-scroll="false"
|
||||
:six-weeks="true"
|
||||
:auto-apply="true"
|
||||
:partial-flow="true"
|
||||
:markers="markers"
|
||||
:enable-time-picker="mode == 'datetime'"
|
||||
:time-picker="mode == 'time'"
|
||||
:placeholder="placeholder" >
|
||||
<template #arrow-right>
|
||||
<img class="slot-icon" src="/images/calendar/navigate_next.svg"/>
|
||||
</template>
|
||||
<template #arrow-left>
|
||||
<img class="slot-icon" src="/images/calendar/navigate_before.svg"/>
|
||||
</template>
|
||||
<template v-if="mode == 'time'" #input-icon>
|
||||
<img class="input-slot-image" src="/images/calendar/clock.svg"/>
|
||||
</template>
|
||||
<template v-else #input-icon>
|
||||
<img class="input-slot-image" src="/images/calendar/calendar.svg"/>
|
||||
</template>
|
||||
<template #clock-icon>
|
||||
<img class="slot-icon" src="/images/calendar/clock.svg"/>
|
||||
</template>
|
||||
<template #calendar-icon>
|
||||
<img class="slot-icon" src="/images/calendar/calendar.svg"/>
|
||||
</template>
|
||||
<template #arrow-up>
|
||||
<img class="slot-icon" src="/images/calendar/up.svg"/>
|
||||
</template>
|
||||
<template #arrow-down>
|
||||
<img class="slot-icon" src="/images/calendar/down.svg"/>
|
||||
</template>
|
||||
</VueDatePicker>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TimePicker from './time_picker.vue'
|
||||
import DatePicker from './date_picker.vue'
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
|
||||
export default {
|
||||
name: 'DateTimePicker',
|
||||
props: {
|
||||
dateOnly: { type: Boolean, default: false },
|
||||
timeOnly: { type: Boolean, default: false },
|
||||
selectorId: { type: String, required: true },
|
||||
mode: { type: String, default: 'datetime' },
|
||||
clearable: { type: Boolean, default: false },
|
||||
teleport: { type: Boolean, default: true },
|
||||
defaultValue: { type: Date, required: false },
|
||||
placeholder: { type: String },
|
||||
standAlone: { type: Boolean, default: false, required: false },
|
||||
|
@ -40,53 +64,105 @@
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
date: '',
|
||||
time: '',
|
||||
datetime: ''
|
||||
manualUpdate: false,
|
||||
datetime: this.defaultValue,
|
||||
time: null,
|
||||
markers: [
|
||||
{
|
||||
date: new Date(),
|
||||
type: 'dot',
|
||||
color: '#3B99FD',
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.defaultValue) {
|
||||
this.time = {
|
||||
hours: this.defaultValue.getHours(),
|
||||
minutes:this.defaultValue.getMinutes(),
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
TimePicker,
|
||||
DatePicker
|
||||
VueDatePicker
|
||||
},
|
||||
methods: {
|
||||
updateDate(value) {
|
||||
this.date = value;
|
||||
this.updateDateTime();
|
||||
},
|
||||
getTime(dateTime) {
|
||||
if(!this.isValidDate(dateTime)) return
|
||||
return `${dateTime.getHours().toString().padStart(2, '0')}:${dateTime.getMinutes().toString().padStart(2, '0')}`
|
||||
},
|
||||
updateTime(value) {
|
||||
this.time = value;
|
||||
this.updateDateTime();
|
||||
},
|
||||
updateDateTime() {
|
||||
this.recalcTimestamp();
|
||||
this.$emit('change', this.datetime);
|
||||
},
|
||||
|
||||
isValidTime() {
|
||||
return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(this.time);
|
||||
},
|
||||
isValidDate(date) {
|
||||
return (date instanceof Date) && !isNaN(date.getTime());
|
||||
},
|
||||
recalcTimestamp() {
|
||||
let date = this.timeOnly ? new Date() : this.date;
|
||||
if (this.isValidDate(date) && (this.dateOnly || this.isValidTime())) {
|
||||
if (this.dateOnly) {
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
} else {
|
||||
date.setHours(this.time.split(':')[0]);
|
||||
date.setMinutes(this.time.split(':')[1]);
|
||||
}
|
||||
this.datetime = date
|
||||
} else {
|
||||
this.datetime = null;
|
||||
watch: {
|
||||
defaultValue: function () {
|
||||
this.datetime = this.defaultValue;
|
||||
this.time = {
|
||||
hours: this.defaultValue ? this.defaultValue.getHours() : 0,
|
||||
minutes: this.defaultValue ? this.defaultValue.getMinutes() : 0
|
||||
}
|
||||
},
|
||||
datetime: function () {
|
||||
if (this.mode == 'time') {
|
||||
|
||||
this.time = {
|
||||
hours: this.datetime ? this.datetime.getHours() : 0,
|
||||
minutes: this.datetime ? this.datetime.getMinutes() : 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (this.manualUpdate) {
|
||||
this.manualUpdate = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.datetime == null) {
|
||||
this.$emit('cleared');
|
||||
}
|
||||
|
||||
if (this.defaultValue != this.datetime) {
|
||||
this.$emit('change', this.datetime);
|
||||
}
|
||||
},
|
||||
time: function () {
|
||||
if (this.manualUpdate) {
|
||||
this.manualUpdate = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.mode != 'time') return;
|
||||
|
||||
let newDate;
|
||||
|
||||
if (this.time) {
|
||||
newDate = new Date();
|
||||
newDate.setHours(this.time.hours);
|
||||
newDate.setMinutes(this.time.minutes);
|
||||
} else {
|
||||
newDate = null;
|
||||
this.$emit('cleared');
|
||||
}
|
||||
|
||||
if (this.defaultValue != newDate) {
|
||||
this.$emit('change', newDate);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compDatetime: {
|
||||
get () {
|
||||
if (this.mode == 'time') {
|
||||
return this.time
|
||||
} else {
|
||||
return this.datetime
|
||||
}
|
||||
},
|
||||
set (val) {
|
||||
if (this.mode == 'time') {
|
||||
this.time = val
|
||||
} else {
|
||||
this.datetime = val
|
||||
}
|
||||
}
|
||||
},
|
||||
format() {
|
||||
if (this.mode == 'time') return 'HH:mm'
|
||||
if (this.mode == 'date') return document.body.dataset.datetimePickerFormatVue
|
||||
return `${document.body.dataset.datetimePickerFormatVue} HH:mm`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@
|
|||
methods: {
|
||||
updateFilter(params) {
|
||||
if (params.value !== '' && params.value !== undefined && params.value !== null) {
|
||||
this.$set(this.filterValues, params.key, params.value);
|
||||
this.filterValues[params.key] = params.value;
|
||||
} else {
|
||||
this.$delete(this.filterValues, params.key);
|
||||
delete this.filterValues[params.key];
|
||||
}
|
||||
},
|
||||
applyFilters() {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
'!mb-0': !openUp,
|
||||
}"
|
||||
v-if="showMenu"
|
||||
v-click-outside="{handler: 'closeMenu', exclude: ['openBtn', 'flyout']}">
|
||||
v-click-outside="closeMenu">
|
||||
<span v-for="(item, i) in listItems" :key="i" class="contents">
|
||||
<div v-if="item.dividerBefore" class="border-0 border-t border-solid border-sn-light-grey"></div>
|
||||
<a :href="item.url" v-if="!item.submenu"
|
||||
|
@ -64,6 +64,7 @@
|
|||
<script>
|
||||
|
||||
import isInViewPort from './isInViewPort.js';
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
|
||||
export default {
|
||||
name: 'DropdownMenu',
|
||||
|
@ -81,6 +82,9 @@ export default {
|
|||
openUp: false
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
'click-outside': vOnClickOutside
|
||||
},
|
||||
watch: {
|
||||
showMenu() {
|
||||
if (this.showMenu) {
|
||||
|
|
|
@ -15,18 +15,21 @@
|
|||
:dragClass="'step-checklist-item-drag'"
|
||||
:chosenClass="'step-checklist-item-chosen'"
|
||||
:handle="'.step-element-grip'"
|
||||
item-key="id"
|
||||
>
|
||||
<div v-for="(item, index) in reorderedItems" :key="item.id" class="step-element-header flex items-center">
|
||||
<div class="step-element-grip step-element-grip--draggable">
|
||||
<i class="sn-icon sn-icon-drag"></i>
|
||||
<template #item="{element, index}">
|
||||
<div class="step-element-header flex items-center">
|
||||
<div class="step-element-grip step-element-grip--draggable">
|
||||
<i class="sn-icon sn-icon-drag"></i>
|
||||
</div>
|
||||
<div class="step-element-name text-center">
|
||||
<strong v-if="includeNumbers" class="step-element-number">{{ index + 1 }}</strong>
|
||||
<i v-if="element.attributes.icon" class="fas" :class="element.attributes.icon"></i>
|
||||
<span :title="nameWithFallbacks(element)" v-if="nameWithFallbacks(element)">{{ nameWithFallbacks(element) }}</span>
|
||||
<span :title="element.attributes.placeholder" v-else class="step-element-name-placeholder">{{ element.attributes.placeholder }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-element-name text-center">
|
||||
<strong v-if="includeNumbers" class="step-element-number">{{ index + 1 }}</strong>
|
||||
<i v-if="item.attributes.icon" class="fas" :class="item.attributes.icon"></i>
|
||||
<span :title="nameWithFallbacks(item)" v-if="nameWithFallbacks(item)">{{ nameWithFallbacks(item) }}</span>
|
||||
<span :title="item.attributes.placeholder" v-else class="step-element-name-placeholder">{{ item.attributes.placeholder }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
<template>
|
||||
<div @click="toggle"
|
||||
ref="container"
|
||||
v-click-outside="{ handler: 'close', exclude: ['optionsContainer'] }"
|
||||
class="sn-select"
|
||||
:class="{
|
||||
'sn-select--open': isOpen,
|
||||
'sn-select--blank': !valueLabel,
|
||||
'disabled cursor-default': disabled,
|
||||
'cursor-pointer': !withEditCursor,
|
||||
'sci-cursor-edit hover:border-sn-sleepy-grey': !disabled && !isOpen && withEditCursor,
|
||||
[className]: true
|
||||
}">
|
||||
<div v-click-outside="close" @click="toggle" ref="container" class="sn-select" :class="{ 'sn-select--open': isOpen, 'sn-select--blank': !valueLabel, 'disabled': disabled }">
|
||||
<slot>
|
||||
<button ref="focusElement" class="sn-select__value">
|
||||
<span>{{ valueLabel || (placeholder || i18n.t('general.select')) }}</span>
|
||||
|
@ -60,8 +49,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
import outsideClick from '../../packs/vue/directives/outside_click';
|
||||
import { vOnClickOutside } from '@vueuse/components'
|
||||
|
||||
export default {
|
||||
name: 'Select',
|
||||
|
@ -78,7 +66,7 @@
|
|||
disabled: { type: Boolean, default: false }
|
||||
},
|
||||
directives: {
|
||||
'click-outside': outsideClick
|
||||
'click-outside': vOnClickOutside
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -98,7 +86,7 @@
|
|||
mounted() {
|
||||
document.addEventListener('scroll', this.updateOptionPosition);
|
||||
},
|
||||
beforeDestroy() {
|
||||
beforeUnmount() {
|
||||
document.removeEventListener('scroll', this.updateOptionPosition);
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
<template>
|
||||
<div v-if="!standAlone" class="sci-input-container time-container right-icon">
|
||||
<input class="time-part sci-input-field"
|
||||
@input="update"
|
||||
:id="this.selectorId"
|
||||
type="text"
|
||||
data-mask-type="time"
|
||||
v-model="value"
|
||||
placeholder="HH:mm"/>
|
||||
<i class="sn-icon sn-icon-created"></i>
|
||||
</div>
|
||||
<span v-else :class="className">
|
||||
<input class="time-part sci-input-field w-full inline-block m-0 p-0 border-none shadow-none outline-none"
|
||||
@input="update"
|
||||
:id="this.selectorId"
|
||||
type="text"
|
||||
data-mask-type="time"
|
||||
:disabled="disabled"
|
||||
v-model="value"
|
||||
placeholder="HH:mm"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'TimePicker',
|
||||
props: {
|
||||
selectorId: { type: String, required: true },
|
||||
defaultValue: { type: String, required: false },
|
||||
standAlone: { type: Boolean, default: true, required: false },
|
||||
className: { type: String, default: '', required: false },
|
||||
disabled: { type: Boolean, default: false }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
Inputmask('datetime', {
|
||||
inputFormat: 'HH:MM',
|
||||
placeholder: 'HH:mm',
|
||||
clearIncomplete: true,
|
||||
showMaskOnHover: true,
|
||||
hourFormat: 24
|
||||
}).mask($('#' + this.selectorId));
|
||||
|
||||
$('#' + this.selectorId).next().click(() => {
|
||||
var inputField = $('#' + this.selectorId);
|
||||
var d = new Date();
|
||||
var h = ('0' + d.getHours()).slice(-2);
|
||||
var m = ('0' + d.getMinutes()).slice(-2);
|
||||
var value= h + ':' + m
|
||||
inputField.val(value);
|
||||
this.value = value;
|
||||
this.update();
|
||||
});
|
||||
|
||||
this.value = this.defaultValue;
|
||||
this.update();
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.$emit('change', this.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -3,28 +3,18 @@
|
|||
|
||||
<div id="dueDateContainer" class="datetime-container"
|
||||
data-update-url="<%= my_module_path(my_module, user, format: :json) %>">
|
||||
<span class="date-text" data-editable="<%= due_date_editable %>"
|
||||
<span class="date-text relative flex items-center" data-editable="<%= due_date_editable %>"
|
||||
data-toggle="tooltip" data-placement="top" title="<%= due_status %>" data-due-status="<%= due_status %>">
|
||||
<span id="dueDateLabelContainer" class="view-block" >
|
||||
<%= render partial: "experiments/table_due_date_label" ,
|
||||
locals: { my_module: my_module, user: user } %>
|
||||
</span>
|
||||
<% if due_date_editable %>
|
||||
<div class="datetime-picker-container" id="due-date">
|
||||
<input id="calendarDueDate<%= my_module.id %>"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input calendar-due-date "
|
||||
readonly
|
||||
placeholder="<%= t('my_modules.details.no_due_date_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
data-positioning-vertical="bottom"
|
||||
value="<%= my_module.due_date ? l(my_module.due_date, format: :full) : '' %>"/>
|
||||
<div class="datetime-picker-container vue-date-time-picker h-full" id="calendarDueDateContainer<%= my_module.id %>">
|
||||
<input ref="input" type="hidden" data-simple-format="true" v-model="date" id="calendarDueDate<%= my_module.id %>" data-default="<%= my_module.due_date %>" />
|
||||
<date-time-picker class="opacity-0" ref="vueDateTime" @change="updateDate" mode="datetime" placeholder="<%= t('my_modules.details.no_due_date_placeholder') %>"></date-time-picker>
|
||||
</div>
|
||||
<div class="sn-icon sn-icon-close clear-date"
|
||||
<div class="sn-icon sn-icon-close clear-date <%= 'tw-hidden' if !my_module.due_date %>"
|
||||
data-toggle='clear-date-time-picker'
|
||||
data-target='calendarDueDate<%= my_module.id %>'>
|
||||
</div>
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
<div class="datetime-picker-container"
|
||||
id="<%= id %>"
|
||||
data-id="<%= id %>"
|
||||
data-use-current="<%= use_current %>"
|
||||
data-datetime-picker-format="<%= datetime_picker_format_date_only %>">
|
||||
<% if label %>
|
||||
<label class="control-label required" for="calendar-<%= id %>"><%= label %></label>
|
||||
<% end %>
|
||||
<span class="sn-icon sn-icon-calendar"></span>
|
||||
<input type="datetime" class="form-control calendar-input" name="calendar[<%= id %>]" id="calendar-<%= id %>" readonly="" data-ts="" placeholder="<%= placeholder %>" value="<%= defined?(setDate) ? setDate : '' %>"/>
|
||||
|
||||
<%= javascript_include_tag 'global_activities/date_picker' %>
|
||||
|
||||
<div class="datetime-picker-container">
|
||||
<div id="date-time-picker-<%= id %>" class="vue-date-time-picker w-full">
|
||||
<% selected_date = '' %>
|
||||
<% selected_date = setDate if defined?(setDate) %>
|
||||
<% selected_date = use_current %>
|
||||
<% if label %>
|
||||
<label class="sci-label" for="calendar-<%= id %>"><%= label %></label>
|
||||
<% end %>
|
||||
<input ref="input" type="hidden" class="calendar-input" id="calendar-<%= id %>" v-model="date" name="calendar[<%= id %>]" data-default="<%= defined?(setDate) ? setDate : '' %>" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate" ref="vueDateTime" placeholder="<%= placeholder %>" @change="updateDate" mode="date"></date-time-picker>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,11 +4,6 @@
|
|||
<%= content_for :sidebar do %>
|
||||
<%= render partial: "/shared/sidebar/templates_sidebar", locals: {active: :label} %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
<%= javascript_include_tag 'application' %>
|
||||
<%= javascript_include_tag 'session_end' %>
|
||||
<%= javascript_include_tag 'sidebar_toggle' %>
|
||||
<%= stylesheet_link_tag 'application_pack', media: 'all' %>
|
||||
<%= stylesheet_link_tag 'application', media: 'all' %>
|
||||
|
||||
|
||||
|
@ -55,6 +56,8 @@
|
|||
<%= stylesheet_link_tag 'tui_image_editor_styles' %>
|
||||
<%= javascript_include_tag 'vue_navigation_navigator' %>
|
||||
<%= javascript_include_tag 'vue_navigation_top_menu' %>
|
||||
<%= javascript_include_tag 'vue_legacy_datetime_picker' %>
|
||||
|
||||
<style> :root { --navigator-navigation-width: <%= session[:navigator_width] || Constants::DEFAULT_NAV_WIDTH %>px; } </style>
|
||||
</head>
|
||||
<body
|
||||
|
@ -69,6 +72,7 @@
|
|||
data-atwho-rep-items-url="<%= atwho_rep_items_team_path(current_team) %>"
|
||||
data-atwho-menu-items="<%= atwho_menu_items_team_path(current_team) %>"
|
||||
data-datetime-picker-format="<%= datetime_picker_format_date_only %>"
|
||||
data-datetime-picker-format-vue="<%= datetime_picker_format_date_only_vue %>"
|
||||
<% end %>
|
||||
>
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<%= form_with model: @my_module, url: my_module_path(@my_module, format: :json), data: { remote: :true }, builder: SciFormHelper::SciFormBuilder do |f| %>
|
||||
<%= f.datetime_picker :due_date,
|
||||
value: @my_module.due_date,
|
||||
label: t('my_modules.due_date.label'),
|
||||
clear: true,
|
||||
time: true %>
|
||||
<label class="sci-label">
|
||||
<%= t('my_modules.due_date.label') %>
|
||||
</label>
|
||||
<div id="date-time-picker" class="vue-date-time-picker">
|
||||
<input ref="input" type="hidden" v-model="date" data-simple-format="true" name="my_module[due_date]" data-default="<%= l(@my_module.due_date, format: :full) if @my_module.due_date %>" />
|
||||
<date-time-picker class="w-64" @cleared="clearDate" ref="vueDateTime" @change="updateDate" mode="datetime"></date-time-picker>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -6,19 +6,12 @@
|
|||
</span>
|
||||
<% if due_date_editable %>
|
||||
<div class="datetime-picker-container" id="due-date">
|
||||
<span class="sn-icon sn-icon-calendar"></span>
|
||||
<input id="calendarDueDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('my_modules.details.no_due_date_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value="<%= my_module.due_date ? l(my_module.due_date, format: :full) : '' %>"/>
|
||||
<div id="calendarDueDateContainer">
|
||||
<input type="hidden" ref="input" v-model="date" data-simple-format="true" id="calendarDueDate" data-default="<%= l(my_module.due_date, format: :full) if my_module.due_date %>
|
||||
" />
|
||||
<date-time-picker class="w-full" ref="vueDateTime" :teleport="false" @change="updateDate" mode="datetime" :placeholder="'<%= t('my_modules.details.no_due_date_placeholder') %>'"></date-time-picker>
|
||||
</div>
|
||||
<span class="sn-icon sn-icon-close clear-date" data-toggle='clear-date-time-picker' data-target='calendarDueDate'></span>
|
||||
</div>
|
||||
<span class="sn-icon sn-icon-close clear-date" data-toggle='clear-date-time-picker' data-target='calendarDueDate'></span>
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
|
@ -6,18 +6,11 @@
|
|||
</span>
|
||||
<% if start_date_editable %>
|
||||
<div class="datetime-picker-container" id="start-date">
|
||||
<span class="sn-icon sn-icon-calendar"></span>
|
||||
<input id="calendarStartDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('my_modules.details.no_start_date_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value="<%= my_module.started_on ? l(my_module.started_on, format: :full) : '' %>"/>
|
||||
<div id="calendarStartDateContainer">
|
||||
<input type="hidden" ref="input" v-model="date" data-simple-format="true" id="calendarStartDate" data-default="<%= l(my_module.started_on, format: :full) if my_module.started_on %>" />
|
||||
<date-time-picker class="w-full" ref="vueDateTime" :teleport="false" @change="updateDate" mode="datetime" :placeholder="'<%= t('my_modules.details.no_start_date_placeholder') %>'"></date-time-picker>
|
||||
</div>
|
||||
<span class="sn-icon sn-icon-close clear-date" data-toggle='clear-date-time-picker' data-target='calendarStartDate'></span>
|
||||
</div>
|
||||
<span class="sn-icon sn-icon-close clear-date" data-toggle='clear-date-time-picker' data-target='calendarStartDate'></span>
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
<%= f.hidden_field :view_mode, value: view_mode%>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<label class="sci-label"><%= t('experiments.canvas.new_my_module_modal.name') %></label>
|
||||
<div class="sci-input-container form-group">
|
||||
<label><%= t('experiments.canvas.new_my_module_modal.name') %></label>
|
||||
<%= text_field_tag 'my_module[name]', '', placeholder: t('experiments.canvas.new_my_module_modal.name_placeholder'), class: "sci-input-field" %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,21 +20,12 @@
|
|||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<div class="form-group">
|
||||
<div class="sci-input-container right-icon my-module-due-date-container">
|
||||
<label for="my_module_due_date"><%= t('experiments.canvas.new_my_module_modal.due_date') %></label>
|
||||
<i class="sn-icon sn-icon-calendar"></i>
|
||||
<input id="my_module_due_date"
|
||||
type="datetime"
|
||||
name="my_module[due_date]"
|
||||
data-toggle='date-time-picker'
|
||||
class="sci-input-field calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('experiments.canvas.new_my_module_modal.due_date_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value=""/>
|
||||
<div class="my-module-due-date-container">
|
||||
<label class="sci-label" for="my_module_due_date"><%= t('experiments.canvas.new_my_module_modal.due_date') %></label>
|
||||
<div id="date-time-picker-my-module" class="vue-date-time-picker w-full">
|
||||
<input ref="input" type="hidden" data-simple-format="true" class="calendar-input" id="date-time-picker-input" v-model="date" name="my_module[due_date]" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate" ref="vueDateTime" placeholder="<%= t('experiments.canvas.new_my_module_modal.due_date_placeholder') %>" @change="updateDate" mode="datetime"></date-time-picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,7 +35,7 @@
|
|||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<%= f.hidden_field :tag_ids%>
|
||||
<div class="form-group">
|
||||
<label><%= t('experiments.canvas.new_my_module_modal.assigned_tags_label') %></label>
|
||||
<label class="sci-label"><%= t('experiments.canvas.new_my_module_modal.assigned_tags_label') %></label>
|
||||
<%= select_tag 'module-tags-selector', options_for_select([]),
|
||||
data: {
|
||||
'tags-create-url': project_create_tag_path(project_id: @experiment.project_id),
|
||||
|
@ -58,7 +49,7 @@
|
|||
<% if can_designate_users_to_new_task?(@experiment) %>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<label><%= t('experiments.canvas.new_my_module_modal.assigned_users') %></label>
|
||||
<label class="sci-label"><%= t('experiments.canvas.new_my_module_modal.assigned_users') %></label>
|
||||
<%= select_tag 'my_module[user_ids]',
|
||||
options_for_select(users.map{ |user|
|
||||
[
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
</h1>
|
||||
</div>
|
||||
<div id="toolbarWrapper" class="toolbar-row" data-width-breakpoint="750">
|
||||
<%= render partial: 'projects/index/toolbar' %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<% provide(:head_title, t("protocols.index.head_title")) %>
|
||||
|
||||
<% if current_team %>
|
||||
|
@ -35,7 +31,7 @@
|
|||
<% end %>
|
||||
|
||||
<div id="protocolFileImportModal">
|
||||
<protocol-file-import-modal
|
||||
<protocol-file-import-modal
|
||||
import-url="<%= import_docx_protocols_path %>"
|
||||
protocol-template-table-url="<%= protocols_path %>"
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
|
||||
<% if params[:preview_report_id] %>
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<% provide(:head_title, t("libraries.show.head_title", library: @repository.name)) %>
|
||||
<%= stylesheet_link_tag 'datatables' %>
|
||||
<% provide(:container_class, "no-second-nav-container") %>
|
||||
|
|
|
@ -2,35 +2,18 @@
|
|||
<div class="created-on-label">
|
||||
<label class="sci-label"><%= label %></label>
|
||||
</div>
|
||||
<div class="flex items-center gap-5">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="datetime-picker-container flex">
|
||||
<span class="sn-icon sn-icon-calendar"></span>
|
||||
<input type="datetime"
|
||||
id="<%= "#{container_class}_from" %>"
|
||||
data-linked-max="#<%= "#{container_class}_to" %>"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input from-date"
|
||||
readonly
|
||||
placeholder="<%= t('filters_modal.from_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value=""/>
|
||||
<div id="<%= "#{container_class}_from_container" %>" class="vue-date-time-picker-filter grow">
|
||||
<input ref="input" class="from-date" type="hidden" v-model="date" id="<%= "#{container_class}_from" %>" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate" ref="vueDateTime" @change="updateDate" mode="datetime" placeholder="<%= t('filters_modal.from_placeholder') %>"></date-time-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="datetime-picker-container flex">
|
||||
<span class="sn-icon sn-icon-calendar"></span>
|
||||
<input type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
id="<%= "#{container_class}_to" %>"
|
||||
data-linked-min="#<%= "#{container_class}_from" %>"
|
||||
class="form-control calendar-input to-date"
|
||||
readonly
|
||||
placeholder="<%= t('filters_modal.to_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value=""/>
|
||||
<div id="<%= "#{container_class}_to_container" %>" class="vue-date-time-picker-filter grow">
|
||||
<input ref="input" class="to-date" type="hidden" v-model="date" id="<%= "#{container_class}_to" %>" />
|
||||
<date-time-picker class="w-full" @cleared="clearDate" ref="vueDateTime" @change="updateDate" mode="datetime" placeholder="<%= t('filters_modal.to_placeholder') %>"></date-time-picker>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<% provide(:head_title, t("users.settings.teams.head_title")) %>
|
||||
<% provide(:container_class, "no-second-nav-container") %>
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
<% content_for :head do %>
|
||||
<meta name="turbolinks-cache-control" content="no-cache">
|
||||
<% end %>
|
||||
|
||||
<% provide(:head_title, t("users.settings.teams.head_title")) %>
|
||||
<% provide(:container_class, "no-second-nav-container") %>
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ const entryList = {
|
|||
vue_navigation_breadcrumbs: './app/javascript/packs/vue/navigation/breadcrumbs.js',
|
||||
vue_protocol_file_import_modal: './app/javascript/packs/vue/protocol_file_import_modal.js',
|
||||
vue_components_export_stock_consumption_modal: './app/javascript/packs/vue/export_stock_consumption_modal.js',
|
||||
vue_components_manage_stock_value_modal: './app/javascript/packs/vue/manage_stock_value_modal.js'
|
||||
vue_components_manage_stock_value_modal: './app/javascript/packs/vue/manage_stock_value_modal.js',
|
||||
vue_legacy_datetime_picker: './app/javascript/packs/vue/legacy/datetime_picker.js',
|
||||
}
|
||||
|
||||
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949
|
||||
|
|
19
package.json
19
package.json
|
@ -31,9 +31,13 @@
|
|||
"@fortawesome/fontawesome-free": "^5.2.0",
|
||||
"@joeattardi/emoji-button": "^4.6.2",
|
||||
"@teselagen/ove": "^0.3.23",
|
||||
"@vue/compiler-sfc": "^3.3.4",
|
||||
"@vuepic/vue-datepicker": "^7.2.0",
|
||||
"@vueuse/components": "^10.5.0",
|
||||
"@vueuse/core": "^10.5.0",
|
||||
"ajv": "6.12.6",
|
||||
"autoprefixer": "10.4.14",
|
||||
"axios": "^1.4.0",
|
||||
"axios": "^1.6.0",
|
||||
"babel-loader": "^8.2.5",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"bootstrap": "^3.4.1",
|
||||
|
@ -78,14 +82,11 @@
|
|||
"tui-color-picker": "^2.2.0",
|
||||
"tui-image-editor": "github:scinote-eln/tui.image-editor#3_15_2_updated",
|
||||
"twemoji": "^12.1.4",
|
||||
"vue": "^2.6.11",
|
||||
"vue-loader": "^15.9.1",
|
||||
"vue-resizable": "2.1.3",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"vue-turbolinks": "^2.2.1",
|
||||
"vue2-perfect-scrollbar": "^1.5.56",
|
||||
"vue2-scrollspy": "^2.3.1",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vue": "^3.3.4",
|
||||
"vue-loader": "^16.0.0",
|
||||
"vue3-draggable-resizable": "^1.6.5",
|
||||
"vue3-perfect-scrollbar": "^1.6.1",
|
||||
"vuedraggable": "^4.1.0",
|
||||
"webpack": "^5.64.4",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-manifest-plugin": "^1.3.2",
|
||||
|
|
9
public/images/calendar/calendar.svg
Normal file
9
public/images/calendar/calendar.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 11C4.26 11 4.49 10.9 4.69 10.7C4.89 10.5 5 10.26 5 9.98C5 9.72 4.9 9.49 4.69 9.29C4.49 9.09 4.25 8.99 4 8.99C3.75 8.99 3.51 9.09 3.31 9.29C3.11 9.49 3 9.72 3 9.98C3 10.26 3.1 10.5 3.31 10.7C3.51 10.9 3.74 11 4 11Z" fill="#1D2939"/>
|
||||
<path d="M4 15C4.26 15 4.49 14.9 4.69 14.7C4.89 14.5 5 14.26 5 13.98C5 13.72 4.9 13.49 4.69 13.29C4.49 13.09 4.25 12.99 4 12.99C3.75 12.99 3.51 13.09 3.31 13.29C3.11 13.49 3 13.72 3 13.98C3 14.26 3.1 14.5 3.31 14.7C3.51 14.9 3.74 15 4 15Z" fill="#1D2939"/>
|
||||
<path d="M12 11C12.26 11 12.49 10.9 12.69 10.7C12.89 10.5 13 10.26 13 9.98C13 9.72 12.9 9.49 12.69 9.29C12.49 9.09 12.25 8.99 12 8.99C11.75 8.99 11.51 9.09 11.31 9.29C11.11 9.49 11 9.72 11 9.98C11 10.26 11.1 10.5 11.31 10.7C11.51 10.9 11.74 11 12 11Z" fill="#1D2939"/>
|
||||
<path d="M12 15C12.26 15 12.49 14.9 12.69 14.7C12.89 14.5 13 14.26 13 13.98C13 13.72 12.9 13.49 12.69 13.29C12.49 13.09 12.25 12.99 12 12.99C11.75 12.99 11.51 13.09 11.31 13.29C11.11 13.49 11 13.72 11 13.98C11 14.26 11.1 14.5 11.31 14.7C11.51 14.9 11.74 15 12 15Z" fill="#1D2939"/>
|
||||
<path d="M8.02 11C8.28 11 8.51 10.9 8.71 10.7C8.91 10.5 9.02 10.26 9.02 9.98C9.02 9.72 8.92 9.49 8.71 9.29C8.51 9.09 8.27 8.99 8.02 8.99C7.77 8.99 7.53 9.09 7.33 9.29C7.13 9.49 7.02 9.72 7.02 9.98C7.02 10.26 7.12 10.5 7.33 10.7C7.53 10.9 7.76 11 8.02 11Z" fill="#1D2939"/>
|
||||
<path d="M8.02 15C8.28 15 8.51 14.9 8.71 14.7C8.91 14.5 9.02 14.26 9.02 13.98C9.02 13.72 8.92 13.49 8.71 13.29C8.51 13.09 8.27 12.99 8.02 12.99C7.77 12.99 7.53 13.09 7.33 13.29C7.13 13.49 7.02 13.72 7.02 13.98C7.02 14.26 7.12 14.5 7.33 14.7C7.53 14.9 7.76 15 8.02 15Z" fill="#1D2939"/>
|
||||
<path d="M14 2H12V0H11V2H5V0H4V2H2C0.9 2 0 2.9 0 4V16C0 17.1 0.9 18 2 18H14C15.1 18 16 17.1 16 16V4C16 2.9 15.1 2 14 2ZM15 16C15 16.55 14.55 17 14 17H2C1.45 17 1 16.55 1 16V7H15V16ZM1 6V4C1 3.45 1.45 3 2 3H14C14.55 3 15 3.45 15 4V6H1Z" fill="#1D2939"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
3
public/images/calendar/clock.svg
Normal file
3
public/images/calendar/clock.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.1256 13.35L12.8256 12.65L8.97559 8.8V4H7.97559V9.2L12.1256 13.35ZM9 18C7.75 18 6.57933 17.7627 5.488 17.288C4.396 16.8127 3.446 16.1707 2.638 15.362C1.82933 14.554 1.18733 13.604 0.712 12.512C0.237333 11.4207 0 10.25 0 9C0 7.75 0.237333 6.579 0.712 5.487C1.18733 4.39567 1.82933 3.44567 2.638 2.637C3.446 1.829 4.396 1.18733 5.488 0.712C6.57933 0.237333 7.75 0 9 0C10.25 0 11.421 0.237333 12.513 0.712C13.6043 1.18733 14.5543 1.829 15.363 2.637C16.171 3.44567 16.8127 4.39567 17.288 5.487C17.7627 6.579 18 7.75 18 9C18 10.25 17.7627 11.4207 17.288 12.512C16.8127 13.604 16.171 14.554 15.363 15.362C14.5543 16.1707 13.6043 16.8127 12.513 17.288C11.421 17.7627 10.25 18 9 18ZM9 17C11.2167 17 13.1043 16.221 14.663 14.663C16.221 13.1043 17 11.2167 17 9C17 6.78333 16.221 4.89567 14.663 3.337C13.1043 1.779 11.2167 1 9 1C6.78333 1 4.896 1.779 3.338 3.337C1.77933 4.89567 1 6.78333 1 9C1 11.2167 1.77933 13.1043 3.338 14.663C4.896 16.221 6.78333 17 9 17Z" fill="#1D2939"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
5
public/images/calendar/down.svg
Normal file
5
public/images/calendar/down.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="down">
|
||||
<path id="down_2" d="M7.02502 9.69999L7.72502 8.99999L12.685 13.96L17.635 8.99999L18.335 9.69999L12.685 15.36L7.02502 9.69999Z" fill="#1D2939"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 267 B |
3
public/images/calendar/navigate_before.svg
Normal file
3
public/images/calendar/navigate_before.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.3 16.6L8 11.3L13.3 6L14 6.7L9.4 11.3L14 15.9L13.3 16.6Z" fill="#1D2939"/>
|
||||
</svg>
|
After Width: | Height: | Size: 190 B |
3
public/images/calendar/navigate_next.svg
Normal file
3
public/images/calendar/navigate_next.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.7 16.6L9 15.9L13.6 11.3L9 6.7L9.7 6L15 11.3L9.7 16.6Z" fill="#1D2939"/>
|
||||
</svg>
|
After Width: | Height: | Size: 187 B |
3
public/images/calendar/up.svg
Normal file
3
public/images/calendar/up.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.335 14.135L17.635 14.835L12.675 9.87498L7.72502 14.835L7.02502 14.135L12.675 8.47498L18.335 14.135Z" fill="#1D2939"/>
|
||||
</svg>
|
After Width: | Height: | Size: 234 B |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue