Merge pull request #1586 from okriuchykhin/ok_SCI_3199

Fix multiple bugs in global activities [SCI-3197][SCI-3199][SCI-3213][SCI-3225]
This commit is contained in:
Alex Kriuchykhin 2019-03-26 16:02:44 +01:00 committed by GitHub
commit 935e3a65cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 154 additions and 142 deletions

View file

@ -1,24 +1,26 @@
/* global animateSpinner */
/* global animateSpinner GlobalActivitiesFilterPrepareArray */
'use strict';
function globalActivitiesInit() {
(function() {
function initExpandCollapseAllButtons() {
$('#global-activities-colapse-all').on('click', function() {
$('#global-activities-colapse-all').on('click', function(ev) {
ev.preventDefault();
$('.activities-group').collapse('hide');
});
$('#global-activities-expand-all').on('click', function() {
$('#global-activities-expand-all').on('click', function(ev) {
ev.preventDefault();
$('.activities-group').collapse('show');
});
}
function initExpandCollapseButton() {
$('.activities-group').on('hidden.bs.collapse', function() {
$(this.dataset.buttonLink)
$('.ga-activities-list').on('hidden.bs.collapse', function(ev) {
$(ev.target.dataset.buttonLink)
.find('.fas').removeClass('fa-caret-down').addClass('fa-caret-right');
});
$('.activities-group').on('shown.bs.collapse', function() {
$(this.dataset.buttonLink)
$('.ga-activities-list').on('shown.bs.collapse', function(ev) {
$(ev.target.dataset.buttonLink)
.find('.fas').removeClass('fa-caret-right').addClass('fa-caret-down');
});
}
@ -28,7 +30,7 @@ function globalActivitiesInit() {
var filters = GlobalActivitiesFilterPrepareArray();
ev.preventDefault();
animateSpinner(null, true);
filters.to_date = moreButton.data('next-date');
filters.from_date = moreButton.data('next-date');
$.ajax({
url: $('.ga-activities-list').data('activities-url'),
data: filters,
@ -41,21 +43,13 @@ function globalActivitiesInit() {
} else {
moreButton.addClass('hidden');
}
(new globalActivitiesInit()).updateCollapseButton();
animateSpinner(null, false);
}
});
});
}
if (this) {
this.updateCollapseButton = function() {
initExpandCollapseButton();
};
}
initExpandCollapseAllButtons();
initExpandCollapseButton();
initShowMoreButton();
}
globalActivitiesInit();
}());

View file

@ -1,3 +1,5 @@
/* global animateSpinner */
// Common code
@ -8,8 +10,14 @@ Date.prototype.date_to_string = function() {
// GA code
function GlobalActivitiesFiltersGetDates() {
var fromDate = $('#calendar-from-date').data('DateTimePicker').date()._d.date_to_string();
var toDate = $('#calendar-to-date').data('DateTimePicker').date()._d.date_to_string();
var fromDate = $('#calendar-from-date').data('DateTimePicker').date();
var toDate = $('#calendar-to-date').data('DateTimePicker').date();
if (fromDate) {
fromDate = fromDate._d.date_to_string();
}
if (toDate) {
toDate = toDate._d.date_to_string();
}
return { from: fromDate, to: toDate };
}
@ -36,33 +44,6 @@ function GlobalActivitiesFilterPrepareArray() {
};
}
function GlobalActivitiesUpdateTopPaneTags(event) {
$('.ga-top .ga-tags').children().remove();
$('<li class="select2-selection__choice">'
+ 'Activity created: '
+ $('.ga-side .date-selector.filter-block')[0].dataset.periodSelect
+ '</li>').appendTo('.ga-top .ga-tags');
$.each($('.ga-side .select2-selection__choice'), function(index, tag) {
var newTag = $(tag.outerHTML).appendTo('.ga-top .ga-tags');
var selectedValues = [];
var parentSelector = $(tag).parents('.select2-container').prev();
var elementToDelete = null;
newTag.find('.select2-selection__choice__remove')
.click(() => {
if (event && event.type === 'select2:select') {
// Adding remove action for native blocks
selectedValues = parentSelector.val();
elementToDelete = $(tag).find('span.select2-block-body')[0].dataset.selectId;
selectedValues = $.grep(selectedValues, v => { return v !== elementToDelete; });
parentSelector.val(selectedValues).change();
} else {
$(tag).find('.select2-selection__choice__remove').click();
}
});
});
}
$(function() {
var updateRunning = false;
var selectors = ['team', 'activity', 'user'];
@ -98,8 +79,38 @@ $(function() {
return state.label + ': ' + state.text;
};
function GlobalActivitiesUpdateTopPaneTags(event) {
var dateContainer = $('.ga-side .date-selector.filter-block');
if (updateRunning) return false;
$('.ga-top .ga-tags').children().remove();
if (dateContainer[0].dataset.periodSelect) {
$('<li class="select2-selection__choice">'
+ dateContainer[0].dataset.periodLabel
+ $('.ga-side .date-selector.filter-block')[0].dataset.periodSelect
+ '</li>').appendTo('.ga-top .ga-tags');
}
$.each($('.ga-side .select2-selection__choice'), function(index, tag) {
var newTag = $(tag.outerHTML).appendTo('.ga-top .ga-tags');
var selectedValues = [];
var parentSelector = $(tag).parents('.select2-container').prev();
var elementToDelete = null;
newTag.find('.select2-selection__choice__remove')
.click(() => {
if (event && event.type === 'select2:select') {
// Adding remove action for native blocks
selectedValues = parentSelector.val();
elementToDelete = $(tag).find('span.select2-block-body')[0].dataset.selectId;
selectedValues = $.grep(selectedValues, v => { return v !== elementToDelete; });
parentSelector.val(selectedValues).change();
} else {
$(tag).find('.select2-selection__choice__remove').click();
}
});
});
}
// update_filter
var reloadActivities = function() {
function reloadActivities() {
var moreButton = $('.btn-more-activities');
if (updateRunning) return false;
updateRunning = true;
@ -118,7 +129,6 @@ $(function() {
} else {
moreButton.addClass('hidden');
}
(new globalActivitiesInit()).updateCollapseButton();
updateRunning = false;
animateSpinner(null, false);
},
@ -127,8 +137,8 @@ $(function() {
animateSpinner(null, false);
}
});
};
return true;
}
// Common selection intialize
$.each(selectors, (index, e) => {
@ -146,11 +156,10 @@ $(function() {
ajax: subjectAjaxQuery,
customSelection: subjectCustomDisplay,
unlimitedSize: true
})
.on('change select2:select', function(e) {
GlobalActivitiesUpdateTopPaneTags(e);
reloadActivities();
});
}).on('change select2:select', function(e) {
GlobalActivitiesUpdateTopPaneTags(e);
reloadActivities();
});
$('.ga-side .subject-selector .clear').click(function() {
$('.ga-side .subject-selector select').select2MultipleClearAll();
});
@ -159,24 +168,30 @@ $(function() {
updateRunning = true;
$.each(selectors, (index, e) => { $('.ga-side .' + e + '-selector select').select2MultipleClearAll(); });
$('.ga-side .subject-selector select').select2MultipleClearAll();
$('#calendar-from-date').data('DateTimePicker').clear();
$('#calendar-to-date').data('DateTimePicker').clear();
updateRunning = false;
reloadActivities();
});
$('#calendar-from-date').on('dp.change', function(e) {
var dateContainer = $('.ga-side .date-selector.filter-block');
$('#calendar-to-date').data('DateTimePicker').minDate(e.date);
dateContainer[0].dataset.periodSelect = $('#calendar-from-date').val() + ' - ' + $('#calendar-to-date').val();
GlobalActivitiesUpdateTopPaneTags();
reloadActivities();
});
$('#calendar-to-date').on('dp.change', function(e) {
var dateContainer = $('.ga-side .date-selector.filter-block');
$('#calendar-from-date').data('DateTimePicker').maxDate(e.date);
dateContainer[0].dataset.periodSelect = $('#calendar-from-date').val() + ' - ' + $('#calendar-to-date').val();
GlobalActivitiesUpdateTopPaneTags();
reloadActivities();
if (!updateRunning) {
$('#calendar-from-date').data('DateTimePicker').minDate(e.date);
dateContainer[0].dataset.periodSelect = $('#calendar-from-date').val() + ' - ' + $('#calendar-to-date').val();
GlobalActivitiesUpdateTopPaneTags();
reloadActivities();
}
});
$('#calendar-from-date').on('dp.change', function(e) {
var dateContainer = $('.ga-side .date-selector.filter-block');
if (!updateRunning) {
$('#calendar-to-date').data('DateTimePicker').maxDate(e.date);
dateContainer[0].dataset.periodSelect = $('#calendar-from-date').val() + ' - ' + $('#calendar-to-date').val();
GlobalActivitiesUpdateTopPaneTags();
reloadActivities();
}
});
GlobalActivitiesUpdateTopPaneTags();
@ -190,30 +205,30 @@ $(function() {
var yesterday = new Date(new Date().setDate(today.getDate() - 1));
var weekDay = today.getDay();
var monday = new Date(new Date().setDate(today.getDate() - weekDay + (weekDay === 0 ? -6 : 1)));
var sunday = new Date(new Date().setDate(new Date(monday).getDate() + 6));
var lastWeek = new Date(new Date().setDate(today.getDate() - 6));
var lastWeekEnd = new Date(new Date().setDate(monday.getDate() - 1));
var lastWeekStart = new Date(new Date().setDate(monday.getDate() - 7));
var firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
var lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);
var lastMonth = new Date(new Date().setDate(today.getDate() - 30));
var lastMonthEnd = new Date(new Date().setDate(firstDay.getDate() - 1));
var lastMonthStart = new Date(lastMonthEnd.getFullYear(), lastMonthEnd.getMonth(), 1);
updateRunning = true;
if (selectPeriod === 'today') {
toDate.date(today);
fromDate.date(today);
toDate.date(today);
} else if (selectPeriod === 'yesterday') {
toDate.date(yesterday);
fromDate.date(yesterday);
toDate.date(yesterday);
} else if (selectPeriod === 'this_week') {
toDate.date(sunday);
fromDate.date(monday);
fromDate.date(today);
toDate.date(monday);
} else if (selectPeriod === 'last_week') {
toDate.date(today);
fromDate.date(lastWeek);
fromDate.date(lastWeekEnd);
toDate.date(lastWeekStart);
} else if (selectPeriod === 'this_month') {
toDate.date(lastDay);
fromDate.date(firstDay);
fromDate.date(today);
toDate.date(firstDay);
} else if (selectPeriod === 'last_month') {
toDate.date(today);
fromDate.date(lastMonth);
fromDate.date(lastMonthEnd);
toDate.date(lastMonthStart);
}
updateRunning = false;
dateContainer[0].dataset.periodSelect = this.innerHTML;

View file

@ -81,7 +81,7 @@
}
.ga-side {
float: right;
.filter-block {
@ -146,6 +146,7 @@
float: left;
height: 2px;
margin: 16px 10px;
margin-top: 38px;
position: relative;
width: 10px;
}

View file

@ -4,7 +4,7 @@ class GlobalActivitiesController < ApplicationController
def index
teams = activity_filters[:teams]
@teams = current_user.teams
teams = @teams.pluck(:id) if teams.blank?
teams = current_team if teams.blank?
@activity_types = Activity.activity_types_list
@user_list = User.where(id: UserTeam.where(team: current_user.teams).select(:user_id))
.distinct

View file

@ -40,7 +40,7 @@ class ReportsController < ApplicationController
render json: ::ReportDatatable.new(
view_context,
current_user,
Report.visible_by(current_user, current_team)
Report.viewable_by_user(current_user, current_team)
)
end
end

View file

@ -1,5 +1,6 @@
class Report < ApplicationRecord
include SearchableModel
include SearchableByNameModel
auto_strip_attributes :name, :description, nullify: false
validates :name,
@ -52,18 +53,8 @@ class Report < ApplicationRecord
end
end
def self.visible_by(user, team)
projects = team.projects.joins(
'LEFT OUTER JOIN user_projects ON user_projects.project_id = projects.id'
).where(archived: false)
# Only admins see all projects of the team
unless user.is_admin_of_team?(team)
projects = projects.where(
'visibility = 1 OR user_projects.user_id = :user_id', user_id: user.id
)
end
where(project: projects)
def self.viewable_by_user(user, teams)
where(project: Project.viewable_by_user(user, teams))
end
def root_elements

View file

@ -18,23 +18,19 @@ class ActivitiesService
query = query.where(owner_id: filters[:users]) if filters[:users]
query = query.where(type_of: filters[:types]) if filters[:types]
if filters[:from_date] && filters[:to_date]
if filters[:from_date].present? && filters[:to_date].present?
activities = query.where(
'created_at >= :from AND created_at <= :to',
'created_at <= :from AND created_at >= :to',
from: Time.zone.parse(filters[:from_date]).beginning_of_day.utc,
to: Time.zone.parse(filters[:to_date]).end_of_day.utc
)
elsif filters[:from_date] && !filters[:to_date]
elsif filters[:from_date].present? && filters[:to_date].blank?
activities = query.where(
'created_at >= :from',
'created_at <= :from',
from: Time.zone.parse(filters[:from_date]).beginning_of_day.utc
)
else
activities = query.where(
'created_at >= :from AND created_at <= :to',
from: Time.now.beginning_of_day.utc,
to: Time.now.end_of_day.utc
)
activities = query
end
activities = activities.order(created_at: :desc)
@ -48,14 +44,16 @@ class ActivitiesService
last_date = results.keys.last
activities = query.where(
'created_at >= :from AND created_at <= :to',
from: Time.zone.parse(last_date).beginning_of_day.utc,
to: Time.zone.parse(last_date).end_of_day.utc
)
'created_at <= :from AND created_at >= :to',
from: Time.zone.parse(last_date).end_of_day.utc,
to: Time.zone.parse(last_date).beginning_of_day.utc
).order(created_at: :desc)
more_left = query.where(
'created_at > :from',
'created_at < :from',
from: Time.zone.parse(last_date).end_of_day.utc
).exists?
results[last_date] = activities.to_a
[results, more_left]
end

View file

@ -4,7 +4,6 @@
<% if activity.old_activity? %>
<%= activity.message&.html_safe %>
<% else %>
<%= activity.id %>
<%= generate_activity_content(activity).html_safe %>
<% end %>
</div>

View file

@ -16,8 +16,8 @@
<script type="text/javascript">
$(function () {
var dt = $('#calendar-<%= id %>');
dt.datetimepicker({ ignoreReadonly: true, locale: '<%= I18n.locale %>', format: '<%= js_format %>' });
$('#calendar-<%= id %>').data('DateTimePicker').date(new Date);
dt.datetimepicker({ useCurrent: <%= use_current %>, ignoreReadonly: true, locale: '<%= I18n.locale %>', format: '<%= js_format %>' });
$('#calendar-<%= id %>').data('DateTimePicker').date(null);
});
</script>
</div>

View file

@ -11,7 +11,9 @@
</div>
</div>
<div class="date-selector filter-block small-right" data-period-select="Today">
<div class="date-selector filter-block small-right"
data-period-label="<%= t('global_activities.index.period_label') %>"
data-period-select="">
<h4 class="title"><strong><%= t('global_activities.index.activity') %></strong></h4>
<div class="date-selector">
@ -23,12 +25,15 @@
<div class="hot-button btn btn-default" data-period="this_month"><%= t('global_activities.index.this_month') %></div>
<div class="hot-button btn btn-default" data-period="last_month"><%= t('global_activities.index.last_month') %></div>
</div>
<div class="from">
<%= render partial: "date_picker", locals: {id: 'from-date', label: false} %>
<h4>
<%= t('global_activities.index.custom_dates_label') %>
</h4>
<div class="to">
<%= render partial: "date_picker", locals: { id: 'to-date', use_current: 'false', label: t('global_activities.index.to_label') } %>
</div>
<div class="separator"></div>
<div class="to">
<%= render partial: "date_picker", locals: {id: 'to-date', label: false} %>
<div class="from">
<%= render partial: "date_picker", locals: { id: 'from-date', use_current: 'true', label: t('global_activities.index.from_label') } %>
</div>
</div>
</div>

View file

@ -1,5 +1,10 @@
<%= render partial: "global_activities/references/my_module.html.erb",
locals: { subject: subject&.my_module, breadcrumbs: breadcrumbs } %>
<% if subject.in_repository? %>
<%= render partial: "global_activities/references/team.html.erb",
locals: { subject: subject&.team, breadcrumbs: breadcrumbs } %>
<% else %>
<%= render partial: "global_activities/references/my_module.html.erb",
locals: { subject: subject&.my_module, breadcrumbs: breadcrumbs } %>
<% end %>
<div class="ga-breadcrumb">
<span class="fas fa-edit"></span>
<% if subject %>

View file

@ -1,7 +1,7 @@
<%= render partial: "global_activities/references/team.html.erb",
locals: { subject: subject&.team, breadcrumbs: breadcrumbs } %>
<div class="ga-breadcrumb">
<%= image_tag 'icon_small/report.png' %>
<span class="fas fa-clipboard-check"></span>
<% if subject %>
<%= link_to reports_path(subject), title: subject.name do %>
<%= subject.name&.truncate(Constants::NAME_TRUNCATION_LENGTH) %>

View file

@ -1,25 +1,29 @@
en:
global_activities:
index:
teams: Team
activity: Actvity created
today: Today
yesterday: Yesterday
this_week: This week
last_week: Last week
this_month: This month
last_month: Last month
clear: clear
activity_type: Activity type
user: User
object: Object
all_teams: All teams
l_teams: teams
all_users: All users
l_users: users
all_activities: All activities
l_activities: activities
clear_filters: Clear filters
teams: "Team"
activity: "Activity created"
period_label: "Activity created: "
today: "Today"
yesterday: "Yesterday"
this_week: "This week"
last_week: "Last week"
this_month: "This month"
last_month: "Last month"
custom_dates_label: "Select custom dates"
from_label: "End date"
to_label: "Start date"
clear: "clear"
activity_type: "Activity type"
user: "User"
object: "Object"
all_teams: "All teams"
l_teams: "teams"
all_users: "All users"
l_users: "users"
all_activities: "All activities"
l_activities: "activities"
clear_filters: "Clear filters"
content:
create_project_html: "%{user} created project %{project}."
rename_project_html: "%{user} renamed project %{project}."
@ -108,6 +112,6 @@ en:
export_protocol_in_repository_html: "%{user} exported protocol %{protocol} from Protocol repository"
invite_user_to_team_html: "%{user} invited user %{user_invited} to team %{team} with user role %{role}"
remove_user_from_team_html: "%{user} removed user %{user_removed} from team %{team}"
change_users_role_on_team_html: "%{user} changed %{user_changed}'s role in team %{team} to %{role}"
change_users_role_on_team_html: "%{user} changed user %{user_changed}'s role in team %{team} to %{role}"
export_projects_html: "%{user} exported project(s) %{projects} to .zip"
export_inventory_items_html: "%{user} exported inventory item(s) from %{repository}"