From 5a59712b8ac29450dfef0af0dd381529f0d9d7ae Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 2 Dec 2015 14:02:12 +0100 Subject: Add "New X" buttons to dashboard and group issue, MR and milestone indexes --- app/views/dashboard/issues.html.haml | 31 ++++++++++++++++----- app/views/dashboard/merge_requests.html.haml | 23 ++++++++++++++-- app/views/dashboard/milestones/index.html.haml | 21 +++++++++++--- app/views/groups/issues.html.haml | 38 ++++++++++++++++++-------- app/views/groups/merge_requests.html.haml | 30 +++++++++++++++----- app/views/groups/milestones/index.html.haml | 24 +++++++++------- app/views/projects/milestones/index.html.haml | 15 ++++++---- 7 files changed, 134 insertions(+), 48 deletions(-) diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index cd602e897b7..829c3c83769 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -4,14 +4,31 @@ - if current_user = auto_discovery_link_tag(:atom, issues_dashboard_url(format: :atom, private_token: current_user.private_token), title: "#{current_user.name} issues") +.project-issuable-filter + .controls + .pull-left + - if current_user + .hidden-xs.pull-left + = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do + %i.fa.fa-rss -.append-bottom-20 - .pull-right - - if current_user - .hidden-xs.pull-left.prepend-top-20 - = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: '' do - %i.fa.fa-rss + - if @projects.any? { |project| can?(current_user, :create_issue, project) } + .dropdown.inline.prepend-left-10 + %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} + %i.fa.fa-plus + New Issue + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - @projects.each do |project| + - if can?(current_user, :create_issue, project) + %li + = link_to new_namespace_project_issue_path(project.namespace, project) do + = project.name_with_namespace = render 'shared/issuable/filter', type: :issues -= render 'shared/issues' +.gray-content-block.second-block + List all issues from all projects you have access to. + +.prepend-top-default + = render 'shared/issues' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index d1f332fa0d3..2e91c8dec8a 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -1,6 +1,25 @@ - page_title "Merge Requests" - header_title "Merge Requests", merge_requests_dashboard_path(assignee_id: current_user.id) -.append-bottom-20 +.project-issuable-filter + .controls + - if @projects.any? { |project| can?(current_user, :create_merge_request, project) } + .dropdown.inline + %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} + %i.fa.fa-plus + New Merge Request + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - @projects.each do |project| + - if can?(current_user, :create_merge_request, project) + %li + = link_to new_namespace_project_merge_request_path(project.namespace, project) do + = project.name_with_namespace + = render 'shared/issuable/filter', type: :merge_requests -= render 'shared/merge_requests' + +.gray-content-block.second-block + List all merge requests from all projects you have access to. + +.prepend-top-default + = render 'shared/merge_requests' diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml index 635251e2374..9aea75e50db 100644 --- a/app/views/dashboard/milestones/index.html.haml +++ b/app/views/dashboard/milestones/index.html.haml @@ -1,12 +1,25 @@ - page_title "Milestones" -- header_title "Milestones", dashboard_milestones_path +- header_title "Milestones", dashboard_milestones_path +.project-issuable-filter + .controls + - if @projects.any? { |project| can?(current_user, :admin_milestone, project) } + .dropdown.inline + %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} + %i.fa.fa-plus + New Milestone + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - @projects.each do |project| + - if can?(current_user, :admin_milestone, project) + %li + = link_to new_namespace_project_milestone_path(project.namespace, project) do + = project.name_with_namespace -= render 'shared/milestones_filter' + = render 'shared/milestones_filter' .gray-content-block - .oneline - List all milestones from all projects you have access to. + List all milestones from all projects you have access to. .milestones %ul.content-list diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 08d97e418a3..5a9739a0cda 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -4,21 +4,35 @@ - if current_user = auto_discovery_link_tag(:atom, issues_group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} issues") +.project-issuable-filter + .controls + .pull-left + - if current_user + .hidden-xs.pull-left + = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do + %i.fa.fa-rss + - if @projects.any? { |project| can?(current_user, :create_issue, project) } + .dropdown.inline.prepend-left-10 + %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} + %i.fa.fa-plus + New Issue + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - @projects.each do |project| + - if can?(current_user, :create_issue, project) + %li + = link_to new_namespace_project_issue_path(project.namespace, project) do + = project.name_with_namespace + + = render 'shared/issuable/filter', type: :issues -= render 'shared/issuable/filter', type: :issues .gray-content-block.second-block - .pull-right - - if current_user - .hidden-xs.pull-left - = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token) do - %i.fa.fa-rss - %div - Only issues from - %strong #{@group.name} - group are listed here. - - if current_user - To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. + Only issues from + %strong #{@group.name} + group are listed here. + - if current_user + To see all issues you should visit #{link_to 'dashboard', issues_dashboard_path} page. .prepend-top-default = render 'shared/issues' diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 425ad8331bf..95c503a3afa 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -1,13 +1,29 @@ - page_title "Merge Requests" - header_title group_title(@group, "Merge Requests", merge_requests_group_path(@group)) -= render 'shared/issuable/filter', type: :merge_requests +.project-issuable-filter + .controls + - if @projects.any? { |project| can?(current_user, :create_merge_request, project) } + .dropdown.inline + %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} + %i.fa.fa-plus + New Merge Request + %b.caret + %ul.dropdown-menu.dropdown-menu-align-right + - @projects.each do |project| + - if can?(current_user, :create_merge_request, project) + %li + = link_to new_namespace_project_merge_request_path(project.namespace, project) do + = project.name_with_namespace + + = render 'shared/issuable/filter', type: :merge_requests + .gray-content-block.second-block - %div - Only merge requests from - %strong #{@group.name} - group are listed here. - - if current_user - To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. + Only merge requests from + %strong #{@group.name} + group are listed here. + - if current_user + To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page. + .prepend-top-default = render 'shared/merge_requests' diff --git a/app/views/groups/milestones/index.html.haml b/app/views/groups/milestones/index.html.haml index 84ec77c6188..b221d3a89a4 100644 --- a/app/views/groups/milestones/index.html.haml +++ b/app/views/groups/milestones/index.html.haml @@ -1,18 +1,22 @@ - page_title "Milestones" - header_title group_title(@group, "Milestones", group_milestones_path(@group)) -= render 'shared/milestones_filter' +.project-issuable-filter + .controls + - if can?(current_user, :admin_milestones, @group) + .pull-right + %span.pull-right.hidden-xs + = link_to new_group_milestone_path(@group), class: "btn btn-new" do + = icon('plus') + New Milestone + + = render 'shared/milestones_filter' + .gray-content-block - - if can?(current_user, :admin_milestones, @group) - .pull-right - %span.pull-right.hidden-xs - = link_to new_group_milestone_path(@group), class: "btn btn-new" do - New Milestone + Only milestones from + %strong #{@group.name} + group are listed here. - .oneline - Only milestones from - %strong #{@group.name} - group are listed here. .milestones %ul.content-list - if @milestones.blank? diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index a207385bd43..114b06457a5 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -1,15 +1,18 @@ - page_title "Milestones" = render "header_title" -= render 'shared/milestones_filter' -.gray-content-block - .pull-right - - if can? current_user, :admin_milestone, @project + +.project-issuable-filter + .controls + - if can?(current_user, :admin_milestone, @project) = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do %i.fa.fa-plus New Milestone - .oneline - Milestone allows you to group issues and set due date for it + + = render 'shared/milestones_filter' + +.gray-content-block + Milestone allows you to group issues and set due date for it .milestones %ul.content-list -- cgit v1.2.1 From 8f817c7b08bcad23e1b047f84cc60d1748104e2a Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 7 Dec 2015 17:10:40 +0100 Subject: Add API group projects endpoint. --- doc/api/groups.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- lib/api/groups.rb | 12 ++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/doc/api/groups.md b/doc/api/groups.md index 0b9f6406d8d..808675d8605 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -1,6 +1,6 @@ # Groups -## List project groups +## List groups Get a list of groups. (As user: my groups, as admin: all groups) @@ -21,6 +21,70 @@ GET /groups You can search for groups by name or path, see below. + +## List a group's projects + +Get a list of projects in this group. + +``` +GET /groups/:id/projects +``` + +Parameters: + +- `archived` (optional) - if passed, limit by archived status +- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at` +- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` +- `search` (optional) - Return list of authorized projects according to a search criteria +- `ci_enabled_first` - Return projects ordered by ci_enabled flag. Projects with enabled GitLab CI go first + +```json +[ + { + "id": 4, + "description": null, + "default_branch": "master", + "public": false, + "visibility_level": 0, + "ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git", + "http_url_to_repo": "http://example.com/diaspora/diaspora-client.git", + "web_url": "http://example.com/diaspora/diaspora-client", + "tag_list": [ + "example", + "disapora client" + ], + "owner": { + "id": 3, + "name": "Diaspora", + "created_at": "2013-09-30T13: 46: 02Z" + }, + "name": "Diaspora Client", + "name_with_namespace": "Diaspora / Diaspora Client", + "path": "diaspora-client", + "path_with_namespace": "diaspora/diaspora-client", + "issues_enabled": true, + "merge_requests_enabled": true, + "builds_enabled": true, + "wiki_enabled": true, + "snippets_enabled": false, + "created_at": "2013-09-30T13: 46: 02Z", + "last_activity_at": "2013-09-30T13: 46: 02Z", + "creator_id": 3, + "namespace": { + "created_at": "2013-09-30T13: 46: 02Z", + "description": "", + "id": 3, + "name": "Diaspora", + "owner_id": 1, + "path": "diaspora", + "updated_at": "2013-09-30T13: 46: 02Z" + }, + "archived": false, + "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png" + } +] +``` + ## Details of a group Get all details of a group. @@ -186,7 +250,7 @@ To get more (up to 100), pass the following as an argument to the API call: /groups?per_page=100 ``` -And to switch pages add: +And to switch pages add: ``` /groups?per_page=100&page=2 -``` \ No newline at end of file +``` diff --git a/lib/api/groups.rb b/lib/api/groups.rb index 024aeec2e14..1a14d870a4a 100644 --- a/lib/api/groups.rb +++ b/lib/api/groups.rb @@ -65,6 +65,18 @@ module API DestroyGroupService.new(group, current_user).execute end + # Get a list of projects in this group + # + # Example Request: + # GET /groups/:id/projects + get ":id/projects" do + group = find_group(params[:id]) + projects = group.projects + projects = filter_projects(projects) + projects = paginate projects + present projects, with: Entities::Project + end + # Transfer a project to the Group namespace # # Parameters: -- cgit v1.2.1 From cbcb8dbe702c0b1532327aeb2dc53caffb6e8ed9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 7 Dec 2015 17:12:04 +0100 Subject: Use select2 dropdown for dashboard/group 'New X' buttons --- app/assets/javascripts/api.js.coffee | 31 ++++++++++++++++++++++ app/assets/javascripts/project_select.js.coffee | 26 ++++++++++++++++++ app/assets/stylesheets/framework/common.scss | 13 +++++++++ app/helpers/selects_helper.rb | 13 +++++++++ app/views/dashboard/issues.html.haml | 13 +-------- app/views/dashboard/merge_requests.html.haml | 13 +-------- app/views/dashboard/milestones/index.html.haml | 13 +-------- app/views/groups/issues.html.haml | 13 +-------- app/views/groups/merge_requests.html.haml | 13 +-------- .../shared/_new_project_item_select.html.haml | 20 ++++++++++++++ 10 files changed, 108 insertions(+), 60 deletions(-) create mode 100644 app/assets/javascripts/project_select.js.coffee create mode 100644 app/views/shared/_new_project_item_select.html.haml diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee index 9e5d594c861..746fa3cea87 100644 --- a/app/assets/javascripts/api.js.coffee +++ b/app/assets/javascripts/api.js.coffee @@ -2,6 +2,8 @@ groups_path: "/api/:version/groups.json" group_path: "/api/:version/groups/:id.json" namespaces_path: "/api/:version/namespaces.json" + group_projects_path: "/api/:version/groups/:id/projects.json" + projects_path: "/api/:version/projects.json" group: (group_id, callback) -> url = Api.buildUrl(Api.group_path) @@ -44,6 +46,35 @@ ).done (namespaces) -> callback(namespaces) + # Return projects list. Filtered by query + projects: (query, callback) -> + url = Api.buildUrl(Api.projects_path) + + $.ajax( + url: url + data: + private_token: gon.api_token + search: query + per_page: 20 + dataType: "json" + ).done (projects) -> + callback(projects) + + # Return group projects list. Filtered by query + groupProjects: (group_id, query, callback) -> + url = Api.buildUrl(Api.group_projects_path) + url = url.replace(':id', group_id) + + $.ajax( + url: url + data: + private_token: gon.api_token + search: query + per_page: 20 + dataType: "json" + ).done (projects) -> + callback(projects) + buildUrl: (url) -> url = gon.relative_url_root + url if gon.relative_url_root? return url.replace(':version', gon.api_version) diff --git a/app/assets/javascripts/project_select.js.coffee b/app/assets/javascripts/project_select.js.coffee new file mode 100644 index 00000000000..43b18a3da59 --- /dev/null +++ b/app/assets/javascripts/project_select.js.coffee @@ -0,0 +1,26 @@ +class @ProjectSelect + constructor: -> + $('.ajax-project-select').each (i, select) -> + @groupId = $(select).data('group-id') + + $(select).select2 + placeholder: "Search for project" + multiple: $(select).hasClass('multiselect') + minimumInputLength: 0 + query: (query) => + callback = (projects) -> + data = { results: projects } + query.callback(data) + + if @groupId + Api.groupProjects @groupId, query.term, callback + else + Api.projects query.term, callback + + id: (project) -> + project.web_url + + text: (project) -> + project.name_with_namespace + + dropdownCssClass: "ajax-project-dropdown" diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 61ecd58e6c5..19b0868dfef 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -441,3 +441,16 @@ table { .alert, .progress { margin-bottom: $gl-padding; } + +.new-project-item-select-holder { + display: inline-block; + position: relative; + + .new-project-item-select { + position: absolute; + top: 0; + right: 0; + width: 250px !important; + visibility: hidden; + } +} diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb index 7e54d4d1b5b..418120a3f73 100644 --- a/app/helpers/selects_helper.rb +++ b/app/helpers/selects_helper.rb @@ -46,6 +46,19 @@ module SelectsHelper select2_tag(id, opts) end + def project_select_tag(id, opts = {}) + opts[:class] ||= '' + opts[:class] << ' ajax-project-select' + + unless opts.delete(:scope) == :all + if @group + opts['data-group-id'] = @group.id + end + end + + hidden_field_tag(id, opts[:selected], opts) + end + def select2_tag(id, opts = {}) css_class = '' css_class << 'multiselect ' if opts[:multiple] diff --git a/app/views/dashboard/issues.html.haml b/app/views/dashboard/issues.html.haml index 829c3c83769..2d3da01178a 100644 --- a/app/views/dashboard/issues.html.haml +++ b/app/views/dashboard/issues.html.haml @@ -12,18 +12,7 @@ = link_to issues_dashboard_url(format: :atom, private_token: current_user.private_token), class: 'btn' do %i.fa.fa-rss - - if @projects.any? { |project| can?(current_user, :create_issue, project) } - .dropdown.inline.prepend-left-10 - %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-plus - New Issue - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - @projects.each do |project| - - if can?(current_user, :create_issue, project) - %li - = link_to new_namespace_project_issue_path(project.namespace, project) do - = project.name_with_namespace + = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 2e91c8dec8a..c5a5ec21f78 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -3,18 +3,7 @@ .project-issuable-filter .controls - - if @projects.any? { |project| can?(current_user, :create_merge_request, project) } - .dropdown.inline - %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-plus - New Merge Request - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - @projects.each do |project| - - if can?(current_user, :create_merge_request, project) - %li - = link_to new_namespace_project_merge_request_path(project.namespace, project) do - = project.name_with_namespace + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request" = render 'shared/issuable/filter', type: :merge_requests diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml index 9aea75e50db..94ff259a338 100644 --- a/app/views/dashboard/milestones/index.html.haml +++ b/app/views/dashboard/milestones/index.html.haml @@ -3,18 +3,7 @@ .project-issuable-filter .controls - - if @projects.any? { |project| can?(current_user, :admin_milestone, project) } - .dropdown.inline - %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-plus - New Milestone - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - @projects.each do |project| - - if can?(current_user, :admin_milestone, project) - %li - = link_to new_namespace_project_milestone_path(project.namespace, project) do - = project.name_with_namespace + = render 'shared/new_project_item_select', path: 'milestones/new', label: "New Milestone" = render 'shared/milestones_filter' diff --git a/app/views/groups/issues.html.haml b/app/views/groups/issues.html.haml index 5a9739a0cda..90ade1e1680 100644 --- a/app/views/groups/issues.html.haml +++ b/app/views/groups/issues.html.haml @@ -12,18 +12,7 @@ = link_to issues_group_url(@group, format: :atom, private_token: current_user.private_token), class: 'btn' do %i.fa.fa-rss - - if @projects.any? { |project| can?(current_user, :create_issue, project) } - .dropdown.inline.prepend-left-10 - %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-plus - New Issue - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - @projects.each do |project| - - if can?(current_user, :create_issue, project) - %li - = link_to new_namespace_project_issue_path(project.namespace, project) do - = project.name_with_namespace + = render 'shared/new_project_item_select', path: 'issues/new', label: "New Issue" = render 'shared/issuable/filter', type: :issues diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml index 95c503a3afa..f662f5a8c17 100644 --- a/app/views/groups/merge_requests.html.haml +++ b/app/views/groups/merge_requests.html.haml @@ -3,18 +3,7 @@ .project-issuable-filter .controls - - if @projects.any? { |project| can?(current_user, :create_merge_request, project) } - .dropdown.inline - %button.dropdown-toggle.btn.btn-new{type: 'button', 'data-toggle' => 'dropdown'} - %i.fa.fa-plus - New Merge Request - %b.caret - %ul.dropdown-menu.dropdown-menu-align-right - - @projects.each do |project| - - if can?(current_user, :create_merge_request, project) - %li - = link_to new_namespace_project_merge_request_path(project.namespace, project) do - = project.name_with_namespace + = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request" = render 'shared/issuable/filter', type: :merge_requests diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml new file mode 100644 index 00000000000..d7243b2d518 --- /dev/null +++ b/app/views/shared/_new_project_item_select.html.haml @@ -0,0 +1,20 @@ +- if @projects.any? + .prepend-left-10.new-project-item-select-holder + = project_select_tag :project_path, class: "new-project-item-select" + %a.btn.btn-new.new-project-item-select-button + = icon('plus') + = local_assigns[:label] + %b.caret + + :javascript + $('.new-project-item-select-button').on('click', function() { + $('.new-project-item-select').select2('open'); + }); + + var relativePath = '#{local_assigns[:path]}'; + + $('.new-project-item-select').on('click', function() { + window.location = $(this).val() + '/' + relativePath; + }); + + new ProjectSelect() -- cgit v1.2.1 From 6fb90a2ca37d2735cda3b904139af1d487bcf125 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 7 Dec 2015 17:24:15 +0100 Subject: Include groups in dashboard "New Milestone" select. --- app/assets/javascripts/project_select.js.coffee | 25 ++++++++++++++++------ app/views/dashboard/milestones/index.html.haml | 2 +- .../shared/_new_project_item_select.html.haml | 2 +- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/project_select.js.coffee b/app/assets/javascripts/project_select.js.coffee index 43b18a3da59..0ae274f3363 100644 --- a/app/assets/javascripts/project_select.js.coffee +++ b/app/assets/javascripts/project_select.js.coffee @@ -2,25 +2,38 @@ class @ProjectSelect constructor: -> $('.ajax-project-select').each (i, select) -> @groupId = $(select).data('group-id') + @includeGroups = $(select).data('include-groups') + + placeholder = "Search for project" + placeholder += " or group" if @includeGroups $(select).select2 - placeholder: "Search for project" - multiple: $(select).hasClass('multiselect') + placeholder: placeholder minimumInputLength: 0 query: (query) => - callback = (projects) -> + finalCallback = (projects) -> data = { results: projects } query.callback(data) + if @includeGroups + projectsCallback = (projects) -> + groupsCallback = (groups) -> + data = groups.concat(projects) + finalCallback(data) + + Api.groups query.term, false, groupsCallback + else + projectsCallback = finalCallback + if @groupId - Api.groupProjects @groupId, query.term, callback + Api.groupProjects @groupId, query.term, projectsCallback else - Api.projects query.term, callback + Api.projects query.term, projectsCallback id: (project) -> project.web_url text: (project) -> - project.name_with_namespace + project.name_with_namespace || project.name dropdownCssClass: "ajax-project-dropdown" diff --git a/app/views/dashboard/milestones/index.html.haml b/app/views/dashboard/milestones/index.html.haml index 94ff259a338..bec1692a4de 100644 --- a/app/views/dashboard/milestones/index.html.haml +++ b/app/views/dashboard/milestones/index.html.haml @@ -3,7 +3,7 @@ .project-issuable-filter .controls - = render 'shared/new_project_item_select', path: 'milestones/new', label: "New Milestone" + = render 'shared/new_project_item_select', path: 'milestones/new', label: "New Milestone", include_groups: true = render 'shared/milestones_filter' diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml index d7243b2d518..c4431d66927 100644 --- a/app/views/shared/_new_project_item_select.html.haml +++ b/app/views/shared/_new_project_item_select.html.haml @@ -1,6 +1,6 @@ - if @projects.any? .prepend-left-10.new-project-item-select-holder - = project_select_tag :project_path, class: "new-project-item-select" + = project_select_tag :project_path, class: "new-project-item-select", data: { include_groups: local_assigns[:include_groups] } %a.btn.btn-new.new-project-item-select-button = icon('plus') = local_assigns[:label] -- cgit v1.2.1 From 0c3f70acf4838194f517c02874b8423303c21b48 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Tue, 8 Dec 2015 13:34:09 +0100 Subject: Add API group projects specs --- spec/requests/api/groups_spec.rb | 59 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 13cced81875..4cfa49d1566 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -10,6 +10,8 @@ describe API::API, api: true do let(:avatar_file_path) { File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') } let!(:group1) { create(:group, avatar: File.open(avatar_file_path)) } let!(:group2) { create(:group) } + let!(:project1) { create(:project, namespace: group1) } + let!(:project2) { create(:project, namespace: group2) } before do group1.add_owner(user1) @@ -67,7 +69,7 @@ describe API::API, api: true do it "should return any existing group" do get api("/groups/#{group2.id}", admin) expect(response.status).to eq(200) - json_response['name'] == group2.name + expect(json_response['name']).to eq(group2.name) end it "should not return a non existing group" do @@ -80,7 +82,7 @@ describe API::API, api: true do it 'should return any existing group' do get api("/groups/#{group1.path}", admin) expect(response.status).to eq(200) - json_response['name'] == group2.name + expect(json_response['name']).to eq(group1.name) end it 'should not return a non existing group' do @@ -95,6 +97,59 @@ describe API::API, api: true do end end + describe "GET /groups/:id/projects" do + context "when authenticated as user" do + it "should return the group's projects" do + get api("/groups/#{group1.id}/projects", user1) + expect(response.status).to eq(200) + expect(json_response.length).to eq(1) + expect(json_response.first['name']).to eq(project1.name) + end + + it "should not return a non existing group" do + get api("/groups/1328/projects", user1) + expect(response.status).to eq(404) + end + + it "should not return a group not attached to user1" do + get api("/groups/#{group2.id}/projects", user1) + expect(response.status).to eq(403) + end + end + + context "when authenticated as admin" do + it "should return any existing group" do + get api("/groups/#{group2.id}/projects", admin) + expect(response.status).to eq(200) + expect(json_response.length).to eq(1) + expect(json_response.first['name']).to eq(project2.name) + end + + it "should not return a non existing group" do + get api("/groups/1328/projects", admin) + expect(response.status).to eq(404) + end + end + + context 'when using group path in URL' do + it 'should return any existing group' do + get api("/groups/#{group1.path}/projects", admin) + expect(response.status).to eq(200) + expect(json_response.first['name']).to eq(project1.name) + end + + it 'should not return a non existing group' do + get api('/groups/unknown/projects', admin) + expect(response.status).to eq(404) + end + + it 'should not return a group not attached to user1' do + get api("/groups/#{group2.path}/projects", user1) + expect(response.status).to eq(403) + end + end + end + describe "POST /groups" do context "when authenticated as user without group permissions" do it "should not create group" do -- cgit v1.2.1