Commit 8d23f267 authored by Jacob Schatz's avatar Jacob Schatz Committed by Alejandro Rodríguez

Merge branch '20840-getting-started-better-empty-state-for-issues-view' into 'master'

Issues empty state

## What does this MR do?

Adds the empty state for the project, dashboard and group issues.

## Are there points in the code the reviewer needs to double check?

## Why was this MR needed?

## Screenshots (if relevant)

### Filtered to show no issues (on group issues page in this case but also dashboard and projects)

![Screen_Shot_2016-11-08_at_20.55.56](/uploads/b598af4a8a5e2c9fbb859abf36e70e4b/Screen_Shot_2016-11-08_at_20.55.56.png)

### Project with no issues

![Screen_Shot_2016-11-08_at_20.57.08](/uploads/8f54fdf1b3101c46299249fa2944207d/Screen_Shot_2016-11-08_at_20.57.08.png)

![Screen_Shot_2016-11-08_at_20.57.17](/uploads/1d2d162e1d845dd05e945d8ebb1d2101/Screen_Shot_2016-11-08_at_20.57.17.png)

### Group with no projects with any issues

![Screen_Shot_2016-11-08_at_20.54.55](/uploads/f28dc2038839d5bda0eb37f37927d5db/Screen_Shot_2016-11-08_at_20.54.55.png)

## 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 #20840 

Closes #20850

