diff --git a/app/assets/images/icon_small/experiment.svg b/app/assets/images/icon_small/experiment.svg
new file mode 100644
index 000000000..74f7c3ad4
--- /dev/null
+++ b/app/assets/images/icon_small/experiment.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/images/icon_small/project.svg b/app/assets/images/icon_small/project.svg
new file mode 100644
index 000000000..27e54e76b
--- /dev/null
+++ b/app/assets/images/icon_small/project.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/images/icon_small/task.svg b/app/assets/images/icon_small/task.svg
new file mode 100644
index 000000000..ed9f717eb
--- /dev/null
+++ b/app/assets/images/icon_small/task.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/assets/javascripts/global_activities/index.js b/app/assets/javascripts/global_activities/index.js
new file mode 100644
index 000000000..2b7a46f1a
--- /dev/null
+++ b/app/assets/javascripts/global_activities/index.js
@@ -0,0 +1,52 @@
+/* global animateSpinner */
+
+'use strict';
+
+(function() {
+ function initExpandCollapseAllButtons() {
+ $('#global-activities-colapse-all').on('click', function() {
+ $('.activities-group').collapse('hide');
+ });
+ $('#global-activities-expand-all').on('click', function() {
+ $('.activities-group').collapse('show');
+ });
+ }
+
+ function initExpandCollapseButton() {
+ $('.activities-group').on('hide.bs.collapse', function() {
+ $(this.dataset.buttonLink)
+ .find('.fas').removeClass('fa-caret-down').addClass('fa-caret-right');
+ });
+ $('.activities-group').on('show.bs.collapse', function() {
+ $(this.dataset.buttonLink)
+ .find('.fas').removeClass('fa-caret-right').addClass('fa-caret-down');
+ });
+ }
+
+ function initShowMoreButton() {
+ var moreButton = $('.btn-more-activities');
+ moreButton.on('click', function(ev) {
+ ev.preventDefault();
+ animateSpinner(null, true);
+ $.ajax({
+ url: $('.global-activities_activities-list').data('activities-url'),
+ data: { from_date: moreButton.data('next-date') },
+ dataType: 'json',
+ type: 'POST',
+ success: function(json) {
+ $('.global-activities_activities-list').html(json.activities_html);
+ if (json.more_activities === true) {
+ moreButton.data('next-date', json.next_date);
+ } else {
+ moreButton.addClass('hidden');
+ }
+ animateSpinner(null, false);
+ }
+ });
+ });
+ }
+
+ initExpandCollapseAllButtons();
+ initExpandCollapseButton();
+ initShowMoreButton();
+}());
diff --git a/app/assets/stylesheets/global_activities.scss b/app/assets/stylesheets/global_activities.scss
index d4075ff8d..b357d555f 100644
--- a/app/assets/stylesheets/global_activities.scss
+++ b/app/assets/stylesheets/global_activities.scss
@@ -12,6 +12,41 @@
grid-area: activities;
min-height: 600px;
}
+
+ .activities-counter-label {
+ margin-left: 10px;
+ }
+
+ .activities-group {
+ list-style: none;
+ padding-left: 0;
+ }
+
+ .activities-group-expand-button {
+ color: $color-emperor;
+ }
+
+ .activity-card {
+ border-radius: 5px;
+ margin-right: 10px;
+ padding: 5px;
+
+ &:hover {
+ background-color: $brand-primary-light;
+ }
+
+ .atwho-user-popover {
+ padding-left: 0;
+ }
+
+ .activity-timestamp {
+ color: $color-silver-chalice;
+ }
+
+ .navigational-breadcrumbs {
+ color: $color-silver-chalice;
+ }
+ }
}
}
@@ -107,6 +142,11 @@
position: relative;
width: 200px;
+ a {
+ color: $color-emperor;
+ margin: 0 5px;
+ }
+
span {
display: inline-block;
text-align: center;
diff --git a/app/assets/stylesheets/themes/global_activities.scss b/app/assets/stylesheets/themes/global_activities.scss
deleted file mode 100644
index e0d6a8802..000000000
--- a/app/assets/stylesheets/themes/global_activities.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-@import 'constants';
-
-.global-activities__container {
- background: white;
- padding: 1em;
- margin-top: 2em;
- grid-template-columns: 3fr 1fr;
- display: grid;
- grid-template-areas:
- "top top"
- "main side";
-}
-
-.global-activities__top{
- grid-area: top;
- grid-template-columns: 1fr 3fr;
-}
-
-.global-activities__main{
- display: grid;
- grid-template-areas:
- "actions search"
- "activities activities";
- grid-area: main;
-}
-
-.global-activities__side{
- grid-area: side;
-}
-
-.global-activities_activities-list{
- border-top: 1px solid $gray-lighter;
- margin-top: 2em;
- grid-area: activities;
- overflow-y: scroll;
- min-height: 600px;
-}
-
-.global-activities__top-actions{
- grid-area: actions;
-}
-
-.global-activities__search-container{
- grid-area: search;
-}
-
-.global-activiteis__title{
- grid-area: title;
- font-size: $font-size-h4;
- color: $gray-darker;
- border-bottom: 1px solid $gray-lighter;
-}
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 7270b7cf7..88f04d663 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -139,7 +139,10 @@ module ApplicationHelper
end
# Generate smart annotation link for one user object
- def popover_for_user_name(user, team = nil, skip_user_status = false)
+ def popover_for_user_name(user,
+ team = nil,
+ skip_user_status = false,
+ skip_avatar = false)
user_still_in_team = user.teams.include?(team)
user_description = %(
diff --git a/app/views/global_activities/_activity_list.html.erb b/app/views/global_activities/_activity_list.html.erb
new file mode 100644
index 000000000..947b87b8d
--- /dev/null
+++ b/app/views/global_activities/_activity_list.html.erb
@@ -0,0 +1,30 @@
+<% @grouped_activities.each do |date, activities| %>
+
+
+
+
+ <%= activities.length %>
+ <%= t("activities.index.#{'activity'.pluralize(activities.length)}_counter_label") %>
+
+
">
+ <% activities.each do |activity| %>
+
+ <%= render partial: 'activity.html.erb', locals: { activity: activity } %>
+
+ <% end %>
+
+
+
+<% end %>
diff --git a/app/views/global_activities/_top_pane.html.erb b/app/views/global_activities/_top_pane.html.erb
index 7aa8b52cb..fc55fbc7a 100644
--- a/app/views/global_activities/_top_pane.html.erb
+++ b/app/views/global_activities/_top_pane.html.erb
@@ -1,7 +1,15 @@
-Global activities
+
+ <%= t('activities.index.global_activities_title') %>
+
@@ -19,4 +27,4 @@
<%= t('global_activities.index.clear_filters') %>
-
\ No newline at end of file
+
diff --git a/app/views/global_activities/index.html.erb b/app/views/global_activities/index.html.erb
index e4fe43564..239571cfe 100644
--- a/app/views/global_activities/index.html.erb
+++ b/app/views/global_activities/index.html.erb
@@ -1,3 +1,4 @@
+<% provide :head_title, t('nav.label.activities') %>
@@ -5,18 +6,24 @@
<%= render partial: "top_pane" %>
-
<%= render partial: "side_filters" %>
-
-
list of activities
+
+ <%= render partial: "activity_list.html.erb" %>
+
+
-<%= javascript_include_tag("global_activities/side_pane") %>
\ No newline at end of file
+<%= javascript_include_tag 'global_activities/index.js' %>
+<%= javascript_include_tag 'global_activities/side_pane.js' %>
diff --git a/app/views/global_activities/references/_experiment.html.erb b/app/views/global_activities/references/_experiment.html.erb
new file mode 100644
index 000000000..3eb02e8a4
--- /dev/null
+++ b/app/views/global_activities/references/_experiment.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/project.html.erb",
+ locals: { subject: subject&.project } %>
+
+ <%= image_tag 'icon_small/experiment.svg' %>
+ <% if subject %>
+ <%= link_to experiment_path(subject), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:experiment].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_my_module.html.erb b/app/views/global_activities/references/_my_module.html.erb
new file mode 100644
index 000000000..8054737b4
--- /dev/null
+++ b/app/views/global_activities/references/_my_module.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/experiment.html.erb",
+ locals: { subject: subject&.experiment } %>
+
+ <%= image_tag 'icon_small/task.svg' %>
+ <% if subject %>
+ <%= link_to my_module_path(subject), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:my_module].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_project.html.erb b/app/views/global_activities/references/_project.html.erb
new file mode 100644
index 000000000..cb865a190
--- /dev/null
+++ b/app/views/global_activities/references/_project.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/team.html.erb",
+ locals: { subject: subject&.team } %>
+
+ <%= image_tag 'icon_small/project.svg' %>
+ <% if subject %>
+ <%= link_to project_path(subject), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:project].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_protocol.html.erb b/app/views/global_activities/references/_protocol.html.erb
new file mode 100644
index 000000000..c6dd37572
--- /dev/null
+++ b/app/views/global_activities/references/_protocol.html.erb
@@ -0,0 +1,19 @@
+<%= render partial: "global_activities/references/my_module.html.erb",
+ locals: { subject: subject&.my_module } %>
+
+
+ <% if subject %>
+ <% if subject.in_repository %>
+ <%= route_to_other_team protocols_path(team: subject.team),
+ subject.team,
+ subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH),
+ title: subject.name %>
+ <% else %>
+ <%= link_to truncated_name, protocols_my_module_path(subject.my_module), title: subject.name %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:protocol].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_report.html.erb b/app/views/global_activities/references/_report.html.erb
new file mode 100644
index 000000000..44c943d8c
--- /dev/null
+++ b/app/views/global_activities/references/_report.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/team.html.erb",
+ locals: { subject: subject&.team } %>
+
+ <%= image_tag 'icon_small/report.png' %>
+ <% if subject %>
+ <%= link_to reports_path(subject), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:report].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_repository.html.erb b/app/views/global_activities/references/_repository.html.erb
new file mode 100644
index 000000000..c0d31f9d3
--- /dev/null
+++ b/app/views/global_activities/references/_repository.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/team.html.erb",
+ locals: { subject: subject&.team } %>
+
+
+ <% if subject %>
+ <%= link_to repositories_path(subject), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:repository].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_result.html.erb b/app/views/global_activities/references/_result.html.erb
new file mode 100644
index 000000000..e77b7c341
--- /dev/null
+++ b/app/views/global_activities/references/_result.html.erb
@@ -0,0 +1,14 @@
+<%= render partial: "global_activities/references/my_module.html.erb",
+ locals: { subject: subject&.my_module } %>
+
+ <%= image_tag 'icon_small/result.png' %>
+ <% if subject %>
+ <%= link_to results_my_module_path(subject.my_module), title: subject.name do %>
+ <%= subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+ <% end %>
+ <% else %>
+
+ <%= breadcrumbs[:result].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/app/views/global_activities/references/_team.html.erb b/app/views/global_activities/references/_team.html.erb
new file mode 100644
index 000000000..0c0a8dcf5
--- /dev/null
+++ b/app/views/global_activities/references/_team.html.erb
@@ -0,0 +1,13 @@
+
+
+ <% if subject %>
+ <%= route_to_other_team projects_path(team: subject.id),
+ subject,
+ subject.name.truncate(Constants::NAME_TRUNCATION_LENGTH),
+ title: subject.name %>
+ <% else %>
+
+ <%= breadcrumbs[:team].truncate(Constants::NAME_TRUNCATION_LENGTH) %>
+
+ <% end %>
+
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index 1d813b231..bcd8a1956 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -90,6 +90,7 @@ Rails.application.config.assets.precompile +=
Rails.application.config.assets.precompile +=
%w(repositories/my_module_repository.js)
Rails.application.config.assets.precompile += %w(activities/index.js)
+Rails.application.config.assets.precompile += %w(global_activities/index.js)
Rails.application.config.assets.precompile += %w(repository_columns/index.js)
Rails.application.config.assets.precompile += %w(repositories/show.js)
Rails.application.config.assets.precompile += %w(sidebar_toggle.js)
diff --git a/config/locales/en.yml b/config/locales/en.yml
index abb63e567..34eba5fd9 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1303,9 +1303,14 @@ en:
see_all: "show all"
activities:
index:
+ global_activities_title: "Global activities"
today: "Today"
- more_activities: "More Activities"
+ more_activities: "Show more activities"
no_activities: "No activities!"
+ activity_counter_label: " activity"
+ activities_counter_label: " activities"
+ expand_all: "Expand all"
+ collapse_all: "Collapse all"
modal:
modal_title: "Activities"
create_project: "%{user} created project %{project} ."
@@ -1372,6 +1377,98 @@ en:
create_report: "%{user} created report %{report} ."
delete_report: "%{user} deleted report %{report} ."
edit_report: "%{user} edited report %{report} ."
+ content:
+ create_project_html: "created project %{project}."
+ rename_project_html: "renamed project %{project}."
+ change_project_visibility_html: "changed project %{project}'s visibility to %{visibility}."
+ archive_project_html: "moved project %{project} to archive."
+ restore_project_html: "restored project %{project} from archive."
+ add_comment_to_project_html: "commented on project %{project}."
+ edit_project_comment_html: "edited comment on project %{project}."
+ delete_project_comment_html: "deleted comment on project %{project}."
+ create_report_html: "created report %{report}."
+ edit_report_html: "edited report %{report}."
+ delete_report_html: "deleted report %{report}."
+ add_result_html: "added %{result_type} result %{result} to task."
+ edit_result_html: "edited %{result_type} result %{result}."
+ add_comment_to_result_html: "commented on result %{result}."
+ edit_result_comment_html: "edited comment on result %{result}."
+ delete_result_comment_html: "deleted comment on result %{result}."
+ archive_result_html: "archived %{result_type] result %{result}."
+ destroy_result_html: "deleted %{result_type] result %{result}."
+ create_module_html: "created task %{task}."
+ clone_module_html: "copied task %{new_task} from task %{original_task} as template."
+ archive_module_html: "archived task %{task}."
+ restore_module_html: "restored task %{task} from archive."
+ add_comment_to_module_html: "commented on task %{task}."
+ edit_module_comment_html: "edited comment on task %{task}."
+ delete_module_comment_html: "deleted comment on task %{task}."
+ change_module_description_html: "edited task %{task]'s description."
+ create_step_html: "created protocol step %{step_num} %{step_name]."
+ edit_step_html: "edited protocol step %{step_num] %{step_name]."
+ destroy_step_html: "deleted protocol step %{step_num} %{step_name}."
+ load_protocol_from_repository_html: "loaded protocol %{protocol] to task %{task} from Protocol repository."
+ load_protocol_from_file_html: "loaded protocol %{protocol] to task %{task} from file."
+ revert_protocol_html: "reverted protocol %{protocol] to Protocol repository version."
+ check_step_checklist_item_html: completed checklist item %{checkbox] (%{completed_counter} completed) in step %{step_num} %{step_name}."
+ uncheck_step_checklist_item_html: "uncompleted checklist item %{checkbox] (%{completed_counter} completed) in step %{step_num} %{step_name}."
+ add_comment_to_step_html: "commented on step %{step_num} %{step_name}."
+ edit_step_comment_html: "edited comment on step %{step_num} %{step_name}."
+ delete_step_comment_html: "deleted comment on step %{step_num} %{step_name}."
+ complete_step_html: "completed step %{step_num} %{step_name} (%{completed_counter} completed)."
+ uncomplete_step_html: "uncompleted step %{step_num} %{step_name} (%{completed_counter} completed)."
+ uncomplete_task_html: "uncompleted task %{task}."
+ complete_task_html: "completed task %{task}."
+ assign_repository_record_html: "assigned inventory item(s) %{items} from inventory %{inventory} to task %{task}."
+ unassign_repository_record_html: "unassigned inventory item(s) %{items} from inventory %{inventory} to task %{task}."
+ assign_user_to_project_html: "assigned user %{user} with user role %{role} to project %{project}."
+ unassign_user_from_project_html: "removed user %{user} from project %{project}."
+ change_user_role_on_project_html: "changed %{user}'s role on project %{project} to %{role}."
+ assign_user_to_module_html: "assigned user %{user} to task %{task}."
+ unassign_user_from_module_html: "removed user %{user} from task %{task}."
+ create_experiment_html: "created experiment %{experiment}."
+ edit_experiment_html: "edited experiment %{experiment}."
+ move_experiment_html: "moved experiment %{experiment} from project %{original_project} to project %{new_project}."
+ clone_experiment_html: "copied experiment %{new_experiment} from experiment %{original_experiment} as a template."
+ archive_experiment_html: "archived experiment %{experiment}."
+ start_edit_wopi_file_result_html: "edited Office online file %{file_name} on result %{result_name}: %{action}."
+ start_edit_wopi_file_step_html: "edited Office online file %{file_name} on step %{step_num} %{step_name}: %{action}."
+ restore_experiment_html: "restored experiment %{experiment}"
+ rename_task_html: "renamed task %{task}"
+ move_task_html: "moved task %{task} from experiment %{experiment_original} to experiment %{experiment_new}"
+ archive_task_html: "archived task %{task}"
+ set_task_due_date_html: "set due date %{date} on task %{task}"
+ change_task_due_date_html: "changed due date %{date} on task %{task}"
+ remove_task_due_date_html: "removed due date %{date} on task %{task}"
+ add_task_tag_html: "added tag %{tag} to task %{task}"
+ edit_task_tag_html: "edited tag %{tag} on task %{task}"
+ remove_task_tag_html: "removed tag %{tag} from task %{task}"
+ create_inventory_html: "created inventory %{inventory}"
+ rename_inventory_html: "renamed inventory %{inventory}"
+ delete_inventory_html: "deleted inventory %{inventory}"
+ create_item_inventory_html: "created inventory item %{item}"
+ edit_item_inventory_html: "edited inventory item %{item}"
+ delete_item_inventory_html: "deleted inventory item %{item}"
+ create_column_inventory_html: "created column %{column} in inventory %{inventory}"
+ edit_column_inventory_html: "edited column %{column} in inventory %{inventory}"
+ delete_column_inventory_html: "deleted column %{column} in inventory %{inventory}"
+ create_protocol_in_repository_html: "created protocol %{protocol} in Protocol repository"
+ add_step_to_protocol_repository_html: "created protocol %{protocol}'s step %{step} in Protocol repository"
+ edit_step_in_protocol_repository_html: "edited protocol %{protocol}'s step %{step} in Protocol repository"
+ delete_step_in_protocol_repository_html: "deleted protocol %{protocol}'s step %{step} in Protocol repository"
+ edit_description_in_protocol_repository_html: "edited protocol %{protocol}'s description in Protocol repository"
+ edit_keywords_in_protocol_repository_html: "edited protocol %{protocol}'s keywords in Protocol repository"
+ edit_authors_in_protocol_repository_html: "edited protocol %{protocol}'s authors in Protocol repository"
+ archive_protocol_in_repository_html: "archived protocol %{protocol} in Protocol repository"
+ restore_protocol_in_repository_html: "restored protocol %{protocol} from archive in Protocol repository"
+ move_protocol_in_repository_html: "moved protocol %{protocol} from %{protocol_storage}"
+ import_protocol_in_repository_html: "imported protocol %{protocol} to Protocol repository from file"
+ export_protocol_in_repository_html: "exported protocol %{protocol} from Protocol repository"
+ invite_user_to_team_html: "invited user %{user} to team %{team} with user role %{user_role}"
+ remove_user_from_team_html: "removed user %{user} from team %{team}"
+ change_users_role_on_team_html: "changed %{user}'s role in team %{team} to %{role}"
+ export_projects_html: "exported project(s) %{projects} to .zip"
+ export_inventory_items_html: "exported inventory item(s) from %{inventory}"
user_my_modules:
new:
diff --git a/config/routes.rb b/config/routes.rb
index 9f6d3d625..f222aed82 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -652,6 +652,8 @@ Rails.application.routes.draw do
get :search_subjects, on: :collection
end
+ post 'global_activities', to: 'global_activities#index'
+
constraints WopiSubdomain do
# Office integration
get 'wopi/files/:id/contents', to: 'wopi#file_contents_get_endpoint'
diff --git a/package.json b/package.json
index 7ef350a3c..90c2a75df 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"@fortawesome/fontawesome-free": "^5.2.0",
"babel-eslint": "^8.2.6",
"babel-plugin-transform-react-jsx-source": "^6.22.0",
- "eslint": "^5.3.0",
+ "eslint": "^5.14.1",
"eslint-config-airbnb": "^15.1.0",
"eslint-config-airbnb-base": "^13.0.0",
"eslint-config-google": "^0.9.1",