mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-21 15:36:22 +08:00
Merge pull request #2413 from aignatov-bio/ai-sci-4350-dashboard-current-tasks-filters
Dashboard current tasks fitler [SCI-4350]
This commit is contained in:
commit
57c665dbdd
|
@ -45,6 +45,7 @@
|
||||||
//= require marvinjslauncher
|
//= require marvinjslauncher
|
||||||
//= require_tree ./repositories/renderers
|
//= require_tree ./repositories/renderers
|
||||||
//= require_directory ./repositories/validators
|
//= require_directory ./repositories/validators
|
||||||
|
//= require_directory ./dashboard
|
||||||
//= require_directory ./sitewide
|
//= require_directory ./sitewide
|
||||||
//= require turbolinks
|
//= require turbolinks
|
||||||
|
|
||||||
|
|
88
app/assets/javascripts/dashboard/current_tasks.js
Normal file
88
app/assets/javascripts/dashboard/current_tasks.js
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/* global dropdownSelector */
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
|
||||||
|
var DasboardCurrentTasksWidget = (function() {
|
||||||
|
function initFilters() {
|
||||||
|
var sortFilter = '.curent-tasks-filters .sort-filter';
|
||||||
|
var viewFilter = '.curent-tasks-filters .view-filter';
|
||||||
|
var projectFilter = '.curent-tasks-filters .project-filter';
|
||||||
|
var experimentFilter = '.curent-tasks-filters .experiment-filter';
|
||||||
|
|
||||||
|
$('.curent-tasks-filters .clear-button').click(() => {
|
||||||
|
dropdownSelector.selectValue(sortFilter, 'date_asc');
|
||||||
|
dropdownSelector.selectValue(viewFilter, 'active');
|
||||||
|
dropdownSelector.clearData(projectFilter);
|
||||||
|
dropdownSelector.clearData(experimentFilter);
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdownSelector.init(sortFilter, {
|
||||||
|
noEmptyOption: true,
|
||||||
|
singleSelect: true,
|
||||||
|
closeOnSelect: true,
|
||||||
|
selectAppearance: 'simple',
|
||||||
|
disableSearch: true
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdownSelector.init(viewFilter, {
|
||||||
|
noEmptyOption: true,
|
||||||
|
singleSelect: true,
|
||||||
|
closeOnSelect: true,
|
||||||
|
selectAppearance: 'simple',
|
||||||
|
disableSearch: true
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdownSelector.init(projectFilter, {
|
||||||
|
singleSelect: true,
|
||||||
|
closeOnSelect: true,
|
||||||
|
emptyOptionAjax: true,
|
||||||
|
selectAppearance: 'simple',
|
||||||
|
ajaxParams: (params) => {
|
||||||
|
params.mode = 'team';
|
||||||
|
return params;
|
||||||
|
},
|
||||||
|
onChange: () => {
|
||||||
|
var selectedValue = dropdownSelector.getValues(projectFilter);
|
||||||
|
if (selectedValue > 0) {
|
||||||
|
dropdownSelector.enableSelector(experimentFilter);
|
||||||
|
} else {
|
||||||
|
dropdownSelector.disableSelector(experimentFilter);
|
||||||
|
}
|
||||||
|
dropdownSelector.clearData(experimentFilter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdownSelector.init(experimentFilter, {
|
||||||
|
singleSelect: true,
|
||||||
|
closeOnSelect: true,
|
||||||
|
emptyOptionAjax: true,
|
||||||
|
selectAppearance: 'simple',
|
||||||
|
ajaxParams: (params) => {
|
||||||
|
params.mode = 'team';
|
||||||
|
params.project_id = dropdownSelector.getValues(projectFilter);
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.curent-tasks-filters').click((e) => {
|
||||||
|
// Prevent filter window close
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
dropdownSelector.closeDropdown(sortFilter);
|
||||||
|
dropdownSelector.closeDropdown(viewFilter);
|
||||||
|
dropdownSelector.closeDropdown(projectFilter);
|
||||||
|
dropdownSelector.closeDropdown(experimentFilter);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: () => {
|
||||||
|
if ($('.current-tasks-widget').length) {
|
||||||
|
initFilters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
$(document).on('turbolinks:load', function() {
|
||||||
|
DasboardCurrentTasksWidget.init();
|
||||||
|
});
|
|
@ -380,7 +380,7 @@ var dropdownSelector = (function() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// on Close we blur search field
|
// on Close we blur search field
|
||||||
dropdownContainer.find('.search-field').blur();
|
dropdownContainer.find('.search-field').blur().val('');
|
||||||
|
|
||||||
// onClose event
|
// onClose event
|
||||||
if (config.onClose) {
|
if (config.onClose) {
|
||||||
|
@ -506,7 +506,7 @@ var dropdownSelector = (function() {
|
||||||
container.find('.dropdown-group, .dropdown-option, .empty-dropdown, .delimiter').remove();
|
container.find('.dropdown-group, .dropdown-option, .empty-dropdown, .delimiter').remove();
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
if (data.length > 0) {
|
if (data.length > 0 && !(data.length === 1 && data[0].value === '')) {
|
||||||
// If we use select-by-group option we need first draw groups
|
// If we use select-by-group option we need first draw groups
|
||||||
if (selector.data('select-by-group')) {
|
if (selector.data('select-by-group')) {
|
||||||
$.each(data, function(gi, group) {
|
$.each(data, function(gi, group) {
|
||||||
|
@ -681,7 +681,7 @@ var dropdownSelector = (function() {
|
||||||
// If we have alteast one tag, we need to remove placeholder from search field
|
// If we have alteast one tag, we need to remove placeholder from search field
|
||||||
if (selector.data('config').selectAppearance === 'simple') {
|
if (selector.data('config').selectAppearance === 'simple') {
|
||||||
let selectedLabel = container.find('.tag-label');
|
let selectedLabel = container.find('.tag-label');
|
||||||
container.find('.search-field').attr('placeholder',
|
container.find('.search-field').prop('placeholder',
|
||||||
selectedLabel.length && selectedLabel.text().trim() !== '' ? selectedLabel.text().trim() : selector.data('placeholder'));
|
selectedLabel.length && selectedLabel.text().trim() !== '' ? selectedLabel.text().trim() : selector.data('placeholder'));
|
||||||
} else {
|
} else {
|
||||||
searchFieldValue.attr('placeholder',
|
searchFieldValue.attr('placeholder',
|
||||||
|
@ -741,14 +741,14 @@ var dropdownSelector = (function() {
|
||||||
ajaxParams = customParams ? customParams(defaultParams) : defaultParams;
|
ajaxParams = customParams ? customParams(defaultParams) : defaultParams;
|
||||||
|
|
||||||
$.get(selector.data('ajax-url'), ajaxParams, (data) => {
|
$.get(selector.data('ajax-url'), ajaxParams, (data) => {
|
||||||
var optionsAjax = data;
|
var optionsAjax = data.constructor === Array ? data : [];
|
||||||
if (selector.data('config').emptyOptionAjax) {
|
if (selector.data('config').emptyOptionAjax) {
|
||||||
optionsAjax = [{
|
optionsAjax = [{
|
||||||
label: '',
|
label: selector.data('placeholder') || '',
|
||||||
value: '',
|
value: '',
|
||||||
group: null,
|
group: null,
|
||||||
params: {}
|
params: {}
|
||||||
}].concat(data);
|
}].concat(optionsAjax);
|
||||||
}
|
}
|
||||||
loadData(selector, container, optionsAjax);
|
loadData(selector, container, optionsAjax);
|
||||||
PerfectSb().update_all();
|
PerfectSb().update_all();
|
||||||
|
@ -837,7 +837,21 @@ var dropdownSelector = (function() {
|
||||||
setData: function(selector, data) {
|
setData: function(selector, data) {
|
||||||
if ($(selector).length === 0) return false;
|
if ($(selector).length === 0) return false;
|
||||||
|
|
||||||
setData($(selector), []);
|
setData($(selector), data);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Select value
|
||||||
|
selectValue: function(selector, value) {
|
||||||
|
var $selector;
|
||||||
|
var option;
|
||||||
|
|
||||||
|
if ($(selector).length === 0) return false;
|
||||||
|
|
||||||
|
$selector = $(selector);
|
||||||
|
option = $selector.find(`option[value="${value}"]`)[0];
|
||||||
|
setData($selector, [convertOptionToJson(option)]);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,60 @@
|
||||||
|
// scss-lint:disable SelectorDepth
|
||||||
|
// scss-lint:disable NestingDepth
|
||||||
|
|
||||||
.dashboard-container .current-tasks-widget {
|
.dashboard-container .current-tasks-widget {
|
||||||
grid-column: 1 / span 9;
|
grid-column: 1 / span 9;
|
||||||
grid-row: 1 / span 6;
|
grid-row: 1 / span 6;
|
||||||
|
|
||||||
|
.filter-container {
|
||||||
|
height: 36px;
|
||||||
|
width: 36px;
|
||||||
|
|
||||||
|
.curent-tasks-filters {
|
||||||
|
padding: 0;
|
||||||
|
width: 230px;
|
||||||
|
|
||||||
|
.header {
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: $border-default;
|
||||||
|
display: flex;
|
||||||
|
height: 44px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 0 5px 0 16px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
@include font-h2;
|
||||||
|
flex-grow: 1;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-block {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 16px 16px;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
label {
|
||||||
|
@include font-small;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
align-items: center;
|
||||||
|
border-top: $border-default;
|
||||||
|
display: flex;
|
||||||
|
height: 68px;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-field {
|
.search-field {
|
||||||
|
@include font-button;
|
||||||
border: 0;
|
border: 0;
|
||||||
flex-basis: 0;
|
flex-basis: 0;
|
||||||
flex-grow: 2000;
|
flex-grow: 2000;
|
||||||
|
@ -95,6 +96,10 @@
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: auto;
|
width: auto;
|
||||||
|
|
||||||
|
&[data-ds-tag-id=""] {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fas {
|
.fas {
|
||||||
|
@ -108,6 +113,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-container {
|
.dropdown-container {
|
||||||
|
@include font-button;
|
||||||
background: $color-white;
|
background: $color-white;
|
||||||
border: 1px solid $color-alto;
|
border: 1px solid $color-alto;
|
||||||
border-radius: 0 0 4px 4px;
|
border-radius: 0 0 4px 4px;
|
||||||
|
@ -163,11 +169,15 @@
|
||||||
background: $color-concrete;
|
background: $color-concrete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[data-value=""] {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
&.select {
|
&.select {
|
||||||
background: $brand-primary;
|
background: $brand-primary;
|
||||||
color: $color-white;
|
color: $color-white;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-icon {
|
.checkbox-icon {
|
||||||
|
@ -267,6 +277,10 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&[data-ds-tag-id=""] {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-times {
|
.fa-times {
|
||||||
|
|
32
app/controllers/dashboard/current_tasks_controller.rb
Normal file
32
app/controllers/dashboard/current_tasks_controller.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Dashboard
|
||||||
|
class CurrentTasksController < ApplicationController
|
||||||
|
include InputSanitizeHelper
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def project_filter
|
||||||
|
projects = current_team.projects.search(current_user, false, params[:query], 1, current_team).select(:id, :name)
|
||||||
|
unless params[:mode] == 'team'
|
||||||
|
projects = projects.where(id: current_user.my_modules.joins(:experiment)
|
||||||
|
.group(:project_id).select(:project_id).pluck(:project_id))
|
||||||
|
end
|
||||||
|
render json: projects.map { |i| { value: i.id, label: escape_input(i.name) } }, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def experiment_filter
|
||||||
|
project = current_team.projects.find_by(id: params[:project_id])
|
||||||
|
unless project
|
||||||
|
render json: []
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
experiments = project.experiments.search(current_user, false, params[:query], 1, current_team).select(:id, :name)
|
||||||
|
unless params[:mode] == 'team'
|
||||||
|
experiments = experiments.where(id: current_user.my_modules
|
||||||
|
.group(:experiment_id).select(:experiment_id).pluck(:experiment_id))
|
||||||
|
end
|
||||||
|
render json: experiments.map { |i| { value: i.id, label: escape_input(i.name) } }, status: :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,2 +1,44 @@
|
||||||
<div class="current-tasks-widget basic-widget">
|
<div class="current-tasks-widget basic-widget">
|
||||||
|
<div class="filter-container dropdown">
|
||||||
|
<div class="btn btn-light icon-btn filter-button" data-toggle="dropdown"><i class="fas fa-filter"></i></div>
|
||||||
|
<div class="dropdown-menu curent-tasks-filters" role="menu">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title"><%= t("dashboard.current_tasks.filter.title") %></div>
|
||||||
|
<div class="btn btn-light clear-button"><i class="fas fa-times-circle"></i><%= t("dashboard.current_tasks.filter.clear") %></div>
|
||||||
|
</div>
|
||||||
|
<div class="select-block">
|
||||||
|
<label><%= t("dashboard.current_tasks.filter.sort") %></label>
|
||||||
|
<select class="sort-filter">
|
||||||
|
<option value="date_asc" ><%= t("dashboard.current_tasks.filter.date_asc") %></option>
|
||||||
|
<option value="date_desc" ><%= t("dashboard.current_tasks.filter.date_desc") %></option>
|
||||||
|
<option value="atoz" ><%= t("dashboard.current_tasks.filter.atoz") %></option>
|
||||||
|
<option value="ztoa" ><%= t("dashboard.current_tasks.filter.ztoa") %></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="select-block">
|
||||||
|
<label><%= t("dashboard.current_tasks.filter.display") %></label>
|
||||||
|
<select class="view-filter">
|
||||||
|
<option value="active" ><%= t("dashboard.current_tasks.filter.active_tasks") %></option>
|
||||||
|
<option value="completed" ><%= t("dashboard.current_tasks.filter.locked_tasks") %></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="select-block">
|
||||||
|
<label><%= t("dashboard.current_tasks.filter.project") %></label>
|
||||||
|
<select class="project-filter"
|
||||||
|
data-ajax-url="<%= project_filter_dashboard_current_tasks_path %>"
|
||||||
|
data-placeholder="<%= t("dashboard.current_tasks.filter.select_project") %>"></select>
|
||||||
|
</div>
|
||||||
|
<div class="select-block">
|
||||||
|
<label><%= t("dashboard.current_tasks.filter.experiment") %></label>
|
||||||
|
<select class="experiment-filter"
|
||||||
|
data-ajax-url="<%= experiment_filter_dashboard_current_tasks_path %>"
|
||||||
|
data-disable-on-load="true"
|
||||||
|
data-disable-placeholder="<%= t("dashboard.current_tasks.filter.select_experiment") %>"
|
||||||
|
data-placeholder="<%= t("dashboard.current_tasks.filter.select_experiment") %>"></select>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="btn btn-primary"><%= t("dashboard.current_tasks.filter.apply") %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
19
config/locales/dashboard/en.yml
Normal file
19
config/locales/dashboard/en.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
en:
|
||||||
|
dashboard:
|
||||||
|
current_tasks:
|
||||||
|
filter:
|
||||||
|
title: "Filters"
|
||||||
|
clear: "Clear"
|
||||||
|
sort: "Sort by"
|
||||||
|
date_asc: "Due Date Ascending"
|
||||||
|
date_desc: "Due Date Descending"
|
||||||
|
atoz: "From A to Z"
|
||||||
|
ztoa: "From Z to A"
|
||||||
|
display: "Display"
|
||||||
|
active_tasks: "Only active tasks"
|
||||||
|
locked_tasks: "Only completed and locked tasks"
|
||||||
|
project: "Project"
|
||||||
|
select_project: "Select Project"
|
||||||
|
experiment: "Experiment"
|
||||||
|
select_experiment: "Select Experiment"
|
||||||
|
apply: "Apply"
|
|
@ -241,6 +241,10 @@ Rails.application.routes.draw do
|
||||||
post 'reports/destroy', to: 'reports#destroy'
|
post 'reports/destroy', to: 'reports#destroy'
|
||||||
|
|
||||||
resource :dashboard, only: :show do
|
resource :dashboard, only: :show do
|
||||||
|
resource :current_tasks, module: 'dashboard', only: :show do
|
||||||
|
get :project_filter
|
||||||
|
get :experiment_filter
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :projects, except: [:new, :destroy] do
|
resources :projects, except: [:new, :destroy] do
|
||||||
|
|
Loading…
Reference in a new issue