Finished global activities refactoring

This commit is contained in:
Anton Ignatov 2019-08-09 14:31:50 +02:00 committed by aignatov-bio
parent fc70ce24f8
commit 17e457c686
9 changed files with 214 additions and 110 deletions

View file

@ -23,11 +23,20 @@ function GlobalActivitiesFiltersGetDates() {
function GlobalActivitiesFilterPrepareArray() {
var convertToInt = (array) => { return array.map(e => { return parseInt(e, 10); }); };
var typesFilter = convertToInt(dropdownSelector.getValues('select[name=activity]') || []);
var typesGroups = dropdownSelector.getValues('select[name=group_activity]') || [];
if (typesFilter.length === 0 && typesGroups.length > 0) {
$.each(typesGroups, (ig, group) => {
$.each($('select[name=activity]').find(`optgroup[label="${group}"] option`), (io, option) => {
typesFilter.push(parseInt(option.value, 10));
});
});
}
return {
teams: convertToInt(dropdownSelector.getValues('select[name=team]') || []),
users: convertToInt(dropdownSelector.getValues('select[name=user]') || []),
types: convertToInt(dropdownSelector.getValues('select[name=activity]') || []),
types: typesFilter,
subjects: {
Project: convertToInt(dropdownSelector.getValues('select[name=project]') || []),
Experiment: convertToInt(dropdownSelector.getValues('select[name=experiment]') || []),
@ -45,6 +54,12 @@ function GlobalActivitiesFilterPrepareArray() {
$(function() {
var updateRunning = false;
var filterSelectors = ['group_activity', 'activity', 'user', 'team', 'project',
'experiment', 'task', 'inventory', 'inventory-item', 'protocol', 'report'];
var clearSelectors = ['group_activity', 'activity', 'user', 'team', 'project',
'inventory', 'protocol', 'report'];
var ajaxParams = function(params) {
var filter = GlobalActivitiesFilterPrepareArray();
filter.query = params.query;
@ -70,14 +85,23 @@ $(function() {
return [];
}
});
$('.activity.clear').click(() => {
updateRunning = true;
dropdownSelector.clearData('select[name=group_activity]');
updateRunning = false;
dropdownSelector.clearData('select[name=activity]');
});
dropdownSelector.init('select[name=user]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
}).initClearButton('select[name=user]', '.user.clear');
dropdownSelector.init('select[name=team]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
}).initClearButton('select[name=team]', '.team.clear');
dropdownSelector.init('select[name=project]', {
ajaxParams: ajaxParams,
onChange: () => {
@ -90,7 +114,8 @@ $(function() {
}
defaultOnChangeActions();
}
});
}).initClearButton('select[name=project]', '.project.clear');
dropdownSelector.init('.select-container.experiment select', {
ajaxParams: ajaxParams,
onChange: () => {
@ -99,10 +124,12 @@ $(function() {
defaultOnChangeActions();
}
});
dropdownSelector.init('select[name=task]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
dropdownSelector.init('select[name=inventory]', {
ajaxParams: ajaxParams,
onChange: () => {
@ -110,24 +137,42 @@ $(function() {
dropdownSelector.disableSelector('select[name=inventory-item]', (selectedValues.length === 0));
defaultOnChangeActions();
}
});
}).initClearButton('select[name=inventory]', '.inventory.clear');
dropdownSelector.init('select[name=inventory-item]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
dropdownSelector.init('select[name=protocol]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
}).initClearButton('select[name=protocol]', '.protocol.clear');
dropdownSelector.init('select[name=report]', {
ajaxParams: ajaxParams,
onChange: defaultOnChangeActions
});
}).initClearButton('select[name=report]', '.report.clear');
$('.ga-side').scroll(() => {
var selectors = ['group_activity', 'activity', 'user', 'team', 'project',
'experiment', 'task', 'inventory', 'inventory-item', 'protocol', 'report'];
$.each(selectors, (i, selector) => { dropdownSelector.updateDropdownDirection(`select[name=${selector}]`); });
$.each(filterSelectors, (i, selector) => { dropdownSelector.updateDropdownDirection(`select[name=${selector}]`); });
});
$('.clear-container').click(() => {
var selectorsCount = $('select[name=project]').length === 1 ? clearSelectors.length - 1 : 1;
updateRunning = true;
$('#calendar-from-date').data('DateTimePicker').clear();
$('#calendar-to-date').data('DateTimePicker').clear();
$('.ga-side .date-selector.filter-block')[0].dataset.periodSelect = '';
$.each(clearSelectors, (i, selector) => {
if (i === selectorsCount) updateRunning = false;
dropdownSelector.clearData(`select[name=${selector}]`);
});
resetHotButtonsBackgroundColor();
});
function GlobalActivitiesUpdateTopPaneTags() {
@ -220,18 +265,6 @@ $(function() {
});
}
$('.ga-tags-container .clear-container span').click(function() {
updateRunning = true;
$('#calendar-from-date').data('DateTimePicker').clear();
$('#calendar-to-date').data('DateTimePicker').clear();
$('.ga-side .date-selector.filter-block')[0].dataset.periodSelect = '';
updateRunning = false;
GlobalActivitiesUpdateTopPaneTags();
reloadActivities();
resetHotButtonsBackgroundColor();
});
$('#calendar-to-date').on('dp.change', function(e) {
var dateContainer = $('.ga-side .date-selector.filter-block');
if (!updateRunning) {

View file

@ -93,7 +93,7 @@ var dropdownSelector = (function() {
var ps;
var dropdownContainer;
if (selectElement.length === 0) return;
if (selectElement.length === 0 || selectElement.next().hasClass('dropdown-selector-container')) return;
dropdownContainer = selectElement.after('<div class="dropdown-selector-container"></div>').next();
@ -103,6 +103,7 @@ var dropdownSelector = (function() {
<div class="dropdown-container"></div>
<div class="input-field">
<input type="text" class="seacrh-field" placeholder="${selectElement.data('placeholder')}"></input>
<i class="fas fa-caret-down"></i>
</div>
<input type="hidden" class="data-field" value="[]">
@ -120,7 +121,8 @@ var dropdownSelector = (function() {
saveData(selectElement, dropdownContainer);
});
}
dropdownContainer.find('.seacrh-field').keyup(() => {
dropdownContainer.find('.seacrh-field').keyup((e) => {
e.stopPropagation();
loadData(selectElement, dropdownContainer);
}).click((e) =>{
e.stopPropagation();
@ -163,6 +165,8 @@ var dropdownSelector = (function() {
// Load data to dropdown list
function loadData(selector, container, ajaxData = null) {
var data;
var containerDropdown = container.find('.dropdown-container');
containerDropdown.css('height', `${containerDropdown.height()}px`);
if (ajaxData) {
data = ajaxData;
} else {
@ -227,6 +231,7 @@ var dropdownSelector = (function() {
PerfectSb().update_all();
refreshDropdownSelection(selector, container);
containerDropdown.css('height', 'auto');
}
// Save data to local field
@ -299,7 +304,7 @@ var dropdownSelector = (function() {
updateCurrentData(container, selectedOptions);
updateTags(selector, container);
}
}, 150);
}, 300);
});
}
@ -375,17 +380,37 @@ var dropdownSelector = (function() {
return {
// Dropdown initialization
init: (selector, config) => {
init: function(selector, config) {
generateDropdown(selector, config);
return this;
},
// Clear button initialization
initClearButton: function(selector, clearButton) {
var container;
if ($(selector).length === 0) return false;
container = $(selector).next();
$(clearButton).click(() => {
updateCurrentData(container, []);
refreshDropdownSelection($(selector), container);
updateTags($(selector), container);
});
return this;
},
// Update dropdown position
updateDropdownDirection: (selector) => {
updateDropdownDirection: function(selector) {
if ($(selector).length === 0) return false;
updateDropdownDirection($(selector), $(selector).next());
return this;
},
// Get only values
getValues: (selector) => {
getValues: function(selector) {
if ($(selector).length === 0) return false;
return $.map(getCurrentData($(selector).next()), (v) => {
@ -393,24 +418,38 @@ var dropdownSelector = (function() {
});
},
// Get all data
getData: (selector) => {
getData: function(selector) {
if ($(selector).length === 0) return false;
return getCurrentData($(selector).next());
},
setData: (selector, data) => {
// Set data to selector
setData: function(selector, data) {
if ($(selector).length === 0) return false;
updateCurrentData($(selector).next(), data);
refreshDropdownSelection($(selector), $(selector).next());
updateTags($(selector), $(selector).next());
return this;
},
disableSelector: (selector, mode) => {
// Clear selector
clearData: function(selector) {
if ($(selector).length === 0) return false;
dropdownSelector.setData(selector, []);
return this;
},
// Disable selector
disableSelector: function(selector, mode) {
if ($(selector).length === 0) return false;
disableDropdown($(selector), $(selector).next(), mode);
return this;
}
};
}());

View file

@ -12,7 +12,7 @@
margin-top: 2em;
padding: 0 15px;
&.task_activities {
&.task-activities {
height: calc(100vh - 136px);
}
@ -27,6 +27,7 @@
position: relative;
width: calc(100% + 30px);
}
.ga-actions {
align-items: center;
border-bottom: 1px solid $color-gainsboro;
@ -35,8 +36,8 @@
.hide-actions {
align-items: center;
display: flex;
color: $color-silver-chalice;
display: flex;
margin-right: 20px;
&:hover {
@ -74,8 +75,8 @@
.fa-search {
color: $color-silver-chalice;
font-size: 18px;
line-height: 30px;
left: 0;
line-height: 30px;
position: absolute;
text-align: center;
top: 0;
@ -85,16 +86,17 @@
}
.ga-tags-container {
align-items: center;
display: flex;
min-height: 36px;
min-height: 38px;
padding: 5px 0;
.ga-tags {
display: flex;
display: flex;
flex-grow: 1;
flex-wrap: wrap;
&::after {
content: '';
content: "";
flex-grow: 1000000000;
}
@ -102,7 +104,7 @@
align-items: center;
background: $color-concrete;
border-radius: 12px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 1px 1px rgba(0, 0, 0, .1);
display: flex;
flex-shrink: 0;
line-height: 13px;
@ -135,7 +137,7 @@
cursor: pointer;
flex-grow: 1;
font-size: 13px;
opacity: 0.7;
opacity: .7;
text-align: right;
}
}
@ -144,6 +146,10 @@
.clear-container {
color: $color-silver-chalice;
cursor: pointer;
flex-shrink: 0;
line-height: 28px;
padding-left: 15px;
user-select: none;
.fas {
margin-right: 5px;
@ -223,14 +229,12 @@
margin: 0;
}
.atwho-user-container {
&:not(:first-child) {
.global-avatar-container {
line-height: 20px;
height: 20px;
line-height: 20px;
margin-left: 0;
position: relative;
top: 1px;
@ -292,12 +296,11 @@
height: 100%;
margin-right: -15px;
overflow: hidden;
padding: 0 15px;
padding: 0 15px 20px;
position: relative;
.filter-block {
display: inline-block;
padding: 10px 0 0;
width: 100%;
.title {
@ -325,11 +328,16 @@
margin-bottom: 5px;
min-height: 36px;
width: 100%;
select {
display: none;
}
}
}
.date-selector {
display: inline-block;
margin-bottom: 5px;
position: relative;
width: 100%;
@ -362,10 +370,6 @@
}
}
.title {
margin-top: 0;
}
.from,
.to {
float: left;

View file

@ -1,3 +1,6 @@
// scss-lint:disable SelectorDepth
// scss-lint:disable NestingDepth
@import "constants";
.dropdown-selector-container {
@ -15,11 +18,23 @@
flex-wrap: wrap;
min-height: 36px;
overflow: hidden;
padding: 3px;
padding: 3px 36px 3px 3px;
position: relative;
transition: .2s;
width: 100%;
.fa-caret-down {
color: $color-silver-chalice;
cursor: pointer;
font-size: 20px;
line-height: 18px;
position: absolute;
right: 8px;
text-align: center;
top: 8px;
width: 18px;
}
.seacrh-field {
border: 0;
flex-basis: 50px;
@ -30,7 +45,7 @@
padding-left: 5px;
&::placeholder {
opacity: 0.7;
opacity: .7;
}
}
@ -38,7 +53,7 @@
align-items: center;
background: $color-concrete;
border-radius: 12px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0 0 1px 1px rgba(0, 0, 0, .1);
display: flex;
flex-shrink: 0;
line-height: 13px;
@ -47,11 +62,6 @@
padding: 5px 7px;
user-select: none;
&.stretch {
flex-grow: 1;
flex-shrink: 1;
}
.tag-label {
display: inline-block;
margin-bottom: 1px;
@ -63,6 +73,7 @@
width: auto;
&.closing {
margin-right: 0;
max-width: 0;
}
}
@ -71,7 +82,7 @@
cursor: pointer;
flex-grow: 1;
font-size: 13px;
opacity: 0.7;
opacity: .7;
text-align: right;
}
}
@ -81,8 +92,7 @@
background: $color-white;
border: 1px solid $color-alto;
border-radius: 0 0 4px 4px;
border-top: 0;
box-shadow: 0px 0px 0px 0px rgba(0,0,0, 0.2);
box-shadow: 0 0 0 0 rgba(0, 0, 0, .2);
display: none;
overflow: hidden;
position: absolute;
@ -92,7 +102,7 @@
width: 100%;
z-index: 10;
.dropdown-select-all{
.dropdown-select-all {
background: $color-white;
border: 0;
border-bottom: 1px solid $color-alto;
@ -118,12 +128,13 @@
}
&.select {
&::before {
content: "\f14a";
}
}
}
.dropdown-option {
align-items: center;
cursor: pointer;
@ -167,8 +178,10 @@
}
&.select {
.group-name.checkbox-icon {
background: $color-concrete;
&::before {
content: "\f14a";
}
@ -188,13 +201,18 @@
&.open {
.input-field {
border-radius: 4px 4px 0 0;
border-bottom: 1px solid $brand-primary;
border-radius: 4px 4px 0 0;
z-index: 12;
.fa-caret-down {
transform: rotate(180deg);
}
}
.dropdown-container {
box-shadow: 0px 1px 2px 0px rgba(0,0,0, 0.2);
border-top: 0;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .2);
display: block;
top: 100%;
}
@ -202,15 +220,16 @@
&.inverse {
.input-field {
border-radius: 0 0 4px 4px;
border-bottom: 1px solid $color-alto;
border-top: 1px solid $brand-primary
border-radius: 0 0 4px 4px;
border-top: 1px solid $brand-primary;
}
.dropdown-container {
border-bottom: 0;
border-radius: 4px 4px 0 0;
bottom: 100%;
box-shadow: 0px -1px 2px 0px rgba(0,0,0, 0.2);
box-shadow: 0 -1px 2px 0 rgba(0, 0, 0, .2);
position: fixed;
top: auto;
}
@ -228,4 +247,4 @@
}
}
}
}
}

View file

@ -127,11 +127,12 @@ class GlobalActivitiesController < ApplicationController
matched = subject.search_by_name(current_user, teams, query, whole_phrase: true)
.where.not(name: nil).where.not(name: '')
.filter_by_teams(filter_teams)
.order(name: :asc)
selected_subject = subject_search_params[:subjects]
matched = matched.where(:project_id => selected_subject['Project']) if subject == Experiment
matched = matched.where(:experiment_id => selected_subject['Experiment']) if subject == MyModule
matched = matched.where(:repository_id => selected_subject['Repository']) if subject == RepositoryRow
matched = matched.where(project_id: selected_subject['Project']) if subject == Experiment
matched = matched.where(experiment_id: selected_subject['Experiment']) if subject == MyModule
matched = matched.where(repository_id: selected_subject['Repository']) if subject == RepositoryRow
matched = matched.limit(Constants::SEARCH_LIMIT).pluck(:id, :name)
matched.map { |pr| { value: pr[0], label: escape_input(pr[1]) } }

View file

@ -1,6 +1,6 @@
<div class="team-selector filter-block small-left">
<h4 class="title"><%= t('global_activities.index.teams') %></h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h6 class="team clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container">
<select name="team"
data-placeholder = "<%= t('global_activities.index.select_teams') %>"
@ -37,10 +37,10 @@
<div class="activity-selector filter-block small-left">
<h4 class="title"><%= t('global_activities.index.activity_type') %></h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h6 class="activity clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container group-activity">
<%= select_tag "group_activity", options_for_select(@activity_types.map{|k,v| [k,k]}),{
'data-placeholder': 'Select Activity groups'
'data-placeholder': t('global_activities.index.select_activity_groups')
} %>
</div>
<div class="select-container activity">
@ -53,7 +53,7 @@
<div class="user-selector filter-block small-left">
<h4 class="title"><%= t('global_activities.index.user') %></h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h6 class="user clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container">
<select name="user"
data-placeholder = "<%= t('global_activities.index.select_users') %>"
@ -63,57 +63,57 @@
</div>
<div class="filter-block small-left">
<h4 class="title">Projects, Experiments, Tasks</h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h4 class="title"><%= t('global_activities.index.projects_experiments_tasks') %></h4>
<h6 class="project clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container project">
<select name="project"
data-placeholder = "Select Projects"
data-placeholder = "<%= t('global_activities.index.select_projects') %>"
data-ajax-url = "<%= project_filter_global_activities_path %>"
></select>
</div>
<div class="select-container experiment">
<select name="experiment"
data-placeholder = "Select Experiments"
data-placeholder = "<%= t('global_activities.index.select_experiments') %>"
data-disable-on-load = "true"
data-disable-placeholder = "Select Projects to enable Experiments"
data-disable-placeholder = "<%= t('global_activities.index.disable_experiments') %>"
data-ajax-url = "<%= experiment_filter_global_activities_path %>"
></select>
</div>
<div class="select-container task">
<select name="task"
data-placeholder = "Select Tasks"
data-placeholder = "<%= t('global_activities.index.select_tasks') %>"
data-disable-on-load = "true"
data-disable-placeholder = "Select Experiments to enable Tasks"
data-disable-placeholder = "<%= t('global_activities.index.disable_tasks') %>"
data-ajax-url = "<%= my_module_filter_global_activities_path %>"
></select>
</div>
</div>
<div class="filter-block small-left">
<h4 class="title">Inventories</h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h4 class="title"><%= t('global_activities.index.inventories') %></h4>
<h6 class="inventory clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container inventory">
<select name="inventory"
data-placeholder = "Select Inventory"
data-placeholder = "<%= t('global_activities.index.select_inventories') %>"
data-ajax-url = "<%= inventory_filter_global_activities_path %>"
></select>
</div>
<div class="select-container inventory-item">
<select name="inventory-item"
data-placeholder = "Select Inventory item"
data-placeholder = "<%= t('global_activities.index.select_inventory_items') %>"
data-disable-on-load = "true"
data-disable-placeholder = "Select Inventories to enable Inventory items"
data-disable-placeholder = "<%= t('global_activities.index.disable_inventory_items') %>"
data-ajax-url = "<%= inventory_item_filter_global_activities_path %>"
></select>
</div>
</div>
<div class="team-selector filter-block small-left">
<h4 class="title">Protocols</h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<div class="filter-block small-left">
<h4 class="title"><%= t('global_activities.index.protocols') %></h4>
<h6 class="protocol clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container">
<select name="protocol"
data-placeholder = "Select Protocol"
data-placeholder = "<%= t('global_activities.index.select_protocols') %>"
data-select-all = "false"
data-ajax-url = "<%= protocol_filter_global_activities_path %>"
></select>
@ -121,12 +121,12 @@
</div>
<div class="team-selector filter-block small-left">
<h4 class="title">Reports</h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<div class="filter-block small-left">
<h4 class="title"><%= t('global_activities.index.reports') %></h4>
<h6 class="report clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container">
<select name="report"
data-placeholder = "Select Report"
data-placeholder = "<%= t('global_activities.index.select_reports') %>"
data-select-all = "false"
data-ajax-url = "<%= report_filter_global_activities_path %>"
></select>

View file

@ -2,7 +2,7 @@
<%= render partial: "shared/sidebar", locals: { current_task: @my_module, page: 'task' } %>
<%= render partial: "shared/secondary_navigation" %>
<div class="global-activities-container container-flex task_activities">
<div class="global-activities-container container-flex task-activities">
<div class="ga-top ">
<%= render partial: "my_modules/activities/top_pane" %>
</div>

View file

@ -1,6 +1,6 @@
<div class="date-selector filter-block small-right"
<div class="date-selector filter-block small-right first"
data-period-label="<%= t('global_activities.index.period_label') %>"
data-period-select="">
<h4 class="title"><%= t('global_activities.index.activity') %></h4>
@ -29,7 +29,7 @@
<div class="activity-selector filter-block small-left">
<h4 class="title"><%= t('global_activities.index.activity_type') %></h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h6 class="activity clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container group-activity">
<%= select_tag "group_activity", options_for_select(@activity_types.map{|k,v| [k,k]}),{
'data-placeholder': 'Select Activity groups'
@ -45,7 +45,7 @@
<div class="user-selector filter-block small-left">
<h4 class="title"><%= t('global_activities.index.user') %></h4>
<h6 class="clear"><%= t('global_activities.index.clear') %></h6>
<h6 class="user clear"><%= t('global_activities.index.clear') %></h6>
<div class="select-container">
<select name="user"
data-placeholder = "<%= t('global_activities.index.select_users') %>"

View file

@ -1,7 +1,7 @@
en:
global_activities:
index:
teams: "Team"
teams: "Teams"
activity: "Activity created"
period_label: "Activity created: "
today: "Today"
@ -14,20 +14,28 @@ en:
from_label: "Select end date"
to_label: "Select start date"
clear: "Clear"
activity_type: "Activity type"
user: "User"
activity_type: "Activity types"
user: "Users"
object: "Object"
all_teams_btn: "Deselect All Teams"
all_users_btn: "Deselect All Users"
all_activities: "All activities"
all_activities_btn: "Select All Activities"
l_activities: "activities"
clear_filters: "Clear filters"
select_teams: "Select Teams"
select_activity_groups: "Select Activity groups"
select_activity_types: "Select Activity types"
select_users: "Select Users"
select_objects: "Select Objects"
deselect_all_objects: "Deselect All Objects"
projects_experiments_tasks: "Projects, Experiments, Tasks"
select_projects: "Select Projects"
select_experiments: "Select Experiments"
disable_experiments: "Select Projects to enable Experiments"
select_tasks: "Select Tasks"
disable_tasks: "Select Experiments to enable Tasks"
inventories: "Inventories"
select_inventories: "Select Inventories"
select_inventory_items: "Select Inventory items"
disable_inventory_items: "Select Inventory to enable Inventory items"
protocols: Protocols
select_protocols: Select Protocols
reports: Reports
select_reports: Select Reports
no_name: "(unnamed)"
content_generation_error: "Failed to render activity content with id: %{activity_id}"
content: