diff options
author | Luke "Jared" Bennett <lbennett@gitlab.com> | 2016-11-06 00:44:32 +0000 |
---|---|---|
committer | Luke "Jared" Bennett <lbennett@gitlab.com> | 2016-11-11 19:31:24 +0000 |
commit | 921eb219455735fa5688e73ad651dd9815dc52f4 (patch) | |
tree | f6684eaa1ab3b9d7b50cc2b56810a1977fdaeef8 | |
parent | 1bc3a5e8474c7146a8cf1b7b66c54589b70caa99 (diff) | |
download | gitlab-ce-921eb219455735fa5688e73ad651dd9815dc52f4.tar.gz |
Added snippets empty state to project snippets and dashboard snippets
Separated filtered and empty states
Added to user page and added absolute empty state to dashboard
-rw-r--r-- | app/assets/javascripts/user_tabs.js.es6 | 14 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/blocks.scss | 6 | ||||
-rw-r--r-- | app/controllers/users_controller.rb | 4 | ||||
-rw-r--r-- | app/views/dashboard/snippets/index.html.haml | 75 | ||||
-rw-r--r-- | app/views/projects/snippets/index.html.haml | 17 | ||||
-rw-r--r-- | app/views/shared/empty_states/_snippets.html.haml | 15 | ||||
-rw-r--r-- | app/views/shared/empty_states/icons/_snippets.svg | 1 | ||||
-rw-r--r-- | app/views/snippets/_snippets.html.haml | 18 | ||||
-rw-r--r-- | app/views/users/show.html.haml | 2 |
9 files changed, 97 insertions, 55 deletions
diff --git a/app/assets/javascripts/user_tabs.js.es6 b/app/assets/javascripts/user_tabs.js.es6 index 2b310da319c..9b5e3bbc48a 100644 --- a/app/assets/javascripts/user_tabs.js.es6 +++ b/app/assets/javascripts/user_tabs.js.es6 @@ -66,6 +66,7 @@ content on the Users#show page. this.action = action || this.defaultAction; this.$parentEl = $(parentEl) || $(document); this._location = window.location; + this.initEmptyStates(); this.$parentEl.find('.nav-links a') .each((i, navLink) => { this.loaded[$(navLink).attr('data-action')] = false; @@ -85,6 +86,12 @@ content on the Users#show page. .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)); } + initEmptyStates() { + this.emptyStates = { + snippets: document.querySelector('#js-user-snippets-empty-state'), + }; + } + tabShown(event) { const $target = $(event.target); const action = $target.data('action'); @@ -113,6 +120,7 @@ content on the Users#show page. } loadTab(source, action) { + if (this.emptyStates[action]) this.emptyStates[action].classList.add('hidden'); return $.ajax({ beforeSend: () => this.toggleLoading(true), complete: () => this.toggleLoading(false), @@ -121,6 +129,7 @@ content on the Users#show page. url: `${source}.json`, success: (data) => { const tabSelector = `div#${action}`; + if (!data.html) return this.showEmptyState(tabSelector, action); this.$parentEl.find(tabSelector).html(data.html); this.loaded[action] = true; return gl.utils.localTimeAgo($('.js-timeago', tabSelector)); @@ -128,6 +137,11 @@ content on the Users#show page. }); } + showEmptyState(tabSelector, action) { + if (this.emptyStates[action]) this.emptyStates[action].classList.remove('hidden'); + this.loaded[action] = true; + } + loadActivities(source) { if (this.loaded['activity']) { return; diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 520c9937e3d..fe2e7f404b6 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -277,4 +277,10 @@ @media(max-width: $screen-xs-max) { margin-top: 0; } + + @media(min-width: $screen-xs-max) { + &.snippets .text-content { + margin-top: 100px; + } + } } diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6a881b271d7..63eada2c968 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -64,9 +64,7 @@ class UsersController < ApplicationController respond_to do |format| format.html { render 'show' } format.json do - render json: { - html: view_to_html_string("snippets/_snippets", collection: @snippets, remote: true) - } + render json: { html: @snippets.blank? ? nil : view_to_html_string("snippets/_snippets", collection: @snippets, remote: true) } end end end diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml index b2af438ea57..9c8108ec98b 100644 --- a/app/views/dashboard/snippets/index.html.haml +++ b/app/views/dashboard/snippets/index.html.haml @@ -1,42 +1,45 @@ - page_title "Snippets" - header_title "Snippets", dashboard_snippets_path -= render 'dashboard/snippets_head' - -.nav-block - .controls.hidden-xs - = link_to new_snippet_path, class: "btn btn-new", title: "New snippet" do - = icon('plus') - 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 +- if current_user.snippets.count.zero? + = render 'shared/empty_states/snippets', button_path: new_snippet_path +- else + = render 'dashboard/snippets_head' + + .nav-block + .controls.hidden-xs + = link_to new_snippet_path, class: "btn btn-new", title: "New snippet" do = icon('plus') New snippet -= render 'snippets/snippets' + .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' diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index e77e1b026f6..f98cdebd3cc 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -1,11 +1,14 @@ - 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 @project.snippets.count.zero? + = render 'shared/empty_states/snippets', button_path: new_namespace_project_snippet_path(@project.namespace, @project) +- else + .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 - .oneline - Share code pastes with others out of git repository + .oneline + Share code pastes with others out of git repository -= render 'snippets/snippets' + = render 'snippets/snippets' diff --git a/app/views/shared/empty_states/_snippets.html.haml b/app/views/shared/empty_states/_snippets.html.haml new file mode 100644 index 00000000000..4c289923a97 --- /dev/null +++ b/app/views/shared/empty_states/_snippets.html.haml @@ -0,0 +1,15 @@ +- button_path = local_assigns.fetch(:button_path, false) + +.row.empty-state.snippets + .col-xs-12.pull-right{ class: "#{'col-sm-6' if button_path}" } + .svg-content + = render 'shared/empty_states/icons/snippets.svg' + .col-xs-12{ class: "#{'col-sm-6' if button_path}" } + .text-content + - if button_path + %h4 + Snippets are small pieces of code or notes that you want to keep. + They can be either public or private. + = link_to 'New snippet', button_path, class: 'btn btn-new', title: 'New snippet', id: 'new_snippet_link' + - else + %h4.text-center There are no snippets to show. diff --git a/app/views/shared/empty_states/icons/_snippets.svg b/app/views/shared/empty_states/icons/_snippets.svg new file mode 100644 index 00000000000..105f25931a8 --- /dev/null +++ b/app/views/shared/empty_states/icons/_snippets.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="758 211 385 296" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><rect id="a" width="248" height="296" x="94" rx="10"/><mask id="c" width="248" height="296" x="0" y="0" fill="#fff"><use xlink:href="#a"/></mask><rect id="b" width="37" height="28" y="14" rx="6"/><mask id="d" width="37" height="28" x="0" y="0" fill="#fff"><use xlink:href="#b"/></mask></defs><g fill="none" fill-rule="evenodd" transform="translate(740.000000, 211.000000)"><g fill="#F9F9F9" transform="translate(203.000000, 140.500000) scale(-1, 1) translate(-203.000000, -140.500000) translate(0.000000, 31.000000)"><rect width="120" height="22" x="30" rx="11"/><rect width="132" height="22" y="44" rx="11"/><rect width="190" height="22" x="208" y="66" rx="11"/><rect width="158" height="22" x="199" y="197" rx="11"/><rect width="158" height="22" x="136" y="154" rx="11"/><rect width="350" height="22" x="31" y="110" rx="11"/><path d="M153 22H21h21.5c6 0 11 5 11 11s-5 11-11 11H21h132-36.5c-6 0-11-5-11-11s5-11 11-11H153zm252 66H288h36.5c6 0 11 5 11 11s-5 11-11 11H288h117-36.5c-6 0-11-5-11-11s5-11 11-11H405zm-174 44H114h36.5c6 0 11 5 11 11s-5 11-11 11H114h117-36.5c-6 0-11-5-11-11s5-11 11-11H231zm75 44H189h21.5c6 0 11 5 11 11s-5 11-11 11H189h117-51.5c-6 0-11-5-11-11s5-11 11-11H306z"/></g><use fill="#FFF" stroke="#EEE" stroke-width="8" mask="url(#c)" xlink:href="#a"/><rect width="200" height="117" x="118" y="22" fill="#FFF" stroke="#FDE5D8" stroke-width="4" stroke-linecap="round" stroke-dasharray="11" rx="6"/><rect width="200" height="117" x="118" y="157" fill="#FFF" stroke="#EEE" stroke-width="4" stroke-linecap="round" stroke-dasharray="11" rx="6"/><g transform="translate(74.998711, 230.815699) rotate(-330.000000) translate(-74.998711, -230.815699) translate(46.998711, 203.315699) translate(27.686210, 27.223611) rotate(-315.000000) translate(-27.686210, -27.223611) translate(18.686210, -2.276389)"><path fill="#FFF" stroke="#B5A7DD" stroke-width="3" d="M4.5 1.5c0-1.3 1-2 2-1.2 0 0 7 2.3 7 12.4v30h-9V1.4z"/><circle cx="9" cy="49.3" r="9" fill="#6B4FBB"/><circle cx="9" cy="49.3" r="4.5" fill="#FFF"/></g><g transform="translate(74.998711, 230.815699) rotate(-330.000000) translate(-74.998711, -230.815699) translate(46.998711, 203.315699) translate(28.167043, 27.223611) scale(-1, 1) rotate(-315.000000) translate(-28.167043, -27.223611) translate(19.167043, -2.276389)"><path fill="#FFF" stroke="#B5A7DD" stroke-width="3" d="M4.5 1.5c0-1.3 1-2 2-1.2 0 0 7 2.3 7 12.4v30h-9V1.4z"/><circle cx="9" cy="29.1" r="2.2" fill="#6B4FBB"/><circle cx="9" cy="49.3" r="9" fill="#6B4FBB"/><circle cx="9" cy="49.3" r="4.5" fill="#FFF"/></g><rect width="200" height="117" x="46" y="11" fill="#FFF" stroke="#E5E5E5" stroke-width="4" stroke-linecap="round" rx="6"/><g transform="translate(65.000000, 40.000000)"><rect width="22" height="6" fill="#E5E5E5" rx="3"/><rect width="22" height="6" x="22" y="18" fill="#FC6D26" rx="3"/><rect width="16" height="6" x="46" fill="#FDE5D8" rx="3"/><rect width="16" height="6" x="86" fill="#FDE5D8" rx="3"/><rect width="16" height="6" y="36" fill="#FDE5D8" rx="3"/><rect width="16" height="6" y="54" fill="#B5A7DD" rx="3"/><rect width="16" height="6" y="18" fill="#B5A7DD" rx="3"/><rect width="16" height="6" x="68" y="18" fill="#E5E5E5" rx="3"/><rect width="16" height="6" x="22" y="54" fill="#FDE5D8" rx="3"/><rect width="12" height="6" x="28" fill="#6B4FBB" rx="3"/><rect width="12" height="6" x="50" y="18" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="22" y="36" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="44" y="54" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="62" y="54" fill="#FC6D26" rx="3"/><rect width="12" height="6" x="40" y="36" fill="#6B4FBB" rx="3"/><rect width="12" height="6" x="68" fill="#FC6D26" rx="3"/></g><g transform="translate(170.000000, 169.000000)"><rect width="200" height="117" fill="#FFF" stroke="#E5E5E5" stroke-width="4" stroke-linecap="round" rx="6"/><g transform="translate(19.000000, 29.000000)"><rect width="22" height="6" fill="#E5E5E5" rx="3"/><rect width="22" height="6" x="22" y="18" fill="#FC6D26" rx="3"/><rect width="16" height="6" x="46" fill="#FDE5D8" rx="3"/><rect width="16" height="6" x="86" fill="#FDE5D8" rx="3"/><rect width="16" height="6" y="36" fill="#FDE5D8" rx="3"/><rect width="16" height="6" y="54" fill="#B5A7DD" rx="3"/><rect width="16" height="6" y="18" fill="#B5A7DD" rx="3"/><rect width="16" height="6" x="68" y="18" fill="#E5E5E5" rx="3"/><rect width="16" height="6" x="22" y="54" fill="#FDE5D8" rx="3"/><rect width="12" height="6" x="28" fill="#6B4FBB" rx="3"/><rect width="12" height="6" x="50" y="18" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="22" y="36" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="44" y="54" fill="#FC6D26" rx="3"/><rect width="12" height="6" x="62" y="54" fill="#E5E5E5" rx="3"/><rect width="12" height="6" x="40" y="36" fill="#6B4FBB" rx="3"/><rect width="12" height="6" x="68" fill="#FC6D26" rx="3"/></g></g><g transform="translate(387.500000, 70.000000) rotate(-15.000000) translate(-387.500000, -70.000000) translate(369.000000, 49.000000)"><path fill="#6B4FBB" d="M30 12v-.5C30 5 25 0 18.5 0S7 5 7 11.5v.5h4v-.5c0-4 3.4-7.5 7.5-7.5 4 0 7.5 3.4 7.5 7.5v.5h4zM7 12h4v5H7zm19 0h4v5h-4z"/><use fill="#FFF" stroke="#B5A7DD" stroke-width="6" mask="url(#d)" xlink:href="#b"/><path fill="#6B4FBB" d="M20 28.7c1.2-.6 2-1.8 2-3.2 0-2-1.6-3.5-3.5-3.5-2 0-3.5 1.6-3.5 3.5 0 1.4.8 2.6 2 3.2v1.8c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5v-1.8z"/></g></g></svg> diff --git a/app/views/snippets/_snippets.html.haml b/app/views/snippets/_snippets.html.haml index 77b66ca74b6..eded9988191 100644 --- a/app/views/snippets/_snippets.html.haml +++ b/app/views/snippets/_snippets.html.haml @@ -1,13 +1,13 @@ - remote = local_assigns.fetch(:remote, false) -.snippets-list-holder - %ul.content-list - = render partial: 'shared/snippets/snippet', collection: @snippets - - if @snippets.empty? - %li - .nothing-here-block Nothing here. +- if @snippets.blank? + = render 'shared/empty_states/snippets' +- else + .snippets-list-holder + %ul.content-list + = render partial: 'shared/snippets/snippet', collection: @snippets - = paginate @snippets, theme: 'gitlab', remote: remote + = paginate @snippets, theme: 'gitlab', remote: remote -:javascript - gl.SnippetsList(); + :javascript + gl.SnippetsList(); diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 1e0752bd3c3..e39a0cc8033 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -120,6 +120,8 @@ #snippets.tab-pane - # This tab is always loaded via AJAX + #js-user-snippets-empty-state.hidden + = render 'shared/empty_states/snippets', button_path: new_snippet_path .loading-status = spinner |