mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-22 03:36:32 +08:00
Add start date to the task [SCI-4504]
This commit is contained in:
parent
404be29fc0
commit
3c53be1f9a
19 changed files with 191 additions and 115 deletions
|
@ -1,23 +1,44 @@
|
|||
/* global I18n dropdownSelector */
|
||||
/* eslint-disable no-use-before-define */
|
||||
|
||||
function updateStartDate() {
|
||||
let updateUrl = $('#startDateContainer').data('update-url');
|
||||
let val = $('#calendarStartDate').val();
|
||||
$.ajax({
|
||||
url: updateUrl,
|
||||
type: 'PATCH',
|
||||
dataType: 'json',
|
||||
data: { my_module: { started_on: val } },
|
||||
success: function(result) {
|
||||
$('#startDateLabelContainer').html(result.start_date_label);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Bind ajax for editing due dates
|
||||
function initStartDatePicker() {
|
||||
$('#calendarStartDate').on('dp.change', function() {
|
||||
updateStartDate();
|
||||
});
|
||||
}
|
||||
|
||||
function updateDueDate() {
|
||||
let updateUrl = $('.due-date-container').data('update-url');
|
||||
let val = $('#calendar-due-date').val();
|
||||
let updateUrl = $('#dueDateContainer').data('update-url');
|
||||
let val = $('#calendarDueDate').val();
|
||||
$.ajax({
|
||||
url: updateUrl,
|
||||
type: 'PATCH',
|
||||
dataType: 'json',
|
||||
data: { my_module: { due_date: val } },
|
||||
success: function(result) {
|
||||
$('#due-date-label-container').html(result.due_date_label);
|
||||
$('#dueDateLabelContainer').html(result.due_date_label);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Bind ajax for editing due dates
|
||||
function initDueDatePicker() {
|
||||
$('#calendar-due-date').on('dp.change', function() {
|
||||
$('#calendarDueDate').on('dp.change', function() {
|
||||
updateDueDate();
|
||||
});
|
||||
}
|
||||
|
@ -190,7 +211,7 @@ function applyTaskCompletedCallBack() {
|
|||
button.find('.btn')
|
||||
.removeClass('btn-default').addClass('btn-primary');
|
||||
}
|
||||
$('.due-date-container').html(data.module_header_due_date);
|
||||
$('#dueDateContainer').html(data.module_header_due_date);
|
||||
initDueDatePicker();
|
||||
$('.task-state-label').html(data.module_state_label);
|
||||
button.find('button').replaceWith(data.new_btn);
|
||||
|
@ -272,4 +293,5 @@ function initTagsSelector() {
|
|||
applyTaskCompletedCallBack();
|
||||
initTagsSelector();
|
||||
bindEditTagsAjax();
|
||||
initStartDatePicker();
|
||||
initDueDatePicker();
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.due-date-container {
|
||||
.datetime-container {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
|
||||
|
@ -121,7 +121,11 @@
|
|||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
#calendar-due-date {
|
||||
#calendarDueDate {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#calendarStartDate {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,21 +143,15 @@ class MyModulesController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
update_params = my_module_params
|
||||
if update_params[:due_date].present?
|
||||
update_params[:due_date] =
|
||||
Time.zone.strptime(update_params[:due_date], I18n.backend.date_format.dup.gsub(/%-/, '%') + ' %H:%M')
|
||||
end
|
||||
@my_module.assign_attributes(update_params)
|
||||
@my_module.assign_attributes(my_module_params)
|
||||
@my_module.last_modified_by = current_user
|
||||
description_changed = @my_module.description_changed?
|
||||
start_date_changes = @my_module.changes[:started_on]
|
||||
due_date_changes = @my_module.changes[:due_date]
|
||||
|
||||
if @my_module.archived_changed?(from: false, to: true)
|
||||
|
||||
saved = @my_module.archive(current_user)
|
||||
elsif @my_module.archived_changed?(from: true, to: false)
|
||||
|
||||
saved = @my_module.restore(current_user)
|
||||
if saved
|
||||
restored = true
|
||||
|
@ -165,28 +159,14 @@ class MyModulesController < ApplicationController
|
|||
end
|
||||
else
|
||||
saved = @my_module.save
|
||||
|
||||
if saved
|
||||
if description_changed
|
||||
log_activity(:change_module_description)
|
||||
TinyMceAsset.update_images(@my_module, params[:tiny_mce_images], current_user)
|
||||
end
|
||||
|
||||
if due_date_changes
|
||||
# rubocop:disable Metrics/BlockNesting # temporary solution
|
||||
type_of = if due_date_changes[0].nil? # set due_date
|
||||
message_items = { my_module_duedate: @my_module.due_date }
|
||||
:set_task_due_date
|
||||
elsif due_date_changes[1].nil? # remove due_date
|
||||
message_items = { my_module_duedate: due_date_changes[0] }
|
||||
:remove_task_due_date
|
||||
else # change due_date
|
||||
message_items = { my_module_duedate: @my_module.due_date }
|
||||
:change_task_due_date
|
||||
end
|
||||
# rubocop:enable Metrics/BlockNesting
|
||||
log_activity(type_of, @my_module, message_items)
|
||||
end
|
||||
log_start_date_change_activity(start_date_changes) if start_date_changes.present?
|
||||
log_due_date_change_activity(due_date_changes) if due_date_changes.present?
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
|
@ -199,7 +179,7 @@ class MyModulesController < ApplicationController
|
|||
redirect_to module_archive_experiment_path(@my_module.experiment)
|
||||
end
|
||||
elsif saved
|
||||
format.json {
|
||||
format.json do
|
||||
alerts = []
|
||||
alerts << 'alert-green' if @my_module.completed?
|
||||
unless @my_module.completed?
|
||||
|
@ -208,6 +188,10 @@ class MyModulesController < ApplicationController
|
|||
end
|
||||
render json: {
|
||||
status: :ok,
|
||||
start_date_label: render_to_string(
|
||||
partial: 'my_modules/start_date_label.html.erb',
|
||||
locals: { my_module: @my_module }
|
||||
),
|
||||
due_date_label: render_to_string(
|
||||
partial: 'my_modules/due_date_label.html.erb',
|
||||
locals: { my_module: @my_module }
|
||||
|
@ -226,12 +210,12 @@ class MyModulesController < ApplicationController
|
|||
),
|
||||
alerts: alerts
|
||||
}
|
||||
}
|
||||
end
|
||||
else
|
||||
format.json {
|
||||
format.json do
|
||||
render json: @my_module.errors,
|
||||
status: :unprocessable_entity
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -725,8 +709,46 @@ class MyModulesController < ApplicationController
|
|||
end
|
||||
|
||||
def my_module_params
|
||||
params.require(:my_module).permit(:name, :description, :due_date,
|
||||
:archived)
|
||||
update_params = params.require(:my_module).permit(:name, :description, :started_on, :due_date, :archived)
|
||||
|
||||
if update_params[:started_on].present?
|
||||
update_params[:started_on] =
|
||||
Time.zone.strptime(update_params[:started_on], I18n.backend.date_format.dup.gsub(/%-/, '%') + ' %H:%M')
|
||||
end
|
||||
if update_params[:due_date].present?
|
||||
update_params[:due_date] =
|
||||
Time.zone.strptime(update_params[:due_date], I18n.backend.date_format.dup.gsub(/%-/, '%') + ' %H:%M')
|
||||
end
|
||||
|
||||
update_params
|
||||
end
|
||||
|
||||
def log_start_date_change_activity(start_date_changes)
|
||||
type_of = if start_date_changes[0].nil? # set started_on
|
||||
message_items = { my_module_started_on: @my_module.due_date }
|
||||
:set_task_start_date
|
||||
elsif start_date_changes[1].nil? # remove started_on
|
||||
message_items = { my_module_started_on: start_date_changes[0] }
|
||||
:remove_task_start_date
|
||||
else # change started_on
|
||||
message_items = { my_module_started_on: @my_module.due_date }
|
||||
:change_task_start_date
|
||||
end
|
||||
log_activity(type_of, @my_module, message_items)
|
||||
end
|
||||
|
||||
def log_due_date_change_activity(due_date_changes)
|
||||
type_of = if due_date_changes[0].nil? # set due_date
|
||||
message_items = { my_module_duedate: @my_module.due_date }
|
||||
:set_task_due_date
|
||||
elsif due_date_changes[1].nil? # remove due_date
|
||||
message_items = { my_module_duedate: due_date_changes[0] }
|
||||
:remove_task_due_date
|
||||
else # change due_date
|
||||
message_items = { my_module_duedate: @my_module.due_date }
|
||||
:change_task_due_date
|
||||
end
|
||||
log_activity(type_of, @my_module, message_items)
|
||||
end
|
||||
|
||||
def log_activity(type_of, my_module = nil, message_items = {})
|
||||
|
@ -747,5 +769,4 @@ class MyModulesController < ApplicationController
|
|||
:page, :starting_timestamp, :from_date, :to_date, types: [], users: [], subjects: {}
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -22,18 +22,9 @@ module BootstrapFormHelper
|
|||
def datetime_picker(name, options = {})
|
||||
id = "#{@object_name}_#{name.to_s}"
|
||||
input_name = "#{@object_name}[#{name.to_s}]"
|
||||
date_format = I18n.backend.date_format.dup
|
||||
value = options[:value] ? options[:value].strftime(date_format + ' %H:%M') : ''
|
||||
value = options[:value] ? options[:value].strftime("#{I18n.backend.date_format} %H:%M") : ''
|
||||
js_locale = I18n.locale.to_s
|
||||
js_format = date_format
|
||||
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 << ' HH:mm' if options[:time] == true
|
||||
js_format = options[:time] ? datetime_picker_format_full : datetime_picker_format_date_only
|
||||
|
||||
label = options[:label] || name.to_s.humanize
|
||||
|
||||
|
@ -266,4 +257,24 @@ module BootstrapFormHelper
|
|||
text_area(name, options)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns date only format string for Bootstrap DateTimePicker
|
||||
def datetime_picker_format_date_only
|
||||
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
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ module Api
|
|||
module V1
|
||||
class TaskSerializer < ActiveModel::Serializer
|
||||
type :tasks
|
||||
attributes :id, :name, :due_date, :description, :state, :archived
|
||||
attributes :id, :name, :started_on, :due_date, :description, :state, :archived
|
||||
has_many :output_tasks, key: :outputs,
|
||||
serializer: TaskSerializer,
|
||||
class_name: 'MyModule'
|
||||
|
|
|
@ -6,16 +6,5 @@
|
|||
</div>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
<%
|
||||
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')
|
||||
%>
|
||||
|
||||
var formatJS = "<%= js_format %>"
|
||||
var formatJS = "<%= datetime_picker_format_date_only %>"
|
||||
</script>
|
||||
|
|
|
@ -4,20 +4,11 @@
|
|||
<% end %>
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input type="datetime" class="form-control calendar-input" name="calendar[<%= id %>]" id="calendar-<%= id %>" readonly="" data-ts="" placeholder="<%= placeholder %>" value="<%= defined?(setDate) ? setDate : '' %>"/>
|
||||
<%
|
||||
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')
|
||||
%>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var dt = $('#calendar-<%= id %>');
|
||||
dt.datetimepicker({ useCurrent: <%= use_current %>, ignoreReadonly: true, locale: '<%= I18n.locale %>', format: '<%= js_format %>' });
|
||||
dt.datetimepicker({ useCurrent: <%= use_current %>, ignoreReadonly: true, locale: '<%= I18n.locale %>', format: '<%= datetime_picker_format_date_only %>' });
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
|
|
|
@ -1,33 +1,23 @@
|
|||
<span class="date-text" data-editable="<%= can_manage_module?(my_module) %>">
|
||||
<span id="due-date-label-container" class="view-block">
|
||||
<% my_module_editable = can_manage_module?(my_module) %>
|
||||
|
||||
<span class="date-text" data-editable="<%= my_module_editable %>">
|
||||
<span id="dueDateLabelContainer" class="view-block">
|
||||
<%= render partial: "due_date_label.html.erb" , locals: { my_module: my_module } %>
|
||||
</span>
|
||||
<% if can_manage_module?(my_module) %>
|
||||
<% if my_module_editable %>
|
||||
<div class="datetime-picker-container" id="due-date">
|
||||
<%
|
||||
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 << ' HH:mm'
|
||||
%>
|
||||
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="calendar-due-date"
|
||||
<input id="calendarDueDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('experiments.canvas.full_zoom.no_due_date') %>"
|
||||
data-date-format="<%= js_format %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value="<%= my_module.due_date ? l(my_module.due_date, format: :full) : '' %>"/>
|
||||
</div>
|
||||
<span class="fas fa-times clear-date" data-toggle='clear-date-time-picker' data-target='calendar-due-date'></span>
|
||||
<span class="fas fa-times clear-date" data-toggle='clear-date-time-picker' data-target='calendarDueDate'></span>
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
23
app/views/my_modules/_module_header_start_date.html.erb
Normal file
23
app/views/my_modules/_module_header_start_date.html.erb
Normal file
|
@ -0,0 +1,23 @@
|
|||
<% my_module_editable = can_manage_module?(my_module) %>
|
||||
|
||||
<span class="date-text" data-editable="<%= my_module_editable %>">
|
||||
<span id="startDateLabelContainer" class="view-block">
|
||||
<%= render partial: "start_date_label.html.erb" , locals: { my_module: my_module } %>
|
||||
</span>
|
||||
<% if my_module_editable %>
|
||||
<div class="datetime-picker-container" id="start-date">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="calendarStartDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('my_modules.module_header.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>
|
||||
<span class="fas fa-times clear-date" data-toggle='clear-date-time-picker' data-target='calendarStartDate'></span>
|
||||
<% end %>
|
||||
</span>
|
|
@ -1,18 +1,20 @@
|
|||
<% my_module_editable = can_manage_module?(@my_module) %>
|
||||
|
||||
<div class="header-container">
|
||||
|
||||
<div class="flex-block date-block">
|
||||
<div class="flex-block-label">
|
||||
<span class="fas block-icon fa-calendar-alt"></span>
|
||||
<span class="hidden-xs hidden-sm hidden-md"><%=t "my_modules.module_header.start_date" %></span>
|
||||
<span class="fas block-icon fa-calendar-alt"></span>
|
||||
<span class="hidden-xs hidden-sm hidden-md"><%= t('my_modules.module_header.start_date') %></span>
|
||||
<div id="startDateContainer" class="datetime-container" data-update-url="<%= my_module_path(@my_module, format: :json) %>">
|
||||
<%= render partial: "module_header_start_date.html.erb", locals: { my_module: @my_module } %>
|
||||
</div>
|
||||
<strong><%= l(@my_module.created_at, format: :full) %></strong>
|
||||
</div>
|
||||
|
||||
<div class="flex-block date-block" >
|
||||
<span class="fas block-icon fa-calendar-alt"></span>
|
||||
<span class="hidden-xs hidden-sm hidden-md"><%=t "my_modules.module_header.due_date" %></span>
|
||||
<div class="due-date-container" data-update-url="<%= my_module_path(@my_module, format: :json) %>">
|
||||
<%= render partial: "module_header_due_date.html.erb",
|
||||
locals: { my_module: @my_module } %>
|
||||
<span class="hidden-xs hidden-sm hidden-md"><%= t('my_modules.module_header.due_date') %></span>
|
||||
<div id="dueDateContainer" class="datetime-container" data-update-url="<%= my_module_path(@my_module, format: :json) %>">
|
||||
<%= render partial: "module_header_due_date.html.erb", locals: { my_module: @my_module } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -36,7 +38,7 @@
|
|||
<div id="module-tags" data-module-tags-url="<%= my_module_my_module_tags_url(@my_module, format: :json) %>">
|
||||
<span class="fas block-icon fa-tags"></span>
|
||||
<span class="hidden-xs hidden-sm tags-title"><%=t "my_modules.module_header.tags" %></span>
|
||||
<%= render partial: "my_modules/tags", locals: { my_module: @my_module, editable: can_manage_module?(@my_module) } %>
|
||||
<%= render partial: "my_modules/tags", locals: { my_module: @my_module, editable: my_module_editable } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
7
app/views/my_modules/_start_date_label.html.erb
Normal file
7
app/views/my_modules/_start_date_label.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<span class="start-date-label">
|
||||
<% if my_module.started_on.present? %>
|
||||
<strong><%= l(my_module.started_on, format: :full) %></strong>
|
||||
<% else %>
|
||||
<%= t('my_modules.module_header.no_start_date') %>
|
||||
<% end %>
|
||||
</span>
|
|
@ -24,6 +24,13 @@
|
|||
<% end %>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="pull-right module-start-date">
|
||||
<% if my_module.started_on.present? %>
|
||||
<%= t('projects.reports.elements.module.started_on', start_date: l(my_module.started_on, format: :full)) %>
|
||||
<% else %>
|
||||
<em><%=t "projects.reports.elements.module.no_start_date" %></em>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pull-right module-due-date">
|
||||
<% if my_module.due_date.present? %>
|
||||
<%=t "projects.reports.elements.module.due_date", due_date: l(my_module.due_date, format: :full) %>
|
||||
|
|
|
@ -188,16 +188,5 @@
|
|||
<%= javascript_pack_tag 'emoji_button' %>
|
||||
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
<%
|
||||
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')
|
||||
%>
|
||||
|
||||
var formatJS = "<%= js_format %>"
|
||||
var formatJS = "<%= datetime_picker_format_date_only %>"
|
||||
</script>
|
||||
|
|
|
@ -279,7 +279,10 @@ class Extends
|
|||
share_inventory_with_all: 134,
|
||||
unshare_inventory_with_all: 135,
|
||||
update_share_with_all_permission_level: 136,
|
||||
protocol_description_in_task_edited: 137
|
||||
protocol_description_in_task_edited: 137,
|
||||
set_task_start_date: 138,
|
||||
change_task_start_date: 139,
|
||||
remove_task_start_date: 140
|
||||
}
|
||||
|
||||
ACTIVITY_GROUPS = {
|
||||
|
|
|
@ -500,6 +500,8 @@ en:
|
|||
title: "Report for project %{project}"
|
||||
module:
|
||||
user_time: "Task created on %{timestamp}."
|
||||
started_on: "Start date: %{started_on}"
|
||||
no_start_date: "No start date"
|
||||
due_date: "Due date: %{due_date}"
|
||||
no_due_date: "No due date"
|
||||
no_description: "No description"
|
||||
|
@ -637,6 +639,8 @@ en:
|
|||
restored_flash: "Task %{module} restored successfully!"
|
||||
module_header:
|
||||
start_date: "Start date:"
|
||||
no_start_date: "not set"
|
||||
no_start_date_placeholder: "+ Add starting date"
|
||||
due_date: "Due date:"
|
||||
tags: "Tags:"
|
||||
no_tags: "Add new Task Tags (optional)"
|
||||
|
|
|
@ -100,6 +100,9 @@ en:
|
|||
rename_task_html: "%{user} renamed task %{my_module}."
|
||||
move_task_html: "%{user} moved task %{my_module} from experiment %{experiment_original} to experiment %{experiment_new}."
|
||||
archive_module_html: "%{user} archived task %{my_module}."
|
||||
set_task_start_date_html: "%{user} set due date %{my_module_started_on} on task %{my_module}."
|
||||
change_task_start_date_html: "%{user} changed start date %{my_module_started_on} on task %{my_module}."
|
||||
remove_task_start_date_html: "%{user} removed start date %{my_module_started_on} on task %{my_module}."
|
||||
set_task_due_date_html: "%{user} set due date %{my_module_duedate} on task %{my_module}."
|
||||
change_task_due_date_html: "%{user} changed due date %{my_module_duedate} on task %{my_module}."
|
||||
remove_task_due_date_html: "%{user} removed due date %{my_module_duedate} on task %{my_module}."
|
||||
|
|
7
db/migrate/20200326114643_add_start_date_to_task.rb
Normal file
7
db/migrate/20200326114643_add_start_date_to_task.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddStartDateToTask < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
add_column :my_modules, :started_on, :datetime, null: true
|
||||
end
|
||||
end
|
|
@ -667,7 +667,8 @@ CREATE TABLE public.my_modules (
|
|||
workflow_order integer DEFAULT '-1'::integer NOT NULL,
|
||||
experiment_id bigint DEFAULT 0 NOT NULL,
|
||||
state smallint DEFAULT 0,
|
||||
completed_on timestamp without time zone
|
||||
completed_on timestamp without time zone,
|
||||
started_on timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
|
@ -7167,6 +7168,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20191210103004'),
|
||||
('20191218072619'),
|
||||
('20200113143828'),
|
||||
('20200204100934');
|
||||
('20200204100934'),
|
||||
('20200326114643');
|
||||
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ describe MyModule, type: :model do
|
|||
it { should have_db_column :experiment_id }
|
||||
it { should have_db_column :state }
|
||||
it { should have_db_column :completed_on }
|
||||
it { should have_db_column :started_on }
|
||||
end
|
||||
|
||||
describe 'Relations' do
|
||||
|
|
Loading…
Add table
Reference in a new issue