From d7727fe6a59569081469358cb9f11552d371d404 Mon Sep 17 00:00:00 2001 From: Alexander Machehin Date: Tue, 5 May 2015 17:25:29 +0500 Subject: [PATCH] improve activity feed --- .../controllers/activity_controller.js | 201 --------------- .../controllers/activity_controller.js.coffee | 244 ++++++++++++++++++ .../javascripts/angularjs/locales.js.erb | 2 - .../services/activity_filter.js.coffee | 27 ++ app/assets/stylesheets/custom_bootstrap.sass | 2 +- app/controllers/home_controller.rb | 46 +++- app/helpers/activity_feeds_helper.rb | 2 +- app/models/activity_feed.rb | 11 +- app/models/comment.rb | 2 +- app/models/concerns/feed/build_list.rb | 16 +- app/models/concerns/feed/comment.rb | 35 +-- app/models/concerns/feed/git.rb | 29 ++- app/models/concerns/feed/issue.rb | 22 +- app/models/concerns/project/finders.rb | 5 +- app/models/issue.rb | 2 +- app/views/home/_activity_tab.html.slim | 24 +- app/views/home/_activity_tabsets.html.slim | 20 ++ app/views/home/_filters.html.slim | 32 +-- app/views/home/_own_activity_tab.html.slim | 9 + app/views/home/_sidebar.html.slim | 1 + .../home/_tracker_and_pulls_tabs.html.slim | 70 ++--- app/views/home/activity.atom.builder | 9 +- app/views/home/activity.html.slim | 6 +- app/views/home/activity.json.jbuilder | 8 +- app/views/home/get_owners_list.json.jbuilder | 3 + .../home/get_project_names_list.json.jbuilder | 3 + .../partials/_build_list_notification.haml | 2 +- .../_git_delete_branch_notification.haml | 4 +- .../partials/_git_new_push_notification.haml | 4 +- .../_new_comment_commit_notification.haml | 4 +- .../partials/_new_comment_notification.haml | 4 +- .../partials/_new_issue_notification.haml | 4 +- .../_wiki_new_commit_notification.haml | 4 +- config/locales/layout/search.ru.yml | 6 +- config/locales/menu.en.yml | 1 + config/locales/menu.ru.yml | 1 + config/locales/models/activity_feed.en.yml | 5 +- config/locales/models/activity_feed.ru.yml | 5 +- config/routes.rb | 9 +- ...wner_name_and_creator_to_activity_feeds.rb | 32 +++ db/schema.rb | 10 +- 41 files changed, 558 insertions(+), 368 deletions(-) delete mode 100644 app/assets/javascripts/angularjs/controllers/activity_controller.js create mode 100644 app/assets/javascripts/angularjs/controllers/activity_controller.js.coffee create mode 100644 app/assets/javascripts/angularjs/services/activity_filter.js.coffee create mode 100644 app/views/home/_activity_tabsets.html.slim create mode 100644 app/views/home/_own_activity_tab.html.slim create mode 100644 app/views/home/get_owners_list.json.jbuilder create mode 100644 app/views/home/get_project_names_list.json.jbuilder create mode 100644 db/migrate/20150502145718_add_owner_name_and_creator_to_activity_feeds.rb diff --git a/app/assets/javascripts/angularjs/controllers/activity_controller.js b/app/assets/javascripts/angularjs/controllers/activity_controller.js deleted file mode 100644 index 742aaa150..000000000 --- a/app/assets/javascripts/angularjs/controllers/activity_controller.js +++ /dev/null @@ -1,201 +0,0 @@ -RosaABF.controller('ActivityCtrl', ['$scope', '$http', '$timeout', '$q', '$filter', '$location', - function($scope, $http, $timeout, $q, $filter, $location) { - $scope.activity_tab = { title: 'activity_menu.activity_feed', filter: 'all', - all: {}, code: {}, tracker: {}, build: {}, wiki: {} }; - $scope.tracker_tab = { title: 'activity_menu.tracker', content: [] , - filter: { all: true, assigned: false, created: false, name: 'all', - all_count: 0, assigned_count: 0, created_count: 0, closed_count: 0 }, - sort: { sort: 'updated', direction: 'desc', updated_class: 'fa-chevron-up' }, - status: 'open', pagination: { page: 1, total_count: 0 } }; - $scope.pull_requests_tab = { title: 'activity_menu.pull_requests', content: [] , - filter: { all: true, assigned: false, created: false, name: 'all', - all_count: 0, assigned_count: 0, created_count: 0, closed_count: 0 }, - sort: { sort: 'updated', direction: 'desc', updated_class: 'fa-chevron-up' }, - status: 'open', pagination: { page: 1, total_count: 0 } }; - - $scope.init = function(active_tab) { - if(active_tab === 'activity') { - $scope.activity_tab.active = true; - } - else if(active_tab === 'issues') { - $scope.tracker_tab.active = true; - } - else if(active_tab === 'pull_requests') { - $scope.pull_requests_tab.active = true; - }; - }; - - $scope.getContent = function(tab){ - var cur_tab = $scope.$eval(tab+'_tab'); - var tmp = $location.path(); - if (tab === 'activity') { - $scope.activity_tab.active = true; - $scope.tracker_tab.active = false; - $scope.pull_requests_tab.active = false; - $scope.getActivityContent(); - if($location.path() !== '/') { - $location.path('/').replace() - }; - } - else if (tab === 'tracker') { - $scope.activity_tab.active = false; - $scope.tracker_tab.active = true; - $scope.pull_requests_tab.active = false; - $scope.getIssuesContent(); - if($location.path() !== '/issues') { - $location.path('/issues').replace() - }; - } - else if (tab === 'pull_requests') { - $scope.activity_tab.active = false; - $scope.tracker_tab.active = false; - $scope.pull_requests_tab.active = true; - $scope.getIssuesContent(); - if($location.path() !== '/pull_requests') { - $location.path('/pull_requests').replace() - }; - }; - }; - - getIssuesTab = function(kind) { - if(kind === 'tracker') { - return $scope.tracker_tab; - } - else if(kind === 'pull_requests') { - return $scope.pull_requests_tab; - }; - }; - - $scope.getTimeLinefaClass = function(content) { - var template = 'btn-warning fa-question'; - - switch(content.kind) { - case 'build_list_notification': - template = 'btn-success fa-gear'; - break; - case 'new_comment_notification': - case 'new_comment_commit_notification': - template = 'btn-warning fa-comment'; - break; - case 'git_new_push_notification': - template = 'bg-primary fa-sign-in'; - break; - case 'new_issue_notification': - template = 'btn-warning fa-check-square-o'; - break; - }; - - return template; - } - - $scope.getCurActivity = function() { - return $scope.activity_tab[$scope.activity_tab.filter]; - }; - - $scope.needShowTimeLabel = function(index) { - var feed = $scope.getCurActivity().feed; - if (feed === undefined) { - return false; - }; - var cur_date = $filter('amDateFormat')(feed[index].date, 'll'); - var prev_date = index == 0 || $filter('amDateFormat')(feed[index-1].date, 'll'); - return cur_date !== prev_date; - }; - - $scope.getTemplate = function(content) { - return content.kind + '.html'; - }; - - $scope.load_more = function() { - var cur_tab = $scope.getCurActivity(); - var path = cur_tab.next_page_link; - if(!path) { - return; - }; - $http.get(path).then(function(res){ - cur_tab.feed.push.apply(cur_tab.feed, res.data.feed); - cur_tab.next_page_link = res.data.next_page_link; - }); - }; - - $scope.changeActivityFilter = function(filter) { - $scope.activity_tab.filter = filter; - $scope.getActivityContent(); - }; - - $scope.getActivityContent = function() { - var path = Routes.root_path({ filter: $scope.activity_tab.filter, format: 'json' }); - $http.get(path).then(function(res) { - $scope.getCurActivity().feed = res.data.feed; - $scope.getCurActivity().next_page_link = res.data.next_page_link; - }); - }; - - $scope.setIssuesFilter = function(kind, issues_filter) { - var filter = getIssuesTab(kind).filter; - - filter.all = false; - filter.assigned = false; - filter.created = false; - filter[issues_filter] = true; - filter.name = issues_filter; - $scope.getIssuesContent(); - }; - - $scope.getIssuesContent = function() { - if($scope.tracker_tab.active) { - var tab = $scope.tracker_tab; - var path = Routes.issues_path({ filter: tab.filter.name, - sort: tab.sort.sort, - direction: tab.sort.direction, - status: tab.status, - page: tab.pagination.page, - format: 'json' }); - } - else if($scope.pull_requests_tab.active) { - var tab = $scope.pull_requests_tab; - var path = Routes.pull_requests_path({ filter: tab.filter.name, - sort: tab.sort.sort, - direction: tab.sort.direction, - status: tab.status, - page: tab.pagination.page, - format: 'json' }); - }; - - $http.get(path).then(function(res) { - tab.content = res.data.content; - tab.filter.all_count = res.data.all_count; - tab.filter.assigned_count = res.data.assigned_count; - tab.filter.created_count = res.data.created_count; - tab.filter.closed_count = res.data.closed_count; - tab.filter.open_count = res.data.open_count; - tab.pagination.page = res.data.page; - tab.pagination.total_items = parseInt(res.data.issues_count, 10); - }); - }; - - $scope.setIssuesSort = function(kind, issues_sort) { - var tab = getIssuesTab(kind); - if(tab.sort.direction === 'desc') { - tab.sort = { sort: issues_sort, direction: 'asc' }; - var sort_class = 'fa-chevron-down'; - } - else { - tab.sort = { sort: issues_sort, direction: 'desc' }; - var sort_class = 'fa-chevron-up'; - }; - tab.sort[issues_sort+'_class'] = sort_class; - $scope.getIssuesContent(); - }; - - $scope.setIssuesStatus = function(kind, issues_status) { - var tab = getIssuesTab(kind); - tab.status = issues_status; - tab.pagination.page = 1; - $scope.getIssuesContent(); - }; - - $scope.selectPage = function(kind, page) { - $scope.getIssuesContent(); - }; -}]); diff --git a/app/assets/javascripts/angularjs/controllers/activity_controller.js.coffee b/app/assets/javascripts/angularjs/controllers/activity_controller.js.coffee new file mode 100644 index 000000000..07a0280c8 --- /dev/null +++ b/app/assets/javascripts/angularjs/controllers/activity_controller.js.coffee @@ -0,0 +1,244 @@ +ActivityController = ($scope, $http, $timeout, $q, $filter, $location, ActivityFilter) -> + + getIssuesTab = (kind)-> + return vm.tracker_tab if kind is 'tracker' + return vm.pull_requests_tab if kind is 'pull_requests' + + vm = this + + + vm.activity_tab = + filter: 'all' + all: {} + code: {} + tracker: {} + build: {} + wiki: {} + owner_filter: null + project_name_filter: null + owner_uname_filter_tmp: null + project_name_filter_tmp: null + + vm.own_activity_tab = $.extend({}, vm.activity_tab) + vm.current_activity_tab = vm.activity_tab + + vm.tracker_tab = + content: [] + filter: + all: true + assigned: false + created: false + name: 'all' + all_count: 0 + assigned_count: 0 + created_count: 0 + closed_count: 0 + sort: + sort: 'updated' + direction: 'desc' + updated_class: 'fa-chevron-up' + status: 'open' + pagination: + page: 1 + total_count: 0 + + vm.pull_requests_tab = $.extend({}, vm.tracker_tab) + + + vm.init = (active_tab)-> + switch active_tab + when 'activity' + vm.activity_tab.active = true + vm.current_activity_tab = vm.activity_tab + when 'own_activity' + vm.own_activity_tab.active = true + vm.current_activity_tab = vm.own_activity_tab + when 'issues' + vm.tracker_tab.active = true + when active_tab is 'pull_requests' + vm.pull_requests_tab.active = true + true + + vm.getContent = (tab)-> + switch tab + when 'activity' + vm.activity_tab.active = true + vm.own_activity_tab.active = false + vm.tracker_tab.active = false + vm.pull_requests_tab.active = false + vm.current_activity_tab = vm.activity_tab + vm.getActivityContent() + if $location.path() isnt '/' + $location.path('/').replace() + + when 'own_activity' + vm.activity_tab.active = false + vm.own_activity_tab.active = true + vm.tracker_tab.active = false + vm.pull_requests_tab.active = false + vm.current_activity_tab = vm.own_activity_tab + vm.getActivityContent() + if $location.path() isnt '/own_activity' + $location.path('/own_activity').replace() + + when 'tracker' + vm.activity_tab.active = false + vm.own_activity_tab.active = false + vm.tracker_tab.active = true + vm.pull_requests_tab.active = false + vm.getIssuesContent() + if $location.path() isnt '/issues' + $location.path('/issues').replace() + + when 'pull_requests' + vm.activity_tab.active = false + vm.own_activity_tab.active = false + vm.tracker_tab.active = false + vm.pull_requests_tab.active = true + vm.getIssuesContent() + if $location.path() isnt '/pull_requests' + $location.path('/pull_requests').replace() + + vm.getTimeLinefaClass = (content)-> + template = switch content.kind + when 'build_list_notification' then 'btn-success fa-gear' + when 'new_comment_notification', 'new_comment_commit_notification' then 'btn-warning fa-comment' + when 'git_new_push_notification' then 'bg-primary fa-sign-in' + when 'new_issue_notification' then 'btn-warning fa-check-square-o' + else 'btn-warning fa-question' + template + + vm.getCurActivity = ()-> + vm.current_activity_tab[vm.current_activity_tab.filter] + + vm.needShowTimeLabel = (index)-> + feed = vm.getCurActivity().feed + return false unless feed + + cur_date = $filter('amDateFormat')(feed[index].date, 'll') + prev_date = index is 0 or $filter('amDateFormat')(feed[index-1].date, 'll') + return cur_date isnt prev_date + + vm.getTemplate = (content)-> + content.kind + '.html' + + vm.load_more = ()-> + cur_tab = vm.getCurActivity() + path = cur_tab.next_page_link + return unless path + + $http.get(path).then (res)-> + cur_tab.feed.push.apply(cur_tab.feed, res.data.feed) + cur_tab.next_page_link = res.data.next_page_link + + vm.changeActivityFilter = (filter)-> + return if vm.current_activity_tab.filter is filter + vm.current_activity_tab.filter = filter + vm.getActivityContent() + + vm.getActivityContent = ()-> + options = + filter: vm.current_activity_tab.filter + owner_filter: vm.current_activity_tab.owner_filter + project_name_filter: vm.current_activity_tab.project_name_filter + format: 'json' + + if vm.activity_tab.active + path = Routes.root_path(options) + else + path = Routes.own_activity_path(options) + + $http.get(path).then (res)-> + vm.getCurActivity().feed = res.data.feed + vm.getCurActivity().next_page_link = res.data.next_page_link + + vm.setIssuesFilter = (kind, issues_filter)-> + filter = getIssuesTab(kind).filter + + filter.all = false + filter.assigned = false + filter.created = false + filter[issues_filter] = true + filter.name = issues_filter + vm.getIssuesContent() + + vm.getIssuesContent = ()-> + if vm.tracker_tab.active + tab = vm.tracker_tab + path = Routes.issues_path( + filter: tab.filter.name + sort: tab.sort.sort + direction: tab.sort.direction + status: tab.status + page: tab.pagination.page + format: 'json') + else if vm.pull_requests_tab.active + tab = vm.pull_requests_tab + path = Routes.pull_requests_path( + filter: tab.filter.name + sort: tab.sort.sort + direction: tab.sort.direction + status: tab.status + page: tab.pagination.page + format: 'json') + + $http.get(path).then (res)-> + tab.content = res.data.content + tab.filter.all_count = res.data.all_count + tab.filter.assigned_count = res.data.assigned_count + tab.filter.created_count = res.data.created_count + tab.filter.closed_count = res.data.closed_count + tab.filter.open_count = res.data.open_count + tab.pagination.page = res.data.page + tab.pagination.total_items = parseInt(res.data.issues_count, 10) + + vm.setIssuesSort = (kind, issues_sort)-> + tab = getIssuesTab(kind) + if tab.sort.direction is 'desc' + tab.sort = { sort: issues_sort, direction: 'asc' } + sort_class = 'fa-chevron-down' + else + tab.sort = { sort: issues_sort, direction: 'desc' } + sort_class = 'fa-chevron-up' + + tab.sort[issues_sort+'_class'] = sort_class + vm.getIssuesContent() + + vm.setIssuesStatus = (kind, issues_status)-> + tab = getIssuesTab(kind) + tab.status = issues_status + tab.pagination.page = 1 + vm.getIssuesContent() + + vm.selectPage = (kind, page)-> + vm.getIssuesContent() + + vm.getOwnersList = (value)-> + return [] if value.length < 1 + ActivityFilter.get_owners(value) + + vm.selectOwnerFilter = (item, model, label)-> + return if vm.current_activity_tab.owner_filter is item.uname + + vm.current_activity_tab.owner_filter = item.uname + vm.current_activity_tab.project_name_filter = null + vm.current_activity_tab.project_name_filter_tmp = null + vm.getActivityContent() + true + + vm.getProjectNamesList = (value)-> + return [] if value.length < 1 + ActivityFilter.get_project_names(vm.current_activity_tab.owner_filter, value) + + vm.selectProjectNameFilter = (item, model, label)-> + return if vm.current_activity_tab.project_name_filter is item.name + vm.current_activity_tab.project_name_filter = item.name + vm.getActivityContent() + true + + +angular + .module("RosaABF") + .controller "ActivityController", ActivityController + +ActivityController.$inject = ['$scope', '$http', '$timeout', '$q', '$filter', '$location', 'ActivityFilter'] diff --git a/app/assets/javascripts/angularjs/locales.js.erb b/app/assets/javascripts/angularjs/locales.js.erb index 4c7262f18..da555bc61 100644 --- a/app/assets/javascripts/angularjs/locales.js.erb +++ b/app/assets/javascripts/angularjs/locales.js.erb @@ -19,7 +19,6 @@ var _locales = { <%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>, // - <%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>, 'tracker.filter.all': '<%= I18n.t('layout.issues.all') %>', 'tracker.filter.assigned': '<%= I18n.t('layout.issues.assigned') %>', 'tracker.filter.created': '<%= I18n.t('layout.issues.created') %>', @@ -66,7 +65,6 @@ var _locales = { <%= BuildList::STATUSES.map{|s| "'build_list.status.#{s}': '#{BuildList.human_status(s)}'"}.join(',') %>, // - <%= I18n.t('activity_menu').map{ |k,v| "'activity_menu.#{k}': '#{v}'" }.join(',') %>, 'tracker.filter.all': '<%= I18n.t('layout.issues.all') %>', 'tracker.filter.assigned': '<%= I18n.t('layout.issues.assigned') %>', 'tracker.filter.created': '<%= I18n.t('layout.issues.created') %>', diff --git a/app/assets/javascripts/angularjs/services/activity_filter.js.coffee b/app/assets/javascripts/angularjs/services/activity_filter.js.coffee new file mode 100644 index 000000000..a8d82e6ca --- /dev/null +++ b/app/assets/javascripts/angularjs/services/activity_filter.js.coffee @@ -0,0 +1,27 @@ +ActivityFilterService = ($http) -> + get_owners: (val) -> + path = Routes.get_owners_list_path( + { + term: val + } + ) + + $http.get(path).then (response) -> + response.data + get_project_names: (owner, val) -> + path = Routes.get_project_names_list_path( + { + owner_uname: owner + term: val + } + ) + + $http.get(path).then (response) -> + response.data + + +angular + .module("RosaABF") + .factory "ActivityFilter", ActivityFilterService + +ActivityFilterService.$inject = ['$http'] diff --git a/app/assets/stylesheets/custom_bootstrap.sass b/app/assets/stylesheets/custom_bootstrap.sass index b1951595b..52e0b202c 100644 --- a/app/assets/stylesheets/custom_bootstrap.sass +++ b/app/assets/stylesheets/custom_bootstrap.sass @@ -38,7 +38,7 @@ $mini-avatar-height: 30px .panel-title a, i.fa-question-circle[data-toggle='modal'], span.fa.fa-times, -.navbar a +.navbar a, ul.dropdown-menu a cursor: pointer footer diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 08b2dc32e..93d33e600 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,5 +1,5 @@ class HomeController < ApplicationController - before_action :authenticate_user!, only: [:activity, :issues, :pull_requests] + before_action :authenticate_user!, except: [:root] skip_after_action :verify_authorized def root @@ -8,21 +8,34 @@ class HomeController < ApplicationController end end - def activity + def activity(is_my_activity = false) @filter = t('feed_menu').has_key?(params[:filter].try(:to_sym)) ? params[:filter].to_sym : :all @activity_feeds = current_user.activity_feeds + .by_project_name(params[:project_name_filter]) + .by_owner_uname(params[:owner_filter]) @activity_feeds = @activity_feeds.where(kind: "ActivityFeed::#{@filter.upcase}".constantize) unless @filter == :all @activity_feeds = @activity_feeds.where(user_id: current_user) if @own_filter == :created @activity_feeds = @activity_feeds.where.not(user_id: current_user) if @own_filter == :not_created + + @activity_feeds = if is_my_activity + @activity_feeds.where(creator_id: current_user) + else + @activity_feeds.where.not(creator_id: current_user) + end + @activity_feeds = @activity_feeds.paginate page: current_page respond_to do |format| format.html { render 'activity' } - format.json {} + format.json { render 'activity' } format.atom end end + def own_activity + activity(true) + end + def issues @created_issues = current_user.issues @assigned_issues = Issue.where(assignee_id: current_user.id) @@ -69,4 +82,31 @@ class HomeController < ApplicationController def pull_requests issues end + + def get_owners_list + if params[:term].present? + users = User.opened.search(params[:term]).pluck(:uname).first(5) + groups = Group.opened.search(params[:term]).pluck(:uname).first(5) + @owners = users | groups + + end + respond_to do |format| + format.json {} + end + end + + def get_project_names_list + if params[:term].present? + @projects = ProjectPolicy::Scope.new(current_user, Project).membered + + @projects = @projects.where(owner_uname: params[:owner_uname]) if params[:owner_uname].present? + @projects = @projects.by_name("%#{params[:term]}%") + .distinct + .pluck(:name) + .first(10) + end + respond_to do |format| + format.json {} + end + end end diff --git a/app/helpers/activity_feeds_helper.rb b/app/helpers/activity_feeds_helper.rb index b2a7b19b7..bf92330c3 100644 --- a/app/helpers/activity_feeds_helper.rb +++ b/app/helpers/activity_feeds_helper.rb @@ -11,7 +11,7 @@ module ActivityFeedsHelper end def get_user_from_activity_item(item) - email = item.data[:user_email] + email = item.data[:creator_email] User.where(email: email).first || User.new(email: email) if email.present? end diff --git a/app/models/activity_feed.rb b/app/models/activity_feed.rb index 0cc809782..7c1ac2f5e 100644 --- a/app/models/activity_feed.rb +++ b/app/models/activity_feed.rb @@ -6,16 +6,19 @@ class ActivityFeed < ActiveRecord::Base WIKI = %w(wiki_new_commit_notification) belongs_to :user - serialize :data + belongs_to :creator, class_name: 'User' + serialize :data attr_accessible :user, :kind, :data default_scope { order created_at: :desc } - scope :outdated, -> { offset(100) } + scope :outdated, -> { offset(200) } + scope :by_project_name, ->(name) { where(project_name: name) if name.present? } + scope :by_owner_uname, ->(owner) { where(project_owner: owner) if owner.present? } - self.per_page = 10 + self.per_page = 20 def partial - 'home/partials/' + self.kind + "home/partials/#{self.kind}" end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 8b0f1d269..11fb7c886 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -199,7 +199,7 @@ class Comment < ActiveRecord::Base if issue_comment? commentable.subscribes.create(user: user) if !commentable.subscribes.exists?(user_id: user.id) elsif commit_comment? - recipients = project.admins + recipients = project.all_members recipients << user << User.find_by(email: commentable.try(:committer).try(:email)) # commentor and committer recipients.compact.uniq.each do |user| options = {project_id: project.id, subscribeable_id: commentable_id, subscribeable_type: commentable.class.name, user_id: user.id} diff --git a/app/models/concerns/feed/build_list.rb b/app/models/concerns/feed/build_list.rb index face782a8..6cbe4529d 100644 --- a/app/models/concerns/feed/build_list.rb +++ b/app/models/concerns/feed/build_list.rb @@ -20,20 +20,20 @@ module Feed::BuildList ) updater = publisher || user - (project.all_members | [publisher].compact).each do |recipient| + (project.all_members | [publisher]).compact.each do |recipient| ActivityFeed.create( - user: recipient, - kind: 'build_list_notification', + user: recipient, + kind: 'build_list_notification', + project_owner: project.owner_uname, + project_name: project.name, + creator_id: updater.id, data: { build_list_id: id, status: status, updated_at: updated_at, project_id: project_id, - project_name: project.name, - project_owner: project.owner.uname, - user_name: updater.name, - user_email: updater.email, - user_id: updater.id + creator_name: updater.name, + creator_email: updater.email } ) end diff --git a/app/models/concerns/feed/comment.rb b/app/models/concerns/feed/comment.rb index b9f5a1248..5bf73923f 100644 --- a/app/models/concerns/feed/comment.rb +++ b/app/models/concerns/feed/comment.rb @@ -18,19 +18,19 @@ module Feed::Comment UserMailer.new_comment_notification(self, subscribe.user_id).deliver ActivityFeed.create( { - user_id: subscribe.user_id, - kind: 'new_comment_notification', - data: { - user_name: user.name, - user_email: user.email, - user_id: user_id, + user_id: subscribe.user_id, + kind: 'new_comment_notification', + project_owner: project.owner_uname, + project_name: project.name, + creator_id: user_id, + data: { + creator_name: user.name, + creator_email: user.email, comment_body: body.truncate(100, omission: '…'), issue_title: commentable.title, issue_serial_id: commentable.serial_id, project_id: commentable.project.id, - comment_id: id, - project_name: project.name, - project_owner: project.owner.uname + comment_id: id } }, without_protection: true ) @@ -47,19 +47,20 @@ module Feed::Comment end ActivityFeed.create( { - user_id: subscribe.user_id, - kind: 'new_comment_commit_notification', + user_id: subscribe.user_id, + kind: 'new_comment_commit_notification', + project_owner: project.owner_uname, + project_name: project.name, + creator_id: user_id, data: { - user_name: user.name, - user_email: user.email, - user_id: user_id, + creator_name: user.name, + creator_email: user.email, + comment_body: body.truncate(100, omission: '…'), commit_message: commentable.message.truncate(70, omission: '…'), commit_id: commentable.id, project_id: project.id, - comment_id: id, - project_name: project.name, - project_owner: project.owner.uname + comment_id: id } }, without_protection: true ) diff --git a/app/models/concerns/feed/git.rb b/app/models/concerns/feed/git.rb index e3976f34a..d9b985359 100644 --- a/app/models/concerns/feed/git.rb +++ b/app/models/concerns/feed/git.rb @@ -13,8 +13,7 @@ module Feed::Git if change_type == 'delete' kind = 'git_delete_branch_notification' - options = {project_id: record.project.id, project_name: record.project.name, branch_name: branch_name, - change_type: change_type, project_owner: record.project.owner.uname} + options = {project_id: record.project.id, branch_name: branch_name, change_type: change_type} else if record.message # online update last_commits, commits = [[record.newrev, record.message.truncate(70, omission: '…')]], [] @@ -26,8 +25,8 @@ module Feed::Git end kind = 'git_new_push_notification' - options = {project_id: record.project.id, project_name: record.project.name, last_commits: last_commits, - branch_name: branch_name, change_type: change_type, project_owner: record.project.owner.uname} + options = {project_id: record.project.id, last_commits: last_commits, + branch_name: branch_name, change_type: change_type} if commits.count > 3 commits = commits[0...-3] options.merge!({other_commits_count: commits.count, other_commits: "#{commits[0].sha[0..9]}...#{commits[-1].sha[0..9]}"}) @@ -44,13 +43,16 @@ module Feed::Git Comment.create_link_on_issues_from_item(record, all_commits) end end - options.merge!({user_id: record.user.id, user_name: record.user.name, user_email: record.user.email}) if record.user + options.merge!({creator_name: record.user.name, creator_email: record.user.email}) if record.user - record.project.admins.each do |recipient| + record.project.all_members.each do |recipient| ActivityFeed.create!( - user: recipient, - kind: kind, - data: options + user: recipient, + kind: kind, + project_owner: record.project.owner_uname, + project_name: record.project.name, + creator_id: record.user.id, + data: options ) next if record.user && record.user.id == recipient.id if recipient.notifier.can_notify && recipient.notifier.update_code @@ -62,12 +64,15 @@ module Feed::Git actor = User.find_by! uname: record[:actor_name] project = Project.find record[:project_id] - project.admins.each do |recipient| + project.all_members.each do |recipient| ActivityFeed.create!( user: recipient, kind: 'wiki_new_commit_notification', - data: {user_id: actor.id, user_name: actor.name, user_email: actor.email, project_id: project.id, - project_name: project.name, commit_sha: record[:commit_sha], project_owner: project.owner.uname} + project_owner: project.owner_uname, + project_name: project.name, + creator_id: actor.id, + data: {creator_name: actor.name, creator_email: actor.email, + project_id: project.id, commit_sha: record[:commit_sha]} ) end end diff --git a/app/models/concerns/feed/issue.rb b/app/models/concerns/feed/issue.rb index 9da3e2836..1d0b951fb 100644 --- a/app/models/concerns/feed/issue.rb +++ b/app/models/concerns/feed/issue.rb @@ -20,17 +20,17 @@ module Feed::Issue UserMailer.new_issue_notification(id, recipient.id).deliver end ActivityFeed.create( - user: recipient, - kind: 'new_issue_notification', + user: recipient, + kind: 'new_issue_notification', + project_owner: project.owner_uname, + project_name: project.name, + creator_id: user_id, data: { - user_name: user.name, - user_email: user.email, - user_id: user_id, + creator_name: user.name, + creator_email: user.email, issue_serial_id: serial_id, issue_title: title, - project_id: project.id, - project_name: project.name, - project_owner: project.owner.uname + project_id: project.id } ) end @@ -47,14 +47,14 @@ module Feed::Issue ActivityFeed.create( user: assignee, kind: 'issue_assign_notification', + project_owner: project.owner_uname, + project_name: project.name, data: { user_name: assignee.name, user_email: assignee.email, issue_serial_id: serial_id, issue_title: title, - project_id: project.id, - project_name: project.name, - project_owner: project.owner.uname + project_id: project.id } ) end diff --git a/app/models/concerns/project/finders.rb b/app/models/concerns/project/finders.rb index a2654cdbf..cf9ca04af 100644 --- a/app/models/concerns/project/finders.rb +++ b/app/models/concerns/project/finders.rb @@ -13,8 +13,9 @@ module Project::Finders q = q.to_s.strip by_name("%#{q}%").search_order if q.present? } - scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? } - scope :by_owner, ->(name) { where('projects.owner_uname ILIKE ?', "%#{name}%") if name.present? } + scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? } + scope :by_owner, ->(name) { where('projects.owner_uname ILIKE ?', "%#{name}%") if name.present? } + scope :by_owner_and_name, ->(*params) { term = params.map(&:strip).join('/').downcase where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present? diff --git a/app/models/issue.rb b/app/models/issue.rb index 83b88c2ad..47f0f5f82 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -99,7 +99,7 @@ class Issue < ActiveRecord::Base end def collect_recipients - recipients = self.project.admins + recipients = self.project.all_members recipients = recipients | [self.assignee] if self.assignee recipients end diff --git a/app/views/home/_activity_tab.html.slim b/app/views/home/_activity_tab.html.slim index 95060d299..d03e86557 100644 --- a/app/views/home/_activity_tab.html.slim +++ b/app/views/home/_activity_tab.html.slim @@ -1,4 +1,6 @@ -tab heading = "{{activity_tab.title | i18n}}" active = "activity_tab.active" select = "getContent('activity')" +tab[ heading= t('activity_menu.activity_feed') + active= "actCtrl.activity_tab.active" + select = "actCtrl.getContent('activity')" ] .row .col-md-3.offset10== render 'sidebar' .col-md-9.offset10 @@ -6,22 +8,4 @@ tab heading = "{{activity_tab.title | i18n}}" active = "activity_tab.active" sel = t 'layout.activity_feed.header' = link_to image_tag('rss.ico', width: '15px', height: '15px', class: 'atom_icon'), atom_activity_feeds_path(format: 'atom', token: current_user.authentication_token) - tabset - - (collection = t 'feed_menu').each do |base, title| - tab heading = title active = (@filter == base) select = "changeActivityFilter('#{base}')" - / The time line - .row.offset10 - .col-md-12.col-sm-12 - ul.timeline - / timeline time label - li.time-label ng-repeat-start = 'item in getCurActivity().feed' - span ng-show = "needShowTimeLabel($index)" - | {{item.date | amDateFormat:'ll'}} - / timeline item - li ng-include = "getTemplate(item)" - .hide ng-repeat-end = true - li - i.img-circle.bg-primary.fa.fa-clock-o - hr - btn.center-block.btn.btn-primary ng-show = 'getCurActivity().next_page_link' ng-click = "load_more()" - = t('layout.activity_feed.load_messages') + == render 'activity_tabsets' diff --git a/app/views/home/_activity_tabsets.html.slim b/app/views/home/_activity_tabsets.html.slim new file mode 100644 index 000000000..e207308fc --- /dev/null +++ b/app/views/home/_activity_tabsets.html.slim @@ -0,0 +1,20 @@ +tabset + - (collection = t 'feed_menu').each do |base, title| + tab heading= title active= (@filter == base) select= "actCtrl.changeActivityFilter('#{base}')" +/ The time line +.row.offset10 + .col-md-12.col-sm-12 + ul.timeline + / timeline time label + li.time-label ng-repeat-start= 'item in actCtrl.getCurActivity().feed' + span ng-show= "actCtrl.needShowTimeLabel($index)" + | {{item.date | amDateFormat:'ll'}} + / timeline item + li ng-include= "actCtrl.getTemplate(item)" + .hide ng-repeat-end= true + li + i.img-circle.bg-primary.fa.fa-clock-o +hr +btn.center-block.btn.btn-primary[ ng-show= 'actCtrl.getCurActivity().next_page_link' + ng-click= "actCtrl.load_more()" ] + = t('layout.activity_feed.load_messages') diff --git a/app/views/home/_filters.html.slim b/app/views/home/_filters.html.slim index a33859664..bc30ae6a9 100644 --- a/app/views/home/_filters.html.slim +++ b/app/views/home/_filters.html.slim @@ -1,15 +1,17 @@ -hr.offset10 - h3=t('layout.relations.filters') - -input.form-control[ name = 'search' - size = 30 - type = 'text' - ng-model = 'search' - placeholder = t('layout.find_project') - ng-change = 'filterProjects()' ] - -ul.nav.nav-pills.nav-stacked - - options_for_filters(@projects, @groups, @owners).each do |options| - li{ 'ng-class' => "{active: #{options[:class_name]}_filter_#{options[:id]}_class}" } - a{ href: '#', 'ng-click' => "change_#{options[:class_name]}_filter(#{options[:id]})" } - = options[:uname] +hr + h4=t('layout.relations.filters') +.form-group + = text_field_tag :owner_uname, nil, + class: 'form-control', + placeholder: t('search.placeholders.owner_filter'), + 'ng-model' => 'actCtrl.current_activity_tab.owner_uname_filter_tmp', + 'typeahead' => 'owner.uname for owner in actCtrl.getOwnersList($viewValue)', + 'typeahead-on-select' => 'actCtrl.selectOwnerFilter($item, $model, $label)' +.form-group + = text_field_tag :project_name, nil, + class: 'form-control', + placeholder: t('search.placeholders.name_filter'), + 'ng-model' => 'actCtrl.current_activity_tab.project_name_filter_tmp', + 'ng-value' => 'actCtrl.current_activity_tab.project_name_filter_tmp', + 'typeahead' => 'project.name for project in actCtrl.getProjectNamesList($viewValue)', + 'typeahead-on-select' => 'actCtrl.selectProjectNameFilter($item, $model, $label)' diff --git a/app/views/home/_own_activity_tab.html.slim b/app/views/home/_own_activity_tab.html.slim new file mode 100644 index 000000000..182d99e32 --- /dev/null +++ b/app/views/home/_own_activity_tab.html.slim @@ -0,0 +1,9 @@ +tab[ heading= t('activity_menu.own_activity') + active= "actCtrl.own_activity_tab.active" + select = "actCtrl.getContent('own_activity')" ] + .row + .col-md-3.offset10== render 'sidebar' + .col-md-9.offset10 + h3 + = t 'layout.activity_feed.own_header' + == render 'activity_tabsets' diff --git a/app/views/home/_sidebar.html.slim b/app/views/home/_sidebar.html.slim index 2bd327745..63e473323 100644 --- a/app/views/home/_sidebar.html.slim +++ b/app/views/home/_sidebar.html.slim @@ -1,6 +1,7 @@ p = link_to t('layout.activity_feed.new_project'), new_project_path, class: 'btn btn-primary btn-small', role: 'button' +== render 'filters' hr h5= t('layout.activity_feed.my_last_projects') diff --git a/app/views/home/_tracker_and_pulls_tabs.html.slim b/app/views/home/_tracker_and_pulls_tabs.html.slim index dd98bb47a..304651f9d 100644 --- a/app/views/home/_tracker_and_pulls_tabs.html.slim +++ b/app/views/home/_tracker_and_pulls_tabs.html.slim @@ -1,70 +1,70 @@ - %w(tracker pull_requests).each do |kind| - tab[ heading = "{{#{kind}_tab.title | i18n}}" - active = "#{kind}_tab.active" - select = "getContent('#{kind}')" ] + tab[ heading= t("activity_menu.#{kind}") + active= "actCtrl.#{kind}_tab.active" + select= "actCtrl.getContent('#{kind}')" ] .row .col-md-3.offset10 ul.nav.nav-pills.nav-stacked - %w(all assigned created).each do |kind_filter| - li ng-class = "{ active: #{kind}_tab.filter.#{kind_filter} }" - a ng-click = "setIssuesFilter('#{kind}', '#{kind_filter}')" - span.badge.pull-right= "{{ #{kind}_tab.filter.#{kind_filter}_count }}" + li ng-class= "{ active: actCtrl.#{kind}_tab.filter.#{kind_filter} }" + a ng-click= "actCtrl.setIssuesFilter('#{kind}', '#{kind_filter}')" + span.badge.pull-right= "{{ actCtrl.#{kind}_tab.filter.#{kind_filter}_count }}" = "{{'#{kind}.filter.#{kind_filter}' | i18n}}" .col-md-9.offset10 tabset.boffset10 - %w(open closed).each do |status| - - count_issues = "({{#{kind}_tab.filter.#{status}_count}})" - tab[ heading = "#{t "layout.issues.statuses.#{status}"} #{count_issues}" - active = "#{kind}_tab.status_#{status}" - ng-click = "setIssuesStatus('#{kind}', '#{status}')" ] + - count_issues = "({{actCtrl.#{kind}_tab.filter.#{status}_count}})" + tab[ heading= "#{t "layout.issues.statuses.#{status}"} #{count_issues}" + active= "actCtrl.#{kind}_tab.status_#{status}" + ng-click= "actCtrl.setIssuesStatus('#{kind}', '#{status}')" ] .pull-right.boffset10 - button.btn.btn-default.roffset5[ type = 'button' - ng-click = "setIssuesSort('#{kind}', 'updated')" ] - span.fa ng-class = "#{kind}_tab.sort.updated_class" + button.btn.btn-default.roffset5[ type= 'button' + ng-click= "actCtrl.setIssuesSort('#{kind}', 'updated')" ] + span.fa ng-class= "actCtrl.#{kind}_tab.sort.updated_class" => t('layout.issues.sort.updated') - button.btn.btn-default[ type = 'button' - ng-click = "setIssuesSort('#{kind}', 'submitted')" ] - span.fa ng-class = "#{kind}_tab.sort.submitted_class" + button.btn.btn-default[ type= 'button' + ng-click= "actCtrl.setIssuesSort('#{kind}', 'submitted')" ] + span.fa ng-class= "actCtrl.#{kind}_tab.sort.submitted_class" => t('layout.issues.sort.submitted') table.table - tr ng-repeat = "issue in #{kind}_tab.content" + tr ng-repeat= "issue in actCtrl.#{kind}_tab.content" td - a ng-href = "{{issue.issue_url}}" + a ng-href= "{{issue.issue_url}}" span.text-info = '{{issue.project_name}} ' | {{issue.title}} - span.label.small.loffset5[ ng-repeat = "label in issue.labels" - ng-style = "{background: label.color}" ] + span.label.small.loffset5[ ng-repeat= "label in issue.labels" + ng-style= "{background: label.color}" ] | {{label.name}} .small = t 'layout.issues.created_by' - a>[ ng-href = "{{issue.user.path}}" ] {{issue.user.uname}} - span.text-muted[ ng-show = '#{kind}_tab.sort.sort == "submitted"' - title = "{{issue.created_at_utc}}" ] + a>[ ng-href= "{{issue.user.path}}" ] {{issue.user.uname}} + span.text-muted[ ng-show= 'actCtrl.#{kind}_tab.sort.sort == "submitted"' + title= "{{issue.created_at_utc}}" ] | {{issue.created_at | amDateFormat:'YYYY-MM-DD HH:mm'}} ( - span am-time-ago = 'issue.created_at' + span am-time-ago= 'issue.created_at' | ) - span> class = 'text-muted' ng-show = '#{kind}_tab.sort.sort == "updated"' + span> class= 'text-muted' ng-show= 'actCtrl.#{kind}_tab.sort.sort == "updated"' = t 'layout.issues.updated_at' - span.text-muted[ ng-show = '#{kind}_tab.sort.sort == "updated"' - title = "{{issue.updated_at_utc}}" ] + span.text-muted[ ng-show= 'actCtrl.#{kind}_tab.sort.sort == "updated"' + title= "{{issue.updated_at_utc}}" ] | {{issue.updated_at | amDateFormat:'YYYY-MM-DD HH:mm'}} ( - span am-time-ago = 'issue.updated_at' + span am-time-ago= 'issue.updated_at' | ) td - a ng-href = "{{issue.issue_url + '#comments'}}" + a ng-href= "{{issue.issue_url + '#comments'}}" span.fa.fa-comments.text-primary = " {{issue.comments_count}}" td - a>[ ng-href = '{{issue.assignee.link}}' - title = "#{t('layout.issues.assigned_to')} {{issue.assignee.fullname}}" ] - img ng-src = '{{issue.assignee.image}}' + a>[ ng-href= '{{issue.assignee.link}}' + title= "#{t('layout.issues.assigned_to')} {{issue.assignee.fullname}}" ] + img ng-src= '{{issue.assignee.image}}' span.text-muted.roffset5 | {{'#' + issue.serial_id}} - = angularjs_paginate( total_items: "#{kind}_tab.pagination.total_items", - page: "#{kind}_tab.pagination.page", + = angularjs_paginate( total_items: "actCtrl.#{kind}_tab.pagination.total_items", + page: "actCtrl.#{kind}_tab.pagination.page", per_page: Issue.per_page, - select_page: "selectPage('#{kind}', page)" ) + select_page: "actCtrl.selectPage('#{kind}', page)" ) diff --git a/app/views/home/activity.atom.builder b/app/views/home/activity.atom.builder index b54d1eb09..f4849c1de 100644 --- a/app/views/home/activity.atom.builder +++ b/app/views/home/activity.atom.builder @@ -4,14 +4,17 @@ atom_feed do |feed| @activity_feeds.each do |activity_feed| feed.entry(activity_feed, url: root_url(anchor: "feed#{activity_feed.id}")) do |entry| - feed_content = raw(render(inline: true, partial: activity_feed.partial, locals: activity_feed.data.merge(activity_feed: activity_feed))) + feed_content = raw(render(inline: true, partial: activity_feed.partial, + locals: activity_feed.data.merge(activity_feed: activity_feed, + project_owner: activity_feed.project_owner, + project_name: activity_feed.project_name))) entry.title(truncate(get_feed_title_from_content(feed_content), length: 50)) entry.content(feed_content, type: 'html') entry.author do |author| - author.name(activity_feed.data[:user_name]) - author.email(activity_feed.data[:user_email]) + author.name(activity_feed.data[:creator_name]) + author.email(activity_feed.data[:creator_email]) end if activity_feed.kind != 'git_delete_branch_notification' end end diff --git a/app/views/home/activity.html.slim b/app/views/home/activity.html.slim index 25df3829c..a9c98e752 100644 --- a/app/views/home/activity.html.slim +++ b/app/views/home/activity.html.slim @@ -1,6 +1,8 @@ -set_meta_tags title: nil .row - .col-xs-12.col-md-10.col-md-offset-1 ng-controller = 'ActivityCtrl' ng-init = "init('#{action_name}')" - tabset.offset10 ng-cloak = true + .col-xs-12.col-md-10.col-md-offset-1[ ng-controller= 'ActivityController as actCtrl' + ng-init= "actCtrl.init('#{action_name}')" ] + tabset.offset10 ng-cloak= true == render 'activity_tab' == render 'tracker_and_pulls_tabs' + == render 'own_activity_tab' diff --git a/app/views/home/activity.json.jbuilder b/app/views/home/activity.json.jbuilder index c3feedd0a..0841693c9 100644 --- a/app/views/home/activity.json.jbuilder +++ b/app/views/home/activity.json.jbuilder @@ -1,5 +1,9 @@ if @activity_feeds.next_page - json.next_page_link root_path(filter: @filter, page: @activity_feeds.next_page, format: :json) + json.next_page_link root_path(filter: @filter, + page: @activity_feeds.next_page, + owner_filter: @owner_filter, + project_name_filter: @project_name_filter, + format: :json) end json.feed do @@ -14,7 +18,7 @@ json.feed do json.uname (user.fullname || user.email) end if user - project_name_with_owner = "#{item.data[:project_owner]}/#{item.data[:project_name]}" + project_name_with_owner = "#{item.project_owner}/#{item.project_name}" @project = Project.find_by_owner_and_name(item.data[:project_owner], item.data[:project_name]) json.project_name_with_owner project_name_with_owner diff --git a/app/views/home/get_owners_list.json.jbuilder b/app/views/home/get_owners_list.json.jbuilder new file mode 100644 index 000000000..bd79d6c15 --- /dev/null +++ b/app/views/home/get_owners_list.json.jbuilder @@ -0,0 +1,3 @@ +json.array!(@owners) do |uname| + json.uname uname +end \ No newline at end of file diff --git a/app/views/home/get_project_names_list.json.jbuilder b/app/views/home/get_project_names_list.json.jbuilder new file mode 100644 index 000000000..da9045ac6 --- /dev/null +++ b/app/views/home/get_project_names_list.json.jbuilder @@ -0,0 +1,3 @@ +json.array!(@projects) do |name| + json.name name +end \ No newline at end of file diff --git a/app/views/home/partials/_build_list_notification.haml b/app/views/home/partials/_build_list_notification.haml index 5617d3529..e3f0253a9 100644 --- a/app/views/home/partials/_build_list_notification.haml +++ b/app/views/home/partials/_build_list_notification.haml @@ -1,4 +1,4 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.persisted? .text diff --git a/app/views/home/partials/_git_delete_branch_notification.haml b/app/views/home/partials/_git_delete_branch_notification.haml index 87b10bf7f..bf856518f 100644 --- a/app/views/home/partials/_git_delete_branch_notification.haml +++ b/app/views/home/partials/_git_delete_branch_notification.haml @@ -1,9 +1,9 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.try(:persisted?) .text %span - -_user_link = defined?(user_email) ? user_link(user, defined?(user_name) ? user_name : user_email) : nil + -_user_link = defined?(creator_email) ? user_link(user, defined?(creator_name) ? creator_name : creator_email) : nil = t('notifications.bodies.delete_branch', branch_name: branch_name, user_link: _user_link).html_safe - name_with_owner = "#{project_owner}/#{project_name}" = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) diff --git a/app/views/home/partials/_git_new_push_notification.haml b/app/views/home/partials/_git_new_push_notification.haml index ab6de1112..a791ff342 100644 --- a/app/views/home/partials/_git_new_push_notification.haml +++ b/app/views/home/partials/_git_new_push_notification.haml @@ -1,10 +1,10 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) - name_with_owner = "#{project_owner}/#{project_name}" .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.try(:persisted?) .text %span - -_user_link = defined?(user_email) ? user_link(user, defined?(user_name) ? user_name : user_email) : nil + -_user_link = defined?(creator_email) ? user_link(user, defined?(creator_name) ? creator_name : creator_email) : nil = raw t("notifications.bodies.#{change_type}_branch", {branch_name: branch_name, user_link: _user_link}) = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) .both diff --git a/app/views/home/partials/_new_comment_commit_notification.haml b/app/views/home/partials/_new_comment_commit_notification.haml index 246626ff1..5d2cd01b4 100644 --- a/app/views/home/partials/_new_comment_commit_notification.haml +++ b/app/views/home/partials/_new_comment_commit_notification.haml @@ -1,10 +1,10 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) - name_with_owner = "#{project_owner}/#{project_name}" .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.persisted? .text %span - = raw t("notifications.bodies.new_comment_notification.title", user_link: user_link(user, user_name)) + = raw t("notifications.bodies.new_comment_notification.title", user_link: user_link(user, creator_name)) = raw t("notifications.bodies.new_comment_notification.commit_content", {commit_link: link_to(commit_message, commit_path(name_with_owner, commit_id) + "#comment#{comment_id}")}) = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) .both diff --git a/app/views/home/partials/_new_comment_notification.haml b/app/views/home/partials/_new_comment_notification.haml index 5e26eba5c..3a961e0ac 100644 --- a/app/views/home/partials/_new_comment_notification.haml +++ b/app/views/home/partials/_new_comment_notification.haml @@ -1,10 +1,10 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) - name_with_owner = "#{project_owner}/#{project_name}" .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.persisted? .text %span - = raw t("notifications.bodies.new_comment_notification.title", {user_link: user_link(user, user_name)}) + = raw t("notifications.bodies.new_comment_notification.title", {user_link: user_link(user, creator_name)}) = raw t("notifications.bodies.new_comment_notification.content", {issue_link: link_to(issue_title, project_issue_path(name_with_owner, issue_serial_id) + "#comment#{comment_id}")}) = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) .both diff --git a/app/views/home/partials/_new_issue_notification.haml b/app/views/home/partials/_new_issue_notification.haml index 031c9524c..cb7055854 100644 --- a/app/views/home/partials/_new_issue_notification.haml +++ b/app/views/home/partials/_new_issue_notification.haml @@ -1,11 +1,11 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) - name_with_owner = "#{project_owner}/#{project_name}" - issue_path = issue_serial_id.present? ? project_issue_path(name_with_owner, issue_serial_id) : '#' .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.persisted? .text %span - = raw t("notifications.bodies.new_issue_notification", { user_link: user_link(user, user_name), issue_link: issue_path }) + = raw t("notifications.bodies.new_issue_notification", { user_link: user_link(user, creator_name), issue_link: issue_path }) = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) .both = datetime_moment activity_feed.created_at, tag: :span, class: 'date' diff --git a/app/views/home/partials/_wiki_new_commit_notification.haml b/app/views/home/partials/_wiki_new_commit_notification.haml index 6ddc48aa9..53b7f5d0d 100644 --- a/app/views/home/partials/_wiki_new_commit_notification.haml +++ b/app/views/home/partials/_wiki_new_commit_notification.haml @@ -1,10 +1,10 @@ --user= User.where(email: user_email).first || User.new(email: user_email) if defined?(user_email) +-user= User.where(email: creator_email).first || User.new(email: creator_email) if defined?(creator_email) - name_with_owner = "#{project_owner}/#{project_name}" .top .image= link_to(image_tag(avatar_url(user, :small), alt: 'avatar'), user_path(user)) if user.persisted? .text %span - = raw t("notifications.bodies.wiki_new_commit_notification", {user_link: user_link(user, user_name), history_link: link_to("wiki", history_project_wiki_index_path(name_with_owner))}) + = raw t("notifications.bodies.wiki_new_commit_notification", {user_link: user_link(user, creator_name), history_link: link_to("wiki", history_project_wiki_index_path(name_with_owner))}) = raw t("notifications.bodies.project", project_link: link_to(name_with_owner, project_path(name_with_owner)) ) .both = datetime_moment activity_feed.created_at, tag: :span, class: 'date' diff --git a/config/locales/layout/search.ru.yml b/config/locales/layout/search.ru.yml index 7d7ab6ea3..941355904 100644 --- a/config/locales/layout/search.ru.yml +++ b/config/locales/layout/search.ru.yml @@ -14,7 +14,11 @@ ru: platforms: Платформы project: - updated: "Обновлен:" + updated: "Обновлен:" + + placeholders: + owner_filter: Владелец проекта + name_filter: Имя проекта simple_form: placeholders: diff --git a/config/locales/menu.en.yml b/config/locales/menu.en.yml index 53e7d9aea..fd636af5f 100644 --- a/config/locales/menu.en.yml +++ b/config/locales/menu.en.yml @@ -40,6 +40,7 @@ en: activity_feed: Activity Feed tracker: Tracker pull_requests: Pull Requests + own_activity: Own activity feed_menu: all: All code: Code diff --git a/config/locales/menu.ru.yml b/config/locales/menu.ru.yml index 0beabbae7..f2162054c 100644 --- a/config/locales/menu.ru.yml +++ b/config/locales/menu.ru.yml @@ -40,6 +40,7 @@ ru: activity_feed: Лента активности tracker: Трекер pull_requests: Пул реквесты + own_activity: Мои действия feed_menu: all: Все code: Код diff --git a/config/locales/models/activity_feed.en.yml b/config/locales/models/activity_feed.en.yml index 68314ca55..e1fe30da9 100644 --- a/config/locales/models/activity_feed.en.yml +++ b/config/locales/models/activity_feed.en.yml @@ -2,6 +2,7 @@ en: layout: activity_feed: header: Activity Feed + own_header: Own Activity Feed my_last_projects: My last projects all_my_projects: All my projects all_my_builds: All my builds @@ -9,10 +10,6 @@ en: new_project: Create project load_messages: show previous messages atom_title: Activity Feed - filters: - all: All - my: Mine - others: Others notifications: subjects: diff --git a/config/locales/models/activity_feed.ru.yml b/config/locales/models/activity_feed.ru.yml index fee899c8d..a466569f4 100644 --- a/config/locales/models/activity_feed.ru.yml +++ b/config/locales/models/activity_feed.ru.yml @@ -2,6 +2,7 @@ ru: layout: activity_feed: header: Лента активности + own_header: Мои действия my_last_projects: Мои последние проекты all_my_projects: Все мои проекты all_my_builds: Все мои сборки @@ -9,10 +10,6 @@ ru: new_project: Создать проект load_messages: показать предыдущие сообщения atom_title: Лента активности - filters: - all: Вся - my: Моя - others: Чужая notifications: subjects: diff --git a/config/routes.rb b/config/routes.rb index eb17da98b..94832cf89 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -144,9 +144,12 @@ Rosa::Application.routes.draw do get '/tour/:id' => 'pages#tour_inside', as: 'tour_inside', id: /projects|sources|builds/ #match '/invite.html' => redirect('/register_requests/new') - get '/activity_feeds.:format' => 'home#activity', as: 'atom_activity_feeds', format: /atom/ - get '/issues' => 'home#issues' - get '/pull_requests' => 'home#pull_requests' + get '/activity_feeds.:format' => 'home#activity', as: 'atom_activity_feeds', format: /atom/ + get '/own_activity' => 'home#own_activity', as: 'own_activity' + get '/issues' => 'home#issues' + get '/pull_requests' => 'home#pull_requests' + get '/get_owners_list' => 'home#get_owners_list' + get '/get_project_names_list' => 'home#get_project_names_list' if APP_CONFIG['anonymous_access'] authenticated do diff --git a/db/migrate/20150502145718_add_owner_name_and_creator_to_activity_feeds.rb b/db/migrate/20150502145718_add_owner_name_and_creator_to_activity_feeds.rb new file mode 100644 index 000000000..c95edfa38 --- /dev/null +++ b/db/migrate/20150502145718_add_owner_name_and_creator_to_activity_feeds.rb @@ -0,0 +1,32 @@ +class AddOwnerNameAndCreatorToActivityFeeds < ActiveRecord::Migration + def up + add_column :activity_feeds, :project_owner, :string + add_column :activity_feeds, :project_name, :string + add_column :activity_feeds, :creator_id, :integer + + add_index :activity_feeds, :project_owner + add_index :activity_feeds, :project_name + add_index :activity_feeds, :creator_id + + ActivityFeed.reset_column_information + ActivityFeed.find_each do |feed| + feed.project_owner = feed.data[:project_owner] + feed.project_name = feed.data[:project_name] + feed.creator_id = feed.data[:user_id] + feed.data[:creator_name] = feed.data[:user_name] + feed.data[:creator_email] = feed.data[:user_email] + feed.data[:project_owner] = nil + feed.data[:project_name] = nil + feed.data[:user_id] = nil + feed.data[:user_name] = nil + feed.data[:user_email] = nil + feed.save + end + end + + def down + remove_column :activity_feeds, :project_owner + remove_column :activity_feeds, :project_name + remove_column :activity_feeds, :creator_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 51a4cfb3d..cdd653967 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,18 +11,24 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150218231015) do +ActiveRecord::Schema.define(version: 20150502145718) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "hstore" create_table "activity_feeds", force: true do |t| - t.integer "user_id", null: false + t.integer "user_id", null: false t.string "kind" t.text "data" t.datetime "created_at" t.datetime "updated_at" + t.string "project_owner" + t.string "project_name" + t.integer "creator_id" + t.index ["creator_id"], :name => "index_activity_feeds_on_creator_id" + t.index ["project_name"], :name => "index_activity_feeds_on_project_name" + t.index ["project_owner"], :name => "index_activity_feeds_on_project_owner" t.index ["user_id", "kind"], :name => "index_activity_feeds_on_user_id_and_kind" end