diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/contexts/projects/update_context.rb | 8 | ||||
-rw-r--r-- | app/controllers/dashboard_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/issues_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/projects/merge_requests_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/projects/notes_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects_controller.rb | 20 | ||||
-rw-r--r-- | app/helpers/search_helper.rb | 4 | ||||
-rw-r--r-- | app/models/ability.rb | 37 | ||||
-rw-r--r-- | app/models/issue.rb | 14 | ||||
-rw-r--r-- | app/models/merge_request.rb | 14 | ||||
-rw-r--r-- | app/models/note.rb | 15 | ||||
-rw-r--r-- | app/models/project.rb | 17 | ||||
-rw-r--r-- | app/views/dashboard/projects.html.haml | 4 | ||||
-rw-r--r-- | app/views/projects/_home_panel.html.haml | 4 | ||||
-rw-r--r-- | app/views/projects/edit.html.haml | 27 |
15 files changed, 147 insertions, 23 deletions
diff --git a/app/contexts/projects/update_context.rb b/app/contexts/projects/update_context.rb index 55a4a6abecb..ed0d451a31a 100644 --- a/app/contexts/projects/update_context.rb +++ b/app/contexts/projects/update_context.rb @@ -10,13 +10,7 @@ module Projects new_branch = params[:project].delete(:default_branch) if project.repository.exists? && new_branch != project.default_branch - GitlabShellWorker.perform_async( - :update_repository_head, - project.path_with_namespace, - new_branch - ) - - project.reload_default_branch + project.change_head(new_branch) end project.update_attributes(params[:project], as: role) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 045e5805bd0..aaab4b40c4c 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -73,6 +73,6 @@ class DashboardController < ApplicationController protected def load_projects - @projects = current_user.authorized_projects.sorted_by_activity + @projects = current_user.authorized_projects.sorted_by_activity.non_archived end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 5dcdba5d388..e7b4c837ae3 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -74,6 +74,7 @@ class Projects::IssuesController < Projects::ApplicationController def update @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id)) + @issue.reset_events_cache respond_to do |format| format.js diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 7d7c1104ec9..6d39673194a 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -97,6 +97,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id)) @merge_request.reload_code @merge_request.mark_as_unchecked + @merge_request.reset_events_cache redirect_to [@merge_request.target_project, @merge_request], notice: 'Merge request was successfully updated.' else render "edit" diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb index 2738a99459d..5ff5c5b7d96 100644 --- a/app/controllers/projects/notes_controller.rb +++ b/app/controllers/projects/notes_controller.rb @@ -39,6 +39,7 @@ class Projects::NotesController < Projects::ApplicationController @note = @project.notes.find(params[:id]) return access_denied! unless can?(current_user, :admin_note, @note) @note.destroy + @note.reset_events_cache respond_to do |format| format.js { render nothing: true } @@ -50,6 +51,7 @@ class Projects::NotesController < Projects::ApplicationController return access_denied! unless can?(current_user, :admin_note, @note) @note.update_attributes(params[:note]) + @note.reset_events_cache respond_to do |format| format.js do diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 1835671fe98..e1c55e7d913 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -5,7 +5,7 @@ class ProjectsController < ApplicationController # Authorize before_filter :authorize_read_project!, except: [:index, :new, :create] - before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer] + before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive] before_filter :require_non_empty_project, only: [:blob, :tree, :graph] layout 'navless', only: [:new, :create, :fork] @@ -116,6 +116,24 @@ class ProjectsController < ApplicationController end end + def archive + return access_denied! unless can?(current_user, :archive_project, project) + project.archive! + + respond_to do |format| + format.html { redirect_to @project } + end + end + + def unarchive + return access_denied! unless can?(current_user, :archive_project, project) + project.unarchive! + + respond_to do |format| + format.html { redirect_to @project } + end + end + private def set_title diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 109acfd192b..f24156e4d85 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -73,14 +73,14 @@ module SearchHelper # Autocomplete results for the current user's projects def projects_autocomplete - current_user.authorized_projects.map do |p| + current_user.authorized_projects.non_archived.map do |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } end end # Autocomplete results for the current user's projects def public_projects_autocomplete - Project.public_or_internal_only(current_user).map do |p| + Project.public_or_internal_only(current_user).non_archived.map do |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 6df56eed5b8..cf925141f2d 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -59,31 +59,35 @@ class Ability # Rules based on role in project if team.masters.include?(user) - rules << project_master_rules + rules += project_master_rules elsif team.developers.include?(user) - rules << project_dev_rules + rules += project_dev_rules elsif team.reporters.include?(user) - rules << project_report_rules + rules += project_report_rules elsif team.guests.include?(user) - rules << project_guest_rules + rules += project_guest_rules end if project.public? || project.internal? - rules << public_project_rules + rules += public_project_rules end if project.owner == user || user.admin? - rules << project_admin_rules + rules += project_admin_rules end if project.group && project.group.has_owner?(user) - rules << project_admin_rules + rules += project_admin_rules end - rules.flatten + if project.archived? + rules -= project_archived_rules + end + + rules end def public_project_rules @@ -125,6 +129,16 @@ class Ability ] end + def project_archived_rules + [ + :write_merge_request, + :push_code, + :push_code_to_protected_branches, + :modify_merge_request, + :admin_merge_request + ] + end + def project_master_rules project_dev_rules + [ :push_code_to_protected_branches, @@ -147,7 +161,8 @@ class Ability :change_namespace, :change_visibility_level, :rename_project, - :remove_project + :remove_project, + :archive_project ] end @@ -160,7 +175,7 @@ class Ability # Only group owner and administrators can manage group if group.has_owner?(user) || user.admin? - rules << [ + rules += [ :manage_group, :manage_namespace ] @@ -174,7 +189,7 @@ class Ability # Only namespace owner and administrators can manage it if namespace.owner == user || user.admin? - rules << [ + rules += [ :manage_namespace ] end diff --git a/app/models/issue.rb b/app/models/issue.rb index d350b237d37..b3609cf2f45 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -64,4 +64,18 @@ class Issue < ActiveRecord::Base def gfm_reference "issue ##{iid}" end + + # Reset issue events cache + # + # Since we do cache @event we need to reset cache in special cases: + # * when an issue is updated + # Events cache stored like events/23-20130109142513. + # The cache key includes updated_at timestamp. + # Thus it will automatically generate a new fragment + # when the event is updated because the key changes. + def reset_events_cache + Event.where(target_id: self.id, target_type: 'Issue'). + order('id DESC').limit(100). + update_all(updated_at: Time.now) + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index e862f35819c..e59aee8b445 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -305,6 +305,20 @@ class MergeRequest < ActiveRecord::Base self.target_project.repository.branch_names.include?(self.target_branch) end + # Reset merge request events cache + # + # Since we do cache @event we need to reset cache in special cases: + # * when a merge request is updated + # Events cache stored like events/23-20130109142513. + # The cache key includes updated_at timestamp. + # Thus it will automatically generate a new fragment + # when the event is updated because the key changes. + def reset_events_cache + Event.where(target_id: self.id, target_type: 'MergeRequest'). + order('id DESC').limit(100). + update_all(updated_at: Time.now) + end + private def dump_commits(commits) diff --git a/app/models/note.rb b/app/models/note.rb index 8284da8616f..b23f7df7742 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -239,4 +239,19 @@ class Note < ActiveRecord::Base def noteable_type=(sType) super(sType.to_s.classify.constantize.base_class.to_s) end + + # Reset notes events cache + # + # Since we do cache @event we need to reset cache in special cases: + # * when a note is updated + # * when a note is removed + # Events cache stored like events/23-20130109142513. + # The cache key includes updated_at timestamp. + # Thus it will automatically generate a new fragment + # when the event is updated because the key changes. + def reset_events_cache + Event.where(target_id: self.id, target_type: 'Note'). + order('id DESC').limit(100). + update_all(updated_at: Time.now) + end end diff --git a/app/models/project.rb b/app/models/project.rb index 506f34ca6b6..1bfc27d723d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -116,6 +116,8 @@ class Project < ActiveRecord::Base scope :public_only, -> { where(visibility_level: PUBLIC) } scope :public_or_internal_only, ->(user) { where("visibility_level IN (:levels)", levels: user ? [ INTERNAL, PUBLIC ] : [ PUBLIC ]) } + scope :non_archived, -> { where(archived: false) } + enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab class << self @@ -132,7 +134,7 @@ class Project < ActiveRecord::Base end def search query - joins(:namespace).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%") + joins(:namespace).where("projects.archived = ?", false).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%") end def find_with_namespace(id) @@ -472,4 +474,17 @@ class Project < ActiveRecord::Base def visibility_level_field visibility_level end + + def archive! + update_attribute(:archived, true) + end + + def unarchive! + update_attribute(:archived, false) + end + + def change_head(branch) + gitlab_shell.update_repository_head(self.path_with_namespace, branch) + reload_default_branch + end end diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml index b42bbf58dc4..23d78720881 100644 --- a/app/views/dashboard/projects.html.haml +++ b/app/views/dashboard/projects.html.haml @@ -82,6 +82,10 @@ = link_to project.forked_from_project.name_with_namespace, project_path(project.forked_from_project) .project-info .pull-right + - if project.archived? + %span.label + %i.icon-book + Archived - project.labels.each do |label| %span.label.label-info %i.icon-tag diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index 19c150b54fb..ae5deb0b6de 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -7,6 +7,10 @@ %span.visibility-level-label = visibility_level_icon(@project.visibility_level) = visibility_level_label(@project.visibility_level) + - if @project.archived? + %span.visibility-level-label + %i.icon-book + Archived .span7 - unless empty_repo diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 57936cff10f..c56919e792c 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -98,6 +98,33 @@ %i.icon-chevron-down .js-toggle-visibility-container.hide + - if can? current_user, :archive_project, @project + .ui-box.ui-box-danger + .title + - if @project.archived? + Unarchive project + - else + Archive project + .ui-box-body + - if @project.archived? + %p + Unarchiving the project will mark its repository as active. + %br + The project can be committed to. + %br + %strong Once active this project shows up in the search and on the dashboard. + = link_to 'Unarchive', unarchive_project_path(@project), confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be comitted to again.", method: :post, class: "btn btn-remove" + - else + %p + Archiving the project will mark its repository as read-only. + %br + It is hidden from the dashboard and doesn't show up in searches. + %br + %strong Archived projects cannot be committed to! + = link_to 'Archive', archive_project_path(@project), confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to.", method: :post, class: "btn btn-remove" + - else + %p.nothing_here_message Only the project owner can archive a project + - if can?(current_user, :change_namespace, @project) .ui-box.ui-box-danger .title Transfer project |