From 3d99ffc862b76c4dcc560aa8d8f4f9c1b7dd3f81 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 2 Mar 2016 11:33:55 +0000 Subject: Edited timeago text on comments Unified the 'edited text' to be the same in descriptions and comments Closes #5538 --- app/assets/javascripts/notes.js.coffee | 1 + app/assets/stylesheets/pages/issuable.scss | 8 ++++++ app/helpers/application_helper.rb | 30 +++++++++++++++++----- app/views/projects/issues/show.html.haml | 5 +--- .../projects/merge_requests/show/_mr_box.html.haml | 5 +--- app/views/projects/notes/_note.html.haml | 10 +------- 6 files changed, 35 insertions(+), 24 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index c95ead22e6c..063304ce89c 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -328,6 +328,7 @@ class @Notes updateNote: (_xhr, note, _status) => # Convert returned HTML to a jQuery object so we can modify it further $html = $(note.html) + $('.js-timeago', $html).timeago() $html.syntaxHighlight() $html.find('.js-task-list-container').taskList('enable') diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 1310e6ad7c7..e417869cc0d 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -262,3 +262,11 @@ color: $gray-darkest; } } + +.edited-text { + color: $gray-darkest; + + .author_link { + color: $gray-darkest; + } +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 368969c6472..cc4d2a8877d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -182,20 +182,36 @@ module ApplicationHelper # Returns an HTML-safe String def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false) element = content_tag :time, time.to_s, - class: "#{html_class} js-timeago js-timeago-pending", + class: "#{html_class} js-timeago", datetime: time.to_time.getutc.iso8601, title: time.in_time_zone.to_s(:medium), data: { toggle: 'tooltip', placement: placement, container: 'body' } - unless skip_js - element << javascript_tag( - "$('.js-timeago-pending').removeClass('js-timeago-pending').timeago()" - ) - end - element end + def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', skip_js: false, include_author: false) + return nil if object.updated_at == object.created_at + + content_tag :small, class: "edited-text" do + output = content_tag :span do + "Edited " + end + output += time_ago_with_tooltip(object.updated_at) + + if include_author + if object.updated_by && object.updated_by != object.author + output += content_tag :span do + " by " + end + output += link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) + end + end + + output + end + end + def render_markup(file_name, file_content) if gitlab_markdown?(file_name) Haml::Helpers.preserve(markdown(file_content)) diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 617b0437807..f507fd7f5b8 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -63,10 +63,7 @@ = markdown(@issue.description, cache_key: [@issue, "description"]) %textarea.hidden.js-task-list-field = @issue.description - - if @issue.updated_at != @issue.created_at - %small - Edited - = time_ago_with_tooltip(@issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago') + = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago') .merge-requests = render 'merge_requests' diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml index 602f787e6cf..a23bd8d18d0 100644 --- a/app/views/projects/merge_requests/show/_mr_box.html.haml +++ b/app/views/projects/merge_requests/show/_mr_box.html.haml @@ -11,7 +11,4 @@ %textarea.hidden.js-task-list-field = @merge_request.description - - if @merge_request.updated_at != @merge_request.created_at - %small - Edited - = time_ago_with_tooltip(@merge_request.updated_at, placement: 'bottom') + = edited_time_ago_with_tooltip(@merge_request, placement: 'bottom') diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml index 52972576aff..2cf32e6093d 100644 --- a/app/views/projects/notes/_note.html.haml +++ b/app/views/projects/notes/_note.html.haml @@ -27,20 +27,13 @@ %span.note-last-update %a{name: dom_id(note), href: "##{dom_id(note)}", title: 'Link here'} = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note_created_ago') - - if note.updated_at != note.created_at - %span.note-updated-at - · - = icon('edit', title: 'edited') - = time_ago_with_tooltip(note.updated_at, placement: 'bottom', html_class: 'note_edited_ago') - - if note.updated_by && note.updated_by != note.author - by #{link_to_member(note.project, note.updated_by, avatar: false, author_class: nil)} - .note-body{class: note_editable?(note) ? 'js-task-list-container' : ''} .note-text = preserve do = markdown(note.note, pipeline: :note, cache_key: [note, "note"]) - if note_editable?(note) = render 'projects/notes/edit_form', note: note + = edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true) - if note.attachment.url .note-attachment @@ -54,4 +47,3 @@ = link_to delete_attachment_namespace_project_note_path(note.project.namespace, note.project, note), title: 'Delete this attachment', method: :delete, remote: true, data: { confirm: 'Are you sure you want to remove the attachment?' }, class: 'danger js-note-attachment-delete' do = icon('trash-o', class: 'cred') - .clear -- cgit v1.2.1 From 538f3e0d716d0f8c107af030fb318808f9e284ac Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 3 Mar 2016 15:07:45 +0000 Subject: Fixed ruby issues from feedback Fixed failing tests --- app/helpers/application_helper.rb | 19 +++++++------------ app/views/projects/_last_commit.html.haml | 2 +- app/views/projects/blame/show.html.haml | 2 +- app/views/projects/commits/_commit.html.haml | 2 +- 4 files changed, 10 insertions(+), 15 deletions(-) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index cc4d2a8877d..f99a14c0e01 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -168,7 +168,6 @@ module ApplicationHelper # time - Time object # placement - Tooltip placement String (default: "top") # html_class - Custom class for `time` element (default: "time_ago") - # skip_js - When true, exclude the `script` tag (default: false) # # By default also includes a `script` element with Javascript necessary to # initialize the `timeago` jQuery extension. If this method is called many @@ -180,7 +179,7 @@ module ApplicationHelper # `html_class` argument is provided. # # Returns an HTML-safe String - def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false) + def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago') element = content_tag :time, time.to_s, class: "#{html_class} js-timeago", datetime: time.to_time.getutc.iso8601, @@ -190,21 +189,17 @@ module ApplicationHelper element end - def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', skip_js: false, include_author: false) - return nil if object.updated_at == object.created_at + def edited_time_ago_with_tooltip(object, placement: 'top', html_class: 'time_ago', include_author: false) + return if object.updated_at == object.created_at content_tag :small, class: "edited-text" do - output = content_tag :span do - "Edited " - end - output += time_ago_with_tooltip(object.updated_at) + output = content_tag(:span, "Edited ") + output << time_ago_with_tooltip(object.updated_at, placement: placement, html_class: html_class) if include_author if object.updated_by && object.updated_by != object.author - output += content_tag :span do - " by " - end - output += link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) + output << content_tag(:span, " by ") + output << link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) end end diff --git a/app/views/projects/_last_commit.html.haml b/app/views/projects/_last_commit.html.haml index 386d72e7787..a47aea7ff1b 100644 --- a/app/views/projects/_last_commit.html.haml +++ b/app/views/projects/_last_commit.html.haml @@ -8,5 +8,5 @@ = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message" · - #{time_ago_with_tooltip(commit.committed_date, skip_js: true)} by + #{time_ago_with_tooltip(commit.committed_date)} by = commit_author_link(commit, avatar: true, size: 24) diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 5f9a92ff93f..1ae83c2383e 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -29,7 +29,7 @@ .light = commit_author_link(commit, avatar: false) authored - #{time_ago_with_tooltip(commit.committed_date, skip_js: true)} + #{time_ago_with_tooltip(commit.committed_date)} %td.line-numbers - line_count = blame_group[:lines].count - (current_line...(current_line + line_count)).each do |i| diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 7f2903589a9..4df4a8ca9e2 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -38,5 +38,5 @@ = commit_author_link(commit, avatar: true, size: 24) authored .committed_ago - #{time_ago_with_tooltip(commit.committed_date, skip_js: true)}   + #{time_ago_with_tooltip(commit.committed_date)}   = link_to_browse_code(project, commit) -- cgit v1.2.1 From 12506abfe794e75fcaa879b92bee09b8da57bf46 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 3 Mar 2016 17:04:32 +0000 Subject: Single if statement --- app/helpers/application_helper.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f99a14c0e01..212fecc3e77 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -196,11 +196,9 @@ module ApplicationHelper output = content_tag(:span, "Edited ") output << time_ago_with_tooltip(object.updated_at, placement: placement, html_class: html_class) - if include_author - if object.updated_by && object.updated_by != object.author - output << content_tag(:span, " by ") - output << link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) - end + if include_author && object.updated_by && object.updated_by != object.author + output << content_tag(:span, " by ") + output << link_to_member(object.project, object.updated_by, avatar: false, author_class: nil) end output -- cgit v1.2.1 From cd1d045fe215bb06a1cc96e12cefda5ef71058a0 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 9 Mar 2016 16:29:15 +0000 Subject: Fixed issue with timeago not firing --- app/helpers/application_helper.rb | 10 ++++++++-- app/views/projects/_last_commit.html.haml | 2 +- app/views/projects/blame/show.html.haml | 2 +- app/views/projects/commits/_commit.html.haml | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 212fecc3e77..5cd494079b0 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -179,13 +179,19 @@ module ApplicationHelper # `html_class` argument is provided. # # Returns an HTML-safe String - def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago') + def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false) element = content_tag :time, time.to_s, - class: "#{html_class} js-timeago", + class: "#{html_class} js-timeago #{"js-timeago-pending" unless skip_js}", datetime: time.to_time.getutc.iso8601, title: time.in_time_zone.to_s(:medium), data: { toggle: 'tooltip', placement: placement, container: 'body' } + unless skip_js + element << javascript_tag( + "$('.js-timeago-pending').removeClass('js-timeago-pending').timeago()" + ) + end + element end diff --git a/app/views/projects/_last_commit.html.haml b/app/views/projects/_last_commit.html.haml index a47aea7ff1b..386d72e7787 100644 --- a/app/views/projects/_last_commit.html.haml +++ b/app/views/projects/_last_commit.html.haml @@ -8,5 +8,5 @@ = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message" · - #{time_ago_with_tooltip(commit.committed_date)} by + #{time_ago_with_tooltip(commit.committed_date, skip_js: true)} by = commit_author_link(commit, avatar: true, size: 24) diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 1ae83c2383e..5f9a92ff93f 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -29,7 +29,7 @@ .light = commit_author_link(commit, avatar: false) authored - #{time_ago_with_tooltip(commit.committed_date)} + #{time_ago_with_tooltip(commit.committed_date, skip_js: true)} %td.line-numbers - line_count = blame_group[:lines].count - (current_line...(current_line + line_count)).each do |i| diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 4df4a8ca9e2..7f2903589a9 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -38,5 +38,5 @@ = commit_author_link(commit, avatar: true, size: 24) authored .committed_ago - #{time_ago_with_tooltip(commit.committed_date)}   + #{time_ago_with_tooltip(commit.committed_date, skip_js: true)}   = link_to_browse_code(project, commit) -- cgit v1.2.1 From c7730121c16e41d797e7f7e00f7a6ad96d78bbb4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 10 Mar 2016 08:39:32 +0000 Subject: Fixed failing rubocop test --- app/helpers/application_helper.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5cd494079b0..f07c79ec611 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -186,11 +186,11 @@ module ApplicationHelper title: time.in_time_zone.to_s(:medium), data: { toggle: 'tooltip', placement: placement, container: 'body' } - unless skip_js - element << javascript_tag( - "$('.js-timeago-pending').removeClass('js-timeago-pending').timeago()" - ) - end + unless skip_js + element << javascript_tag( + "$('.js-timeago-pending').removeClass('js-timeago-pending').timeago()" + ) + end element end -- cgit v1.2.1 From 42fcd3881fcece5c9bd4b720460d6cade573b151 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 10 Mar 2016 22:08:11 +0100 Subject: External Users The user has the rights of a public user execpt it can never create a project, group, or team. Also it cant view internal projects. --- app/controllers/admin/users_controller.rb | 2 +- app/finders/projects_finder.rb | 11 +++++----- app/models/ability.rb | 34 +++++++++++++++---------------- app/models/user.rb | 12 +++++++++++ app/views/admin/users/_form.html.haml | 5 +++++ app/views/admin/users/show.html.haml | 4 ++++ 6 files changed, 44 insertions(+), 24 deletions(-) (limited to 'app') diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 87f4fb455b8..be192964a93 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -150,7 +150,7 @@ class Admin::UsersController < Admin::ApplicationController :email, :remember_me, :bio, :name, :username, :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, :hide_no_password, - :projects_limit, :can_create_group, :admin, :key_id + :projects_limit, :can_create_group, :admin, :key_id, :external ) end diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 0e5a8f5ee0f..711d9019a3d 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -51,13 +51,12 @@ class ProjectsFinder end def all_projects(current_user) - if current_user - [ - current_user.authorized_projects, - public_and_internal_projects - ] + return [Project.public_only] unless current_user + + if current_user.external? + [current_user.authorized_projects, public_projects] else - [Project.public_only] + [current_user.authorized_projects, public_and_internal_projects] end end diff --git a/app/models/ability.rb b/app/models/ability.rb index fe9e0aab717..ccac08b7d3f 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -109,23 +109,10 @@ class Ability key = "/user/#{user.id}/project/#{project.id}" RequestStore.store[key] ||= begin - team = project.team + # Push abilities on the users team role + rules.push(*project_team_rules(project.team, user)) - # Rules based on role in project - if team.master?(user) - rules.push(*project_master_rules) - - elsif team.developer?(user) - rules.push(*project_dev_rules) - - elsif team.reporter?(user) - rules.push(*project_report_rules) - - elsif team.guest?(user) - rules.push(*project_guest_rules) - end - - if project.public? || project.internal? + if project.public? || (project.internal? && !user.external?) rules.push(*public_project_rules) # Allow to read builds for internal projects @@ -148,6 +135,19 @@ class Ability end end + def project_team_rules(team, user) + # Rules based on role in project + if team.master?(user) + project_master_rules + elsif team.developer?(user) + project_dev_rules + elsif team.reporter?(user) + project_report_rules + elsif team.guest?(user) + project_guest_rules + end + end + def public_project_rules @public_project_rules ||= project_guest_rules + [ :download_code, @@ -356,7 +356,7 @@ class Ability ] end - if snippet.public? || snippet.internal? + if snippet.public? || (snippet.internal? && !user.external?) rules << :read_personal_snippet end diff --git a/app/models/user.rb b/app/models/user.rb index 043bc825ade..adff238c60f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -59,6 +59,7 @@ # hide_project_limit :boolean default(FALSE) # unlock_token :string # otp_grace_period_started_at :datetime +# external :boolean default(FALSE) # require 'carrierwave/orm/activerecord' @@ -77,6 +78,7 @@ class User < ActiveRecord::Base add_authentication_token_field :authentication_token default_value_for :admin, false + default_value_for :external, false default_value_for :can_create_group, gitlab_config.default_can_create_group default_value_for :can_create_team, false default_value_for :hide_no_ssh_key, false @@ -179,6 +181,7 @@ class User < ActiveRecord::Base after_update :update_emails_with_primary_email, if: ->(user) { user.email_changed? } before_save :ensure_authentication_token + before_save :ensure_external_user_rights after_save :ensure_namespace_correct after_initialize :set_projects_limit after_create :post_create_hook @@ -848,4 +851,13 @@ class User < ActiveRecord::Base def send_devise_notification(notification, *args) devise_mailer.send(notification, self, *args).deliver_later end + + def ensure_external_user_rights + return unless self.external? + + self.can_create_team = false + self.can_create_group = false + self.projects_limit = 0 + self.hide_project_limit = true + end end diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index e18dd9bc905..5506827edc4 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -61,6 +61,11 @@ .col-sm-10 You cannot remove your own admin rights - else .col-sm-10= f.check_box :admin + + .form-group + = f.label :external, class: 'control-label' + .col-sm-10= f.check_box :external + %fieldset %legend Profile .form-group diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 2bdbae19588..d37489bebea 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -47,6 +47,10 @@ - else Disabled + %li + %span.light External User: + %strong + = @user.external? ? "Yes" : "No" %li %span.light Can create groups: %strong -- cgit v1.2.1 From fc8d64b3a0fc5aeb048b2bce79b2ae93a4fcc798 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Sat, 12 Mar 2016 15:02:38 +0100 Subject: Remove Project#publicish --- app/models/project.rb | 6 ------ app/views/dashboard/projects/_zero_authorized_projects.html.haml | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index 1f18ad78164..51952ba72a2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -252,12 +252,6 @@ class Project < ActiveRecord::Base where('projects.last_activity_at < ?', 6.months.ago) end - def publicish(user) - visibility_levels = [Project::PUBLIC] - visibility_levels << Project::INTERNAL if user - where(visibility_level: visibility_levels) - end - def with_push joins(:events).where('events.action = ?', Event::PUSHED) end diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index c3efa7727b1..65edc05b793 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -1,4 +1,4 @@ -- publicish_project_count = Project.publicish(current_user).count +- publicish_project_count = ProjectsFinder.new.execute(current_user).count %h3.page-title Welcome to GitLab! %p.light Self hosted Git management application. %hr @@ -18,7 +18,7 @@ - if current_user.can_create_project? .link_holder = link_to new_project_path, class: "btn btn-new" do - %i.fa.fa-plus + =icon('plus') New Project - if current_user.can_create_group? -- cgit v1.2.1 From 76eeb316df2f256d0d3c41d97421f709a21a02a8 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Sun, 13 Mar 2016 10:05:32 +0100 Subject: Create an external users tab on Admin user list Also incorporates the review into this, mainly spec changes. --- app/finders/projects_finder.rb | 13 +++++++++---- app/models/user.rb | 5 +++-- app/views/admin/users/_form.html.haml | 3 ++- app/views/admin/users/index.html.haml | 4 ++++ 4 files changed, 18 insertions(+), 7 deletions(-) (limited to 'app') diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 711d9019a3d..4a6c2fbd71c 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -40,18 +40,23 @@ class ProjectsFinder private def group_projects(current_user, group) - if current_user + return [group.projects.public_only] unless current_user + + if current_user.external? [ group_projects_for_user(current_user, group), - group.projects.public_and_internal_only + group.projects.public_only ] else - [group.projects.public_only] + [ + group_projects_for_user(current_user, group), + group.projects.public_and_internal_only + ] end end def all_projects(current_user) - return [Project.public_only] unless current_user + return [public_projects] unless current_user if current_user.external? [current_user.authorized_projects, public_projects] diff --git a/app/models/user.rb b/app/models/user.rb index adff238c60f..34f1cfc0be6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -229,6 +229,7 @@ class User < ActiveRecord::Base # Scopes scope :admins, -> { where(admin: true) } scope :blocked, -> { with_states(:blocked, :ldap_blocked) } + scope :external, -> { where(external: true) } scope :active, -> { with_state(:active) } scope :not_in_project, ->(project) { project.users.present? ? where("id not in (:ids)", ids: project.users.map(&:id) ) : all } scope :without_projects, -> { where('id NOT IN (SELECT DISTINCT(user_id) FROM members)') } @@ -284,6 +285,8 @@ class User < ActiveRecord::Base self.with_two_factor when 'wop' self.without_projects + when 'external' + self.external else self.active end @@ -855,9 +858,7 @@ class User < ActiveRecord::Base def ensure_external_user_rights return unless self.external? - self.can_create_team = false self.can_create_group = false self.projects_limit = 0 - self.hide_project_limit = true end end diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index 5506827edc4..b910040a16a 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -58,13 +58,14 @@ = f.label :admin, class: 'control-label' - if current_user == @user .col-sm-10= f.check_box :admin, disabled: true - .col-sm-10 You cannot remove your own admin rights + .col-sm-10 You cannot remove your own admin rights. - else .col-sm-10= f.check_box :admin .form-group = f.label :external, class: 'control-label' .col-sm-10= f.check_box :external + .col-sm-10 External users can not see internal or private projects unless access is explicitly granted. Also, external user can not create projects or groups. %fieldset %legend Profile diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index b6b1168bd37..4394e181008 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -19,6 +19,10 @@ = link_to admin_users_path(filter: 'two_factor_disabled') do 2FA Disabled %small.badge= number_with_delimiter(User.without_two_factor.count) + %li.filter-external{class: "#{'active' if params[:filter] == 'external'}"} + = link_to admin_users_path(filter: 'external') do + External + %small.badge= number_with_delimiter(User.external.count) %li{class: "#{'active' if params[:filter] == "blocked"}"} = link_to admin_users_path(filter: "blocked") do Blocked -- cgit v1.2.1 From ab418e27a9121704d623343417126b0bdae08e79 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Mon, 14 Mar 2016 22:06:23 +0100 Subject: Improve external users feature --- app/finders/projects_finder.rb | 4 ++-- app/views/admin/users/_form.html.haml | 2 +- app/views/admin/users/index.html.haml | 6 ++++-- app/views/dashboard/projects/_zero_authorized_projects.html.haml | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 70c073f7d5c..3a5fc5b5907 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -47,9 +47,9 @@ class ProjectsFinder group.shared_projects.visible_to_user(current_user) ] if current_user.external? - user_group_projects.push(group.projects.public_only) + user_group_projects << group.projects.public_only else - user_group_projects.push(group.projects.public_and_internal_only) + user_group_projects << group.projects.public_and_internal_only end end diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml index b910040a16a..d2527ede995 100644 --- a/app/views/admin/users/_form.html.haml +++ b/app/views/admin/users/_form.html.haml @@ -65,7 +65,7 @@ .form-group = f.label :external, class: 'control-label' .col-sm-10= f.check_box :external - .col-sm-10 External users can not see internal or private projects unless access is explicitly granted. Also, external user can not create projects or groups. + .col-sm-10 External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects or groups. %fieldset %legend Profile diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml index 4394e181008..0ee8dc962b9 100644 --- a/app/views/admin/users/index.html.haml +++ b/app/views/admin/users/index.html.haml @@ -74,12 +74,14 @@ %li .list-item-name - if user.blocked? - %i.fa.fa-lock.cred + = icon("lock", class: "cred") - else - %i.fa.fa-user.cgreen + = icon("user", class: "cgreen") = link_to user.name, [:admin, user] - if user.admin? %strong.cred (Admin) + - if user.external? + %strong.cred (External) - if user == current_user %span.cred It's you! .pull-right diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index 65edc05b793..d54c7cad7be 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -18,7 +18,7 @@ - if current_user.can_create_project? .link_holder = link_to new_project_path, class: "btn btn-new" do - =icon('plus') + = icon('plus') New Project - if current_user.can_create_group? -- cgit v1.2.1 From b5c8f5727b5261d86ce52b976a355e7f223a563a Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 15 Mar 2016 11:34:49 +0100 Subject: Hide builds from Project's settings when the feature is disabled --- app/assets/javascripts/project_new.js.coffee | 13 ++++++ app/views/projects/_builds_settings.html.haml | 60 +++++++++++++++++++++++++ app/views/projects/edit.html.haml | 65 +-------------------------- 3 files changed, 75 insertions(+), 63 deletions(-) create mode 100644 app/views/projects/_builds_settings.html.haml (limited to 'app') diff --git a/app/assets/javascripts/project_new.js.coffee b/app/assets/javascripts/project_new.js.coffee index fecdb9fc2e7..63dee4ed5d7 100644 --- a/app/assets/javascripts/project_new.js.coffee +++ b/app/assets/javascripts/project_new.js.coffee @@ -3,3 +3,16 @@ class @ProjectNew $('.project-edit-container').on 'ajax:before', => $('.project-edit-container').hide() $('.save-project-loader').show() + @toggleSettings() + @toggleSettingsOnclick() + + + toggleSettings: -> + checked = $("#project_builds_enabled").prop("checked") + if checked + $('.builds-feature').show() + else + $('.builds-feature').hide() + + toggleSettingsOnclick: -> + $("#project_builds_enabled").on 'click', @toggleSettings diff --git a/app/views/projects/_builds_settings.html.haml b/app/views/projects/_builds_settings.html.haml new file mode 100644 index 00000000000..95ab9ecf3e8 --- /dev/null +++ b/app/views/projects/_builds_settings.html.haml @@ -0,0 +1,60 @@ +%fieldset.builds-feature + %legend + Builds: + .form-group + .col-sm-offset-2.col-sm-10 + %p Get recent application code using the following command: + .radio + = f.label :build_allow_git_fetch_false do + = f.radio_button :build_allow_git_fetch, 'false' + %strong git clone + %br + %span.descr Slower but makes sure you have a clean dir before every build + .radio + = f.label :build_allow_git_fetch_true do + = f.radio_button :build_allow_git_fetch, 'true' + %strong git fetch + %br + %span.descr Faster + + .form-group + = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label' + .col-sm-10 + = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' + %p.help-block per build in minutes + .form-group + = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label' + .col-sm-10 + .input-group + %span.input-group-addon / + = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' + %span.input-group-addon / + %p.help-block + We will use this regular expression to find test coverage output in build trace. + Leave blank if you want to disable this feature + .bs-callout.bs-callout-info + %p Below are examples of regex for existing tools: + %ul + %li + Simplecov (Ruby) - + %code \(\d+.\d+\%\) covered + %li + pytest-cov (Python) - + %code \d+\%\s*$ + %li + phpunit --coverage-text --colors=never (PHP) - + %code ^\s*Lines:\s*\d+.\d+\% + + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :public_builds do + = f.check_box :public_builds + %strong Public builds + .help-block Allow everyone to access builds for Public and Internal projects + + .form-group + = f.label :runners_token, "Runners token", class: 'control-label' + .col-sm-10 + = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' + %p.help-block The secure token used to checkout project. diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index f2e56081afe..6d872cd0b21 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -84,6 +84,8 @@ %br %span.descr Share code pastes with others out of git repository + = render 'builds_settings', f: f + %fieldset.features %legend Project avatar: @@ -110,69 +112,6 @@ %hr = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" - %fieldset.features - %legend - Continuous Integration - .form-group - .col-sm-offset-2.col-sm-10 - %p Get recent application code using the following command: - .radio - = f.label :build_allow_git_fetch_false do - = f.radio_button :build_allow_git_fetch, 'false' - %strong git clone - %br - %span.descr Slower but makes sure you have a clean dir before every build - .radio - = f.label :build_allow_git_fetch_true do - = f.radio_button :build_allow_git_fetch, 'true' - %strong git fetch - %br - %span.descr Faster - - .form-group - = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label' - .col-sm-10 - = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0' - %p.help-block per build in minutes - .form-group - = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label' - .col-sm-10 - .input-group - %span.input-group-addon / - = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered' - %span.input-group-addon / - %p.help-block - We will use this regular expression to find test coverage output in build trace. - Leave blank if you want to disable this feature - .bs-callout.bs-callout-info - %p Below are examples of regex for existing tools: - %ul - %li - Simplecov (Ruby) - - %code \(\d+.\d+\%\) covered - %li - pytest-cov (Python) - - %code \d+\%\s*$ - %li - phpunit --coverage-text --colors=never (PHP) - - %code ^\s*Lines:\s*\d+.\d+\% - - .form-group - .col-sm-offset-2.col-sm-10 - .checkbox - = f.label :public_builds do - = f.check_box :public_builds - %strong Public builds - .help-block Allow everyone to access builds for Public and Internal projects - - %fieldset.features - %legend - Advanced settings - .form-group - = f.label :runners_token, "CI token", class: 'control-label' - .col-sm-10 - = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' - %p.help-block The secure token used to checkout project. .form-actions = f.submit 'Save changes', class: "btn btn-save" -- cgit v1.2.1 From 228007dfbcd8f97c66c1802f3b69abd7d02c7d26 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Fri, 12 Feb 2016 19:42:25 +0100 Subject: new-branch-button --- app/assets/stylesheets/pages/issues.scss | 5 +++++ app/controllers/projects/branches_controller.rb | 16 +++++++++++++--- app/controllers/projects/issues_controller.rb | 1 + app/models/issue.rb | 14 ++++++++++++++ app/services/merge_requests/build_service.rb | 11 +++++++++++ app/views/projects/issues/_merge_requests.html.haml | 2 +- app/views/projects/issues/_new_branch.html.haml | 5 +++++ app/views/projects/issues/_related_branches.html.haml | 15 +++++++++++++++ app/views/projects/issues/show.html.haml | 2 ++ 9 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 app/views/projects/issues/_new_branch.html.haml create mode 100644 app/views/projects/issues/_related_branches.html.haml (limited to 'app') diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 1b686c58eaf..5f1810cbaf6 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -49,6 +49,11 @@ form.edit-issue { margin: 0; } +.related-branches-title { + font-size: 16px; + font-weight: 600; +} + .merge-requests-title { font-size: 16px; font-weight: 600; diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 4db3b3bf23d..cf68f50b1f9 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -9,7 +9,7 @@ class Projects::BranchesController < Projects::ApplicationController @sort = params[:sort] || 'name' @branches = @repository.branches_sorted_by(@sort) @branches = Kaminari.paginate_array(@branches).page(params[:page]).per(PER_PAGE) - + @max_commits = @branches.reduce(0) do |memo, branch| diverging_commit_counts = repository.diverging_commit_counts(branch) [memo, diverging_commit_counts[:behind], diverging_commit_counts[:ahead]].max @@ -23,8 +23,7 @@ class Projects::BranchesController < Projects::ApplicationController def create branch_name = sanitize(strip_tags(params[:branch_name])) branch_name = Addressable::URI.unescape(branch_name) - ref = sanitize(strip_tags(params[:ref])) - ref = Addressable::URI.unescape(ref) + result = CreateBranchService.new(project, current_user). execute(branch_name, ref) @@ -49,4 +48,15 @@ class Projects::BranchesController < Projects::ApplicationController format.js { render status: status[:return_code] } end end + + private + + def ref + if params[:ref] + ref_escaped = sanitize(strip_tags(params[:ref])) + Addressable::URI.unescape(ref_escaped) + else + @project.default_branch + end + end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index b0a03ee45cc..aa7a178dcf4 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -65,6 +65,7 @@ class Projects::IssuesController < Projects::ApplicationController @notes = @issue.notes.nonawards.with_associations.fresh @noteable = @issue @merge_requests = @issue.referenced_merge_requests(current_user) + @related_branches = @issue.related_branches - @merge_requests.map(&:source_branch) respond_with(@issue) end diff --git a/app/models/issue.rb b/app/models/issue.rb index 5f58c0508fd..243d9a5db62 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -94,6 +94,10 @@ class Issue < ActiveRecord::Base end.sort_by(&:iid) end + def related_branches + self.project.repository.branch_names.select { |branch| /\A#{iid}-/ =~ branch } + end + # Reset issue events cache # # Since we do cache @event we need to reset cache in special cases: @@ -120,4 +124,14 @@ class Issue < ActiveRecord::Base note.all_references(current_user).merge_requests end.uniq.select { |mr| mr.open? && mr.closes_issue?(self) } end + + def to_branch_name + "#{iid}-#{title.parameterize}"[0,25] + end + + def new_branch_button?(current_user) + !self.closed? && + referenced_merge_requests(current_user).empty? && + related_branches.empty? + end end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 954746a39a5..8f1b735b8df 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -47,6 +47,17 @@ module MergeRequests merge_request.title = merge_request.source_branch.titleize.humanize end + # When your branch name starts with an iid followed by a dash this pattern will + # be interpreted as the use wants to close that issue on this project + # Pattern example: 112-fix-mep-mep + # Will lead to appending `Closes #112` to the description + if merge_request.source_branch =~ /\A\d+-/ + closes_issue = "Closes ##{Regexp.last_match(0)[0...-1]}" + closes_issue.prepend("\n") if merge_request.description.present? + + merge_request.description << closes_issue + end + merge_request end diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml index d9868ad1f0a..d6b38b327ff 100644 --- a/app/views/projects/issues/_merge_requests.html.haml +++ b/app/views/projects/issues/_merge_requests.html.haml @@ -1,4 +1,4 @@ --if @merge_requests.any? +- if @merge_requests.any? %h2.merge-requests-title = pluralize(@merge_requests.count, 'Related Merge Request') %ul.unstyled-list diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml new file mode 100644 index 00000000000..4d5fa61a91a --- /dev/null +++ b/app/views/projects/issues/_new_branch.html.haml @@ -0,0 +1,5 @@ +- if current_user && can?(current_user, :push_code, @project) && @issue.new_branch_button?(current_user) + .pull-right + = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name), method: :post, class: 'btn' do + = icon('code-fork') + New Branch diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml new file mode 100644 index 00000000000..56387661989 --- /dev/null +++ b/app/views/projects/issues/_related_branches.html.haml @@ -0,0 +1,15 @@ +- if @related_branches.any? + %h2.related-branches-title + = pluralize(@related_branches.count, 'Related Branch') + %ul.unstyled-list + - @related_branches.each do |branch| + %li + - sha = @project.repository.find_branch(branch).target + - ci_commit = @project.ci_commit(sha) if sha + - if ci_commit + %span.related-branch-ci-status + = render_ci_status(ci_commit) + %span.related-branch-info + %strong + = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch) do + = branch diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 0242276cd84..1e8308277cc 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -70,8 +70,10 @@ .merge-requests = render 'merge_requests' + = render 'related_branches' .content-block.content-block-small + = render 'new_branch' = render 'votes/votes_block', votable: @issue .row -- cgit v1.2.1 From ad97bebfed2e65951c7dc39ee80b32089a032804 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 17 Feb 2016 07:11:48 +0100 Subject: Enhance new branch button on an issue --- app/controllers/projects/branches_controller.rb | 6 ++++++ app/models/issue.rb | 11 ++++++----- app/services/merge_requests/build_service.rb | 12 ++++++++---- app/services/system_note_service.rb | 9 +++++++++ app/views/projects/issues/_new_branch.html.haml | 4 ++-- 5 files changed, 31 insertions(+), 11 deletions(-) (limited to 'app') diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index cf68f50b1f9..bcbd3aa5d9b 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -27,6 +27,12 @@ class Projects::BranchesController < Projects::ApplicationController result = CreateBranchService.new(project, current_user). execute(branch_name, ref) + if params[:issue_id] + issue = Issue.where(id: params[:issue_id], project: @project).limit(1).first + + SystemNoteService.new_issue_branch(issue, @project, current_user, branch_name) + end + if result[:status] == :success @branch = result[:branch] redirect_to namespace_project_tree_path(@project.namespace, @project, diff --git a/app/models/issue.rb b/app/models/issue.rb index 243d9a5db62..3b6bff6c577 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -95,7 +95,7 @@ class Issue < ActiveRecord::Base end def related_branches - self.project.repository.branch_names.select { |branch| /\A#{iid}-/ =~ branch } + self.project.repository.branch_names.select { |branch| branch.start_with? "#{iid}-" } end # Reset issue events cache @@ -126,12 +126,13 @@ class Issue < ActiveRecord::Base end def to_branch_name - "#{iid}-#{title.parameterize}"[0,25] + "#{iid}-#{title.parameterize}" end - def new_branch_button?(current_user) + def can_be_worked_on?(current_user) !self.closed? && - referenced_merge_requests(current_user).empty? && - related_branches.empty? + !self.project.forked? && + referenced_merge_requests(current_user).none? { |mr| mr.closes_issue?(self) } && + related_branches.empty? end end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 8f1b735b8df..fa34753c4fd 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -51,11 +51,15 @@ module MergeRequests # be interpreted as the use wants to close that issue on this project # Pattern example: 112-fix-mep-mep # Will lead to appending `Closes #112` to the description - if merge_request.source_branch =~ /\A\d+-/ - closes_issue = "Closes ##{Regexp.last_match(0)[0...-1]}" - closes_issue.prepend("\n") if merge_request.description.present? + if match = merge_request.source_branch.match(/\A(\d+)-/) + iid = match[1] + closes_issue = "Closes ##{iid}" - merge_request.description << closes_issue + if merge_request.description.present? + merge_request.description << closes_issue.prepend("\n") + else + merge_request.description = closes_issue + end end merge_request diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 58a861ee08e..751815c5b18 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -207,6 +207,15 @@ class SystemNoteService create_note(noteable: noteable, project: project, author: author, note: body) end + # Called when a branch is created from the 'new branch' button on a issue + # Example note text: + # + # "Started branch `201-issue-branch-button`" + def self.new_issue_branch(issue, project, author, branch) + body = "Started branch `#{branch}`" + create_note(noteable: issue, project: project, author: author, note: body) + end + # Called when a Mentionable references a Noteable # # noteable - Noteable object being referenced diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml index 4d5fa61a91a..a6b97b90e64 100644 --- a/app/views/projects/issues/_new_branch.html.haml +++ b/app/views/projects/issues/_new_branch.html.haml @@ -1,5 +1,5 @@ -- if current_user && can?(current_user, :push_code, @project) && @issue.new_branch_button?(current_user) +- if current_user && can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user) .pull-right - = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name), method: :post, class: 'btn' do + = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_id: @issue.id), method: :post, class: 'btn', title: @issue.to_branch_name do = icon('code-fork') New Branch -- cgit v1.2.1 From e831a3b869cbb82e9a4294a5f9309ba56df46589 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Fri, 19 Feb 2016 11:58:02 +0100 Subject: Link in the note when started a new branch from an issue --- app/services/system_note_service.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 751815c5b18..b65ac47bce3 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -212,7 +212,10 @@ class SystemNoteService # # "Started branch `201-issue-branch-button`" def self.new_issue_branch(issue, project, author, branch) - body = "Started branch `#{branch}`" + h = Gitlab::Application.routes.url_helpers + link = "#{Gitlab.config.gitlab.url}#{h.namespace_project_compare_path(project.namespace, project, from: project.default_branch, to: branch)}" + + body = "Started branch [#{branch}](#{link})" create_note(noteable: issue, project: project, author: author, note: body) end -- cgit v1.2.1 From 2b97c921196a7be904bfe4f0a31347c3583c9e88 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Mon, 22 Feb 2016 09:20:04 +0100 Subject: Incorporate review --- app/assets/stylesheets/pages/issues.scss | 7 +------ app/controllers/projects/branches_controller.rb | 7 +++---- app/models/issue.rb | 19 ++++++++++++------- app/services/system_note_service.rb | 2 +- app/views/projects/issues/_new_branch.html.haml | 2 +- app/views/projects/issues/_related_branches.html.haml | 2 +- 6 files changed, 19 insertions(+), 20 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 5f1810cbaf6..0f2e14d1a20 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -49,12 +49,7 @@ form.edit-issue { margin: 0; } -.related-branches-title { - font-size: 16px; - font-weight: 600; -} - -.merge-requests-title { +.merge-requests-title, .related-branches-title { font-size: 16px; font-weight: 600; } diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index bcbd3aa5d9b..43ea717cbd2 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -27,10 +27,9 @@ class Projects::BranchesController < Projects::ApplicationController result = CreateBranchService.new(project, current_user). execute(branch_name, ref) - if params[:issue_id] - issue = Issue.where(id: params[:issue_id], project: @project).limit(1).first - - SystemNoteService.new_issue_branch(issue, @project, current_user, branch_name) + if params[:issue_iid] + issue = @project.issues.find_by(iid: params[:issue_iid]) + SystemNoteService.new_issue_branch(issue, @project, current_user, branch_name) if issue end if result[:status] == :success diff --git a/app/models/issue.rb b/app/models/issue.rb index 3b6bff6c577..ec275d5f5b5 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -87,11 +87,16 @@ class Issue < ActiveRecord::Base end def referenced_merge_requests(current_user = nil) - Gitlab::ReferenceExtractor.lazily do - [self, *notes].flat_map do |note| - note.all_references(current_user).merge_requests - end - end.sort_by(&:iid) + if defined?(@referenced_merge_requests) + @referenced_merge_requests[current_user] ||= Gitlab::ReferenceExtractor.lazily do + [self, *notes].flat_map do |note| + note.all_references(current_user).merge_requests + end + end.sort_by(&:iid).uniq + else + @referenced_merge_requests = {} + referenced_merge_requests(current_user) + end end def related_branches @@ -132,7 +137,7 @@ class Issue < ActiveRecord::Base def can_be_worked_on?(current_user) !self.closed? && !self.project.forked? && - referenced_merge_requests(current_user).none? { |mr| mr.closes_issue?(self) } && - related_branches.empty? + self.related_branches.empty? && + self.referenced_merge_requests(current_user).empty? end end diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index b65ac47bce3..5ea7d405e4d 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -213,7 +213,7 @@ class SystemNoteService # "Started branch `201-issue-branch-button`" def self.new_issue_branch(issue, project, author, branch) h = Gitlab::Application.routes.url_helpers - link = "#{Gitlab.config.gitlab.url}#{h.namespace_project_compare_path(project.namespace, project, from: project.default_branch, to: branch)}" + link = "#{h.namespace_project_compare_url(project.namespace, project, from: project.default_branch, to: branch)}" body = "Started branch [#{branch}](#{link})" create_note(noteable: issue, project: project, author: author, note: body) diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml index a6b97b90e64..e66e4669d48 100644 --- a/app/views/projects/issues/_new_branch.html.haml +++ b/app/views/projects/issues/_new_branch.html.haml @@ -1,5 +1,5 @@ - if current_user && can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user) .pull-right - = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_id: @issue.id), method: :post, class: 'btn', title: @issue.to_branch_name do + = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid), method: :post, class: 'btn', title: @issue.to_branch_name do = icon('code-fork') New Branch diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml index 56387661989..b10cd03515f 100644 --- a/app/views/projects/issues/_related_branches.html.haml +++ b/app/views/projects/issues/_related_branches.html.haml @@ -11,5 +11,5 @@ = render_ci_status(ci_commit) %span.related-branch-info %strong - = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch) do + = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "label-branch" do = branch -- cgit v1.2.1 From 48274581551b73575149463be0c050f6b5a564ee Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Tue, 15 Mar 2016 20:17:51 +0100 Subject: Incorporate the review and update spec The feature spec now also tests the absence of the new branch button --- app/models/issue.rb | 22 +++++++++++----------- app/services/system_note_service.rb | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'app') diff --git a/app/models/issue.rb b/app/models/issue.rb index ec275d5f5b5..781298a63b2 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -87,20 +87,20 @@ class Issue < ActiveRecord::Base end def referenced_merge_requests(current_user = nil) - if defined?(@referenced_merge_requests) - @referenced_merge_requests[current_user] ||= Gitlab::ReferenceExtractor.lazily do - [self, *notes].flat_map do |note| - note.all_references(current_user).merge_requests - end - end.sort_by(&:iid).uniq - else - @referenced_merge_requests = {} - referenced_merge_requests(current_user) + @referenced_merge_requests ||= {} + @referenced_merge_requests[current_user] ||= begin + Gitlab::ReferenceExtractor.lazily do + [self, *notes].flat_map do |note| + note.all_references(current_user).merge_requests + end + end.sort_by(&:iid).uniq end end def related_branches - self.project.repository.branch_names.select { |branch| branch.start_with? "#{iid}-" } + self.project.repository.branch_names.select do |branch| + branch =~ /\A#{iid}-(?!\d+-stable)/i + end end # Reset issue events cache @@ -138,6 +138,6 @@ class Issue < ActiveRecord::Base !self.closed? && !self.project.forked? && self.related_branches.empty? && - self.referenced_merge_requests(current_user).empty? + self.closed_by_merge_requests(current_user).empty? end end diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 5ea7d405e4d..f09b77c4a57 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -213,9 +213,9 @@ class SystemNoteService # "Started branch `201-issue-branch-button`" def self.new_issue_branch(issue, project, author, branch) h = Gitlab::Application.routes.url_helpers - link = "#{h.namespace_project_compare_url(project.namespace, project, from: project.default_branch, to: branch)}" + link = h.namespace_project_compare_url(project.namespace, project, from: project.default_branch, to: branch) - body = "Started branch [#{branch}](#{link})" + body = "Started branch [`#{branch}`](#{link})" create_note(noteable: issue, project: project, author: author, note: body) end -- cgit v1.2.1 From dce43b4bea88c753c6aeb43d2d283bef4d11eff1 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 15 Mar 2016 17:17:05 +0000 Subject: Pre-selects values on issue and merge request dropdown Closes #14290 --- app/helpers/issuables_helper.rb | 28 ++++++++++++++++++++++++++++ app/views/shared/issuable/_filter.html.haml | 8 ++++---- 2 files changed, 32 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 2dfeddf7368..29b78ac9100 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -20,6 +20,34 @@ module IssuablesHelper base_issuable_scope(issuable).where('iid < ?', issuable.iid).first end + def user_dropdown_label(user_id, default_label) + return "Unassigned" if user_id == "0" + + user = @project.team.users.find_by(id: user_id) + + if user + user.name + else + default_label + end + end + + def labels_dropdown_label(label_name) + if !label_name + "Label" + else + label_name + end + end + + def milestone_dropdown_label(milestone_name) + if !milestone_name + "Milestone" + else + milestone_name + end + end + private def sidebar_gutter_collapsed? diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index 3eb0db276b2..74ccaa53da2 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -9,19 +9,19 @@ .filter-item.inline - if params[:author_id] = hidden_field_tag(:author_id, params[:author_id]) - = dropdown_tag("Author", options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author", + = dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author", placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id" } }) .filter-item.inline - if params[:assignee_id] = hidden_field_tag(:assignee_id, params[:assignee_id]) - = dropdown_tag("Assignee", options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee", + = dropdown_tag(user_dropdown_label(params[:assignee_id], "Assignee"), options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee", placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id" } }) .filter-item.inline.milestone-filter - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) - = dropdown_tag("Milestone", options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + = dropdown_tag(milestone_dropdown_label(params[:milestone_title]), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: (namespace_project_milestones_path(@project.namespace, @project, :js) if @project) } }) do - if @project %ul.dropdown-footer-list @@ -42,7 +42,7 @@ .dropdown %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: (namespace_project_labels_path(@project.namespace, @project, :js) if @project)}} %span.dropdown-toggle-text - Label + = labels_dropdown_label(params[:label_name]) = icon('chevron-down') .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable .dropdown-page-one -- cgit v1.2.1 From 2e07ee7f01e9bd525c98ae3f84025dd8699fdf8a Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 15 Mar 2016 18:28:25 +0000 Subject: Fixed failing tests --- app/helpers/issuables_helper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 29b78ac9100..b254c62da26 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -23,7 +23,8 @@ module IssuablesHelper def user_dropdown_label(user_id, default_label) return "Unassigned" if user_id == "0" - user = @project.team.users.find_by(id: user_id) + user = @project.team.users.find_by(id: user_id) if @project + user = User.find_by_id(user_id) if !@project if user user.name -- cgit v1.2.1 From 438d614b2780e280256af81f1e3f2f1847b3405e Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 08:48:27 +0000 Subject: Removed label/milestone helper methods --- app/helpers/issuables_helper.rb | 26 ++++++++------------------ app/views/shared/issuable/_filter.html.haml | 4 ++-- 2 files changed, 10 insertions(+), 20 deletions(-) (limited to 'app') diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index b254c62da26..23f389b8c5f 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -23,8 +23,14 @@ module IssuablesHelper def user_dropdown_label(user_id, default_label) return "Unassigned" if user_id == "0" - user = @project.team.users.find_by(id: user_id) if @project - user = User.find_by_id(user_id) if !@project + if @project + member = @project.team.find_member(user_id) + if member + user = member.user + end + else + user = User.find(user_id) + end if user user.name @@ -33,22 +39,6 @@ module IssuablesHelper end end - def labels_dropdown_label(label_name) - if !label_name - "Label" - else - label_name - end - end - - def milestone_dropdown_label(milestone_name) - if !milestone_name - "Milestone" - else - milestone_name - end - end - private def sidebar_gutter_collapsed? diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index 74ccaa53da2..dfdc84ba4cc 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -21,7 +21,7 @@ .filter-item.inline.milestone-filter - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) - = dropdown_tag(milestone_dropdown_label(params[:milestone_title]), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + = dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: (namespace_project_milestones_path(@project.namespace, @project, :js) if @project) } }) do - if @project %ul.dropdown-footer-list @@ -42,7 +42,7 @@ .dropdown %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: (namespace_project_labels_path(@project.namespace, @project, :js) if @project)}} %span.dropdown-toggle-text - = labels_dropdown_label(params[:label_name]) + = h(params[:label_name] || "Label") = icon('chevron-down') .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable .dropdown-page-one -- cgit v1.2.1 From 2941a76fe0fa5305bd6e31e6c47477732e3e7cec Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 08:51:09 +0000 Subject: Added skip_js comment [ci skip] --- app/helpers/application_helper.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index f07c79ec611..ffddd0400fc 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -168,6 +168,7 @@ module ApplicationHelper # time - Time object # placement - Tooltip placement String (default: "top") # html_class - Custom class for `time` element (default: "time_ago") + # skip_js - When true, exclude the `script` tag (default: false) # # By default also includes a `script` element with Javascript necessary to # initialize the `timeago` jQuery extension. If this method is called many -- cgit v1.2.1 From d94dc565ba479e969ad548991b411e058330d8f9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 11:44:53 +0000 Subject: Fixed alignment of download dropdown With the new dropdown CSS - some dropdowns might look a bit odd --- app/assets/stylesheets/framework/dropdowns.scss | 6 ++++++ app/views/projects/repositories/_download_archive.html.haml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 309da34da07..d71ca9842aa 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -9,6 +9,12 @@ border-left: $caret-width-base solid transparent; } +.btn-group { + .caret { + margin-left: 0; + } +} + .dropdown { position: relative; } diff --git a/app/views/projects/repositories/_download_archive.html.haml b/app/views/projects/repositories/_download_archive.html.haml index b9486a9b492..24658319060 100644 --- a/app/views/projects/repositories/_download_archive.html.haml +++ b/app/views/projects/repositories/_download_archive.html.haml @@ -10,7 +10,7 @@ %span.caret %span.sr-only Select Archive Format - %ul.col-xs-10.dropdown-menu{ role: 'menu' } + %ul.col-xs-10.dropdown-menu.dropdown-menu-align-right{ role: 'menu' } %li = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), rel: 'nofollow' do %i.fa.fa-download -- cgit v1.2.1 From 18295585d9d2a7177f52fc451db7b0d542cc49b5 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Wed, 9 Mar 2016 08:19:54 +0100 Subject: Fix MergeRequest#source_sha when there is no diff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `MergeRequest#source_sha` is expected to return the sha of the source branch last commit. But when a open Merge Request has no diff (e.g. all commits have already been merged to the target branch), `merge_request.source_sha` incorrectly returns `nil`. This was un-noticed before – but now that !2217 has been merged, it makes `Gitlab::Git::Commit.between` raise an "Unexpected nil argument" exception. This fixes the crash, by making sure that `source_sha` returns a correct result even when there is no diff available. --- app/models/merge_request.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 188325045e2..30a7bd47be7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -520,7 +520,11 @@ class MergeRequest < ActiveRecord::Base end def source_sha - last_commit.try(:sha) + last_commit.try(:sha) || source_tip.try(:sha) + end + + def source_tip + source_branch && source_project.repository.commit(source_branch) end def fetch_ref -- cgit v1.2.1 From 65565bb304238a2e7d260faccd1a033d6da343e9 Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Wed, 16 Mar 2016 21:38:38 +0100 Subject: fix horizontal overflow that occurs in the code tag --- app/assets/stylesheets/pages/notes.scss | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'app') diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 1f631ab03eb..f7eeadcb5bf 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -108,6 +108,12 @@ ul.notes { word-wrap: break-word; @include md-typography; + pre { + code { + white-space: pre-wrap; + } + } + // Reset ul style types since we're nested inside a ul already & > ul { list-style-type: disc; -- cgit v1.2.1 From 49f2a4e3a6ebe2deb02abe48145e5ff33ccb7971 Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Wed, 16 Mar 2016 23:30:01 +0100 Subject: fix bug causing dropdown to get cut off in project page --- app/assets/stylesheets/pages/projects.scss | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'app') diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index a29b735eb0f..aca4d8d1b7a 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -33,6 +33,13 @@ .project-settings-dropdown { margin-left: 10px; display: inline-block; + + .dropdown-menu { + left: auto; + width: auto; + right: 0px; + max-width: 240px; + } } } -- cgit v1.2.1 From 5d3cd7fd3783d7e94894431ec13843a03feb77a5 Mon Sep 17 00:00:00 2001 From: connorshea Date: Wed, 16 Mar 2016 17:40:12 -0600 Subject: Follow the CSS Style Guide rules for including a space after the property colon. Fixes violations of SpaceAfterPropertyColon. Discussed in #14299. [ci skip] --- app/assets/stylesheets/framework/common.scss | 24 ++++++++++++------------ app/assets/stylesheets/framework/variables.scss | 2 +- app/assets/stylesheets/pages/appearances.scss | 2 +- app/assets/stylesheets/pages/dashboard.scss | 6 +++--- app/assets/stylesheets/pages/events.scss | 4 ++-- app/assets/stylesheets/pages/issuable.scss | 2 +- app/assets/stylesheets/pages/login.scss | 4 ++-- app/assets/stylesheets/pages/notes.scss | 10 +++++----- app/assets/stylesheets/pages/projects.scss | 8 ++++---- app/assets/stylesheets/pages/tree.scss | 2 +- 10 files changed, 32 insertions(+), 32 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 180926b3b97..bc03c2180be 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -8,20 +8,20 @@ /** COMMON CLASSES **/ .prepend-top-0 { margin-top: 0; } .prepend-top-5 { margin-top: 5px; } -.prepend-top-10 { margin-top:10px } +.prepend-top-10 { margin-top: 10px } .prepend-top-default { margin-top: $gl-padding !important; } -.prepend-top-20 { margin-top:20px } -.prepend-left-10 { margin-left:10px } +.prepend-top-20 { margin-top: 20px } +.prepend-left-10 { margin-left: 10px } .prepend-left-default { margin-left: $gl-padding; } -.prepend-left-20 { margin-left:20px } +.prepend-left-20 { margin-left: 20px } .append-right-5 { margin-right: 5px } -.append-right-10 { margin-right:10px } +.append-right-10 { margin-right: 10px } .append-right-default { margin-right: $gl-padding; } -.append-right-20 { margin-right:20px } -.append-bottom-0 { margin-bottom:0 } -.append-bottom-10 { margin-bottom:10px } -.append-bottom-15 { margin-bottom:15px } -.append-bottom-20 { margin-bottom:20px } +.append-right-20 { margin-right: 20px } +.append-bottom-0 { margin-bottom: 0 } +.append-bottom-10 { margin-bottom: 10px } +.append-bottom-15 { margin-bottom: 15px } +.append-bottom-20 { margin-bottom: 20px } .append-bottom-default { margin-bottom: $gl-padding; } .inline { display: inline-block } .center { text-align: center } @@ -134,10 +134,10 @@ p.time { // Fix issue with notes & lists creating a bunch of bottom borders. li.note { - img { max-width:100% } + img { max-width: 100% } .note-title { li { - border-bottom:none !important; + border-bottom: none !important; } } } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 5e3546bc6ff..211ead7319d 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -27,7 +27,7 @@ $gl-gray: #5a5a5a; $gl-padding: 16px; $gl-btn-padding: 10px; $gl-vert-padding: 6px; -$gl-padding-top:10px; +$gl-padding-top: 10px; $gl-avatar-size: 40px; $secondary-text: #7f8fa4; $error-exclamation-point: #e62958; diff --git a/app/assets/stylesheets/pages/appearances.scss b/app/assets/stylesheets/pages/appearances.scss index e2070f17c3b..878f44116ba 100644 --- a/app/assets/stylesheets/pages/appearances.scss +++ b/app/assets/stylesheets/pages/appearances.scss @@ -4,7 +4,7 @@ } .appearance-light-logo-preview { - background-color: $background-color; + background-color: $background-color; max-width: 72px; padding: 10px; margin-bottom: 10px; diff --git a/app/assets/stylesheets/pages/dashboard.scss b/app/assets/stylesheets/pages/dashboard.scss index 88639399148..cf7567513ec 100644 --- a/app/assets/stylesheets/pages/dashboard.scss +++ b/app/assets/stylesheets/pages/dashboard.scss @@ -11,15 +11,15 @@ } .dashboard-search-filter { - padding:5px; + padding: 5px; .search-text-input { - float:left; + float: left; @extend .col-md-2; } .btn { margin-left: 5px; - float:left; + float: left; } } diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index e7da0a2f689..b39a9abf40f 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -94,7 +94,7 @@ } } - &:last-child { border:none } + &:last-child { border: none } .event_commits { li { @@ -138,7 +138,7 @@ @include str-truncated(100%); padding: 5px 0; font-size: 13px; - float:left; + float: left; margin-right: -150px; padding-right: 150px; line-height: 20px; diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index faa2ebfda78..c975ca0ce43 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -59,7 +59,7 @@ .issuable-sidebar { .block { @include clearfix; - padding: $gl-padding 0; + padding: $gl-padding 0; border-bottom: 1px solid $border-gray-light; // This prevents the mess when resizing the sidebar // of elements repositioning themselves.. diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index d9c47881265..bc41f7d306f 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -28,7 +28,7 @@ img { max-width: 100%; - margin-bottom: 30px; + margin-bottom: 30px; } a { @@ -85,7 +85,7 @@ &.middle { border-top: 0; - margin-bottom:0; + margin-bottom: 0; @include border-radius(0); } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 969c79a9be9..c40dc79537e 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -3,9 +3,9 @@ */ @-webkit-keyframes targe3-note { - from { background:#fffff0; } - 50% { background:#ffffd3; } - to { background:#fffff0; } + from { background: #fffff0; } + 50% { background: #ffffd3; } + to { background: #fffff0; } } ul.notes { @@ -93,12 +93,12 @@ ul.notes { .discussion { overflow: hidden; display: block; - position:relative; + position: relative; } .note { display: block; - position:relative; + position: relative; .note-body { overflow: auto; diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 3fe2c9a3346..6c600c99d51 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -286,11 +286,11 @@ table.table.protected-branches-list tr.no-border { padding-bottom: 4px; ul.nav { - display:inline-block; + display: inline-block; } .nav li { - display:inline; + display: inline; } .nav > li > a { @@ -303,11 +303,11 @@ table.table.protected-branches-list tr.no-border { } li { - display:inline; + display: inline; } a { - float:left; + float: left; font-size: 17px; } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index ef63b010600..73c7c9f687c 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -46,7 +46,7 @@ img { position: relative; - top:-1px; + top: -1px; } } -- cgit v1.2.1 From f54bf00309e310cabb2fec55d860f0670f3b79ac Mon Sep 17 00:00:00 2001 From: Gabriel Mazetto Date: Thu, 17 Mar 2016 00:24:12 -0300 Subject: =?UTF-8?q?Back-porting=20PostReceive=20refactor=20made=20for=20EE?= =?UTF-8?q?=20=F0=9F=8D=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/workers/post_receive.rb | 46 +++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'app') diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 14d7813412e..3cc232ef1ae 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -1,6 +1,5 @@ class PostReceive include Sidekiq::Worker - include Gitlab::Identifier sidekiq_options queue: :post_receive @@ -11,51 +10,44 @@ class PostReceive log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"") end - repo_path.gsub!(/\.git\z/, "") - repo_path.gsub!(/\A\//, "") + post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes) - project = Project.find_with_namespace(repo_path) - - if project.nil? + if post_received.project.nil? log("Triggered hook for non-existing project with full path \"#{repo_path} \"") return false end - changes = Base64.decode64(changes) unless changes.include?(" ") - changes = utf8_encode_changes(changes) - changes = changes.lines + if post_received.wiki? + # Nothing defined here yet. + elsif post_received.regular_project? + process_project_changes(post_received) + else + log("Triggered hook for unidentifiable repository type with full path \"#{repo_path} \"") + false + end + end - changes.each do |change| + def process_project_changes(post_received) + post_received.changes.each do |change| oldrev, newrev, ref = change.strip.split(' ') - @user ||= identify(identifier, project, newrev) + @user ||= post_received.identify(newrev) unless @user - log("Triggered hook for non-existing user \"#{identifier} \"") + log("Triggered hook for non-existing user \"#{post_received.identifier} \"") return false end if Gitlab::Git.tag_ref?(ref) - GitTagPushService.new.execute(project, @user, oldrev, newrev, ref) + GitTagPushService.new.execute(post_received.project, @user, oldrev, newrev, ref) else - GitPushService.new(project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute + GitPushService.new(post_received.project, @user, oldrev: oldrev, newrev: newrev, ref: ref).execute end end end - def utf8_encode_changes(changes) - changes = changes.dup - - changes.force_encoding("UTF-8") - return changes if changes.valid_encoding? - - # Convert non-UTF-8 branch/tag names to UTF-8 so they can be dumped as JSON. - detection = CharlockHolmes::EncodingDetector.detect(changes) - return changes unless detection && detection[:encoding] - - CharlockHolmes::Converter.convert(changes, detection[:encoding], 'UTF-8') - end - + private + def log(message) Gitlab::GitLogger.error("POST-RECEIVE: #{message}") end -- cgit v1.2.1 From 81439c9093707d8964258db9481715b3ca0e7a3a Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 09:13:20 +0000 Subject: Moved code to single line if --- app/helpers/issuables_helper.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 23f389b8c5f..81df2094392 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -25,11 +25,9 @@ module IssuablesHelper if @project member = @project.team.find_member(user_id) - if member - user = member.user - end + user = member.user if member else - user = User.find(user_id) + user = User.find_by(id: user_id) end if user -- cgit v1.2.1 From 2057bc02a31a20765e165b503b877350e892908b Mon Sep 17 00:00:00 2001 From: Jacob Vosmaer Date: Thu, 17 Mar 2016 11:02:11 +0100 Subject: Do not retry "git gc" --- app/services/projects/housekeeping_service.rb | 2 +- app/workers/gitlab_shell_one_shot_worker.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 app/workers/gitlab_shell_one_shot_worker.rb (limited to 'app') diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb index bccd67d3dbf..a0973c5d260 100644 --- a/app/services/projects/housekeeping_service.rb +++ b/app/services/projects/housekeeping_service.rb @@ -24,7 +24,7 @@ module Projects def execute raise LeaseTaken if !try_obtain_lease - GitlabShellWorker.perform_async(:gc, @project.path_with_namespace) + GitlabShellOneShotWorker.perform_async(:gc, @project.path_with_namespace) ensure @project.update_column(:pushes_since_gc, 0) end diff --git a/app/workers/gitlab_shell_one_shot_worker.rb b/app/workers/gitlab_shell_one_shot_worker.rb new file mode 100644 index 00000000000..4ddbcf574d5 --- /dev/null +++ b/app/workers/gitlab_shell_one_shot_worker.rb @@ -0,0 +1,10 @@ +class GitlabShellOneShotWorker + include Sidekiq::Worker + include Gitlab::ShellAdapter + + sidekiq_options queue: :gitlab_shell, retry: false + + def perform(action, *arg) + gitlab_shell.send(action, *arg) + end +end -- cgit v1.2.1 From feb538dddd5e2e6b09860d34b4a17c3e46a006c8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 10:21:48 +0000 Subject: Fixed filter spacing Closes #14350 --- app/assets/stylesheets/framework/filters.scss | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index c431e2b0df3..40a508c1ebc 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -3,22 +3,11 @@ vertical-align: top; } -@media (min-width: 800px) { +@media (min-width: $screen-sm-min) { .issues-filters, .issues_bulk_update { - select, .select2-container { - width: 120px !important; - display: inline-block; - } - } -} - -@media (min-width: 1200px) { - .issues-filters, - .issues_bulk_update { - select, .select2-container { - width: 150px !important; - display: inline-block; + .dropdown-menu-toggle { + width: 132px; } } } -- cgit v1.2.1 From 9337406671755ebd9175866cd86f1d6da4265d49 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 17 Mar 2016 11:48:07 +0100 Subject: Fix specs Spinach was right, I was a fool.. --- app/models/issue.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/models/issue.rb b/app/models/issue.rb index 781298a63b2..2447f860c5a 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -98,6 +98,7 @@ class Issue < ActiveRecord::Base end def related_branches + return [] if self.project.empty_repo? self.project.repository.branch_names.select do |branch| branch =~ /\A#{iid}-(?!\d+-stable)/i end -- cgit v1.2.1 From 019fed0f72116a73f0d410fe0c892fc9a19921e7 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Thu, 17 Mar 2016 12:16:34 +0100 Subject: Reuse `no_cache_headers` method in badges controller --- app/controllers/projects/badges_controller.rb | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'app') diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb index dc9c96df003..6ff47c4033a 100644 --- a/app/controllers/projects/badges_controller.rb +++ b/app/controllers/projects/badges_controller.rb @@ -1,5 +1,5 @@ class Projects::BadgesController < Projects::ApplicationController - before_action :set_no_cache + before_action :no_cache_headers def build respond_to do |format| @@ -10,15 +10,4 @@ class Projects::BadgesController < Projects::ApplicationController end end end - - private - - def set_no_cache - expires_now - - # Add some deprecated headers for older agents - # - response.headers['Pragma'] = 'no-cache' - response.headers['Expires'] = 'Fri, 01 Jan 1990 00:00:00 GMT' - end end -- cgit v1.2.1 From fa570525dbe35fb598b8a269198e1173da6d7ae3 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Tue, 23 Feb 2016 15:09:35 -0500 Subject: Adds small AJAX optimistic functionality to todos. Fixes #13656 A good first step and boring solution. --- app/assets/javascripts/dispatcher.js.coffee | 3 +- app/assets/javascripts/todos.js.coffee | 48 +++++++++++++++++++++++++++ app/assets/stylesheets/framework/flash.scss | 6 ++++ app/controllers/dashboard/todos_controller.rb | 7 +++- app/views/dashboard/todos/_todo.html.haml | 2 +- app/views/dashboard/todos/index.html.haml | 6 ++-- 6 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 app/assets/javascripts/todos.js.coffee (limited to 'app') diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index 1be86e3b820..f5e1ca9860d 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -14,7 +14,6 @@ class Dispatcher path = page.split(':') shortcut_handler = null - switch page when 'projects:issues:index' Issues.init() @@ -25,6 +24,8 @@ class Dispatcher new ZenMode() when 'projects:milestones:show', 'groups:milestones:show', 'dashboard:milestones:show' new Milestone() + when 'dashboard:todos:index' + new Todos() when 'projects:milestones:new', 'projects:milestones:edit' new ZenMode() new DropzoneInput($('.milestone-form')) diff --git a/app/assets/javascripts/todos.js.coffee b/app/assets/javascripts/todos.js.coffee new file mode 100644 index 00000000000..b68c143b4bb --- /dev/null +++ b/app/assets/javascripts/todos.js.coffee @@ -0,0 +1,48 @@ +class @Todos + _this = null; + constructor: (@name) -> + _this = @ + @initBtnListeners() + + initBtnListeners: -> + $('.done-todo').on('click', @doneClicked) + + doneClicked: (e) -> + $this = $(this) + doneURL = $this.attr('href') + e.preventDefault() + e.stopImmediatePropagation() + $spinner = $('').addClass('fa fa-spinner fa-spin') + $this.addClass("disabled") + $this.append($spinner) + $.ajax + type: 'POST' + url: doneURL + dataType: 'json' + data: '_method': 'delete' + error: (data, textStatus, jqXHR) -> + new Flash('Unable to update your todos.', 'alert') + _this.clearDone($this.closest('li')) + return + + success: (data, textStatus, jqXHR) -> + new Flash(data.notice, 'success') + _this.clearDone($this.closest('li')) + return + + clearDone: ($row) -> + $ul = $row.closest('ul') + $row.remove() + if not $ul.find('li').length + Turbolinks.visit(location.href) + else + $pendingBadge = $('.todos-pending .badge') + $pendingBadge.text parseInt($pendingBadge.text()) - 1 + + $doneBadge = $('.todos-done .badge') + $doneBadge.text parseInt($doneBadge.text()) + 1 + + $mainTodosPendingBadge = $('.todos-pending-count') + $mainTodosPendingBadge.text parseInt($mainTodosPendingBadge.text()) - 1 + return + \ No newline at end of file diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index 1bfd0213995..244d0e2f0c8 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -5,6 +5,12 @@ width: 100%; z-index: 100; + .flash-success { + @extend .alert; + @extend .alert-success; + margin: 0; + } + .flash-notice { @extend .alert; @extend .alert-info; diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 43cf8fa71af..54f718d0110 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -8,9 +8,14 @@ class Dashboard::TodosController < Dashboard::ApplicationController def destroy todo.done! + todo_notice = 'Todo was successfully marked as done.' + respond_to do |format| - format.html { redirect_to dashboard_todos_path, notice: 'Todo was successfully marked as done.' } + format.html { redirect_to dashboard_todos_path, notice: todo_notice } format.js { render nothing: true } + format.json do + render json: { status: 'OK', notice: todo_notice } + end end end diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index 45cfe3da188..b7deb9da543 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -16,7 +16,7 @@ - if todo.pending? .todo-actions.pull-right - = link_to 'Done', [:dashboard, todo], method: :delete, class: 'btn' + = link_to 'Done', [:dashboard, todo], method: :delete, class: 'btn done-todo' .todo-body .todo-note diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index 946d7df3933..b5b8fb4d14e 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -3,13 +3,15 @@ .top-area %ul.nav-links - %li{class: ('active' if params[:state].blank? || params[:state] == 'pending')} + - todo_pending_active = ('active' if params[:state].blank? || params[:state] == 'pending') + %li{class: "todos-pending #{todo_pending_active}"} = link_to todos_filter_path(state: 'pending') do %span To do %span{class: 'badge'} = todos_pending_count - %li{class: ('active' if params[:state] == 'done')} + - todo_done_active = ('active' if params[:state] == 'done') + %li{class: "todos-done #{todo_done_active}"} = link_to todos_filter_path(state: 'done') do %span Done -- cgit v1.2.1 From 8f8720209f1f325042cbe3f134797c85cc0c64c4 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Fri, 4 Mar 2016 09:15:48 -0500 Subject: Remove `Flash` from todos when finished --- app/assets/javascripts/todos.js.coffee | 1 - 1 file changed, 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/todos.js.coffee b/app/assets/javascripts/todos.js.coffee index b68c143b4bb..811652c8d8b 100644 --- a/app/assets/javascripts/todos.js.coffee +++ b/app/assets/javascripts/todos.js.coffee @@ -26,7 +26,6 @@ class @Todos return success: (data, textStatus, jqXHR) -> - new Flash(data.notice, 'success') _this.clearDone($this.closest('li')) return -- cgit v1.2.1 From 421215e3385860af42530895c22021c0704275e2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 12:54:02 +0000 Subject: Removed the flash success message Removes the group if empty --- app/assets/javascripts/todos.js.coffee | 52 +++++++++++---------------- app/assets/stylesheets/framework/buttons.scss | 10 ++++++ app/assets/stylesheets/framework/flash.scss | 6 ---- app/controllers/dashboard/todos_controller.rb | 4 +-- app/views/dashboard/todos/_todo.html.haml | 4 ++- 5 files changed, 35 insertions(+), 41 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/todos.js.coffee b/app/assets/javascripts/todos.js.coffee index 811652c8d8b..951b786b1fd 100644 --- a/app/assets/javascripts/todos.js.coffee +++ b/app/assets/javascripts/todos.js.coffee @@ -1,47 +1,35 @@ class @Todos - _this = null; constructor: (@name) -> - _this = @ + @clearListeners() @initBtnListeners() - + + clearListeners: -> + $('.done-todo').off('click') + initBtnListeners: -> $('.done-todo').on('click', @doneClicked) - - doneClicked: (e) -> - $this = $(this) - doneURL = $this.attr('href') + + doneClicked: (e) => e.preventDefault() e.stopImmediatePropagation() - $spinner = $('').addClass('fa fa-spinner fa-spin') - $this.addClass("disabled") - $this.append($spinner) + + $this = $(e.currentTarget) + $this.disable() + $.ajax type: 'POST' - url: doneURL + url: $this.attr('href') dataType: 'json' data: '_method': 'delete' - error: (data, textStatus, jqXHR) -> - new Flash('Unable to update your todos.', 'alert') - _this.clearDone($this.closest('li')) - return - - success: (data, textStatus, jqXHR) -> - _this.clearDone($this.closest('li')) - return + success: (data) => + @clearDone $this.closest('li'), data - clearDone: ($row) -> + clearDone: ($row, data) -> $ul = $row.closest('ul') $row.remove() + + $('.todos-pending .badge, .todos-pending-count').text data.count + $('.todos-done .badge').text data.done_count + if not $ul.find('li').length - Turbolinks.visit(location.href) - else - $pendingBadge = $('.todos-pending .badge') - $pendingBadge.text parseInt($pendingBadge.text()) - 1 - - $doneBadge = $('.todos-done .badge') - $doneBadge.text parseInt($doneBadge.text()) + 1 - - $mainTodosPendingBadge = $('.todos-pending-count') - $mainTodosPendingBadge.text parseInt($mainTodosPendingBadge.text()) - 1 - return - \ No newline at end of file + $ul.parents('.panel').remove() diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index fa115a4bf56..657c5f033c7 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -208,3 +208,13 @@ background-color: #e4e7ed !important; } } + +.btn-loading { + &:not(.disabled) .fa { + display: none; + } + + .fa { + margin-right: 5px; + } +} diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index 244d0e2f0c8..1bfd0213995 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -5,12 +5,6 @@ width: 100%; z-index: 100; - .flash-success { - @extend .alert; - @extend .alert-success; - margin: 0; - } - .flash-notice { @extend .alert; @extend .alert-info; diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 54f718d0110..10120dfdf3b 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -1,5 +1,5 @@ class Dashboard::TodosController < Dashboard::ApplicationController - before_action :find_todos, only: [:index, :destroy_all] + before_action :find_todos, only: [:index, :destroy, :destroy_all] def index @todos = @todos.page(params[:page]).per(PER_PAGE) @@ -14,7 +14,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController format.html { redirect_to dashboard_todos_path, notice: todo_notice } format.js { render nothing: true } format.json do - render json: { status: 'OK', notice: todo_notice } + render json: { count: @todos.size, done_count: current_user.todos.done.count } end end end diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index b7deb9da543..42f3cf4de02 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -16,7 +16,9 @@ - if todo.pending? .todo-actions.pull-right - = link_to 'Done', [:dashboard, todo], method: :delete, class: 'btn done-todo' + = link_to [:dashboard, todo], method: :delete, class: 'btn btn-loading done-todo' do + = icon('spinner spin') + Done .todo-body .todo-note -- cgit v1.2.1 From 41c107beccda574aefd3e5d992345087b2e0d848 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 13:08:59 +0000 Subject: Mark all as done through AJAX --- app/assets/javascripts/todos.js.coffee | 31 ++++++++++++++++++++++----- app/controllers/dashboard/todos_controller.rb | 4 ++++ app/views/dashboard/todos/_todo.html.haml | 2 +- app/views/dashboard/todos/index.html.haml | 6 ++++-- 4 files changed, 35 insertions(+), 8 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/todos.js.coffee b/app/assets/javascripts/todos.js.coffee index 951b786b1fd..b6b4bd90e6a 100644 --- a/app/assets/javascripts/todos.js.coffee +++ b/app/assets/javascripts/todos.js.coffee @@ -5,9 +5,11 @@ class @Todos clearListeners: -> $('.done-todo').off('click') + $('.js-todos-mark-all').off('click') initBtnListeners: -> $('.done-todo').on('click', @doneClicked) + $('.js-todos-mark-all').on('click', @allDoneClicked) doneClicked: (e) => e.preventDefault() @@ -22,14 +24,33 @@ class @Todos dataType: 'json' data: '_method': 'delete' success: (data) => - @clearDone $this.closest('li'), data + @clearDone $this.closest('li') + @updateBadges data - clearDone: ($row, data) -> + allDoneClicked: (e) => + e.preventDefault() + e.stopImmediatePropagation() + + $this = $(e.currentTarget) + $this.disable() + + $.ajax + type: 'POST' + url: $this.attr('href') + dataType: 'json' + data: '_method': 'delete' + success: (data) => + $this.remove() + $('.js-todos-list').remove() + @updateBadges data + + clearDone: ($row) -> $ul = $row.closest('ul') $row.remove() - $('.todos-pending .badge, .todos-pending-count').text data.count - $('.todos-done .badge').text data.done_count - if not $ul.find('li').length $ul.parents('.panel').remove() + + updateBadges: (data) -> + $('.todos-pending .badge, .todos-pending-count').text data.count + $('.todos-done .badge').text data.done_count diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 10120dfdf3b..7857af9c5de 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -25,6 +25,10 @@ class Dashboard::TodosController < Dashboard::ApplicationController respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } format.js { render nothing: true } + format.json do + find_todos + render json: { count: @todos.size, done_count: current_user.todos.done.count } + end end end diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index 42f3cf4de02..4c848a50181 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -17,8 +17,8 @@ - if todo.pending? .todo-actions.pull-right = link_to [:dashboard, todo], method: :delete, class: 'btn btn-loading done-todo' do - = icon('spinner spin') Done + = icon('spinner spin') .todo-body .todo-note diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index b5b8fb4d14e..623381375a5 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -20,7 +20,9 @@ .nav-controls - if @todos.any?(&:pending?) - = link_to 'Mark all as done', destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn', method: :delete + = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete do + Mark all as done + = icon('spinner spin') .todos-filters .gray-content-block.second-block @@ -44,7 +46,7 @@ .prepend-top-default - if @todos.any? - @todos.group_by(&:project).each do |group| - .panel.panel-default.panel-small + .panel.panel-default.panel-small.js-todos-list - project = group[0] .panel-heading = link_to project.name_with_namespace, namespace_project_path(project.namespace, project) -- cgit v1.2.1 From 4b5e06a944c46043b735952bd02754993de84744 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Thu, 17 Mar 2016 09:18:16 -0400 Subject: Added comment to make builds run --- app/assets/stylesheets/pages/notes.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'app') diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index f7eeadcb5bf..4f9c18b85d4 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -108,6 +108,7 @@ ul.notes { word-wrap: break-word; @include md-typography; + // On diffs code should wrap nicely and not overflow pre { code { white-space: pre-wrap; -- cgit v1.2.1 From 4117c815df73ba80258ca472470735826c68753a Mon Sep 17 00:00:00 2001 From: Geoffrey Lalonde Date: Thu, 17 Mar 2016 07:54:56 -0700 Subject: adjusted behavior so canceled builds tagged as allowed to fail do not fail build --- app/models/commit_status.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 3b1aa0f5c80..3377a85a55a 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -114,7 +114,7 @@ class CommitStatus < ActiveRecord::Base end def ignored? - failed? && allow_failure? + allow_failure? && (failed? || canceled?) end def duration -- cgit v1.2.1 From 21952cc7f13c6bf3eaf7c8515d59b79dd2fc6188 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 17 Mar 2016 17:29:09 +0100 Subject: Add side padding to content-list if inside panel Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/framework/lists.scss | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app') diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index bfec0911b3c..2b4bb1eebf9 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -141,6 +141,10 @@ ul.content-list { } } +.panel > .content-list > li { + padding: $gl-padding-top $gl-padding; +} + ul.controls { padding-top: 1px; float: right; -- cgit v1.2.1 From 5ae95b1880f99bf0414dccacc51b624c00d6b305 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 17 Mar 2016 17:59:58 +0100 Subject: Add space to separate different files in diff Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/pages/diff.scss | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index db06b8288c2..d5862a11aca 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -1,7 +1,7 @@ // Common .diff-file { border: 1px solid $border-color; - border-top: none; + margin-bottom: $gl-padding; .diff-header { position: relative; @@ -361,3 +361,11 @@ border-color: $border; } } + +.files { + margin-top: -1px; + + .diff-file:last-child { + margin-bottom: 0; + } +} -- cgit v1.2.1 From 028c751040b6acc29f3127d5f2d119b899a85205 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Thu, 17 Mar 2016 12:20:24 -0500 Subject: Revert link color from blue --- app/assets/stylesheets/framework/blocks.scss | 4 ---- 1 file changed, 4 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 90c3ce0e84c..c36f29dda0e 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -28,10 +28,6 @@ border-bottom: 1px solid $border-color; color: $gl-gray; - a { - color: $md-link-color; - } - &.oneline-block { line-height: 42px; } -- cgit v1.2.1 From 6048910aeef723faa535ce7ba6bb88a5e3360df9 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 17 Mar 2016 13:38:35 -0400 Subject: Prevent a 500 when a repository's root_ref is nil Closes #14259 --- app/views/layouts/header/_default.html.haml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 77d01a7736c..f3090b96702 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -46,6 +46,8 @@ %h1.title= title = render 'shared/outdated_browser' + - if @project && !@project.empty_repo? - :javascript - var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, @ref || @project.repository.root_ref)}"; + - if ref = @ref || @project.repository.root_ref + :javascript + var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, ref)}"; -- cgit v1.2.1 From cd05d3f78d2093baab39f6c3c114d1ab7138309f Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 17 Mar 2016 16:53:05 +0100 Subject: Cache project avatars stored in Git The avatar logic has been moved from Project to Repository as this makes caching easier. The logic itself in turn has been changed so that the logo file names are cached in Redis. This cache is flushed upon pushing a commit but _only_ if: 1. The commit was pushed to the default branch 2. The commit actually changes any of the logo files If no branch or commit is given the cache is flushed anyway, this ensures that calling Repository#expire_cache without any arguments still flushes the avatar cache (e.g. this is used when removing a project). Fixes gitlab-org/gitlab-ce#14363 --- app/models/project.rb | 5 +---- app/models/repository.rb | 36 +++++++++++++++++++++++++++++++++--- app/services/git_push_service.rb | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) (limited to 'app') diff --git a/app/models/project.rb b/app/models/project.rb index ab4913e99a8..412c6c6732d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -571,10 +571,7 @@ class Project < ActiveRecord::Base end def avatar_in_git - @avatar_file ||= 'logo.png' if repository.blob_at_branch('master', 'logo.png') - @avatar_file ||= 'logo.jpg' if repository.blob_at_branch('master', 'logo.jpg') - @avatar_file ||= 'logo.gif' if repository.blob_at_branch('master', 'logo.gif') - @avatar_file + repository.avatar end def avatar_url diff --git a/app/models/repository.rb b/app/models/repository.rb index e555e97689d..036919c27b2 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -3,6 +3,10 @@ require 'securerandom' class Repository class CommitError < StandardError; end + # Files to use as a project avatar in case no avatar was uploaded via the web + # UI. + AVATAR_FILES = %w{logo.png logo.jpg logo.gif} + include Gitlab::ShellAdapter attr_accessor :path_with_namespace, :project @@ -241,12 +245,13 @@ class Repository @branches = nil end - def expire_cache(branch_name = nil) + def expire_cache(branch_name = nil, revision = nil) cache_keys.each do |key| cache.expire(key) end expire_branch_cache(branch_name) + expire_avatar_cache(branch_name, revision) # This ensures this particular cache is flushed after the first commit to a # new repository. @@ -316,6 +321,23 @@ class Repository cache.expire(:branch_names) end + def expire_avatar_cache(branch_name = nil, revision = nil) + # Avatars are pulled from the default branch, thus if somebody pushes to a + # different branch there's no need to expire anything. + return if branch_name && branch_name != root_ref + + # We don't want to flush the cache if the commit didn't actually make any + # changes to any of the possible avatar files. + if revision && commit = self.commit(revision) + return unless commit.diffs. + any? { |diff| AVATAR_FILES.include?(diff.new_path) } + end + + cache.expire(:avatar) + + @avatar = nil + end + # Runs code just before a repository is deleted. def before_delete expire_cache if exists? @@ -350,8 +372,8 @@ class Repository end # Runs code after a new commit has been pushed. - def after_push_commit(branch_name) - expire_cache(branch_name) + def after_push_commit(branch_name, revision) + expire_cache(branch_name, revision) end # Runs code after a new branch has been created. @@ -857,6 +879,14 @@ class Repository end end + def avatar + @avatar ||= cache.fetch(:avatar) do + AVATAR_FILES.find do |file| + blob_at_branch('master', file) + end + end + end + private def cache diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb index d840ab5e340..14e2a2c0699 100644 --- a/app/services/git_push_service.rb +++ b/app/services/git_push_service.rb @@ -17,7 +17,7 @@ class GitPushService < BaseService # 6. Checks if the project's main language has changed # def execute - @project.repository.after_push_commit(branch_name) + @project.repository.after_push_commit(branch_name, params[:newrev]) if push_remove_branch? @project.repository.after_remove_branch -- cgit v1.2.1 From cfb10c103f1298b7c4ec94c76f66445a5969d13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D=C3=A1vila?= Date: Thu, 17 Mar 2016 15:16:34 -0500 Subject: Check push permissions only when pushing directly to target branch. --- app/services/commits/revert_service.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/services/commits/revert_service.rb b/app/services/commits/revert_service.rb index 9cb918d7a2e..a3c950ede1f 100644 --- a/app/services/commits/revert_service.rb +++ b/app/services/commits/revert_service.rb @@ -9,7 +9,8 @@ module Commits @commit = params[:commit] @create_merge_request = params[:create_merge_request].present? - validate and commit + check_push_permissions unless @create_merge_request + commit rescue Repository::CommitError, Gitlab::Git::Repository::InvalidBlobName, GitHooksService::PreReceiveError, ValidationError, ReversionError => ex error(ex.message) @@ -45,11 +46,11 @@ module Commits end end - def validate + def check_push_permissions allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch) unless allowed - raise_error('You are not allowed to push into this branch') + raise ValidationError.new('You are not allowed to push into this branch') end true -- cgit v1.2.1 From 81d191ede9eed2ef63d772a40038679944d8fd69 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 17 Mar 2016 17:50:59 +0100 Subject: Removed Repository#rebuild_cache This method is not used or tested anywhere. --- app/models/repository.rb | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'app') diff --git a/app/models/repository.rb b/app/models/repository.rb index 036919c27b2..53d3d90859f 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -301,18 +301,6 @@ class Repository @tag_count = nil end - def rebuild_cache - cache_keys.each do |key| - cache.expire(key) - send(key) - end - - branches.each do |branch| - cache.expire(:"diverging_commit_counts_#{branch.name}") - diverging_commit_counts(branch) - end - end - def lookup_cache @lookup_cache ||= {} end -- cgit v1.2.1 From 3d7feeede32a81df06f80f6f3599bfe62aa6e13d Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 17 Mar 2016 17:52:19 +0100 Subject: Don't rebuild diverging commit count caches When calling Repository#build_cache we _don't_ want to build the diverging commit count cache as doing so can be _very_ slow for repositories with lots of branches. Because these caches are built whenever needed (= when actually viewing the list of branches in the web UI) we can safely remove this code from Repository#build_cache. --- app/models/repository.rb | 6 ------ 1 file changed, 6 deletions(-) (limited to 'app') diff --git a/app/models/repository.rb b/app/models/repository.rb index 53d3d90859f..25d24493f6e 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -227,12 +227,6 @@ class Repository send(key) end end - - branches.each do |branch| - unless cache.exist?(:"diverging_commit_counts_#{branch.name}") - send(:diverging_commit_counts, branch) - end - end end def expire_tags_cache -- cgit v1.2.1 From 613e0bc5411bd767eeca5439876d61d843957826 Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Thu, 17 Mar 2016 22:34:42 +0100 Subject: Fix inconsistency in the header of issue and merge request pages --- app/views/projects/issues/show.html.haml | 11 +++++------ .../projects/merge_requests/show/_mr_title.html.haml | 17 ++++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'app') diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 1e8308277cc..494f58c57cd 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -25,17 +25,16 @@ %strong.identifier Issue ##{@issue.iid} %span.creator - by + opened .editor-details .editor-details + = time_ago_with_tooltip(@issue.created_at) + by %strong - = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-xs") - %span.hidden-xs - = '@' + @issue.author.username + = link_to_member(@project, @issue.author, avatar: false, size: 24, mobile_classes: "hidden-xs") %strong - = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", + = link_to_member(@project, @issue.author, avatar: false, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) - = time_ago_with_tooltip(@issue.created_at) .pull-right.issue-btn-group - if can?(current_user, :create_issue, @project) diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index a75c0d96c57..c6cbe8589ef 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -8,18 +8,21 @@ = icon('angle-double-left') .issue-meta %strong.identifier - Merge Request ##{@merge_request.iid} + %span.hidden-sm.hidden-md.hidden-lg + MR + %span.hidden-xs + Merge Request + !#{@merge_request.iid} %span.creator - by + opened .editor-details + = time_ago_with_tooltip(@merge_request.created_at) + by %strong - = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-xs") - %span.hidden-xs - = '@' + @merge_request.author.username + = link_to_member(@project, @merge_request.author, avatar: false, size: 24, mobile_classes: "hidden-xs") %strong - = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", + = link_to_member(@project, @merge_request.author, avatar: false, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) - = time_ago_with_tooltip(@merge_request.created_at) .issue-btn-group.pull-right - if can?(current_user, :update_merge_request, @merge_request) -- cgit v1.2.1 From 6b86d3fb800bb551af4a446b87dfd64c963733a3 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 16:16:48 -0300 Subject: Add an option to user make an issue confidential --- app/controllers/projects/issues_controller.rb | 2 +- app/views/shared/issuable/_form.html.haml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index aa7a178dcf4..0907733fe42 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -158,7 +158,7 @@ class Projects::IssuesController < Projects::ApplicationController def issue_params params.require(:issue).permit( - :title, :assignee_id, :position, :description, + :title, :assignee_id, :position, :description, :confidential, :milestone_id, :state_event, :task_num, label_ids: [] ) end diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index d5a4aad05d9..9ef729e960c 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -29,6 +29,15 @@ = render 'projects/notes/hints' .clearfix .error-alert + +- if issuable.is_a?(Issue) && !issuable.project.private? + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :confidential do + = f.check_box :confidential + This issue is confidential and should only be visible to team members + - if can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project) %hr .form-group -- cgit v1.2.1 From 34ee75379cf8e6459b8926fbf956a8316f87eea7 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 16:38:51 -0300 Subject: Restrict access to confidential issues --- app/controllers/projects/issues_controller.rb | 6 +++++- app/finders/issues_finder.rb | 6 ++++++ app/models/ability.rb | 17 ++++++++++++++++- app/models/issue.rb | 7 +++++++ 4 files changed, 34 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 0907733fe42..6603f28a082 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -5,7 +5,7 @@ class Projects::IssuesController < Projects::ApplicationController before_action :issue, only: [:edit, :update, :show] # Allow read any issue - before_action :authorize_read_issue! + before_action :authorize_read_issue!, only: [:show] # Allow write(create) issue before_action :authorize_create_issue!, only: [:new, :create] @@ -128,6 +128,10 @@ class Projects::IssuesController < Projects::ApplicationController end alias_method :subscribable_resource, :issue + def authorize_read_issue! + return render_404 unless can?(current_user, :read_issue, @issue) + end + def authorize_update_issue! return render_404 unless can?(current_user, :update_issue, @issue) end diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb index 20a2b0ce8f0..c2befa5a5b3 100644 --- a/app/finders/issues_finder.rb +++ b/app/finders/issues_finder.rb @@ -19,4 +19,10 @@ class IssuesFinder < IssuableFinder def klass Issue end + + private + + def init_collection + Issue.visible_to_user(current_user) + end end diff --git a/app/models/ability.rb b/app/models/ability.rb index ccac08b7d3f..e22da4806e6 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -49,7 +49,6 @@ class Ability rules = [ :read_project, :read_wiki, - :read_issue, :read_label, :read_milestone, :read_project_snippet, @@ -63,6 +62,9 @@ class Ability # Allow to read builds by anonymous user if guests are allowed rules << :read_build if project.public_builds? + # Allow to read issues by anonymous user if issue is not confidential + rules << :read_issue unless subject.is_a?(Issue) && subject.confidential? + rules - project_disabled_features_rules(project) else [] @@ -321,6 +323,7 @@ class Ability end rules += project_abilities(user, subject.project) + rules = filter_confidential_issues_abilities(user, subject, rules) if subject.is_a?(Issue) rules end end @@ -439,5 +442,17 @@ class Ability :"admin_#{name}" ] end + + def filter_confidential_issues_abilities(user, issue, rules) + return rules if user.admin? || !issue.confidential? + + unless issue.author == user || issue.assignee == user || issue.project.team.member?(user.id) + rules.delete(:admin_issue) + rules.delete(:read_issue) + rules.delete(:update_issue) + end + + rules + end end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 2447f860c5a..053387cffd7 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -58,6 +58,13 @@ class Issue < ActiveRecord::Base attributes end + def self.visible_to_user(user) + return where(confidential: false) if user.blank? + return all if user.admin? + + where('issues.confidential = false OR (issues.confidential = true AND (issues.author_id = :user_id OR issues.assignee_id = :user_id OR issues.project_id IN(:project_ids)))', user_id: user.id, project_ids: user.authorized_projects.select(:id)) + end + def self.reference_prefix '#' end -- cgit v1.2.1 From 7ee528336ad86e478b6db6d0039aec607c8f0192 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 17:39:56 -0300 Subject: Restrict access for confidential issues on autocomplete --- app/controllers/projects_controller.rb | 2 +- app/services/projects/autocomplete_service.rb | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 36f37221c58..c9930480770 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -134,7 +134,7 @@ class ProjectsController < ApplicationController def autocomplete_sources note_type = params['type'] note_id = params['type_id'] - autocomplete = ::Projects::AutocompleteService.new(@project) + autocomplete = ::Projects::AutocompleteService.new(@project, current_user) participants = ::Projects::ParticipantsService.new(@project, current_user).execute(note_type, note_id) @suggestions = { diff --git a/app/services/projects/autocomplete_service.rb b/app/services/projects/autocomplete_service.rb index 7408e09ed1e..ba50305dbd5 100644 --- a/app/services/projects/autocomplete_service.rb +++ b/app/services/projects/autocomplete_service.rb @@ -1,11 +1,7 @@ module Projects class AutocompleteService < BaseService - def initialize(project) - @project = project - end - def issues - @project.issues.opened.select([:iid, :title]) + @project.issues.visible_to_user(current_user).opened.select([:iid, :title]) end def merge_requests -- cgit v1.2.1 From f2ba4e3d364671cb100446b584502c5522a751df Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 17:48:19 -0300 Subject: Restrict access to confidential issues on search results --- app/services/search/global_service.rb | 2 +- app/services/search/project_service.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/services/search/global_service.rb b/app/services/search/global_service.rb index e1e94c5cc38..aa9837038a6 100644 --- a/app/services/search/global_service.rb +++ b/app/services/search/global_service.rb @@ -11,7 +11,7 @@ module Search projects = ProjectsFinder.new.execute(current_user) projects = projects.in_namespace(group.id) if group - Gitlab::SearchResults.new(projects, params[:search]) + Gitlab::SearchResults.new(current_user, projects, params[:search]) end end end diff --git a/app/services/search/project_service.rb b/app/services/search/project_service.rb index c08881dce4b..4b500914cfb 100644 --- a/app/services/search/project_service.rb +++ b/app/services/search/project_service.rb @@ -7,7 +7,8 @@ module Search end def execute - Gitlab::ProjectSearchResults.new(project, + Gitlab::ProjectSearchResults.new(current_user, + project, params[:search], params[:repository_ref]) end -- cgit v1.2.1 From 1029f4101b1de98ec7ffa706530bf405ffa71060 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 17:53:21 -0300 Subject: Fix issues count on project view --- app/helpers/application_helper.rb | 2 +- app/views/layouts/nav/_project.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 883c2871746..e6ceb213532 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -301,7 +301,7 @@ module ApplicationHelper if project.nil? nil elsif current_controller?(:issues) - project.issues.send(entity).count + project.issues.visible_to_user(current_user).send(entity).count elsif current_controller?(:merge_requests) project.merge_requests.send(entity).count end diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 0ae83ee01eb..86b46e8c75e 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -67,7 +67,7 @@ %span Issues - if @project.default_issues_tracker? - %span.count.issue_counter= number_with_delimiter(@project.issues.opened.count) + %span.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count) - if project_nav_tab? :merge_requests = nav_link(controller: :merge_requests) do -- cgit v1.2.1 From 482bfd1a6d454652feb1f64c0c0e1c50ce701986 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 17:59:30 -0300 Subject: Restrict access for confidential issues on milestone view --- app/helpers/milestones_helper.rb | 2 +- app/models/concerns/milestoneish.rb | 20 ++++++++++++-------- app/models/milestone.rb | 4 ++-- app/views/projects/milestones/show.html.haml | 2 +- app/views/shared/milestones/_milestone.html.haml | 4 ++-- app/views/shared/milestones/_summary.html.haml | 8 ++++---- app/views/shared/milestones/_tabs.html.haml | 4 ++-- app/views/shared/milestones/_top.html.haml | 4 ++-- 8 files changed, 26 insertions(+), 22 deletions(-) (limited to 'app') diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index e8ac8788d9d..92ed0891e92 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -38,7 +38,7 @@ module MilestonesHelper def milestone_progress_bar(milestone) options = { class: 'progress-bar progress-bar-success', - style: "width: #{milestone.percent_complete}%;" + style: "width: #{milestone.percent_complete(current_user)}%;" } content_tag :div, class: 'progress' do diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index d67df7c1d9c..5b8e3f654ea 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -1,18 +1,18 @@ module Milestoneish - def closed_items_count - issues.closed.size + merge_requests.closed_and_merged.size + def closed_items_count(user = nil) + issues_visible_to_user(user).closed.size + merge_requests.closed_and_merged.size end - def total_items_count - issues.size + merge_requests.size + def total_items_count(user = nil) + issues_visible_to_user(user).size + merge_requests.size end - def complete? - total_items_count == closed_items_count + def complete?(user = nil) + total_items_count(user) == closed_items_count(user) end - def percent_complete - ((closed_items_count * 100) / total_items_count).abs + def percent_complete(user = nil) + ((closed_items_count(user) * 100) / total_items_count(user)).abs rescue ZeroDivisionError 0 end @@ -22,4 +22,8 @@ module Milestoneish (due_date - Date.today).to_i end + + def issues_visible_to_user(user = nil) + issues.visible_to_user(user) + end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 374590ba0c5..de7183bf6b4 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -121,8 +121,8 @@ class Milestone < ActiveRecord::Base active? && issues.opened.count.zero? end - def is_empty? - total_items_count.zero? + def is_empty?(user = nil) + total_items_count(user).zero? end def author_id diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index b4597043a27..be63875ab34 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -42,7 +42,7 @@ = preserve do = markdown @milestone.description -- if @milestone.complete? && @milestone.active? +- if @milestone.complete?(current_user) && @milestone.active? .alert.alert-success.prepend-top-default %span All issues for this milestone are closed. You may close milestone now. diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index f01138af3f0..6b25745c554 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -6,10 +6,10 @@ .col-sm-6 %strong= link_to_gfm truncate(milestone.title, length: 100), milestone_path .col-sm-6 - .pull-right.light #{milestone.percent_complete}% complete + .pull-right.light #{milestone.percent_complete(current_user)}% complete .row .col-sm-6 - = link_to pluralize(milestone.issues.size, 'Issue'), issues_path + = link_to pluralize(milestone.issues_visible_to_user(current_user).size, 'Issue'), issues_path · = link_to pluralize(milestone.merge_requests.size, 'Merge Request'), merge_requests_path .col-sm-6= milestone_progress_bar(milestone) diff --git a/app/views/shared/milestones/_summary.html.haml b/app/views/shared/milestones/_summary.html.haml index 59d4ae29f79..385c6596606 100644 --- a/app/views/shared/milestones/_summary.html.haml +++ b/app/views/shared/milestones/_summary.html.haml @@ -3,15 +3,15 @@ .context.prepend-top-default .milestone-summary %h4 Progress - %strong= milestone.issues.size + %strong= milestone.issues_visible_to_user(current_user).size issues: %span.milestone-stat - %strong= milestone.issues.opened.size + %strong= milestone.issues_visible_to_user(current_user).opened.size open and - %strong= milestone.issues.closed.size + %strong= milestone.issues_visible_to_user(current_user).closed.size closed %span.milestone-stat - %strong== #{milestone.percent_complete}% + %strong== #{milestone.percent_complete(current_user)}% complete %span.milestone-stat diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 57d7ee85a3b..2b6ce2d7e7a 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -2,7 +2,7 @@ %li.active = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do Issues - %span.badge= milestone.issues.size + %span.badge= milestone.issues_visible_to_user(current_user).size %li = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do Merge Requests @@ -21,7 +21,7 @@ .tab-content.milestone-content .tab-pane.active#tab-issues - = render 'shared/milestones/issues_tab', issues: milestone.issues, show_project_name: show_project_name, show_full_project_name: show_full_project_name + = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name .tab-pane#tab-merge-requests = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name .tab-pane#tab-participants diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml index 4cf1d948b5b..cab8743a077 100644 --- a/app/views/shared/milestones/_top.html.haml +++ b/app/views/shared/milestones/_top.html.haml @@ -28,7 +28,7 @@ %h2.title = markdown escape_once(milestone.title), pipeline: :single_line -- if milestone.complete? && milestone.active? +- if milestone.complete?(current_user) && milestone.active? .alert.alert-success.prepend-top-default - close_msg = group ? 'You may close the milestone now.' : 'Navigate to the project to close the milestone.' %span All issues for this milestone are closed. #{close_msg} @@ -47,7 +47,7 @@ - project_name = group ? ms.project.name : ms.project.name_with_namespace = link_to project_name, namespace_project_milestone_path(ms.project.namespace, ms.project, ms) %td - = ms.issues.opened.count + = ms.issues_visible_to_user(current_user).opened.count %td - if ms.closed? Closed -- cgit v1.2.1 From 7d403ec46ffd5778a68eebb9117e08f605938b15 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 18:00:03 -0300 Subject: Add eye-slash icon to confidential issues --- app/helpers/issues_helper.rb | 4 ++++ app/views/projects/issues/_issue.html.haml | 1 + app/views/projects/issues/show.html.haml | 1 + app/views/search/results/_issue.html.haml | 1 + app/views/shared/milestones/_issuable.html.haml | 2 ++ 5 files changed, 9 insertions(+) (limited to 'app') diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index ae4ebc0854a..e00d3204027 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -98,6 +98,10 @@ module IssuesHelper end.sort.to_sentence(last_word_connector: ', or ') end + def confidential_icon(issue) + icon('eye-slash') if issue.confidential? + end + def emoji_icon(name, unicode = nil, aliases = []) unicode ||= Emoji.emoji_filename(name) rescue "" diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index a44f34c2a68..00e1a3d8069 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -5,6 +5,7 @@ .issue-title %span.issue-title-text + = confidential_icon(issue) = link_to_gfm issue.title, issue_path(issue), class: "title" %ul.controls.light - if issue.closed? diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index c3ee5c80e5f..ce5b84ee712 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -22,6 +22,7 @@ = icon('angle-double-left') .issue-meta + = confidential_icon(@issue) %strong.identifier Issue ##{@issue.iid} %span.creator diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml index 45d700781f3..710f5613c81 100644 --- a/app/views/search/results/_issue.html.haml +++ b/app/views/search/results/_issue.html.haml @@ -1,5 +1,6 @@ .search-result-row %h4 + = confidential_icon(issue) = link_to [issue.project.namespace.becomes(Namespace), issue.project, issue] do %span.term.str-truncated= issue.title .pull-right ##{issue.iid} diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index f7c6fc14adf..85888096722 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -10,6 +10,8 @@ %strong #{project.name} · - elsif show_full_project_name %strong #{project.name_with_namespace} · + - if issuable.is_a?(Issue) + = confidential_icon(issuable) = link_to_gfm issuable.title, [project.namespace.becomes(Namespace), project, issuable], title: issuable.title %div{class: 'issuable-detail'} = link_to [project.namespace.becomes(Namespace), project, issuable] do -- cgit v1.2.1 From 9222459ea36ce7bfafdf76742a5a44db7957db8d Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 17 Mar 2016 18:03:10 -0300 Subject: Restrict access to confidential issues on activity feed --- app/helpers/events_helper.rb | 2 +- app/models/event.rb | 6 ++++-- app/views/events/_event.html.haml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 37a888d9c60..a67a6b208e2 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -194,7 +194,7 @@ module EventsHelper end def event_to_atom(xml, event) - if event.proper? + if event.proper?(current_user) xml.entry do event_link = event_feed_url(event) event_title = event_feed_title(event) diff --git a/app/models/event.rb b/app/models/event.rb index 9a0bbf50f8b..a5cfeaf388e 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -73,15 +73,17 @@ class Event < ActiveRecord::Base end end - def proper? + def proper?(user = nil) if push? true elsif membership_changed? true elsif created_project? true + elsif issue? + Ability.abilities.allowed?(user, :read_issue, issue) else - ((issue? || merge_request? || note?) && target) || milestone? + ((merge_request? || note?) && target) || milestone? end end diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index 36fb2d51629..2d9d9dd6342 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -1,4 +1,4 @@ -- if event.proper? +- if event.proper?(current_user) .event-item{class: "#{event.body? ? "event-block" : "event-inline" }"} .event-item-timestamp #{time_ago_with_tooltip(event.created_at)} -- cgit v1.2.1 From 3e98e5971b76d3847a1abd361bc120bf8bcfa214 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 4 Mar 2016 17:37:07 +0000 Subject: Improved issue sidebar Updated the spacing throughout the sidebar so that it fits better on smaller screens Added more participants button Closes #13353 --- app/assets/javascripts/issue.js.coffee | 24 ++++ app/assets/stylesheets/pages/issuable.scss | 146 +++++++++++++--------- app/helpers/projects_helper.rb | 4 +- app/views/shared/issuable/_participants.html.haml | 13 +- app/views/shared/issuable/_sidebar.html.haml | 46 +++---- 5 files changed, 145 insertions(+), 88 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index d663e34871c..47db7c63ec6 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -7,6 +7,7 @@ class @Issue # Prevent duplicate event bindings @disableTaskList() @fixAffixScroll() + @initParticipants() if $('a.btn-close').length @initTaskList() @initIssueBtnEventListeners() @@ -84,3 +85,26 @@ class @Issue type: 'PATCH' url: $('form.js-issuable-update').attr('action') data: patchData + + initParticipants: -> + $(document).on "click", ".js-participants-more", @toggleHiddenParticipants + + # hide any participants from number 6 + $(".js-participants-author").each (i) -> + if i > 6 + $(@) + .addClass "js-participants-hidden hidden" + + toggleHiddenParticipants: (e) -> + e.preventDefault() + + currentText = $(this).text().trim() + lessText = $(this).data("less-text") + originalText = $(this).data("original-text") + + if currentText is originalText + $(this).text(lessText) + else + $(this).text(originalText) + + $(".js-participants-hidden").toggleClass "hidden" diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 6f93299404c..3c0fe8e6e43 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -1,34 +1,3 @@ -@media (max-width: $screen-sm-max) { - .issuable-affix { - margin-top: 20px; - } -} - -@media (max-width: $screen-md-max) { - .issuable-affix { - position: static; - } -} - -@media (min-width: $screen-md-max) { - .issuable-affix { - &.affix-top { - position: static; - } - - &.affix { - position: fixed; - top: 70px; - margin-right: 35px; - - &.no-affix { - position: relative; - top: 0; - } - } - } -} - .issuable-details { section { .issuable-discussion { @@ -54,6 +23,10 @@ padding: 6px 10px; } } + + &.has-labels { + margin-bottom: -5px; + } } .issuable-sidebar { @@ -66,8 +39,9 @@ width: $gutter_inner_width; // -- - &:first-child { - padding-top: 5px; + &.issuable-sidebar-header { + padding-top: 0; + padding-bottom: 10px; } &:last-child { @@ -75,7 +49,6 @@ } span { - margin-top: 7px; display: inline-block; } @@ -84,7 +57,7 @@ } .issuable-count { - + margin-top: 7px; } .gutter-toggle { @@ -99,19 +72,19 @@ .title { color: $gl-text-color; - margin-bottom: 8px; + margin-bottom: 10px; + line-height: 1; .avatar { margin-left: 0; } - label { - font-weight: normal; - margin-right: 4px; - } - .edit-link { color: $gl-gray; + + &:hover { + color: $md-link-color; + } } } @@ -144,11 +117,6 @@ .btn-clipboard { color: $gl-gray; } - - .participants .avatar { - margin-top: 6px; - margin-right: 2px; - } } .right-sidebar { @@ -163,8 +131,12 @@ &.right-sidebar-expanded { width: $gutter_width; - hr { - display: none; + .value { + line-height: 1; + } + + .bold { + font-weight: 600; } .sidebar-collapsed-icon { @@ -172,8 +144,23 @@ } .gutter-toggle { + margin-top: 7px; border-left: 1px solid $border-gray-light; } + + .avatar { + float: left; + margin-right: 10px; + margin-bottom: 0; + margin-left: 0; + } + + .username { + display: block; + margin-top: 4px; + font-size: 13px; + font-weight: normal; + } } .subscribe-button { @@ -193,14 +180,6 @@ width: $sidebar_collapsed_width; padding-top: 0; - hr { - margin: 0; - color: $gray-normal; - border-color: $gray-normal; - width: 62px; - margin-left: -20px - } - .block { width: $sidebar_collapsed_width - 1px; margin-left: -19px; @@ -209,12 +188,18 @@ overflow: hidden; } + .participants { + border-bottom: 1px solid $border-gray-light; + } + .hide-collapsed { display: none; } .gutter-toggle { - margin-left: -36px; + width: 100%; + margin-left: 0; + padding-left: 25px; } .sidebar-collapsed-icon { @@ -241,6 +226,11 @@ } } } + + .sidebar-collapsed-user { + padding-bottom: 0; + margin-bottom: 10px; + } } .btn { @@ -251,6 +241,13 @@ border: 1px solid $border-gray-dark; } } + + a { + &:hover { + color: $md-link-color; + text-decoration: none; + } + } } .btn-default.gutter-toggle { @@ -270,3 +267,38 @@ color: $gray-darkest; } } + +.participants-list { + margin: -5px -5px; +} + +.participants-author { + display: inline-block; + padding: 5px 5px; + + .author_link { + display: block; + } + + .avatar.avatar-inline { + margin: 0; + } +} + +.participants-more { + margin-top: 5px; + margin-left: 5px; + + a { + color: #8c8c8c; + + &:hover { + color: $gl-text-color; + text-decoration: none; + } + + &:focus { + text-decoration: none; + } + } +} diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index b5acb80b720..5473419ef24 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -26,7 +26,7 @@ module ProjectsHelper image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar] end - def link_to_member(project, author, opts = {}) + def link_to_member(project, author, opts = {}, &block) default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" } opts = default_opts.merge(opts) @@ -44,6 +44,8 @@ module ProjectsHelper author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name] end + author_html << capture(&block) if block + author_html = author_html.html_safe if opts[:name] diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index f1d92ef48b2..8fe1c9af118 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,3 +1,5 @@ +- participants_size = participants.size +- participants_extra = participants_size - 7 .block.participants .sidebar-collapsed-icon = icon('users') @@ -5,6 +7,11 @@ = participants.count .title.hide-collapsed = pluralize participants.count, "participant" - - participants.each do |participant| - %span.hide-collapsed - = link_to_member(@project, participant, name: false, size: 24) + .hide-collapsed.participants-list + - participants.each do |participant| + .participants-author.js-participants-author + = link_to_member(@project, participant, name: false, size: 24) + - if participants_extra > 0 + %div.participants-more + %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}} + + #{participants_size - 7} more diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 23b1ed1e51b..6f07571f24f 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -1,13 +1,12 @@ %aside.right-sidebar{ class: sidebar_gutter_collapsed_class } .issuable-sidebar - .block + .block.issuable-sidebar-header %span.issuable-count.hide-collapsed.pull-left = issuable.iid of = issuables_count(issuable) - %span.pull-right - %a.gutter-toggle.js-sidebar-toggle{href: '#'} - = sidebar_gutter_toggle_icon + %a.gutter-toggle.pull-right.js-sidebar-toggle{href: '#'} + = sidebar_gutter_toggle_icon .issuable-nav.hide-collapsed.pull-right.btn-group{role: 'group', "aria-label" => '...'} - if prev_issuable = prev_issuable_for(issuable) = link_to 'Prev', [@project.namespace.becomes(Namespace), @project, prev_issuable], class: 'btn btn-default prev-btn' @@ -22,20 +21,20 @@ = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| .block.assignee - .sidebar-collapsed-icon + .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: issuable.assignee.to_reference} - if issuable.assignee = link_to_member_avatar(issuable.assignee, size: 24) - else = icon('user') .title.hide-collapsed - %label - Assignee + Assignee - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.bold.hide-collapsed - if issuable.assignee - %strong= link_to_member(@project, issuable.assignee, size: 24) + = link_to_member(@project, issuable.assignee, size: 32) do + %span.username + = issuable.assignee.to_reference - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee) %a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'} = icon('exclamation-triangle') @@ -54,18 +53,13 @@ - else No .title.hide-collapsed - %label - Milestone + Milestone - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.bold.hide-collapsed - if issuable.milestone - %span.back-to-milestone - = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do - %strong - = icon('clock-o') - = issuable.milestone.title + = link_to namespace_project_milestone_path(@project.namespace, @project, issuable.milestone) do + = issuable.milestone.title - else .light None .selectbox.hide-collapsed @@ -80,11 +74,10 @@ %span = issuable.labels.count .title.hide-collapsed - %label Labels + Labels - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project) - .pull-right - = link_to 'Edit', '#', class: 'edit-link' - .value.issuable-show-labels.hide-collapsed + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.issuable-show-labels.hide-collapsed{class: ("has-labels" if issuable.labels.any?)} - if issuable.labels.any? - issuable.labels.each do |label| = link_to_label(label, type: issuable.to_ability_name) @@ -95,14 +88,13 @@ { selected: issuable.label_ids }, multiple: true, class: 'select2 js-select2', data: { placeholder: "Select labels" } = render "shared/issuable/participants", participants: issuable.participants(current_user) - %hr - if current_user - subscribed = issuable.subscribed?(current_user) .block.light.subscription{data: {url: toggle_subscription_path(issuable)}} .sidebar-collapsed-icon = icon('rss') .title.hide-collapsed - %label.light Notifications + Notifications - subscribtion_status = subscribed ? 'subscribed' : 'unsubscribed' %button.btn.btn-block.btn-gray.subscribe-button.hide-collapsed{:type => 'button'} %span= subscribed ? 'Unsubscribe' : 'Subscribe' -- cgit v1.2.1 From 704cf9df2b610893412524efcdbc81b204de6d46 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 4 Mar 2016 17:39:48 +0000 Subject: Fixed tooltip issue for participants --- app/assets/stylesheets/pages/issuable.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 3c0fe8e6e43..dd4d867c48a 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -148,7 +148,7 @@ border-left: 1px solid $border-gray-light; } - .avatar { + .assignee .avatar { float: left; margin-right: 10px; margin-bottom: 0; -- cgit v1.2.1 From e0f47c3489d082df7f62d622ac273ae1354b50a9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Sun, 6 Mar 2016 12:06:52 +0000 Subject: Fixed issue when user doesnt exist Fixed button hover color --- app/assets/stylesheets/pages/issuable.scss | 11 +---------- app/views/shared/issuable/_sidebar.html.haml | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index dd4d867c48a..7e6ab5d5c64 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -242,7 +242,7 @@ } } - a { + a:not(.btn) { &:hover { color: $md-link-color; text-decoration: none; @@ -291,14 +291,5 @@ a { color: #8c8c8c; - - &:hover { - color: $gl-text-color; - text-decoration: none; - } - - &:focus { - text-decoration: none; - } } } diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 6f07571f24f..eacb2837abd 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -21,7 +21,7 @@ = form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f| .block.assignee - .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: issuable.assignee.to_reference} + .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)} - if issuable.assignee = link_to_member_avatar(issuable.assignee, size: 24) - else -- cgit v1.2.1 From 021d79e3ac1cfcac875866f1d70176552d1bf159 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 7 Mar 2016 08:40:19 +0000 Subject: Links to user on collapsed issue sidebar --- app/assets/stylesheets/pages/issuable.scss | 4 ++++ app/views/shared/issuable/_sidebar.html.haml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 7e6ab5d5c64..2760af8a48a 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -214,6 +214,10 @@ margin-top: 0; } + .author { + display: none; + } + .btn-clipboard { border: none; diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index eacb2837abd..2b95b19facc 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -23,7 +23,7 @@ .block.assignee .sidebar-collapsed-icon.sidebar-collapsed-user{data: {toggle: "tooltip", placement: "left", container: "body"}, title: (issuable.assignee.to_reference if issuable.assignee)} - if issuable.assignee - = link_to_member_avatar(issuable.assignee, size: 24) + = link_to_member(@project, issuable.assignee, size: 24) - else = icon('user') .title.hide-collapsed -- cgit v1.2.1 From 38ea9c6cf7c7c063f841ebe95477e9f48d7bc430 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 10 Mar 2016 17:09:57 +0000 Subject: Reused some variables Set global JS variable to sync view up --- app/assets/javascripts/issue.js.coffee | 4 ++-- app/views/shared/issuable/_participants.html.haml | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index 47db7c63ec6..424c354b755 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -91,7 +91,7 @@ class @Issue # hide any participants from number 6 $(".js-participants-author").each (i) -> - if i > 6 + if i >= PARTICIPANTS_ROW $(@) .addClass "js-participants-hidden hidden" @@ -101,7 +101,7 @@ class @Issue currentText = $(this).text().trim() lessText = $(this).data("less-text") originalText = $(this).data("original-text") - + if currentText is originalText $(this).text(lessText) else diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index 8fe1c9af118..75a330c9e5f 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,5 +1,8 @@ +- participants_row = 7 - participants_size = participants.size -- participants_extra = participants_size - 7 +- participants_extra = participants_size - participants_row +:javascript + var PARTICIPANTS_ROW = #{participants_row}; .block.participants .sidebar-collapsed-icon = icon('users') @@ -14,4 +17,4 @@ - if participants_extra > 0 %div.participants-more %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}} - + #{participants_size - 7} more + + #{participants_extra} more -- cgit v1.2.1 From b2e673e523ec0e6ff3d2c27d113e9d6a74a80d7a Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 15 Mar 2016 11:10:42 +0000 Subject: Removed global JS var --- app/assets/javascripts/issue.js.coffee | 9 +++++---- app/views/shared/issuable/_participants.html.haml | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee index 424c354b755..f50df1f5ea3 100644 --- a/app/assets/javascripts/issue.js.coffee +++ b/app/assets/javascripts/issue.js.coffee @@ -87,13 +87,14 @@ class @Issue data: patchData initParticipants: -> + _this = @ $(document).on "click", ".js-participants-more", @toggleHiddenParticipants - # hide any participants from number 6 $(".js-participants-author").each (i) -> - if i >= PARTICIPANTS_ROW + if i >= _this.PARTICIPANTS_ROW_COUNT $(@) - .addClass "js-participants-hidden hidden" + .addClass "js-participants-hidden" + .hide() toggleHiddenParticipants: (e) -> e.preventDefault() @@ -107,4 +108,4 @@ class @Issue else $(this).text(originalText) - $(".js-participants-hidden").toggleClass "hidden" + $(".js-participants-hidden").toggle() diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index 75a330c9e5f..3fb409ff727 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -1,8 +1,6 @@ - participants_row = 7 - participants_size = participants.size - participants_extra = participants_size - participants_row -:javascript - var PARTICIPANTS_ROW = #{participants_row}; .block.participants .sidebar-collapsed-icon = icon('users') @@ -18,3 +16,5 @@ %div.participants-more %a.js-participants-more{href: "#", data: {original_text: "+ #{participants_size - 7} more", less_text: "- show less"}} + #{participants_extra} more +:javascript + Issue.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row}; -- cgit v1.2.1 From 8357a23ac81d16c566542b363d1dcb893aafc51c Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 15 Mar 2016 17:24:01 +0000 Subject: Fixes issue with any milestone value in dropdown not being selectable Closes #14293 --- app/assets/javascripts/milestone_select.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index 5e884454a65..dd2a35bef4d 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -46,7 +46,7 @@ class @MilestoneSelect milestone.title id: (milestone) -> if !useId - if milestone.title isnt "Any milestone" + if milestone.title isnt "Any Milestone" milestone.title else "" -- cgit v1.2.1 From 72830aa8095bffeb844c71d5b202a1b1b9213eb8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 08:53:57 +0000 Subject: Removed comparing against text --- app/assets/javascripts/milestone_select.js.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index dd2a35bef4d..86b806f53a3 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -30,6 +30,7 @@ class @MilestoneSelect if showAny data.unshift( + any: true title: 'Any Milestone' ) @@ -46,7 +47,7 @@ class @MilestoneSelect milestone.title id: (milestone) -> if !useId - if milestone.title isnt "Any Milestone" + if !milestone.any? milestone.title else "" -- cgit v1.2.1 From fa6fae18a95656c0f300fff86214ad62626131b2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Mar 2016 09:49:44 +0000 Subject: Changed any variable name to save confusion --- app/assets/javascripts/milestone_select.js.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index 86b806f53a3..32159a7c179 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -30,7 +30,7 @@ class @MilestoneSelect if showAny data.unshift( - any: true + isAny: true title: 'Any Milestone' ) @@ -47,7 +47,7 @@ class @MilestoneSelect milestone.title id: (milestone) -> if !useId - if !milestone.any? + if !milestone.isAny? milestone.title else "" -- cgit v1.2.1 From 3f0d780c19d821e74a4a89634ada10dedec0dbeb Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Fri, 11 Mar 2016 17:40:59 +0100 Subject: Show a notice for diffs that are too large This builds on the changes introduced in https://gitlab.com/gitlab-org/gitlab_git/merge_requests/72 and results in merge requests with large diffs (e.g. due to them containing minified CSS) loading much faster. --- app/views/projects/diffs/_file.html.haml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'app') diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml index 3ac058a3bf8..dc34032b1b8 100644 --- a/app/views/projects/diffs/_file.html.haml +++ b/app/views/projects/diffs/_file.html.haml @@ -42,13 +42,17 @@ .diff-content.diff-wrap-lines -# Skipp all non non-supported blobs - return unless blob.respond_to?('text?') - - if blob_text_viewable?(blob) - - if diff_view == 'parallel' - = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i - - else - = render "projects/diffs/text_file", diff_file: diff_file, index: i - - elsif blob.image? - - old_file = project.repository.prev_blob_for_diff(diff_commit, diff_file) - = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i + - if diff_file.too_large? + .nothing-here-block + This diff could not be displayed because it is too large. - else - .nothing-here-block No preview for this file type + - if blob_text_viewable?(blob) + - if diff_view == 'parallel' + = render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob, index: i + - else + = render "projects/diffs/text_file", diff_file: diff_file, index: i + - elsif blob.image? + - old_file = project.repository.prev_blob_for_diff(diff_commit, diff_file) + = render "projects/diffs/image", diff_file: diff_file, old_file: old_file, file: blob, index: i + - else + .nothing-here-block No preview for this file type -- cgit v1.2.1 From 4885423feadb563a8474b8c01415527a28c8ef9b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Mar 2016 11:36:48 +0000 Subject: Fixes issue with close button not working on MR Closes #14383 --- app/assets/javascripts/notes.js.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee index b164231e7ef..82532216589 100644 --- a/app/assets/javascripts/notes.js.coffee +++ b/app/assets/javascripts/notes.js.coffee @@ -627,10 +627,10 @@ class @Notes if closebtn.text() isnt closetext closebtn.text(closetext) - if reopenbtn.is(':not(.btn-comment-and-reopen)') + if reopenbtn.is('.btn-comment-and-reopen') reopenbtn.removeClass('btn-comment-and-reopen') - if closebtn.is(':not(.btn-comment-and-close)') + if closebtn.is('.btn-comment-and-close') closebtn.removeClass('btn-comment-and-close') if discardbtn.is(':visible') -- cgit v1.2.1 From 882ebfc29661f4e78aabbb63230ef9ae08770a36 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 15 Mar 2016 18:20:22 +0000 Subject: Changing filter dropdowns shows loading Instead of doing a full refresh of the page - i've modified the filterResults method on the Issues object to work for this form as well --- app/assets/javascripts/gl_dropdown.js.coffee | 6 +++++- app/assets/javascripts/issues.js.coffee | 16 +++++++++------- app/assets/javascripts/labels_select.js.coffee | 19 ++++++++++++++----- app/assets/javascripts/milestone_select.js.coffee | 8 +++++++- app/assets/javascripts/users_select.js.coffee | 8 +++++++- 5 files changed, 42 insertions(+), 15 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee index 4f038477755..c81e8bf760a 100644 --- a/app/assets/javascripts/gl_dropdown.js.coffee +++ b/app/assets/javascripts/gl_dropdown.js.coffee @@ -246,11 +246,15 @@ class GitLabDropdown if oldValue value = "#{oldValue},#{value}" else - @dropdown.find(ACTIVE_CLASS).removeClass ACTIVE_CLASS + @dropdown.find(".#{ACTIVE_CLASS}").removeClass ACTIVE_CLASS # Toggle active class for the tick mark el.toggleClass "is-active" + # Toggle the dropdown label + if @options.toggleLabel + $(@el).find(".dropdown-toggle-text").text @options.toggleLabel(selectedObject) + if value? if !field.length # Create hidden input for form diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index a0acf3028bf..b6bc86f8af2 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -41,18 +41,20 @@ @timer = null $("#issue_search").keyup -> clearTimeout(@timer) - @timer = setTimeout(Issues.filterResults, 500) + @timer = setTimeout( -> + Issues.filterResults $("#issue_search_form") + , 500) - filterResults: => - form = $("#issue_search_form") - search = $("#issue_search").val() + filterResults: (form) => $('.issues-holder').css("opacity", '0.5') - issues_url = form.attr('action') + '?' + form.serialize() + form_action = form.attr('action') + form_data = form.serialize() + issues_url = form_action + ("#{if form_action.indexOf("?") < 0 then '?' else '&'}") + form_data $.ajax type: "GET" - url: form.attr('action') - data: form.serialize() + url: form_action + data: form_data complete: -> $('.issues-holder').css("opacity", '1.0') success: (data) -> diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index 5ade2cb66cb..ed978f1bdb2 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -10,6 +10,7 @@ class @LabelsSelect newColorField = $('#new_label_color') showNo = $(dropdown).data('show-no') showAny = $(dropdown).data('show-any') + defaultLabel = $(dropdown).text().trim() if newLabelField.length $('.suggest-colors-dropdown a').on "click", (e) -> @@ -51,13 +52,13 @@ class @LabelsSelect if showNo data.unshift( - id: "0" - title: 'No label' + id: 0 + title: 'No Label' ) if showAny data.unshift( - title: 'Any label' + title: 'Any Label' ) if data.length > 2 @@ -83,10 +84,18 @@ class @LabelsSelect search: fields: ['title'] selectable: true + toggleLabel: (selected) -> + if selected && selected.title isnt "Any Label" + selected.title + else + defaultLabel fieldName: $(dropdown).data('field-name') id: (label) -> - label.title + if label.title is "Any Label" + "" + else + label.title clicked: -> if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents('form').submit() + Issues.filterResults $(dropdown).parents("form") ) diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index 32159a7c179..f38c375c61a 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -7,6 +7,7 @@ class @MilestoneSelect showNo = $(dropdown).data('show-no') showAny = $(dropdown).data('show-any') useId = $(dropdown).data('use-id') + defaultLabel = $(dropdown).text().trim() $(dropdown).glDropdown( data: (term, callback) -> @@ -42,6 +43,11 @@ class @MilestoneSelect search: fields: ['title'] selectable: true + toggleLabel: (selected) -> + if selected && selected.id + selected.title + else + defaultLabel fieldName: $(dropdown).data('field-name') text: (milestone) -> milestone.title @@ -57,5 +63,5 @@ class @MilestoneSelect milestone.title is selectedMilestone clicked: -> if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents('form').submit() + Issues.filterResults $(dropdown).parents("form") ) diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 987c6f4b8d2..46faae111c4 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -10,6 +10,7 @@ class @UsersSelect showAnyUser = $(dropdown).data('any-user') firstUser = $(dropdown).data('first-user') selectedId = $(dropdown).data('selected') + defaultLabel = $(dropdown).text().trim() $(dropdown).glDropdown( data: (term, callback) => @@ -53,9 +54,14 @@ class @UsersSelect fields: ['name', 'username'] selectable: true fieldName: $(dropdown).data('field-name') + toggleLabel: (selected) -> + if selected && selected.id? + selected.name + else + defaultLabel clicked: -> if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents('form').submit() + Issues.filterResults $(dropdown).parents("form") renderRow: (user) -> username = if user.username then "@#{user.username}" else "" avatar = if user.avatar_url then user.avatar_url else false -- cgit v1.2.1 From 16d02de56ec0e52f8aaec7f9954de8497cfe9922 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 09:04:15 +0000 Subject: Fixed issue with dashboard issues not reloading --- app/assets/javascripts/labels_select.js.coffee | 9 +++++++-- app/assets/javascripts/milestone_select.js.coffee | 6 +++++- app/assets/javascripts/users_select.js.coffee | 6 +++++- 3 files changed, 17 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index ed978f1bdb2..269f2008e2d 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -58,6 +58,7 @@ class @LabelsSelect if showAny data.unshift( + any: true title: 'Any Label' ) @@ -91,11 +92,15 @@ class @LabelsSelect defaultLabel fieldName: $(dropdown).data('field-name') id: (label) -> - if label.title is "Any Label" + if label.any? "" else label.title clicked: -> - if $(dropdown).hasClass "js-filter-submit" + page = $("body").data "page" + + if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" Issues.filterResults $(dropdown).parents("form") + else if $(dropdown).hasClass "js-filter-submit" + $(dropdown).parents("form").submit() ) diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index f38c375c61a..a4bf8654de4 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -62,6 +62,10 @@ class @MilestoneSelect isSelected: (milestone) -> milestone.title is selectedMilestone clicked: -> - if $(dropdown).hasClass "js-filter-submit" + page = $("body").data "page" + + if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" Issues.filterResults $(dropdown).parents("form") + else if $(dropdown).hasClass "js-filter-submit" + $(dropdown).parents("form").submit() ) diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 46faae111c4..44ed31d04b2 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -60,8 +60,12 @@ class @UsersSelect else defaultLabel clicked: -> - if $(dropdown).hasClass "js-filter-submit" + page = $("body").data "page" + + if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" Issues.filterResults $(dropdown).parents("form") + else if $(dropdown).hasClass "js-filter-submit" + $(dropdown).parents("form").submit() renderRow: (user) -> username = if user.username then "@#{user.username}" else "" avatar = if user.avatar_url then user.avatar_url else false -- cgit v1.2.1 From e8d52499db51021096d4b91596e4a207f4f5e62d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Mar 2016 10:12:52 +0000 Subject: Fixed some CS styling issues Fixed bug where wouldn't work on MR index --- app/assets/javascripts/issues.js.coffee | 20 +++---- app/assets/javascripts/labels_select.js.coffee | 63 ++++++++++++----------- app/assets/javascripts/milestone_select.js.coffee | 41 ++++++++------- app/assets/javascripts/users_select.js.coffee | 35 +++++++------ 4 files changed, 85 insertions(+), 74 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee index b6bc86f8af2..1127b289264 100644 --- a/app/assets/javascripts/issues.js.coffee +++ b/app/assets/javascripts/issues.js.coffee @@ -46,21 +46,23 @@ , 500) filterResults: (form) => - $('.issues-holder').css("opacity", '0.5') - form_action = form.attr('action') - form_data = form.serialize() - issues_url = form_action + ("#{if form_action.indexOf("?") < 0 then '?' else '&'}") + form_data + $('.issues-holder, .merge-requests-holder').css("opacity", '0.5') + formAction = form.attr('action') + formData = form.serialize() + issuesUrl = formAction + issuesUrl += ("#{if formAction.indexOf("?") < 0 then '?' else '&'}") + issuesUrl += formData $.ajax type: "GET" - url: form_action - data: form_data + url: formAction + data: formData complete: -> - $('.issues-holder').css("opacity", '1.0') + $('.issues-holder, .merge-requests-holder').css("opacity", '1.0') success: (data) -> - $('.issues-holder').html(data.html) + $('.issues-holder, .merge-requests-holder').html(data.html) # Change url so if user reload a page - search results are saved - history.replaceState {page: issues_url}, document.title, issues_url + history.replaceState {page: issuesUrl}, document.title, issuesUrl Issues.reload() dataType: "json" diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index 269f2008e2d..e6c1446f14f 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -1,31 +1,32 @@ class @LabelsSelect constructor: -> $('.js-label-select').each (i, dropdown) -> - projectId = $(dropdown).data('project-id') - labelUrl = $(dropdown).data("labels") - selectedLabel = $(dropdown).data('selected') + $dropdown = $(dropdown) + projectId = $dropdown.data('project-id') + labelUrl = $dropdown.data('labels') + selectedLabel = $dropdown.data('selected') if selectedLabel - selectedLabel = selectedLabel.split(",") + selectedLabel = selectedLabel.split(',') newLabelField = $('#new_label_name') newColorField = $('#new_label_color') - showNo = $(dropdown).data('show-no') - showAny = $(dropdown).data('show-any') - defaultLabel = $(dropdown).text().trim() + showNo = $dropdown.data('show-no') + showAny = $dropdown.data('show-any') + defaultLabel = $dropdown.text().trim() if newLabelField.length - $('.suggest-colors-dropdown a').on "click", (e) -> + $('.suggest-colors-dropdown a').on 'click', (e) -> e.preventDefault() e.stopPropagation() - newColorField.val $(this).data("color") + newColorField.val $(this).data('color') $('.js-dropdown-label-color-preview') - .css 'background-color', $(this).data("color") + .css 'background-color', $(this).data('color') .addClass 'is-active' - $('.js-new-label-btn').on "click", (e) -> + $('.js-new-label-btn').on 'click', (e) -> e.preventDefault() e.stopPropagation() - if newLabelField.val() isnt "" && newColorField.val() isnt "" + if newLabelField.val() isnt '' and newColorField.val() isnt '' $('.js-new-label-btn').disable() # Create new label with API @@ -34,9 +35,9 @@ class @LabelsSelect color: newColorField.val() }, (label) -> $('.js-new-label-btn').enable() - $('.dropdown-menu-back', $(dropdown).parent()).trigger "click" + $('.dropdown-menu-back', $dropdown.parent()).trigger 'click' - $(dropdown).glDropdown( + $dropdown.glDropdown( data: (term, callback) -> # We have to fetch the JS version of the labels list because there is no # public facing JSON url for labels @@ -58,23 +59,23 @@ class @LabelsSelect if showAny data.unshift( - any: true + isAny: true title: 'Any Label' ) if data.length > 2 - data.splice 2, 0, "divider" + data.splice 2, 0, 'divider' callback data renderRow: (label) -> if $.isArray(selectedLabel) - selected = "" + selected = '' $.each selectedLabel, (i, selectedLbl) -> selectedLbl = selectedLbl.trim() - if selected is "" && label.title is selectedLbl - selected = "is-active" + if selected is '' and label.title is selectedLbl + selected = 'is-active' else - selected = if label.title is selectedLabel then "is-active" else "" + selected = if label.title is selectedLabel then 'is-active' else '' "
  • @@ -86,21 +87,23 @@ class @LabelsSelect fields: ['title'] selectable: true toggleLabel: (selected) -> - if selected && selected.title isnt "Any Label" + if selected and selected.title isnt 'Any Label' selected.title else defaultLabel - fieldName: $(dropdown).data('field-name') + fieldName: $dropdown.data('field-name') id: (label) -> - if label.any? - "" + if label.isAny? + '' else label.title clicked: -> - page = $("body").data "page" - - if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" - Issues.filterResults $(dropdown).parents("form") - else if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents("form").submit() + page = $('body').data 'page' + isIssueIndex = page is 'projects:issues:index' + isMRIndex = page is page is 'projects:merge_requests:index' + + if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + Issues.filterResults $dropdown.closest('form') + else if $dropdown.hasClass 'js-filter-submit' + $dropdown.closest('form').submit() ) diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index a4bf8654de4..0287d98b1ec 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -1,15 +1,16 @@ class @MilestoneSelect constructor: -> $('.js-milestone-select').each (i, dropdown) -> - projectId = $(dropdown).data('project-id') - milestonesUrl = $(dropdown).data('milestones') - selectedMilestone = $(dropdown).data('selected') - showNo = $(dropdown).data('show-no') - showAny = $(dropdown).data('show-any') - useId = $(dropdown).data('use-id') - defaultLabel = $(dropdown).text().trim() + $dropdown = $(dropdown) + projectId = $dropdown.data('project-id') + milestonesUrl = $dropdown.data('milestones') + selectedMilestone = $dropdown.data('selected') + showNo = $dropdown.data('show-no') + showAny = $dropdown.data('show-any') + useId = $dropdown.data('use-id') + defaultLabel = $dropdown.text().trim() - $(dropdown).glDropdown( + $dropdown.glDropdown( data: (term, callback) -> $.ajax( url: milestonesUrl @@ -17,7 +18,7 @@ class @MilestoneSelect html = $(data) data = [] html.find('.milestone strong a').each -> - link = $(@).attr("href").split("/") + link = $(@).attr('href').split('/') data.push( id: link[link.length - 1] title: $(@).text().trim() @@ -25,7 +26,7 @@ class @MilestoneSelect if showNo data.unshift( - id: "0" + id: '0' title: 'No Milestone' ) @@ -36,7 +37,7 @@ class @MilestoneSelect ) if data.length > 2 - data.splice 2, 0, "divider" + data.splice 2, 0, 'divider' callback(data) filterable: true @@ -44,11 +45,11 @@ class @MilestoneSelect fields: ['title'] selectable: true toggleLabel: (selected) -> - if selected && selected.id + if selected && 'id' of selected selected.title else defaultLabel - fieldName: $(dropdown).data('field-name') + fieldName: $dropdown.data('field-name') text: (milestone) -> milestone.title id: (milestone) -> @@ -56,16 +57,18 @@ class @MilestoneSelect if !milestone.isAny? milestone.title else - "" + '' else milestone.id isSelected: (milestone) -> milestone.title is selectedMilestone clicked: -> - page = $("body").data "page" + page = $('body').data 'page' + isIssueIndex = page is 'projects:issues:index' + isMRIndex = page is page is 'projects:merge_requests:index' - if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" - Issues.filterResults $(dropdown).parents("form") - else if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents("form").submit() + if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + Issues.filterResults $dropdown.closest('form') + else if $dropdown.hasClass 'js-filter-submit' + $dropdown.closest('form').submit() ) diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 44ed31d04b2..0e950146176 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -4,15 +4,16 @@ class @UsersSelect @userPath = "/autocomplete/users/:id.json" $('.js-user-search').each (i, dropdown) => - @projectId = $(dropdown).data('project-id') - @showCurrentUser = $(dropdown).data('current-user') - showNullUser = $(dropdown).data('null-user') - showAnyUser = $(dropdown).data('any-user') - firstUser = $(dropdown).data('first-user') - selectedId = $(dropdown).data('selected') - defaultLabel = $(dropdown).text().trim() - - $(dropdown).glDropdown( + $dropdown = $(dropdown) + @projectId = $dropdown.data('project-id') + @showCurrentUser = $dropdown.data('current-user') + showNullUser = $dropdown.data('null-user') + showAnyUser = $dropdown.data('any-user') + firstUser = $dropdown.data('first-user') + selectedId = $dropdown.data('selected') + defaultLabel = $dropdown.text().trim() + + $dropdown.glDropdown( data: (term, callback) => @users term, (users) => if term.length is 0 @@ -53,19 +54,21 @@ class @UsersSelect search: fields: ['name', 'username'] selectable: true - fieldName: $(dropdown).data('field-name') + fieldName: $dropdown.data('field-name') toggleLabel: (selected) -> if selected && selected.id? selected.name else defaultLabel clicked: -> - page = $("body").data "page" - - if $(dropdown).hasClass("js-filter-submit") && page is "projects:issues:index" - Issues.filterResults $(dropdown).parents("form") - else if $(dropdown).hasClass "js-filter-submit" - $(dropdown).parents("form").submit() + page = $('body').data 'page' + isIssueIndex = page is 'projects:issues:index' + isMRIndex = page is page is 'projects:merge_requests:index' + + if $dropdown.hasClass('js-filter-submit') and (isIssueIndex or isMRIndex) + Issues.filterResults $dropdown.closest('form') + else if $dropdown.hasClass 'js-filter-submit' + $dropdown.closest('form').submit() renderRow: (user) -> username = if user.username then "@#{user.username}" else "" avatar = if user.avatar_url then user.avatar_url else false -- cgit v1.2.1 From c51af604e5bfdb33eb3d46ff2073066d10bce05d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Mar 2016 10:14:39 +0000 Subject: Another CS style fix --- app/assets/javascripts/users_select.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 0e950146176..48831dd6bc4 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -56,7 +56,7 @@ class @UsersSelect selectable: true fieldName: $dropdown.data('field-name') toggleLabel: (selected) -> - if selected && selected.id? + if selected && 'id' of selected selected.name else defaultLabel -- cgit v1.2.1 From c29da3f8ca1d759b8cbecb91b6e0529b18cc5c85 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 16 Mar 2016 20:31:30 -0300 Subject: Trigger a todo for mentions on commits page --- app/helpers/todos_helper.rb | 11 ++++++-- app/models/todo.rb | 29 +++++++++++++++++++- app/services/todo_service.rb | 65 +++++++++++++++++++++++++++----------------- 3 files changed, 76 insertions(+), 29 deletions(-) (limited to 'app') diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 07ddc691d85..9604a4e01b4 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -16,14 +16,19 @@ module TodosHelper def todo_target_link(todo) target = todo.target_type.titleize.downcase - link_to "#{target} #{todo.target.to_reference}", todo_target_path(todo), { title: h(todo.target.title) } + link_to "#{target} #{todo.to_reference}", todo_target_path(todo), { title: h(todo.target.title) } end def todo_target_path(todo) anchor = dom_id(todo.note) if todo.note.present? - polymorphic_path([todo.project.namespace.becomes(Namespace), - todo.project, todo.target], anchor: anchor) + if todo.for_commit? + namespace_project_commit_path(todo.project.namespace.becomes(Namespace), todo.project, + todo.target, anchor: anchor) + else + polymorphic_path([todo.project.namespace.becomes(Namespace), + todo.project, todo.target], anchor: anchor) + end end def todos_filter_params diff --git a/app/models/todo.rb b/app/models/todo.rb index 5f91991f781..b00a1b3dc7d 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -27,7 +27,9 @@ class Todo < ActiveRecord::Base delegate :name, :email, to: :author, prefix: true, allow_nil: true - validates :action, :project, :target, :user, presence: true + validates :action, :project, :target_type, :user, presence: true + validates :target_id, presence: true, if: ->(t) { t.target_type.present? && t.target_type != 'Commit' } + validates :commit_id, presence: true, if: ->(t) { t.target_type.present? && t.target_type == 'Commit' } default_scope { reorder(id: :desc) } @@ -50,4 +52,29 @@ class Todo < ActiveRecord::Base target.title end end + + def for_commit? + target_type == "Commit" + end + + # override to return commits, which are not active record + def target + if for_commit? + project.commit(commit_id) + else + super + end + # Temp fix to prevent app crash + # if note commit id doesn't exist + rescue + nil + end + + def to_reference + if for_commit? + Commit.truncate_sha(commit_id) + else + target.to_reference + end + end end diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index 4392e2d17fe..1027c309121 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -103,24 +103,16 @@ class TodoService # * mark all pending todos related to the target for the current user as done # def mark_pending_todos_as_done(target, user) - pending_todos(user, target.project, target).update_all(state: :done) + attributes = attributes_for_target(target) + pending_todos(user, attributes).update_all(state: :done) end private - def create_todos(project, target, author, users, action, note = nil) + def create_todos(users, attributes) Array(users).each do |user| - next if pending_todos(user, project, target).exists? - - Todo.create( - project: project, - user_id: user.id, - author_id: author.id, - target_id: target.id, - target_type: target.class.name, - action: action, - note: note - ) + next if pending_todos(user, attributes).exists? + Todo.create(attributes.merge(user_id: user.id)) end end @@ -130,8 +122,8 @@ class TodoService end def handle_note(note, author) - # Skip system notes, notes on commit, and notes on project snippet - return if note.system? || ['Commit', 'Snippet'].include?(note.noteable_type) + # Skip system notes, and notes on project snippet + return if note.system? || ['Snippet'].include?(note.noteable_type) project = note.project target = note.noteable @@ -142,13 +134,39 @@ class TodoService def create_assignment_todo(issuable, author) if issuable.assignee && issuable.assignee != author - create_todos(issuable.project, issuable, author, issuable.assignee, Todo::ASSIGNED) + attributes = attributes_for_todo(issuable.project, issuable, author, Todo::ASSIGNED) + create_todos(issuable.assignee, attributes) end end - def create_mention_todos(project, issuable, author, note = nil) - mentioned_users = filter_mentioned_users(project, note || issuable, author) - create_todos(project, issuable, author, mentioned_users, Todo::MENTIONED, note) + def create_mention_todos(project, target, author, note = nil) + mentioned_users = filter_mentioned_users(project, note || target, author) + attributes = attributes_for_todo(project, target, author, Todo::MENTIONED, note) + create_todos(mentioned_users, attributes) + end + + def attributes_for_target(target) + attributes = { + project_id: target.project.id, + target_id: target.id, + target_type: target.class.name, + commit_id: nil + } + + if target.is_a?(Commit) + attributes.merge!(target_id: nil, commit_id: target.id) + end + + attributes + end + + def attributes_for_todo(project, target, author, action, note = nil) + attributes_for_target(target).merge!( + project_id: project.id, + author_id: author.id, + action: action, + note: note + ) end def filter_mentioned_users(project, target, author) @@ -160,11 +178,8 @@ class TodoService mentioned_users.uniq end - def pending_todos(user, project, target) - user.todos.pending.where( - project_id: project.id, - target_id: target.id, - target_type: target.class.name - ) + def pending_todos(user, criteria = {}) + valid_keys = [:project_id, :target_id, :target_type, :commit_id] + user.todos.pending.where(criteria.slice(*valid_keys)) end end -- cgit v1.2.1 From fb72271e24663c74e6dd66e610fd1add98628648 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 16 Mar 2016 20:56:23 -0300 Subject: Use todo.done without ! in the controller to mark todo as done --- app/controllers/dashboard/todos_controller.rb | 4 ++-- app/models/todo.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'app') diff --git a/app/controllers/dashboard/todos_controller.rb b/app/controllers/dashboard/todos_controller.rb index 7857af9c5de..be488483b09 100644 --- a/app/controllers/dashboard/todos_controller.rb +++ b/app/controllers/dashboard/todos_controller.rb @@ -6,7 +6,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController end def destroy - todo.done! + todo.done todo_notice = 'Todo was successfully marked as done.' @@ -20,7 +20,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController end def destroy_all - @todos.each(&:done!) + @todos.each(&:done) respond_to do |format| format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' } diff --git a/app/models/todo.rb b/app/models/todo.rb index b00a1b3dc7d..68263a64d5a 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -38,7 +38,7 @@ class Todo < ActiveRecord::Base state_machine :state, initial: :pending do event :done do - transition [:pending, :done] => :done + transition [:pending] => :done end state :pending -- cgit v1.2.1 From a5bad46505d152fe824fb9c51cb15a2a45caff14 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 16 Mar 2016 21:02:20 -0300 Subject: Update schema info comment on todo related files --- app/models/todo.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/todo.rb b/app/models/todo.rb index 68263a64d5a..024cdcc0d87 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -5,14 +5,15 @@ # id :integer not null, primary key # user_id :integer not null # project_id :integer not null -# target_id :integer not null +# target_id :integer # target_type :string not null # author_id :integer -# note_id :integer # action :integer not null # state :string not null # created_at :datetime # updated_at :datetime +# note_id :integer +# commit_id :string # class Todo < ActiveRecord::Base -- cgit v1.2.1 From 2eeeb266e36abdbe78be8f71081bb19e83175819 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 18 Mar 2016 10:27:26 -0300 Subject: Reuse `for_commit?` on conditional validations --- app/models/todo.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/todo.rb b/app/models/todo.rb index 024cdcc0d87..4be5806b8d1 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -29,8 +29,8 @@ class Todo < ActiveRecord::Base delegate :name, :email, to: :author, prefix: true, allow_nil: true validates :action, :project, :target_type, :user, presence: true - validates :target_id, presence: true, if: ->(t) { t.target_type.present? && t.target_type != 'Commit' } - validates :commit_id, presence: true, if: ->(t) { t.target_type.present? && t.target_type == 'Commit' } + validates :target_id, presence: true, unless: :for_commit? + validates :commit_id, presence: true, if: :for_commit? default_scope { reorder(id: :desc) } -- cgit v1.2.1 From 231d4fb9f8a30e97fd9bcb7176ad8337557f6ea0 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 18 Mar 2016 10:32:22 -0300 Subject: Use `Commit#short_id` instead of `Commit.truncate_sha` --- app/models/todo.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/todo.rb b/app/models/todo.rb index 4be5806b8d1..b135407a8ee 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -73,7 +73,7 @@ class Todo < ActiveRecord::Base def to_reference if for_commit? - Commit.truncate_sha(commit_id) + target.short_id else target.to_reference end -- cgit v1.2.1 From 71cc3caa85e8c04a397d243ffa96c20842414a11 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 18 Mar 2016 10:34:23 -0300 Subject: Use `Note#for_project_snippet?` to skip notes on project snippet --- app/services/todo_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index 1027c309121..f2662922e90 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -123,7 +123,7 @@ class TodoService def handle_note(note, author) # Skip system notes, and notes on project snippet - return if note.system? || ['Snippet'].include?(note.noteable_type) + return if note.system? || note.for_project_snippet? project = note.project target = note.noteable -- cgit v1.2.1 From 0858cb097afcaa529e5e0fe7154af53f66ce62fe Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 18:08:35 +0000 Subject: Fixed issue with labels dropdown getting wrong labels --- app/assets/javascripts/labels_select.js.coffee | 9 --------- app/assets/javascripts/milestone_select.js.coffee | 9 --------- app/controllers/projects/labels_controller.rb | 7 +++++++ app/controllers/projects/milestones_controller.rb | 8 ++++++++ app/views/shared/issuable/_filter.html.haml | 4 ++-- 5 files changed, 17 insertions(+), 20 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index e6c1446f14f..4f03c367758 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -39,18 +39,9 @@ class @LabelsSelect $dropdown.glDropdown( data: (term, callback) -> - # We have to fetch the JS version of the labels list because there is no - # public facing JSON url for labels $.ajax( url: labelUrl ).done (data) -> - html = $(data) - data = [] - html.find('.label-row a').each -> - data.push( - title: $(@).text().trim() - ) - if showNo data.unshift( id: 0 diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index 0287d98b1ec..5c35107ae6a 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -15,15 +15,6 @@ class @MilestoneSelect $.ajax( url: milestonesUrl ).done (data) -> - html = $(data) - data = [] - html.find('.milestone strong a').each -> - link = $(@).attr('href').split('/') - data.push( - id: link[link.length - 1] - title: $(@).text().trim() - ) - if showNo data.unshift( id: '0' diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 40d8098690a..c61793f89af 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -12,6 +12,13 @@ class Projects::LabelsController < Projects::ApplicationController def index @labels = @project.labels.page(params[:page]).per(PER_PAGE) + + respond_to do |format| + format.html + format.json do + render json: @labels.to_json + end + end end def new diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index da46731d945..cfb0435717e 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -19,7 +19,15 @@ class Projects::MilestonesController < Projects::ApplicationController end @milestones = @milestones.includes(:project) + @milestones_all = @milestones @milestones = @milestones.page(params[:page]).per(PER_PAGE) + + respond_to do |format| + format.html + format.json do + render json: @milestones_all.to_json + end + end end def new diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index dfdc84ba4cc..318691ac7c3 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -22,7 +22,7 @@ - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) = dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", - placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: (namespace_project_milestones_path(@project.namespace, @project, :js) if @project) } }) do + placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: (namespace_project_milestones_path(@project.namespace, @project, :json) if @project) } }) do - if @project %ul.dropdown-footer-list - if can? current_user, :admin_milestone, @project @@ -40,7 +40,7 @@ - if params[:label_name] = hidden_field_tag(:label_name, params[:label_name]) .dropdown - %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: (namespace_project_labels_path(@project.namespace, @project, :js) if @project)}} + %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project)}} %span.dropdown-toggle-text = h(params[:label_name] || "Label") = icon('chevron-down') -- cgit v1.2.1 From 645b7a0a3389dca3a709f65a52ae765f213078f2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 18:37:25 +0000 Subject: Full labels data in JSON --- app/controllers/projects/labels_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index c61793f89af..5f471d405f5 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -16,7 +16,7 @@ class Projects::LabelsController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: @labels.to_json + render json: @project.labels end end end -- cgit v1.2.1 From d847db79cb6a99d9cfb6f4c57587887942965388 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Mar 2016 19:14:31 +0000 Subject: Fixes issue on dashboard issues They would try to load JSON from a project even though it isn't a single project --- app/controllers/dashboard_controller.rb | 18 +++++++ app/helpers/labels_helper.rb | 12 +++-- app/helpers/milestones_helper.rb | 13 +++-- app/views/shared/issuable/_filter.html.haml | 59 +--------------------- .../shared/issuable/_label_dropdown.html.haml | 39 ++++++++++++++ .../shared/issuable/_milestone_dropdown.html.haml | 16 ++++++ 6 files changed, 90 insertions(+), 67 deletions(-) create mode 100644 app/views/shared/issuable/_label_dropdown.html.haml create mode 100644 app/views/shared/issuable/_milestone_dropdown.html.haml (limited to 'app') diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 139e40db180..614e28b6dce 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -20,6 +20,24 @@ class DashboardController < Dashboard::ApplicationController end end + def labels + respond_to do |format| + format.json do + projects + render json: view_context.projects_labels_options + end + end + end + + def milestones + respond_to do |format| + format.json do + projects + render json: view_context.projects_milestones_options + end + end + end + protected def load_events diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 4455dcd0e20..361811163f9 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -116,12 +116,14 @@ module LabelsHelper else Label.where(project_id: @projects) end + end - grouped_labels = GlobalLabel.build_collection(labels) - grouped_labels.unshift(Label::None) - grouped_labels.unshift(Label::Any) - - options_from_collection_for_select(grouped_labels, 'name', 'title', params[:label_name]) + def labels_filter_path + if @project + namespace_project_labels_path(@project.namespace, @project, :json) + else + labels_dashboard_path(:json) + end end def label_subscription_status(label) diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index 92ed0891e92..de60be4eb25 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -56,12 +56,15 @@ module MilestonesHelper epoch = DateTime.parse('1970-01-01') grouped_milestones = GlobalMilestone.build_collection(milestones) - grouped_milestones = grouped_milestones.sort_by { |x| x.due_date.nil? ? epoch : x.due_date } - grouped_milestones.unshift(Milestone::None) - grouped_milestones.unshift(Milestone::Any) - grouped_milestones.unshift(Milestone::Upcoming) + grouped_milestones.sort_by { |x| x.due_date.nil? ? epoch : x.due_date } + end - options_from_collection_for_select(grouped_milestones, 'name', 'title', params[:milestone_title]) + def milestones_filter_dropdown_path + if @project + namespace_project_milestones_path(@project.namespace, @project, :json) + else + milestones_dashboard_path(:json) + end end def milestone_remaining_days(milestone) diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index 318691ac7c3..cb25d332ffa 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -19,65 +19,10 @@ placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id" } }) .filter-item.inline.milestone-filter - - if params[:milestone_title] - = hidden_field_tag(:milestone_title, params[:milestone_title]) - = dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", - placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: (namespace_project_milestones_path(@project.namespace, @project, :json) if @project) } }) do - - if @project - %ul.dropdown-footer-list - - if can? current_user, :admin_milestone, @project - %li - = link_to new_namespace_project_milestone_path(@project.namespace, @project), title: "New Milestone" do - Create new - %li - = link_to namespace_project_milestones_path(@project.namespace, @project) do - - if can? current_user, :admin_milestone, @project - Manage milestones - - else - View milestones + = render "shared/issuable/milestone_dropdown" .filter-item.inline.labels-filter - - if params[:label_name] - = hidden_field_tag(:label_name, params[:label_name]) - .dropdown - %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project)}} - %span.dropdown-toggle-text - = h(params[:label_name] || "Label") - = icon('chevron-down') - .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable - .dropdown-page-one - = dropdown_title("Filter by label") - = dropdown_filter("Search labels") - = dropdown_content - - if @project - = dropdown_footer do - %ul.dropdown-footer-list - - if can? current_user, :admin_label, @project - %li - %a.dropdown-toggle-page{href: "#"} - Create new - %li - = link_to namespace_project_labels_path(@project.namespace, @project) do - - if can? current_user, :admin_label, @project - Manage labels - - else - View labels - - if can? current_user, :admin_label, @project - .dropdown-page-two - = dropdown_title("Create new label", back: true) - = dropdown_content do - %input#new_label_color{type: "hidden"} - %input#new_label_name.dropdown-input-field{type: "text", placeholder: "Name new label"} - .dropdown-label-color-preview.js-dropdown-label-color-preview - .suggest-colors.suggest-colors-dropdown - - suggested_colors.each do |color| - = link_to '#', style: "background-color: #{color}", data: { color: color } do -   - %button.btn.btn-primary.js-new-label-btn{type: "button"} - Create - = dropdown_loading - .dropdown-loading - = icon('spinner spin') + = render "shared/issuable/label_dropdown" .pull-right = render 'shared/sort_dropdown' diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml new file mode 100644 index 00000000000..cb490e5b759 --- /dev/null +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -0,0 +1,39 @@ +- if params[:label_name] + = hidden_field_tag(:label_name, params[:label_name]) +.dropdown + %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: labels_filter_path}} + %span.dropdown-toggle-text + = h(params[:label_name] || "Label") + = icon('chevron-down') + .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable + .dropdown-page-one + = dropdown_title("Filter by label") + = dropdown_filter("Search labels") + = dropdown_content + - if @project + = dropdown_footer do + %ul.dropdown-footer-list + - if can? current_user, :admin_label, @project + %li + %a.dropdown-toggle-page{href: "#"} + Create new + %li + = link_to namespace_project_labels_path(@project.namespace, @project) do + - if can? current_user, :admin_label, @project + Manage labels + - else + View labels + - if can? current_user, :admin_label, @project and @project + .dropdown-page-two + = dropdown_title("Create new label", back: true) + = dropdown_content do + %input#new_label_color{type: "hidden"} + %input#new_label_name.dropdown-input-field{type: "text", placeholder: "Name new label"} + .dropdown-label-color-preview.js-dropdown-label-color-preview + .suggest-colors.suggest-colors-dropdown + - suggested_colors.each do |color| + = link_to '#', style: "background-color: #{color}", data: { color: color } do +   + %button.btn.btn-primary.js-new-label-btn{type: "button"} + Create + = dropdown_loading diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml new file mode 100644 index 00000000000..640b23c401b --- /dev/null +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -0,0 +1,16 @@ +- if params[:milestone_title] + = hidden_field_tag(:milestone_title, params[:milestone_title]) += dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: milestones_filter_dropdown_path } }) do + - if @project + %ul.dropdown-footer-list + - if can? current_user, :admin_milestone, @project + %li + = link_to new_namespace_project_milestone_path(@project.namespace, @project), title: "New Milestone" do + Create new + %li + = link_to namespace_project_milestones_path(@project.namespace, @project) do + - if can? current_user, :admin_milestone, @project + Manage milestones + - else + View milestones -- cgit v1.2.1 From 0eecc214853fc07b9237b50ab65a6c702cbfaeb4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 09:09:06 +0000 Subject: Updated controller with before_action Fixed other issues based on feedback --- app/controllers/dashboard_controller.rb | 4 +--- app/controllers/projects/milestones_controller.rb | 8 ++++---- app/helpers/dropdowns_helper.rb | 2 +- app/views/shared/issuable/_label_dropdown.html.haml | 2 +- app/views/shared/issuable/_milestone_dropdown.html.haml | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) (limited to 'app') diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 614e28b6dce..36986d9a18d 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -3,7 +3,7 @@ class DashboardController < Dashboard::ApplicationController include MergeRequestsAction before_action :event_filter, only: :activity - before_action :projects, only: [:issues, :merge_requests] + before_action :projects, only: [:issues, :merge_requests, :labels, :milestones] respond_to :html @@ -23,7 +23,6 @@ class DashboardController < Dashboard::ApplicationController def labels respond_to do |format| format.json do - projects render json: view_context.projects_labels_options end end @@ -32,7 +31,6 @@ class DashboardController < Dashboard::ApplicationController def milestones respond_to do |format| format.json do - projects render json: view_context.projects_milestones_options end end diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index cfb0435717e..7b70f5fa7d7 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -19,13 +19,13 @@ class Projects::MilestonesController < Projects::ApplicationController end @milestones = @milestones.includes(:project) - @milestones_all = @milestones - @milestones = @milestones.page(params[:page]).per(PER_PAGE) respond_to do |format| - format.html + format.html do + @milestones = @milestones.page(params[:page]).per(PER_PAGE) + end format.json do - render json: @milestones_all.to_json + render json: @milestones_all end end end diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb index 74f326e0b83..ceff1fbb161 100644 --- a/app/helpers/dropdowns_helper.rb +++ b/app/helpers/dropdowns_helper.rb @@ -24,7 +24,7 @@ module DropdownsHelper capture(&block) if block && !options.has_key?(:footer_content) end - if block && options.has_key?(:footer_content) + if block && options[:footer_content] output << content_tag(:div, class: "dropdown-footer") do capture(&block) end diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml index cb490e5b759..8399c8fba13 100644 --- a/app/views/shared/issuable/_label_dropdown.html.haml +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -1,7 +1,7 @@ - if params[:label_name] = hidden_field_tag(:label_name, params[:label_name]) .dropdown - %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: (@project.id if @project), labels: labels_filter_path}} + %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path}} %span.dropdown-toggle-text = h(params[:label_name] || "Label") = icon('chevron-down') diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 640b23c401b..6e5abdeb667 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,7 +1,7 @@ - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) = dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", - placeholder: "Search milestones", footer_content: true, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: (@project.id if @project), milestones: milestones_filter_dropdown_path } }) do + placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path } }) do - if @project %ul.dropdown-footer-list - if can? current_user, :admin_milestone, @project -- cgit v1.2.1 From a45cb688095eda294b0242a09d28168d4e279421 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Mar 2016 10:40:54 +0000 Subject: Fixed failing tests --- app/controllers/projects/milestones_controller.rb | 2 +- app/helpers/labels_helper.rb | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'app') diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 7b70f5fa7d7..0998b191c07 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -25,7 +25,7 @@ class Projects::MilestonesController < Projects::ApplicationController @milestones = @milestones.page(params[:page]).per(PER_PAGE) end format.json do - render json: @milestones_all + render json: @milestones end end end diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 361811163f9..49f701e9bee 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -110,12 +110,11 @@ module LabelsHelper end def projects_labels_options - labels = - if @project - @project.labels - else - Label.where(project_id: @projects) - end + if @project + @project.labels + else + Label.where(project_id: @projects) + end end def labels_filter_path -- cgit v1.2.1 From 2a8858ca8adbc54d7e24e698fa8ce370a1e91157 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 18 Mar 2016 13:24:47 -0300 Subject: Rename `Todo#to_reference` to `Todo#target_reference` Since we're not actually returning a todo reference. --- app/helpers/todos_helper.rb | 2 +- app/models/todo.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 9604a4e01b4..edc5686cf08 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -16,7 +16,7 @@ module TodosHelper def todo_target_link(todo) target = todo.target_type.titleize.downcase - link_to "#{target} #{todo.to_reference}", todo_target_path(todo), { title: h(todo.target.title) } + link_to "#{target} #{todo.target_reference}", todo_target_path(todo), { title: todo.target.title } end def todo_target_path(todo) diff --git a/app/models/todo.rb b/app/models/todo.rb index b135407a8ee..ab804d712a0 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -71,7 +71,7 @@ class Todo < ActiveRecord::Base nil end - def to_reference + def target_reference if for_commit? target.short_id else -- cgit v1.2.1 From 2f210adee260a42bbecca5e099bb2e0cf18aacc6 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Mar 2016 12:21:07 +0000 Subject: Fixes issue with filter label missing on labels & milestones --- app/assets/javascripts/labels_select.js.coffee | 2 +- app/assets/javascripts/milestone_select.js.coffee | 2 +- app/assets/javascripts/users_select.js.coffee | 2 +- app/views/shared/issuable/_filter.html.haml | 4 ++-- app/views/shared/issuable/_label_dropdown.html.haml | 4 ++-- app/views/shared/issuable/_milestone_dropdown.html.haml | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/labels_select.js.coffee b/app/assets/javascripts/labels_select.js.coffee index 4f03c367758..4a0c18a99a6 100644 --- a/app/assets/javascripts/labels_select.js.coffee +++ b/app/assets/javascripts/labels_select.js.coffee @@ -11,7 +11,7 @@ class @LabelsSelect newColorField = $('#new_label_color') showNo = $dropdown.data('show-no') showAny = $dropdown.data('show-any') - defaultLabel = $dropdown.text().trim() + defaultLabel = $dropdown.data('default-label') if newLabelField.length $('.suggest-colors-dropdown a').on 'click', (e) -> diff --git a/app/assets/javascripts/milestone_select.js.coffee b/app/assets/javascripts/milestone_select.js.coffee index 5c35107ae6a..e17a1adb648 100644 --- a/app/assets/javascripts/milestone_select.js.coffee +++ b/app/assets/javascripts/milestone_select.js.coffee @@ -8,7 +8,7 @@ class @MilestoneSelect showNo = $dropdown.data('show-no') showAny = $dropdown.data('show-any') useId = $dropdown.data('use-id') - defaultLabel = $dropdown.text().trim() + defaultLabel = $dropdown.data('default-label') $dropdown.glDropdown( data: (term, callback) -> diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee index 48831dd6bc4..3d6452d2f46 100644 --- a/app/assets/javascripts/users_select.js.coffee +++ b/app/assets/javascripts/users_select.js.coffee @@ -11,7 +11,7 @@ class @UsersSelect showAnyUser = $dropdown.data('any-user') firstUser = $dropdown.data('first-user') selectedId = $dropdown.data('selected') - defaultLabel = $dropdown.text().trim() + defaultLabel = $dropdown.data('default-label') $dropdown.glDropdown( data: (term, callback) => diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index cb25d332ffa..ac20f7d1f7e 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -10,13 +10,13 @@ - if params[:author_id] = hidden_field_tag(:author_id, params[:author_id]) = dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author", - placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id" } }) + placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id", default_label: "Author" } }) .filter-item.inline - if params[:assignee_id] = hidden_field_tag(:assignee_id, params[:assignee_id]) = dropdown_tag(user_dropdown_label(params[:assignee_id], "Assignee"), options: { toggle_class: "js-user-search js-filter-submit js-assignee-search", title: "Filter by assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee", - placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id" } }) + placeholder: "Search assignee", data: { any_user: "Any Assignee", first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: (@project.id if @project), selected: params[:assignee_id], field_name: "assignee_id", default_label: "Assignee" } }) .filter-item.inline.milestone-filter = render "shared/issuable/milestone_dropdown" diff --git a/app/views/shared/issuable/_label_dropdown.html.haml b/app/views/shared/issuable/_label_dropdown.html.haml index 8399c8fba13..87617315181 100644 --- a/app/views/shared/issuable/_label_dropdown.html.haml +++ b/app/views/shared/issuable/_label_dropdown.html.haml @@ -1,9 +1,9 @@ - if params[:label_name] = hidden_field_tag(:label_name, params[:label_name]) .dropdown - %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path}} + %button.dropdown-menu-toggle.js-label-select.js-filter-submit{type: "button", data: {toggle: "dropdown", field_name: "label_name", show_no: "true", show_any: "true", selected: params[:label_name], project_id: @project.try(:id), labels: labels_filter_path, default_label: "Label"}} %span.dropdown-toggle-text - = h(params[:label_name] || "Label") + = h(params[:label_name].presence || "Label") = icon('chevron-down') .dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable .dropdown-page-one diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 6e5abdeb667..0434506c8d7 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -1,7 +1,7 @@ - if params[:milestone_title] = hidden_field_tag(:milestone_title, params[:milestone_title]) -= dropdown_tag(h(params[:milestone_name] || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", - placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path } }) do += dropdown_tag(h(params[:milestone_title].presence || "Milestone"), options: { title: "Filter by milestone", toggle_class: 'js-milestone-select js-filter-submit', filter: true, dropdown_class: "dropdown-menu-selectable", + placeholder: "Search milestones", footer_content: @project.present?, data: { show_no: true, show_any: true, field_name: "milestone_title", selected: params[:milestone_title], project_id: @project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do - if @project %ul.dropdown-footer-list - if can? current_user, :admin_milestone, @project -- cgit v1.2.1 From 02b0c37cabf0456a4c36680fb1313b1107f35f54 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 18 Mar 2016 13:27:27 -0300 Subject: Refactor `Todo#target` --- app/models/todo.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'app') diff --git a/app/models/todo.rb b/app/models/todo.rb index ab804d712a0..d85f7bfdf57 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -61,14 +61,10 @@ class Todo < ActiveRecord::Base # override to return commits, which are not active record def target if for_commit? - project.commit(commit_id) + project.commit(commit_id) rescue nil else super end - # Temp fix to prevent app crash - # if note commit id doesn't exist - rescue - nil end def target_reference -- cgit v1.2.1 From 3837f4413a0773d7d57a659d2ab8ccfcbe67ea7e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 18 Mar 2016 17:37:10 +0100 Subject: Re-group scss variables Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/framework/variables.scss | 68 +++++++++++++++++-------- 1 file changed, 47 insertions(+), 21 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 211ead7319d..61b52136c67 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -1,45 +1,71 @@ -$row-hover: #f4f8fe; +/* + * Layout + */ +$sidebar_collapsed_width: 62px; +$sidebar_width: 230px; +$gutter_collapsed_width: 62px; +$gutter_width: 290px; +$gutter_inner_width: 258px; + +/* + * UI elements + */ +$border-color: #efeff1; +$table-border-color: #eef0f2; +$background-color: #faf9f9; + +/* + * Text + */ +$secondary-text: #555; +$placeholder-color: #8f8f8f; $gl-text-color: #54565b; $gl-text-green: #4a2; $gl-text-red: #d12f19; $gl-text-orange: #d90; $gl-header-color: #323232; $gl-link-color: #333c48; +$gl-gray: #5a5a5a; $md-text-color: #444; $md-link-color: #3084bb; -$progress-color: #c0392b; -$gl-font-size: 15px; + +/* + * Lists + */ +$list-title-color: #333; +$list-text-color: #555; $list-font-size: 15px; -$sidebar_collapsed_width: 62px; -$sidebar_width: 230px; -$gutter_collapsed_width: 62px; -$gutter_width: 290px; -$gutter_inner_width: 258px; -$avatar_radius: 50%; + + +/* + * Code + */ $code_font_size: 13px; $code_line_height: 1.5; -$border-color: #efeff1; -$table-border-color: #eef0f2; -$background-color: #faf9f9; -$header-height: 58px; -$fixed-layout-width: 1280px; -$gl-gray: #5a5a5a; + +/* + * Padding + */ $gl-padding: 16px; $gl-btn-padding: 10px; $gl-vert-padding: 6px; $gl-padding-top: 10px; + +/* + * Misc + */ +$row-hover: #f4f8fe; +$progress-color: #c0392b; +$gl-font-size: 15px; +$avatar_radius: 50%; +$header-height: 58px; +$fixed-layout-width: 1280px; $gl-avatar-size: 40px; -$secondary-text: #7f8fa4; $error-exclamation-point: #e62958; $border-radius-default: 3px; -$list-title-color: #333; -$list-text-color: #555; - $btn-transparent-color: #8f8f8f; - $ssh-key-icon-color: #8f8f8f; $ssh-key-icon-size: 18px; - $provider-btn-group-border: #e5e5e5; $provider-btn-not-active-color: #4688f1; -- cgit v1.2.1 From 5e2728891ecc375ee51d17aad1c40898cf3e16c1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 18 Mar 2016 17:48:52 +0100 Subject: Cleanup somce css colors Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/framework/variables.scss | 25 ++++++++++++++----------- app/assets/stylesheets/pages/events.scss | 7 ++++--- app/assets/stylesheets/pages/issues.scss | 6 +++--- app/assets/stylesheets/pages/todos.scss | 7 ++++--- 4 files changed, 25 insertions(+), 20 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 61b52136c67..d455a3d8e29 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -17,25 +17,29 @@ $background-color: #faf9f9; /* * Text */ -$secondary-text: #555; -$placeholder-color: #8f8f8f; -$gl-text-color: #54565b; +$gl-font-size: 15px; +$gl-title-color: #333; +$gl-text-color: #555; +$gl-placeholder-color: #8f8f8f; $gl-text-green: #4a2; $gl-text-red: #d12f19; $gl-text-orange: #d90; -$gl-header-color: #323232; +$gl-header-color: $gl-title-color; $gl-link-color: #333c48; -$gl-gray: #5a5a5a; -$md-text-color: #444; -$md-link-color: #3084bb; +$gl-gray: $gl-text-color; /* * Lists */ -$list-title-color: #333; -$list-text-color: #555; -$list-font-size: 15px; +$list-font-size: $gl-font-size; +$list-title-color: $gl-title-color; +$list-text-color: $gl-text-color; +/* + * Markdown + */ +$md-text-color: #444; +$md-link-color: #3084bb; /* * Code @@ -56,7 +60,6 @@ $gl-padding-top: 10px; */ $row-hover: #f4f8fe; $progress-color: #c0392b; -$gl-font-size: 15px; $avatar_radius: 50%; $header-height: 58px; $fixed-layout-width: 1280px; diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index b39a9abf40f..040e1d38678 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -6,7 +6,7 @@ font-size: $gl-font-size; padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top); border-bottom: 1px solid $table-border-color; - color: #7f8fa4; + color: $list-text-color; &.event-inline { .avatar { @@ -31,9 +31,10 @@ .event-title { @include str-truncated(calc(100% - 174px)); font-weight: 600; + color: $list-title-color; - .author_name { - color: #333; + a { + color: $list-title-color; } } diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 7ac4bc468d6..76bd6d9a8a7 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -130,14 +130,14 @@ form.edit-issue { } .issue-closed-by-widget { - color: $secondary-text; + color: $gl-text-color; margin-left: 52px; } .editor-details { display: block; - + @media (min-width: $screen-sm-min) { display: inline-block; } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index 27970eba159..dbd6585fc31 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -16,7 +16,7 @@ .todo-item { font-size: $gl-font-size; padding-left: $gl-avatar-size + $gl-padding-top; - color: $secondary-text; + color: $gl-text-color; a { color: #4c4e54; @@ -29,9 +29,10 @@ .todo-title { @include str-truncated(calc(100% - 174px)); font-weight: 600; + color: $list-title-color; - .author-name { - color: #333; + a { + color: $list-title-color; } } -- cgit v1.2.1 From 5e39846e4b139428940c6a4677667c8b0fbb78ce Mon Sep 17 00:00:00 2001 From: Arinde Eniola Date: Fri, 18 Mar 2016 16:21:09 +0100 Subject: Add avatar to issue and MR pages header --- app/views/projects/issues/show.html.haml | 4 ++-- app/views/projects/merge_requests/show/_mr_title.html.haml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index ce5b84ee712..52df3de8a27 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -32,9 +32,9 @@ = time_ago_with_tooltip(@issue.created_at) by %strong - = link_to_member(@project, @issue.author, avatar: false, size: 24, mobile_classes: "hidden-xs") + = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-xs") %strong - = link_to_member(@project, @issue.author, avatar: false, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", + = link_to_member(@project, @issue.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) .pull-right.issue-btn-group diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml index c6cbe8589ef..eeb605e2dc5 100644 --- a/app/views/projects/merge_requests/show/_mr_title.html.haml +++ b/app/views/projects/merge_requests/show/_mr_title.html.haml @@ -19,9 +19,9 @@ = time_ago_with_tooltip(@merge_request.created_at) by %strong - = link_to_member(@project, @merge_request.author, avatar: false, size: 24, mobile_classes: "hidden-xs") + = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-xs") %strong - = link_to_member(@project, @merge_request.author, avatar: false, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", + = link_to_member(@project, @merge_request.author, size: 24, mobile_classes: "hidden-sm hidden-md hidden-lg", by_username: true, avatar: false) .issue-btn-group.pull-right -- cgit v1.2.1 From 4a8a8282d93fa8a486fdd3adc67a40fee737861d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 18 Mar 2016 09:28:41 +0100 Subject: Fix an issue when the target branch of a MR had been deleted Before displaying the "diverged commits" note, we're checking if the MR is open, but we should check if it's mergeable instead because this check ensure the source and target branches exist. This was introduced by !2217 and fixes #14388. --- app/views/projects/merge_requests/_show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index ee5b9fd95a8..b9695157f68 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -34,7 +34,7 @@ %span into = link_to namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch" do = @merge_request.target_branch - - if @merge_request.open? && @merge_request.diverged_from_target_branch? + - if @merge_request.mergeable? && @merge_request.diverged_from_target_branch? %span (#{pluralize(@merge_request.diverged_commits_count, 'commit')} behind) = render "projects/merge_requests/show/how_to_merge" -- cgit v1.2.1 From bc92de8f038012b284ea1cbfbb2f0950943ebd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 18 Mar 2016 18:16:04 +0100 Subject: Add a safeguard in MergeRequest#compute_diverged_commits_count We have to ensure source_sha and target_sha are not nil before calling Gitlab::Git::Commit.between. --- app/models/merge_request.rb | 5 ++++- app/views/projects/merge_requests/_show.html.haml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 30a7bd47be7..a6140b5b04c 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -516,7 +516,7 @@ class MergeRequest < ActiveRecord::Base end def target_sha - @target_sha ||= target_project.repository.commit(target_branch).sha + @target_sha ||= target_project.repository.commit(target_branch).try(:sha) end def source_sha @@ -572,8 +572,11 @@ class MergeRequest < ActiveRecord::Base end def compute_diverged_commits_count + return 0 unless source_sha && target_sha + Gitlab::Git::Commit.between(target_project.repository.raw_repository, source_sha, target_sha).size end + private :compute_diverged_commits_count def diverged_from_target_branch? diverged_commits_count > 0 diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml index b9695157f68..ee5b9fd95a8 100644 --- a/app/views/projects/merge_requests/_show.html.haml +++ b/app/views/projects/merge_requests/_show.html.haml @@ -34,7 +34,7 @@ %span into = link_to namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch" do = @merge_request.target_branch - - if @merge_request.mergeable? && @merge_request.diverged_from_target_branch? + - if @merge_request.open? && @merge_request.diverged_from_target_branch? %span (#{pluralize(@merge_request.diverged_commits_count, 'commit')} behind) = render "projects/merge_requests/show/how_to_merge" -- cgit v1.2.1 From daeed3fdf309771a1c6827ed5b024c2f883bbeb5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 18 Mar 2016 19:02:08 +0100 Subject: Refactor colors and lists * Introduce 2 color links: black and blue * Use black color link for UI elements like lists * Refactor lists to use .title nested under li * Make all lists (events, todos, activity, projects etc) use style * List colorschema is now 333 for links and 555 for text Signed-off-by: Dmitriy Zaporozhets --- app/assets/stylesheets/framework/lists.scss | 7 +++-- app/assets/stylesheets/framework/variables.scss | 31 ++++++++++---------- app/assets/stylesheets/pages/commits.scss | 2 +- app/assets/stylesheets/pages/events.scss | 8 ++--- app/assets/stylesheets/pages/issues.scss | 2 +- app/assets/stylesheets/pages/todos.scss | 18 ------------ app/assets/stylesheets/pages/tree.scss | 2 +- app/views/dashboard/todos/_todo.html.haml | 2 +- app/views/dashboard/todos/index.html.haml | 2 +- app/views/projects/issues/_issue.html.haml | 6 ++-- .../merge_requests/_merge_request.html.haml | 6 ++-- app/views/shared/groups/_group.html.haml | 13 +++++---- app/views/shared/projects/_project.html.haml | 34 ++++++++++++---------- app/views/shared/snippets/_snippet.html.haml | 4 +-- 14 files changed, 61 insertions(+), 76 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index 2b4bb1eebf9..b17c8bcbb1e 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -111,14 +111,17 @@ ul.content-list { > li { border-color: $table-border-color; - color: $list-text-color; font-size: $list-font-size; + color: $list-text-color; .title { - color: $list-title-color; font-weight: 600; } + a { + color: $gl-dark-link-color; + } + .description { p { @include str-truncated; diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index d455a3d8e29..be626678bd7 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -10,36 +10,37 @@ $gutter_inner_width: 258px; /* * UI elements */ -$border-color: #efeff1; +$border-color: #efeff1; $table-border-color: #eef0f2; -$background-color: #faf9f9; +$background-color: #faf9f9; /* * Text */ -$gl-font-size: 15px; -$gl-title-color: #333; -$gl-text-color: #555; +$gl-font-size: 15px; +$gl-title-color: #333; +$gl-text-color: #555; +$gl-text-green: #4a2; +$gl-text-red: #d12f19; +$gl-text-orange: #d90; +$gl-link-color: #3084bb; +$gl-dark-link-color: #333; $gl-placeholder-color: #8f8f8f; -$gl-text-green: #4a2; -$gl-text-red: #d12f19; -$gl-text-orange: #d90; -$gl-header-color: $gl-title-color; -$gl-link-color: #333c48; -$gl-gray: $gl-text-color; +$gl-gray: $gl-text-color; +$gl-header-color: $gl-title-color; /* * Lists */ -$list-font-size: $gl-font-size; +$list-font-size: $gl-font-size; $list-title-color: $gl-title-color; -$list-text-color: $gl-text-color; +$list-text-color: $gl-text-color; /* * Markdown */ -$md-text-color: #444; -$md-link-color: #3084bb; +$md-text-color: $gl-text-color; +$md-link-color: $gl-link-color; /* * Code diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index d57be1b2daa..33b3c7558ed 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -55,7 +55,7 @@ li.commit { } .commit-row-message { - color: $gl-link-color; + color: $gl-dark-link-color; &:hover { text-decoration: underline; diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 040e1d38678..84eefd01cfe 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -21,7 +21,7 @@ } a { - color: #4c4e54; + color: $gl-dark-link-color; } .avatar { @@ -31,11 +31,7 @@ .event-title { @include str-truncated(calc(100% - 174px)); font-weight: 600; - color: $list-title-color; - - a { - color: $list-title-color; - } + color: $list-text-color; } .event-body { diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 76bd6d9a8a7..6a1d28590c2 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -3,7 +3,7 @@ padding: 10px $gl-padding; position: relative; - .issue-title { + .title { margin-bottom: 2px; } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index dbd6585fc31..f983e9829e6 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -14,26 +14,8 @@ } .todo-item { - font-size: $gl-font-size; - padding-left: $gl-avatar-size + $gl-padding-top; - color: $gl-text-color; - - a { - color: #4c4e54; - } - - .avatar { - margin-left: -($gl-avatar-size + $gl-padding-top); - } - .todo-title { @include str-truncated(calc(100% - 174px)); - font-weight: 600; - color: $list-title-color; - - a { - color: $list-title-color; - } } .todo-body { diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 73c7c9f687c..25b5e95583e 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -41,7 +41,7 @@ vertical-align: middle; i, a { - color: $gl-link-color; + color: $gl-dark-link-color; } img { diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index 4c848a50181..e3a4d64df01 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -2,7 +2,7 @@ .todo-item.todo-block = image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:'' - .todo-title + .todo-title.title %span.author-name - if todo.author = link_to_author(todo) diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index 623381375a5..f9ec3a89158 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -51,7 +51,7 @@ .panel-heading = link_to project.name_with_namespace, namespace_project_path(project.namespace, project) - %ul.well-list.todos-list + %ul.content-list.todos-list = render group[1] = paginate @todos, theme: "gitlab" - else diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 00e1a3d8069..4aa92d0b39e 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -3,11 +3,11 @@ .issue-check = check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue" - .issue-title + .issue-title.title %span.issue-title-text = confidential_icon(issue) - = link_to_gfm issue.title, issue_path(issue), class: "title" - %ul.controls.light + = link_to_gfm issue.title, issue_path(issue) + %ul.controls - if issue.closed? %li CLOSED diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 18cf3f14f0b..13d0cbdde1d 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -1,8 +1,8 @@ %li{ class: mr_css_classes(merge_request) } - .merge-request-title + .merge-request-title.title %span.merge-request-title-text - = link_to_gfm merge_request.title, merge_request_path(merge_request), class: "title" - %ul.controls.light + = link_to_gfm merge_request.title, merge_request_path(merge_request) + %ul.controls - if merge_request.merged? %li MERGED diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml index fb9a8db0889..f172350f5ff 100644 --- a/app/views/shared/groups/_group.html.haml +++ b/app/views/shared/groups/_group.html.haml @@ -10,7 +10,7 @@ %i.fa.fa-cogs = link_to leave_group_group_members_path(group), data: { confirm: leave_group_message(group.name) }, method: :delete, class: "btn-sm btn btn-grouped", title: 'Leave this group' do - %i.fa.fa-sign-out + = icon('sign-out') .stats %span @@ -22,12 +22,13 @@ = number_with_delimiter(group.users.count) = image_tag group_icon(group), class: "avatar s40 hidden-xs" - = link_to group, class: 'group-name title' do - = group.name + .title + = link_to group, class: 'group-name' do + = group.name - - if group_member - as - %span #{group_member.human_access} + - if group_member + as + %span #{group_member.human_access} - if group.description.present? .description diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 97cfb76cdb0..872d2bdf46d 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -7,26 +7,11 @@ - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && project.commit - css_class += " no-description" if project.description.blank? && !show_last_commit_as_description - ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit -- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.2'] +- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.3'] - cache_key.push(ci_commit.status) if ci_commit %li.project-row{ class: css_class } = cache(cache_key) do - = link_to project_path(project), class: dom_class(project) do - - if avatar - .dash-project-avatar - - if use_creator_avatar - = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' - - else - = project_icon(project, alt: '', class: 'avatar project-avatar s40') - %span.project-full-name.title - %span.namespace-name - - if project.namespace && !skip_namespace - = project.namespace.human_name - \/ - %span.project-name.filter-title - = project.name - .controls - if project.main_language %span @@ -45,6 +30,23 @@ %span.visibility-icon.has_tooltip{data: { container: 'body', placement: 'left' }, title: "#{visibility_level_label(project.visibility_level)} - #{project_visibility_level_description(project.visibility_level)}"} = visibility_level_icon(project.visibility_level, fw: false) + + .title + = link_to project_path(project), class: dom_class(project) do + - if avatar + .dash-project-avatar + - if use_creator_avatar + = image_tag avatar_icon(project.creator.email, 40), class: "avatar s40", alt:'' + - else + = project_icon(project, alt: '', class: 'avatar project-avatar s40') + %span.project-full-name + %span.namespace-name + - if project.namespace && !skip_namespace + = project.namespace.human_name + \/ + %span.project-name.filter-title + = project.name + - if show_last_commit_as_description .description = link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit), diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml index a316a085107..c96dfefe17f 100644 --- a/app/views/shared/snippets/_snippet.html.haml +++ b/app/views/shared/snippets/_snippet.html.haml @@ -1,8 +1,8 @@ %li.snippet-row = image_tag avatar_icon(snippet.author_email), class: "avatar s40 hidden-xs", alt: '' - .snippet-title - = link_to reliable_snippet_path(snippet), class: 'title' do + .title + = link_to reliable_snippet_path(snippet) do = truncate(snippet.title, length: 60) - if snippet.private? %span.label.label-gray -- cgit v1.2.1 From 733ae58798f6736af156e94b6906ac9c0b76fa3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Coutable?= Date: Fri, 18 Mar 2016 21:49:56 +0100 Subject: Dedupe labels in labels selector in Dashboard pages Also moved useless helper methods and directly to the DashboardController. --- app/controllers/dashboard_controller.rb | 11 +++++++++-- app/helpers/labels_helper.rb | 8 -------- app/helpers/milestones_helper.rb | 13 ------------- 3 files changed, 9 insertions(+), 23 deletions(-) (limited to 'app') diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 36986d9a18d..b538c7d1608 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -21,17 +21,24 @@ class DashboardController < Dashboard::ApplicationController end def labels + labels = Label.where(project_id: @projects).select(:title, :color).uniq(:title) + respond_to do |format| format.json do - render json: view_context.projects_labels_options + render json: labels end end end def milestones + milestones = Milestone.where(project_id: @projects).active + epoch = DateTime.parse('1970-01-01') + grouped_milestones = GlobalMilestone.build_collection(milestones) + grouped_milestones = grouped_milestones.sort_by { |x| x.due_date.nil? ? epoch : x.due_date } + respond_to do |format| format.json do - render json: view_context.projects_milestones_options + render json: grouped_milestones end end end diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 49f701e9bee..e238a7b4c26 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -109,14 +109,6 @@ module LabelsHelper end end - def projects_labels_options - if @project - @project.labels - else - Label.where(project_id: @projects) - end - end - def labels_filter_path if @project namespace_project_labels_path(@project.namespace, @project, :json) diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index de60be4eb25..c9d8787bd19 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -46,19 +46,6 @@ module MilestonesHelper end end - def projects_milestones_options - milestones = - if @project - @project.milestones - else - Milestone.where(project_id: @projects) - end.active - - epoch = DateTime.parse('1970-01-01') - grouped_milestones = GlobalMilestone.build_collection(milestones) - grouped_milestones.sort_by { |x| x.due_date.nil? ? epoch : x.due_date } - end - def milestones_filter_dropdown_path if @project namespace_project_milestones_path(@project.namespace, @project, :json) -- cgit v1.2.1