diff --git a/app/assets/javascripts/dashboard/current_tasks.js b/app/assets/javascripts/dashboard/current_tasks.js index 88bbf0a97..b5954d4a2 100644 --- a/app/assets/javascripts/dashboard/current_tasks.js +++ b/app/assets/javascripts/dashboard/current_tasks.js @@ -1,4 +1,4 @@ -/* global dropdownSelector I18n animateSpinner PerfectSb InfiniteScroll */ +/* global dropdownSelector animateSpinner PerfectSb InfiniteScroll */ /* eslint-disable no-param-reassign */ var DasboardCurrentTasksWidget = (function() { @@ -11,15 +11,14 @@ var DasboardCurrentTasksWidget = (function() { $.each(json.data, (i, task) => { var currentTaskItem = `
${task.project}/${task.experiment}
-
-
${task.name}
-
- ${I18n.t('dashboard.current_tasks.due_date', { date: task.due_date })} -
-
-
-
${task.state.text}
-
+
${task.name}
+
+ + ${task.due_date.text} + +
+
+ ${task.status_name}
`; $(container).append(currentTaskItem); diff --git a/app/assets/stylesheets/dashboard/current_tasks.scss b/app/assets/stylesheets/dashboard/current_tasks.scss index ae83941f0..38a171da5 100644 --- a/app/assets/stylesheets/dashboard/current_tasks.scss +++ b/app/assets/stylesheets/dashboard/current_tasks.scss @@ -133,28 +133,33 @@ } } - .current-tasks-list { - display: flex; - flex-direction: column; + .current-tasks-list-wrapper { height: 100%; overflow-y: auto; - padding: 0 10px; position: relative; + } + + .current-tasks-list { + align-items: center; + display: grid; + grid-template-columns: auto max-content max-content; + padding: 0 1em; &.disabled { pointer-events: none; } .current-task-item { - border-bottom: $border-tertiary; color: $color-volcano; - padding: 6px; + display: contents; text-decoration: none; .current-task-breadcrumbs { @include font-small; color: $color-silver-chalice; + grid-column: 1 / span 3; line-height: 14px; + margin-top: .5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -166,39 +171,54 @@ } } - .item-row { - display: flex; + .row-border { + border-bottom: $border-tertiary; + height: 32px; + line-height: 24px; + padding-bottom: 8px; + } - .task-name { - flex-grow: 1; - font-size: $font-size-base; - font-weight: bold; - overflow: hidden; - padding-right: 10px; - text-overflow: ellipsis; - white-space: nowrap; + .task-name { + flex-grow: 1; + font-size: $font-size-base; + font-weight: bold; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .task-due-date { + flex-basis: 280px; + flex-shrink: 0; + padding: 0 2em 0 1em; + + .fas { + padding: 4px; } - .task-due-date { - flex-basis: 280px; - flex-shrink: 0; - font-size: 14px; + &.overdue { + color: $brand-danger; + } - .fas { - padding: 4px; - } + &.day-prior { + color: $brand-warning; + } - &.overdue { - color: $brand-danger; - } + &.completed { + color: $brand-success; + } + } - &.day-prior { - color: $brand-warning; - } + .task-status-container { + grid-column: 3; + text-align: right; - &.completed { - color: $brand-success; - } + .task-status { + @include font-small; + border-radius: $border-radius-tag; + color: $color-white; + font-weight: bold; + padding: .25em .5em; } } @@ -207,93 +227,6 @@ } } } - - .task-progress-container { - height: 20px; - max-width: 250px; - min-width: 150px; - position: relative; - width: 100%; - - &::after { - @include font-small; - @include font-awesome; - content: ""; - line-height: 18px; - position: absolute; - right: 8px; - top: 1px; - } - - .task-progress { - background: $brand-focus-light; - border: $border-tertiary; - border-radius: $border-radius-tag; - display: flex; - height: 20px; - position: relative; - - &::after { - background: $color-white; - content: ""; - height: 18px; - width: 100%; - } - } - - .task-progress-label { - @include font-small; - font-weight: bold; - height: 20px; - left: 0; - line-height: 20px; - padding-left: 8px; - position: absolute; - top: 0; - width: calc(100% - 30px); - } - - &.overdue { - .task-progress { - background: $brand-danger-light; - } - - .task-progress-label { - color: $brand-danger; - } - - &::after { - color: $brand-danger; - content: $font-fas-exclamation-triangle; - } - } - - &.day-prior { - .task-progress-label { - color: $brand-warning; - } - } - - &.completed { - .task-progress { - outline: $border-success; - } - - .task-progress, - .task-progress::after { - background: $brand-success-light; - } - - .task-progress-label { - color: $brand-success; - } - - &::after { - color: $brand-success; - content: $font-fas-check; - } - } - } } @media (max-width: 1500px) { @@ -370,22 +303,33 @@ } .current-tasks-list { + grid-template-columns: auto; + .current-task-item { - .item-row { - flex-wrap: wrap; - .task-due-date { - @include font-small; + .current-task-breadcrumbs { + grid-column: 1; + } - .fas { - display: none; - } + .task-name { + border: 0; + padding: 0; + height: 1.5em; + } + + .task-due-date { + @include font-small; + border: 0; + padding-left: 0; + + .fas { + display: none; } + } - .task-progress-container { - flex-basis: 100%; - max-width: none; - } + .task-status-container { + grid-column: 1; + text-align: left; } } } diff --git a/app/controllers/dashboard/current_tasks_controller.rb b/app/controllers/dashboard/current_tasks_controller.rb index 30cd0b22a..3da93e6cf 100644 --- a/app/controllers/dashboard/current_tasks_controller.rb +++ b/app/controllers/dashboard/current_tasks_controller.rb @@ -41,7 +41,9 @@ module Dashboard end page = (params[:page] || 1).to_i - tasks = tasks.with_step_statistics.search_by_name(current_user, current_team, task_filters[:query]) + tasks = tasks.search_by_name(current_user, current_team, task_filters[:query]) + .joins(:my_module_status) + .select('my_modules.*', 'my_module_statuses.name as status_name', 'my_module_statuses.color as status_color') .preload(experiment: :project).page(page).per(Constants::INFINITE_SCROLL_LIMIT) tasks_list = tasks.map do |task| @@ -50,9 +52,9 @@ module Dashboard experiment: escape_input(task.experiment.name), project: escape_input(task.experiment.project.name), name: escape_input(task.name), - due_date: task.due_date.present? ? I18n.l(task.due_date, format: :full_date) : nil, - state: task_state(task), - steps_precentage: task.steps_completed_percentage } + due_date: prepare_due_date(task), + status_color: task.status_color, + status_name: task.status_name } end render json: { data: tasks_list, next_page: tasks.next_page } @@ -90,29 +92,26 @@ module Dashboard private - def task_state(task) - if task.state == 'completed' - task_state_class = task.state - task_state_text = t('dashboard.current_tasks.progress_bar.completed') - else - task_state_text = t('dashboard.current_tasks.progress_bar.in_progress') - task_state_class = 'day-prior' if task.is_one_day_prior? - if task.is_overdue? - task_state_text = t('dashboard.current_tasks.progress_bar.overdue') - task_state_class = 'overdue' - end - if task.steps_total.positive? - task_state_text += t('dashboard.current_tasks.progress_bar.completed_steps', - steps: task.steps_completed, total_steps: task.steps_total) - end - end - { text: task_state_text, class: task_state_class } - end - def filter_by_state(tasks) tasks.where(my_modules: { state: task_filters[:view] }) end + def prepare_due_date(task) + if task.due_date.present? + due_date_formatted = I18n.l(task.due_date, format: :full_date) + if task.is_overdue? + return { state: 'overdue', text: I18n.t('dashboard.current_tasks.due_date_overdue_html', + date: due_date_formatted) } + elsif task.is_one_day_prior? + return { state: 'day-prior', text: I18n.t('dashboard.current_tasks.due_date_html', + date: due_date_formatted) } + end + + return { state: '', text: I18n.t('dashboard.current_tasks.due_date_html', date: due_date_formatted) } + end + { state: nil, text: nil } + end + def task_filters params.permit(:project_id, :experiment_id, :mode, :view, :sort, :query, :page) end diff --git a/app/models/my_module.rb b/app/models/my_module.rb index 537999eb8..caebcffea 100644 --- a/app/models/my_module.rb +++ b/app/models/my_module.rb @@ -83,16 +83,6 @@ class MyModule < ApplicationRecord end) scope :workflow_ordered, -> { order(workflow_order: :asc) } scope :uncomplete, -> { where(state: 'uncompleted') } - scope :with_step_statistics, (lambda do - left_outer_joins(protocols: :steps) - .group(:id) - .select('my_modules.*') - .select('COUNT(steps.id) AS steps_total') - .select('COUNT(steps.id) FILTER (where steps.completed = true) AS steps_completed') - .select('CASE COUNT(steps.id) WHEN 0 THEN 0 ELSE'\ - '((COUNT(steps.id) FILTER (where steps.completed = true)) * 100 / COUNT(steps.id)) '\ - 'END AS steps_completed_percentage') - end) # A module takes this much space in canvas (x, y) in database WIDTH = 30 diff --git a/app/views/dashboards/_current_tasks.html.erb b/app/views/dashboards/_current_tasks.html.erb index 99d278056..afcc33440 100644 --- a/app/views/dashboards/_current_tasks.html.erb +++ b/app/views/dashboards/_current_tasks.html.erb @@ -59,8 +59,10 @@
-
+
+
+
@@ -80,4 +82,4 @@

<%= I18n.t('dashboard.current_tasks.no_tasks.search_result.title') %>

- \ No newline at end of file + diff --git a/config/locales/dashboard/en.yml b/config/locales/dashboard/en.yml index 0fa346e4e..0d2ba5749 100644 --- a/config/locales/dashboard/en.yml +++ b/config/locales/dashboard/en.yml @@ -30,7 +30,8 @@ en: title: "Your Team has no tasks at the moment." search_result: title: "No results." - due_date: "Due date: %{date}" + due_date_html: "Due date: %{date}" + due_date_overdue_html: "Due date: %{date} (overdue)" progress_bar: in_progress: "In progress" overdue: "Overdue"