See merge request !7309
parent f6a69b41
...@@ -254,3 +254,32 @@ ...@@ -254,3 +254,32 @@
.content-block-small { .content-block-small {
padding: 10px 0; padding: 10px 0;
} }
.empty-state {
margin: 100px 0 0;
.text-content {
max-width: 460px;
margin: 0 auto;
padding: $gl-padding;
}
.svg-content {
text-align: center;
svg {
max-width: 425px;
width: 100%;
padding: $gl-padding;
}
}
@media(max-width: $screen-xs-max) {
margin-top: 50px;
text-align: center;
.btn {
width: 100%;
}
}
}
...@@ -48,4 +48,8 @@ module GroupsHelper ...@@ -48,4 +48,8 @@ module GroupsHelper
"#{status.humanize} #{projects_lfs_status(group)}" "#{status.humanize} #{projects_lfs_status(group)}"
end end
end end
def group_issues(group)
IssuesFinder.new(current_user, group_id: group.id).execute
end
end end
...@@ -455,4 +455,8 @@ module ProjectsHelper ...@@ -455,4 +455,8 @@ module ProjectsHelper
def project_child_container_class(view_path) def project_child_container_class(view_path)
view_path == "projects/issues/issues" ? "prepend-top-default" : "project-show-#{view_path}" view_path == "projects/issues/issues" ? "prepend-top-default" : "project-show-#{view_path}"
end end
def project_issues(project)
IssuesFinder.new(current_user, project_id: project.id).execute
end
end end
...@@ -3,24 +3,27 @@ ...@@ -3,24 +3,27 @@
- if current_user - if current_user
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues") = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@group.name} issues")
.top-area - if group_issues(@group).exists?
= render 'shared/issuable/nav', type: :issues .top-area
.nav-controls = render 'shared/issuable/nav', type: :issues
- if current_user .nav-controls
= link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do - if current_user
= icon('rss') = link_to url_for(params.merge(format: :atom, private_token: current_user.private_token)), class: 'btn' do
%span.icon-label = icon('rss')
Subscribe %span.icon-label
= render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" Subscribe
= render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue"
= render 'shared/issuable/filter', type: :issues = render 'shared/issuable/filter', type: :issues
.row-content-block.second-block .row-content-block.second-block
Only issues from Only issues from the
%strong #{@group.name} %strong #{@group.name}
group are listed here. group are listed here.
- if current_user - if current_user
To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page.
.prepend-top-default .prepend-top-default
= render 'shared/issues' = render 'shared/issues'
- else
= render 'shared/empty_states/issues', project_select_button: true
%ul.content-list.issues-list.issuable-list %ul.content-list.issues-list.issuable-list
= render partial: "projects/issues/issue", collection: @issues = render partial: "projects/issues/issue", collection: @issues
- if @issues.blank? - if @issues.blank?
%li = render 'shared/empty_states/issues'
.nothing-here-block No issues to show
- if @issues.present? - if @issues.present?
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
- if current_user - if current_user
= auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues") = auto_discovery_link_tag(:atom, url_for(params.merge(format: :atom, private_token: current_user.private_token)), title: "#{@project.name} issues")
%div{ class: (container_class) } - if project_issues(@project).exists?
- if @project.issues.any? %div{ class: (container_class) }
.top-area .top-area
= render 'shared/issuable/nav', type: :issues = render 'shared/issuable/nav', type: :issues
.nav-controls .nav-controls
...@@ -36,21 +36,5 @@ ...@@ -36,21 +36,5 @@
= render 'issues' = render 'issues'
- if new_issue_email - if new_issue_email
= render 'issue_by_email', email: new_issue_email = render 'issue_by_email', email: new_issue_email
- else - else
.blank-state.blank-state-welcome = render 'shared/empty_states/issues', button_path: new_namespace_project_issue_path(@project.namespace, @project)
%h2.blank-state-title.blank-state-welcome-title
Welcome to GitLab Issues
%p.blank-state-text
Code, test, and deploy together
.blank-state
.blank-state-icon
= custom_icon("issues", size: 50)
%h3.blank-state-title
You don't have any issues right now.
%p.blank-state-text
Issues are the best way to track your project progress
- if can? current_user, :create_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do
New Issue
- if new_issue_email
= render 'issue_by_email', email: new_issue_email
...@@ -13,4 +13,4 @@ ...@@ -13,4 +13,4 @@
= render 'projects/issues/issue', issue: issue = render 'projects/issues/issue', issue: issue
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
- else - else
.nothing-here-block No issues to show = render 'shared/empty_states/issues'
- button_path = local_assigns.fetch(:button_path, false)
- project_select_button = local_assigns.fetch(:project_select_button, false)
- has_button = button_path || project_select_button
.row.empty-state
.pull-right.col-xs-12{ class: "#{'col-sm-6' if has_button}" }
.svg-content
= render 'shared/empty_states/icons/issues.svg'
.col-xs-12{ class: "#{'col-sm-6' if has_button}" }
.text-content
- if has_button
%h4
The Issue Tracker is a good place to add things that need to be improved or solved in a project!
%p
An issue can be a bug, a todo or a feature request that needs to be discussed in a project.
Besides, issues are searchable and filterable.
- if project_select_button
= render 'shared/new_project_item_select', path: 'issues/new', label: 'New issue'
- else
= link_to 'New issue', button_path, class: 'btn btn-new', title: 'New issue', id: 'new_issue_link'
- else
%h4.text-center There are no issues to show.
This diff is collapsed.
...@@ -62,7 +62,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps ...@@ -62,7 +62,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end end
step 'I click link "New Issue"' do step 'I click link "New Issue"' do
click_link "New Issue" page.has_link?('New Issue') ? click_link('New Issue') : click_link('New issue')
end end
step 'I click "author" dropdown' do step 'I click "author" dropdown' do
......
...@@ -3,8 +3,8 @@ require 'rails_helper' ...@@ -3,8 +3,8 @@ require 'rails_helper'
describe 'Filter issues', feature: true do describe 'Filter issues', feature: true do
include WaitForAjax include WaitForAjax
let!(:project) { create(:project) }
let!(:group) { create(:group) } let!(:group) { create(:group) }
let!(:project) { create(:project, group: group) }
let!(:user) { create(:user)} let!(:user) { create(:user)}
let!(:milestone) { create(:milestone, project: project) } let!(:milestone) { create(:milestone, project: project) }
let!(:label) { create(:label, project: project) } let!(:label) { create(:label, project: project) }
...@@ -127,7 +127,7 @@ describe 'Filter issues', feature: true do ...@@ -127,7 +127,7 @@ describe 'Filter issues', feature: true do
expect(page).to have_content wontfix.title expect(page).to have_content wontfix.title
end end
find('body').click find('.dropdown-menu-close-icon').click
expect(find('.filtered-labels')).to have_content(wontfix.title) expect(find('.filtered-labels')).to have_content(wontfix.title)
...@@ -135,7 +135,7 @@ describe 'Filter issues', feature: true do ...@@ -135,7 +135,7 @@ describe 'Filter issues', feature: true do
wait_for_ajax wait_for_ajax
find('.dropdown-menu-labels a', text: label.title).click find('.dropdown-menu-labels a', text: label.title).click
find('body').click find('.dropdown-menu-close-icon').click
expect(find('.filtered-labels')).to have_content(wontfix.title) expect(find('.filtered-labels')).to have_content(wontfix.title)
expect(find('.filtered-labels')).to have_content(label.title) expect(find('.filtered-labels')).to have_content(label.title)
...@@ -150,8 +150,8 @@ describe 'Filter issues', feature: true do ...@@ -150,8 +150,8 @@ describe 'Filter issues', feature: true do
it "selects and unselects `won't fix`" do it "selects and unselects `won't fix`" do
find('.dropdown-menu-labels a', text: wontfix.title).click find('.dropdown-menu-labels a', text: wontfix.title).click
find('.dropdown-menu-labels a', text: wontfix.title).click find('.dropdown-menu-labels a', text: wontfix.title).click
# Close label dropdown to load
find('body').click find('.dropdown-menu-close-icon').click
expect(page).not_to have_css('.filtered-labels') expect(page).not_to have_css('.filtered-labels')
end end
end end
......
...@@ -371,10 +371,12 @@ describe 'Issues', feature: true do ...@@ -371,10 +371,12 @@ describe 'Issues', feature: true do
describe 'when I want to reset my incoming email token' do describe 'when I want to reset my incoming email token' do
let(:project1) { create(:project, namespace: @user.namespace) } let(:project1) { create(:project, namespace: @user.namespace) }
let(:issue) { create(:issue, project: project1) }
before do before do
allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true)
project1.team << [@user, :master] project1.team << [@user, :master]
project1.issues << issue
visit namespace_project_issues_path(@user.namespace, project1) visit namespace_project_issues_path(@user.namespace, project1)
end end
...@@ -576,7 +578,10 @@ describe 'Issues', feature: true do ...@@ -576,7 +578,10 @@ describe 'Issues', feature: true do
describe 'new issue by email' do describe 'new issue by email' do
shared_examples 'show the email in the modal' do shared_examples 'show the email in the modal' do
let(:issue) { create(:issue, project: project) }
before do before do
project.issues << issue
stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
visit namespace_project_issues_path(project.namespace, project) visit namespace_project_issues_path(project.namespace, project)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment