diff --git a/app/assets/javascripts/repositories/renderers/columns/date_time_helper.js b/app/assets/javascripts/repositories/renderers/columns/date_time_helper.js
new file mode 100644
index 000000000..7d5742eb0
--- /dev/null
+++ b/app/assets/javascripts/repositories/renderers/columns/date_time_helper.js
@@ -0,0 +1,186 @@
+/* global Inputmask formatJS */
+/* 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 (Object.prototype.toString.call(date) === '[object Date]') && !isNaN(date.getTime());
+ }
+
+ function addLeadingZero(value) {
+ return ('0' + value).slice(-2);
+ }
+
+ function recalcTimestamp(date, timeStr) {
+ if (!isValidTimeStr(timeStr)) {
+ date.setHours(0);
+ date.setMinutes(0);
+ return date;
+ }
+ let hours = timeStr.split(':')[0];
+ let mins = timeStr.split(':')[1];
+ date.setHours(hours);
+ date.setMinutes(mins);
+ 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($input, date, timeStr, format) {
+ let formId = $input.data('form-id');
+ let columnId = $input.data('column-id');
+ let hiddenFieldContainer = $input.parent().find('.cell-timestamp-container');
+ let hasTime = isValidTimeStr(timeStr);
+ let hasDate = isValidDate(date);
+ let value;
+ let hiddenField;
+
+ if (!hasDate) { // Date needs to be presence
+ value = '';
+ } else if (format === 'time' && !hasTime) { // Delete time value
+ value = '';
+ } else if (format === 'datetime' && !hasTime) { // Delete date time value
+ value = '';
+ } else {
+ // create date time format
+ value = stringDateTimeFormat(recalcTimestamp(date, timeStr), 'full');
+ }
+
+ hiddenField = `
+ `;
+
+ hiddenFieldContainer.html(hiddenField);
+ }
+
+ function initChangeEvents($cell) {
+ $cell.find('input[data-mask-type=time]').on('change', function() {
+ let timeStr = $(this).val();
+ let $container = $(this).parent().find('.cell-timestamp-container');
+ let dateStr = $container.data('current-date');
+ let columnType = $container.data('datetime-type');
+ if (columnType === 'time' && !isValidDate(dateStr)) {
+ // new time without value for date
+ dateStr = stringDateTimeFormat(new Date(), 'dateonly');
+ }
+
+ insertHiddenField($(this), new Date(dateStr), timeStr, columnType);
+ });
+
+ $cell.find('.calendar-input').on('dp.change', function(e) {
+ let date = e.date._d;
+ let timeStr = $(this).parent().find('input[data-mask-type=time]').val();
+ let $container = $(this).parent().find('.cell-timestamp-container');
+
+ if (date !== undefined) {
+ $container.data('current-date', stringDateTimeFormat(date, 'dateonly'));
+ } else {
+ $container.data('current-date', '');
+ }
+ insertHiddenField($(this), date, timeStr, $container.data('datetime-type'));
+ });
+ }
+
+ function dateInputField(formId, columnId, value) {
+ return `
+
+ `;
+ }
+
+ function timeInputField(formId, columnId, value) {
+ return `
+
+ `;
+ }
+
+ function initDateEditMode(formId, columnId, $cell, date, datetime) {
+ let inputFields = `
+
+ `;
+
+ $cell.html(inputFields);
+
+ $cell.find('.calendar-input').datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
+ initChangeEvents($cell);
+ }
+
+ function initTimeEditMode(formId, columnId, $cell, time, datetime) {
+ let inputFields = `
+
+ `;
+
+ $cell.html(inputFields);
+
+ Inputmask('datetime', {
+ inputFormat: 'HH:MM',
+ placeholder: 'HH:mm',
+ clearIncomplete: true,
+ showMaskOnHover: true,
+ hourFormat: 24
+ }).mask($cell.find('input[data-mask-type="time"]'));
+
+ initChangeEvents($cell);
+ }
+
+ function initDateTimeEditMode(formId, columnId, $cell, date, time, datetime) {
+ let inputFields = `
+
+ `;
+
+ $cell.html(inputFields);
+
+ 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 });
+ initChangeEvents($cell);
+ }
+
+ return {
+ initDateEditMode: initDateEditMode,
+ initTimeEditMode: initTimeEditMode,
+ initDateTimeEditMode: initDateTimeEditMode,
+ };
+}());
diff --git a/app/assets/javascripts/repositories/renderers/edit_renderers.js b/app/assets/javascripts/repositories/renderers/edit_renderers.js
index 88a69fbb3..cb939fd3c 100644
--- a/app/assets/javascripts/repositories/renderers/edit_renderers.js
+++ b/app/assets/javascripts/repositories/renderers/edit_renderers.js
@@ -1,4 +1,4 @@
-/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS */
+/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS DateTimeHelper*/
$.fn.dataTable.render.editRowName = function(formId, cell) {
let $cell = $(cell.node());
@@ -89,15 +89,31 @@ $.fn.dataTable.render.editRepositoryStatusValue = function(formId, columnId, cel
};
$.fn.dataTable.render.editRepositoryDateTimeValue = function(formId, columnId, cell) {
- return '';
+ let $cell = $(cell.node());
+ let $span = $cell.find('span').first();
+ let date = $span.data('date');
+ let time = $span.data('time');
+ let datetime = $span.data('datetime');
+
+ DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, date, time, datetime);
};
$.fn.dataTable.render.editRepositoryDateValue = function(formId, columnId, cell) {
- return '';
+ let $cell = $(cell.node());
+ let $span = $cell.find('span').first();
+ let date = $span.data('date');
+ let datetime = $span.data('datetime');
+
+ DateTimeHelper.initDateEditMode(formId, columnId, $cell, date, datetime);
};
$.fn.dataTable.render.editRepositoryTimeValue = function(formId, columnId, cell) {
- return '';
+ let $cell = $(cell.node());
+ let $span = $cell.find('span').first();
+ let time = $span.data('time');
+ let datetime = $span.data('datetime');
+
+ DateTimeHelper.initTimeEditMode(formId, columnId, $cell, time, datetime);
};
$.fn.dataTable.render.editRepositoryDateTimeRangeValue = function(formId, columnId, cell) {
diff --git a/app/assets/javascripts/repositories/renderers/new_renderers.js b/app/assets/javascripts/repositories/renderers/new_renderers.js
index 9439b0aad..f707debd9 100644
--- a/app/assets/javascripts/repositories/renderers/new_renderers.js
+++ b/app/assets/javascripts/repositories/renderers/new_renderers.js
@@ -1,4 +1,4 @@
-/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS */
+/* global ListColumnHelper ChecklistColumnHelper Status SmartAnnotation I18n GLOBAL_CONSTANTS DateTimeHelper formatJS */
$.fn.dataTable.render.newRowName = function(formId, $cell) {
$cell.html(`
@@ -85,3 +85,19 @@ $.fn.dataTable.render.newRepositoryNumberValue = function(formId, columnId, $cel
SmartAnnotation.init($cell.find('input'));
};
+
+$.fn.dataTable.render.newRepositoryDateTimeValue = function(formId, columnId, $cell) {
+ DateTimeHelper.initDateTimeEditMode(formId, columnId, $cell, '', '', '');
+};
+
+$.fn.dataTable.render.newRepositoryTimeValue = function(formId, columnId, $cell) {
+ DateTimeHelper.initTimeEditMode(formId, columnId, $cell, '', '');
+};
+
+$.fn.dataTable.render.newRepositoryDateValue = function(formId, columnId, $cell) {
+ DateTimeHelper.initDateEditMode(formId, columnId, $cell, '', '');
+};
+
+$.fn.dataTable.render.newRepositoryCheckboxValue = function(formId, columnId) {
+ return '';
+};
diff --git a/app/assets/javascripts/repositories/renderers/view_renderers.js b/app/assets/javascripts/repositories/renderers/view_renderers.js
index acb1bf6b6..62c1718da 100644
--- a/app/assets/javascripts/repositories/renderers/view_renderers.js
+++ b/app/assets/javascripts/repositories/renderers/view_renderers.js
@@ -55,7 +55,7 @@ $.fn.dataTable.render.defaultRepositoryDateValue = function() {
};
$.fn.dataTable.render.RepositoryDateValue = function(data) {
- return data.value;
+ return `${data.value.formatted}`;
};
$.fn.dataTable.render.defaultRepositoryDateTimeValue = function() {
@@ -63,7 +63,9 @@ $.fn.dataTable.render.defaultRepositoryDateTimeValue = function() {
};
$.fn.dataTable.render.RepositoryDateTimeValue = function(data) {
- return data.value;
+ return `${data.value.formatted}`;
};
$.fn.dataTable.render.defaultRepositoryTimeValue = function() {
@@ -71,7 +73,8 @@ $.fn.dataTable.render.defaultRepositoryTimeValue = function() {
};
$.fn.dataTable.render.RepositoryTimeValue = function(data) {
- return data.value;
+ return `${data.value.formatted}`;
};
$.fn.dataTable.render.defaultRepositoryTimeRangeValue = function() {
@@ -79,7 +82,7 @@ $.fn.dataTable.render.defaultRepositoryTimeRangeValue = function() {
};
$.fn.dataTable.render.RepositoryTimeRangeValue = function(data) {
- return data.value;
+ return `${data.value.formatted}`;
};
$.fn.dataTable.render.defaultRepositoryDateTimeRangeValue = function() {
diff --git a/app/assets/javascripts/repositories/validators/base_validator.js b/app/assets/javascripts/repositories/validators/base_validator.js
index 26a0942a6..35f887a7f 100644
--- a/app/assets/javascripts/repositories/validators/base_validator.js
+++ b/app/assets/javascripts/repositories/validators/base_validator.js
@@ -37,3 +37,7 @@ $.fn.dataTable.render.RepositoryChecklistValueValidator = function() {
$.fn.dataTable.render.RepositoryNumberValueValidator = function() {
return true;
};
+
+$.fn.dataTable.render.RepositoryDateTimeValueValidator = function() {
+ return true;
+}
diff --git a/app/models/repository_cell.rb b/app/models/repository_cell.rb
index 194acbc6a..88d391216 100644
--- a/app/models/repository_cell.rb
+++ b/app/models/repository_cell.rb
@@ -23,7 +23,7 @@ class RepositoryCell < ApplicationRecord
belongs_to :repository_date_value,
(lambda do
includes(:repository_cell)
- .where(repository_cells: { value_type: 'RepositoryDateValue' })
+ .where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
end),
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
belongs_to :repository_list_value,
@@ -56,14 +56,14 @@ class RepositoryCell < ApplicationRecord
belongs_to :repository_date_time_value,
(lambda do
includes(:repository_cell)
- .where(repository_cells: { value_type: 'RepositoryDateTimeValue' })
+ .where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
end),
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
belongs_to :repository_time_value,
(lambda do
includes(:repository_cell)
- .where(repository_cells: { value_type: 'RepositoryTimeValue' })
+ .where(repository_cells: { value_type: 'RepositoryDateTimeValueBase' })
end),
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
diff --git a/app/serializers/repository_datatable/repository_date_time_value_serializer.rb b/app/serializers/repository_datatable/repository_date_time_value_serializer.rb
index a58f84cf3..73998746d 100644
--- a/app/serializers/repository_datatable/repository_date_time_value_serializer.rb
+++ b/app/serializers/repository_datatable/repository_date_time_value_serializer.rb
@@ -3,7 +3,12 @@
module RepositoryDatatable
class RepositoryDateTimeValueSerializer < RepositoryBaseValueSerializer
def value
- I18n.l(object.data, format: :full_with_comma)
+ {
+ formatted: I18n.l(object.data, format: :full_with_comma),
+ date_formatted: I18n.l(object.data, format: :full_date),
+ time_formatted: I18n.l(object.data, format: :time),
+ datetime: object.data.strftime('%Y/%m/%d %H:%M')
+ }
end
end
end
diff --git a/app/serializers/repository_datatable/repository_date_value_serializer.rb b/app/serializers/repository_datatable/repository_date_value_serializer.rb
index a70ca09ec..8ae7618bc 100644
--- a/app/serializers/repository_datatable/repository_date_value_serializer.rb
+++ b/app/serializers/repository_datatable/repository_date_value_serializer.rb
@@ -3,7 +3,10 @@
module RepositoryDatatable
class RepositoryDateValueSerializer < RepositoryBaseValueSerializer
def value
- I18n.l(object.data, format: :full_date)
+ {
+ formatted: I18n.l(object.data, format: :full_date),
+ datetime: object.data.strftime('%Y/%m/%d %H:%M')
+ }
end
end
end
diff --git a/app/serializers/repository_datatable/repository_time_value_serializer.rb b/app/serializers/repository_datatable/repository_time_value_serializer.rb
index 28edaf57e..ea059feec 100644
--- a/app/serializers/repository_datatable/repository_time_value_serializer.rb
+++ b/app/serializers/repository_datatable/repository_time_value_serializer.rb
@@ -3,7 +3,10 @@
module RepositoryDatatable
class RepositoryTimeValueSerializer < RepositoryBaseValueSerializer
def value
- I18n.l(object.data, format: :time)
+ {
+ formatted: I18n.l(object.data, format: :time),
+ datetime: object.data.strftime('%Y/%m/%d %H:%M')
+ }
end
end
end
diff --git a/app/views/repositories/show.html.erb b/app/views/repositories/show.html.erb
index 22ec7869d..4eccd8ebf 100644
--- a/app/views/repositories/show.html.erb
+++ b/app/views/repositories/show.html.erb
@@ -170,3 +170,17 @@
<%= javascript_include_tag "repositories/show" %>
<%= javascript_include_tag "repositories/index" %>
<%= javascript_pack_tag 'custom/inputmask' %>
+
+