diff options
author | Fatih Acet <acetfatih@gmail.com> | 2016-12-12 21:06:20 +0300 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2016-12-12 21:06:20 +0300 |
commit | 01b767bd98237fc669b0576062341c91d519b60d (patch) | |
tree | 090a44e5fa24094665e30c56b1d06d4038f8f79a | |
parent | 927a75567a9ff61f4c7ccdc4caa4280bbcab551c (diff) | |
parent | 730ff2e50b600f3e3c79e69fd4978faf6a06ce1b (diff) |
Merge branch '19990-update-snippets-page-design' into 'master'
Resolve "Updated UI for Snippets pages"
## What does this MR do?
## Are there points in the code the reviewer needs to double check?
## Why was this MR needed?
## Screenshots (if relevant)
## Does this MR meet the acceptance criteria?
- [ ] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added
- [ ] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- [ ] API support added
- Tests
- [ ] Added for this feature/bug
- [ ] All builds are passing
- [ ] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [ ] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [ ] Branch has no merge conflicts with `master` (if it does - rebase it please)
- [ ] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
## What are the relevant issue numbers?
Closes #19990
See merge request !7861
-rw-r--r-- | app/assets/stylesheets/pages/snippets.scss | 20 | ||||
-rw-r--r-- | app/controllers/projects/snippets_controller.rb | 8 | ||||
-rw-r--r-- | app/finders/snippets_finder.rb | 42 | ||||
-rw-r--r-- | app/helpers/snippets_helper.rb | 11 | ||||
-rw-r--r-- | app/views/dashboard/_snippets_head.html.haml | 20 | ||||
-rw-r--r-- | app/views/dashboard/snippets/index.html.haml | 42 | ||||
-rw-r--r-- | app/views/explore/snippets/index.html.haml | 10 | ||||
-rw-r--r-- | app/views/projects/snippets/_actions.html.haml | 14 | ||||
-rw-r--r-- | app/views/projects/snippets/index.html.haml | 20 | ||||
-rw-r--r-- | app/views/search/results/_snippet_title.html.haml | 2 | ||||
-rw-r--r-- | app/views/shared/snippets/_header.html.haml | 12 | ||||
-rw-r--r-- | app/views/shared/snippets/_snippet.html.haml | 31 | ||||
-rw-r--r-- | app/views/snippets/_actions.html.haml | 14 | ||||
-rw-r--r-- | app/views/snippets/_snippets.html.haml | 3 | ||||
-rw-r--r-- | app/views/snippets/_snippets_scope_menu.html.haml | 31 | ||||
-rw-r--r-- | features/steps/project/snippets.rb | 2 | ||||
-rw-r--r-- | spec/features/dashboard/datetime_on_tooltips_spec.rb | 2 | ||||
-rw-r--r-- | spec/finders/snippets_finder_spec.rb | 25 |
18 files changed, 187 insertions, 122 deletions
diff --git a/app/assets/stylesheets/pages/snippets.scss b/app/assets/stylesheets/pages/snippets.scss index 857eb76131a..ff13b86acf0 100644 --- a/app/assets/stylesheets/pages/snippets.scss +++ b/app/assets/stylesheets/pages/snippets.scss @@ -1,3 +1,13 @@ +.snippet-row { + .title { + margin-bottom: 2px; + } + + .snippet-filename { + padding: 0 2px; + } +} + .snippet-form-holder .file-holder .file-title { padding: 2px; } @@ -24,11 +34,17 @@ padding-bottom: $gl-padding; } +.snippet-header { + padding: $gl-padding 0; +} + .snippet-title { font-size: 24px; font-weight: 600; - padding: $gl-padding; - padding-left: 0; +} + +.snippet-edited-ago { + color: $gray-darkest; } .snippet-actions { diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index e290a0eadda..0720be2e55d 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -19,10 +19,12 @@ class Projects::SnippetsController < Projects::ApplicationController respond_to :html def index - @snippets = SnippetsFinder.new.execute(current_user, { + @snippets = SnippetsFinder.new.execute( + current_user, filter: :by_project, - project: @project - }) + project: @project, + scope: params[:scope] + ) @snippets = @snippets.page(params[:page]) end diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb index 0586a923a74..da6e6e87a6f 100644 --- a/app/finders/snippets_finder.rb +++ b/app/finders/snippets_finder.rb @@ -11,7 +11,7 @@ class SnippetsFinder when :by_user then by_user(current_user, user, params[:scope]) when :by_project - by_project(current_user, params[:project]) + by_project(current_user, params[:project], params[:scope]) end end @@ -32,35 +32,35 @@ class SnippetsFinder def by_user(current_user, user, scope) snippets = user.snippets.fresh - return snippets.are_public unless current_user - - if user == current_user - case scope - when 'are_internal' then - snippets.are_internal - when 'are_private' then - snippets.are_private - when 'are_public' then - snippets.are_public - else - snippets - end + if current_user + include_private = user == current_user + by_scope(snippets, scope, include_private) else - snippets.public_and_internal + snippets.are_public end end - def by_project(current_user, project) + def by_project(current_user, project, scope) snippets = project.snippets.fresh if current_user - if project.team.member?(current_user) || current_user.admin? - snippets - else - snippets.public_and_internal - end + include_private = project.team.member?(current_user) || current_user.admin? + by_scope(snippets, scope, include_private) else snippets.are_public end end + + def by_scope(snippets, scope = nil, include_private = false) + case scope.to_s + when 'are_private' + include_private ? snippets.are_private : Snippet.none + when 'are_internal' + snippets.are_internal + when 'are_public' + snippets.are_public + else + include_private ? snippets : snippets.public_and_internal + end + end end diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb index 7e33a562077..8c02b4061ca 100644 --- a/app/helpers/snippets_helper.rb +++ b/app/helpers/snippets_helper.rb @@ -8,6 +8,17 @@ module SnippetsHelper end end + # Return the path of a snippets index for a user or for a project + # + # @returns String, path to snippet index + def subject_snippets_path(subject = nil, opts = nil) + if subject.is_a?(Project) + namespace_project_snippets_path(subject.namespace, subject, opts) + else # assume subject === User + dashboard_snippets_path(opts) + end + end + # Get an array of line numbers surrounding a matching # line, bounded by min/max. # diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml index b25e8ea1f0c..02e90bbfa55 100644 --- a/app/views/dashboard/_snippets_head.html.haml +++ b/app/views/dashboard/_snippets_head.html.haml @@ -1,7 +1,13 @@ -%ul.nav-links - = nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do - = link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do - Your Snippets - = nav_link(page: explore_snippets_path) do - = link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do - Explore Snippets +.top-area + %ul.nav-links + = nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do + = link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do + Your Snippets + = nav_link(page: explore_snippets_path) do + = link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do + Explore Snippets + + - if current_user + .nav-controls.hidden-xs + = link_to new_snippet_path, class: "btn btn-new", title: "New snippet" do + New snippet diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml index b2af438ea57..85cbe0bf0e6 100644 --- a/app/views/dashboard/snippets/index.html.haml +++ b/app/views/dashboard/snippets/index.html.haml @@ -2,41 +2,11 @@ - header_title "Snippets", dashboard_snippets_path = render 'dashboard/snippets_head' += render partial: 'snippets/snippets_scope_menu', locals: { include_private: true } -.nav-block - .controls.hidden-xs - = link_to new_snippet_path, class: "btn btn-new", title: "New snippet" do - = icon('plus') - New snippet +.visible-xs + + = link_to new_snippet_path, class: "btn btn-new btn-block", title: "New snippet" do + New snippet - .nav-links.snippet-scope-menu - %li{ class: ("active" unless params[:scope]) } - = link_to dashboard_snippets_path do - All - %span.badge - = current_user.snippets.count - - %li{ class: ("active" if params[:scope] == "are_private") } - = link_to dashboard_snippets_path(scope: 'are_private') do - Private - %span.badge - = current_user.snippets.are_private.count - - %li{ class: ("active" if params[:scope] == "are_internal") } - = link_to dashboard_snippets_path(scope: 'are_internal') do - Internal - %span.badge - = current_user.snippets.are_internal.count - - %li{ class: ("active" if params[:scope] == "are_public") } - = link_to dashboard_snippets_path(scope: 'are_public') do - Public - %span.badge - = current_user.snippets.are_public.count - - .visible-xs - = link_to new_snippet_path, class: "btn btn-new btn-block", title: "New snippet" do - = icon('plus') - New snippet - -= render 'snippets/snippets' += render partial: 'snippets/snippets', locals: { link_project: true } diff --git a/app/views/explore/snippets/index.html.haml b/app/views/explore/snippets/index.html.haml index 7def9eacdc9..e5706d04736 100644 --- a/app/views/explore/snippets/index.html.haml +++ b/app/views/explore/snippets/index.html.haml @@ -6,12 +6,4 @@ - else = render 'explore/head' -.row-content-block - - if current_user - = link_to new_snippet_path, class: "btn btn-new btn-wide-on-sm pull-right", title: "New snippet" do - New snippet - - .oneline - Public snippets created by you and other users are listed here - -= render 'snippets/snippets' += render partial: 'snippets/snippets', locals: { link_project: true } diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml index 32e1f8a21b0..068a6610350 100644 --- a/app/views/projects/snippets/_actions.html.haml +++ b/app/views/projects/snippets/_actions.html.haml @@ -1,13 +1,13 @@ .hidden-xs - - if can?(current_user, :create_project_snippet, @project) - = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-create new-snippet-link', title: "New snippet" do - New snippet - - if can?(current_user, :update_project_snippet, @snippet) - = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-danger", title: 'Delete Snippet' do - Delete - if can?(current_user, :update_project_snippet, @snippet) - = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do + = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped" do Edit + - if can?(current_user, :update_project_snippet, @snippet) + = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-inverted btn-remove", title: 'Delete Snippet' do + Delete + - if can?(current_user, :create_project_snippet, @project) + = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-inverted btn-create', title: "New snippet" do + New snippet - if can?(current_user, :create_project_snippet, @project) || can?(current_user, :update_project_snippet, @snippet) .visible-xs-block.dropdown %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index e77e1b026f6..84e05cd6d88 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -1,11 +1,19 @@ - page_title "Snippets" -.sub-header-block - - if can?(current_user, :create_project_snippet, @project) - = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new btn-wide-on-sm pull-right", title: "New snippet" do - New snippet +- if current_user + .top-area + - include_private = @project.team.member?(current_user) || current_user.admin? + = render partial: 'snippets/snippets_scope_menu', locals: { subject: @project, include_private: include_private } + + .nav-controls.hidden-xs + - if can?(current_user, :create_project_snippet, @project) + = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new", title: "New snippet" do + New snippet - .oneline - Share code pastes with others out of git repository +- if can?(current_user, :create_project_snippet, @project) + .visible-xs + + = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new btn-block", title: "New snippet" do + New snippet = render 'snippets/snippets' diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml index c414acb6a11..027d42396b4 100644 --- a/app/views/search/results/_snippet_title.html.haml +++ b/app/views/search/results/_snippet_title.html.haml @@ -14,7 +14,7 @@ = link_to snippet_title.project.name_with_namespace, namespace_project_path(snippet_title.project.namespace, snippet_title.project) .snippet-info - = "##{snippet_title.id}" + = snippet_title.to_reference %span by = link_to user_snippets_path(snippet_title.author) do diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml index d7506e07ff6..d084f5e9684 100644 --- a/app/views/shared/snippets/_header.html.haml +++ b/app/views/shared/snippets/_header.html.haml @@ -8,10 +8,6 @@ %span.creator authored = time_ago_with_tooltip(@snippet.created_at, placement: 'bottom', html_class: 'snippet_updated_ago') - - if @snippet.updated_at != @snippet.created_at - %span - = icon('edit', title: 'edited') - = time_ago_with_tooltip(@snippet.updated_at, placement: 'bottom', html_class: 'snippet_edited_ago') by #{link_to_member(@project, @snippet.author, size: 24, author_class: "author item-title", avatar_class: "hidden-xs")} .snippet-actions @@ -20,5 +16,9 @@ - else = render "snippets/actions" -%h2.snippet-title.prepend-top-0.append-bottom-0 - = markdown_field(@snippet, :title) +.snippet-header + %h2.snippet-title.prepend-top-0.append-bottom-0 + = markdown_field(@snippet, :title) + + - if @snippet.updated_at != @snippet.created_at + = edited_time_ago_with_tooltip(@snippet, placement: 'bottom', html_class: 'snippet-edited-ago') diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml index ea17bec8677..5d2d2317f22 100644 --- a/app/views/shared/snippets/_snippet.html.haml +++ b/app/views/shared/snippets/_snippet.html.haml @@ -1,17 +1,16 @@ +- link_project = local_assigns.fetch(:link_project, false) + %li.snippet-row = image_tag avatar_icon(snippet.author_email), class: "avatar s40 hidden-xs", alt: '' .title = link_to reliable_snippet_path(snippet) do = snippet.title - - if snippet.private? - %span.label.label-gray.hidden-xs - = icon('lock') - private - %span.monospace.pull-right.hidden-xs - = snippet.file_name + - if snippet.file_name + %span.snippet-filename.monospace.hidden-xs + = snippet.file_name - %ul.controls.visible-xs + %ul.controls %li - note_count = snippet.notes.user.count = link_to reliable_snippet_path(snippet, anchor: 'notes'), class: ('no-comments' if note_count.zero?) do @@ -22,11 +21,17 @@ = visibility_level_label(snippet.visibility_level) = visibility_level_icon(snippet.visibility_level, fw: false) - %small.pull-right.cgray.hidden-xs - - if snippet.project_id? - = link_to snippet.project.name_with_namespace, namespace_project_path(snippet.project.namespace, snippet.project) - - .snippet-info.hidden-xs + .snippet-info + #{snippet.to_reference} · + authored #{time_ago_with_tooltip(snippet.created_at, placement: 'bottom', html_class: 'snippet-created-ago')} + by = link_to user_snippets_path(snippet.author) do = snippet.author_name - authored #{time_ago_with_tooltip(snippet.created_at)} + - if link_project && snippet.project_id? + %span.hidden-xs + in + = link_to namespace_project_path(snippet.project.namespace, snippet.project) do + = snippet.project.name_with_namespace + + .pull-right.snippet-updated-at + %span updated #{time_ago_with_tooltip(snippet.updated_at, placement: 'bottom')} diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml index 1d0e549ed3d..95fc7198104 100644 --- a/app/views/snippets/_actions.html.haml +++ b/app/views/snippets/_actions.html.haml @@ -1,13 +1,13 @@ .hidden-xs - - if current_user - = link_to new_snippet_path, class: "btn btn-grouped btn-create new-snippet-link", title: "New snippet" do - New snippet - - if can?(current_user, :admin_personal_snippet, @snippet) - = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-danger", title: 'Delete Snippet' do - Delete - if can?(current_user, :update_personal_snippet, @snippet) - = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do + = link_to edit_snippet_path(@snippet), class: "btn btn-grouped" do Edit + - if can?(current_user, :admin_personal_snippet, @snippet) + = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-inverted btn-remove", title: 'Delete Snippet' do + Delete + - if current_user + = link_to new_snippet_path, class: "btn btn-grouped btn-inverted btn-create", title: "New snippet" do + New snippet - if current_user .visible-xs-block.dropdown %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml index 77b66ca74b6..ac3701233ad 100644 --- a/app/views/snippets/_snippets.html.haml +++ b/app/views/snippets/_snippets.html.haml @@ -1,8 +1,9 @@ - remote = local_assigns.fetch(:remote, false) +- link_project = local_assigns.fetch(:link_project, false) .snippets-list-holder %ul.content-list - = render partial: 'shared/snippets/snippet', collection: @snippets + = render partial: 'shared/snippets/snippet', collection: @snippets, locals: { link_project: link_project } - if @snippets.empty? %li .nothing-here-block Nothing here. diff --git a/app/views/snippets/_snippets_scope_menu.html.haml b/app/views/snippets/_snippets_scope_menu.html.haml new file mode 100644 index 00000000000..2dda5fed647 --- /dev/null +++ b/app/views/snippets/_snippets_scope_menu.html.haml @@ -0,0 +1,31 @@ +- subject = local_assigns.fetch(:subject, current_user) +- include_private = local_assigns.fetch(:include_private, false) + +.nav-links.snippet-scope-menu + %li{ class: ("active" unless params[:scope]) } + = link_to subject_snippets_path(subject) do + All + %span.badge + - if include_private + = subject.snippets.count + - else + = subject.snippets.public_and_internal.count + + - if include_private + %li{ class: ("active" if params[:scope] == "are_private") } + = link_to subject_snippets_path(subject, scope: 'are_private') do + Private + %span.badge + = subject.snippets.are_private.count + + %li{ class: ("active" if params[:scope] == "are_internal") } + = link_to subject_snippets_path(subject, scope: 'are_internal') do + Internal + %span.badge + = subject.snippets.are_internal.count + + %li{ class: ("active" if params[:scope] == "are_public") } + = link_to subject_snippets_path(subject, scope: 'are_public') do + Public + %span.badge + = subject.snippets.are_public.count diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index 5e7d539add6..a3bebfa4b71 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -22,7 +22,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I click link "New snippet"' do - click_link "New snippet" + first(:link, "New snippet").click end step 'I click link "Snippet one"' do diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index 365cb445df1..44dfc2dff45 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -36,7 +36,7 @@ feature 'Tooltips on .timeago dates', feature: true, js: true do visit user_snippets_path(user) wait_for_ajax() - page.find('.js-timeago').hover + page.find('.js-timeago.snippet-created-ago').hover end it 'has the datetime formated correctly' do diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb index 4427443208a..975e99c5807 100644 --- a/spec/finders/snippets_finder_spec.rb +++ b/spec/finders/snippets_finder_spec.rb @@ -93,16 +93,39 @@ describe SnippetsFinder do expect(snippets).not_to include(@snippet1, @snippet2) end - it "returns public and internal snippets for none project members" do + it "returns public and internal snippets for non project members" do snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) expect(snippets).to include(@snippet2, @snippet3) expect(snippets).not_to include(@snippet1) end + it "returns public snippets for non project members" do + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_public") + expect(snippets).to include(@snippet3) + expect(snippets).not_to include(@snippet1, @snippet2) + end + + it "returns internal snippets for non project members" do + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_internal") + expect(snippets).to include(@snippet2) + expect(snippets).not_to include(@snippet1, @snippet3) + end + + it "does not return private snippets for non project members" do + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_private") + expect(snippets).not_to include(@snippet1, @snippet2, @snippet3) + end + it "returns all snippets for project members" do project1.team << [user, :developer] snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1) expect(snippets).to include(@snippet1, @snippet2, @snippet3) end + + it "returns private snippets for project members" do + project1.team << [user, :developer] + snippets = SnippetsFinder.new.execute(user, filter: :by_project, project: project1, scope: "are_private") + expect(snippets).to include(@snippet1) + end end end |