Merge pull request #10206 from opf/feature/41138/index-action-team-planner
[41138] Add index action to team plannerpull/10231/head
commit
9e0c47c171
@ -0,0 +1,76 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
|
||||||
|
#-- copyright |
||||||
|
# OpenProject is an open source project management software. |
||||||
|
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License version 3. |
||||||
|
# |
||||||
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||||
|
# Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License |
||||||
|
# as published by the Free Software Foundation; either version 2 |
||||||
|
# of the License, or (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
# |
||||||
|
# See COPYRIGHT and LICENSE files for more details. |
||||||
|
#++ |
||||||
|
|
||||||
|
module TeamPlanner |
||||||
|
class RowCell < ::RowCell |
||||||
|
include ApplicationHelper |
||||||
|
include ::Redmine::I18n |
||||||
|
|
||||||
|
def query |
||||||
|
model |
||||||
|
end |
||||||
|
|
||||||
|
delegate :project, to: :query |
||||||
|
|
||||||
|
def name |
||||||
|
link_to query.name, project_team_planner_path(project, query.id) |
||||||
|
end |
||||||
|
|
||||||
|
def created_at |
||||||
|
format_time(query.created_at) |
||||||
|
end |
||||||
|
|
||||||
|
def assignees |
||||||
|
query |
||||||
|
.filters |
||||||
|
.detect { |filter| filter.name == :assigned_to_id } |
||||||
|
.then { |filter| filter ? filter.values.count : 0 } |
||||||
|
end |
||||||
|
|
||||||
|
def button_links |
||||||
|
[delete_link].compact |
||||||
|
end |
||||||
|
|
||||||
|
def delete_link |
||||||
|
if table.current_user.allowed_to?(:manage_team_planner, project) |
||||||
|
link_to( |
||||||
|
op_icon('icon icon-delete'), |
||||||
|
project_team_planner_path(project, query.id), |
||||||
|
method: :delete, |
||||||
|
data: { |
||||||
|
confirm: I18n.t(:text_are_you_sure), |
||||||
|
'qa-selector': "team-planner-remove-#{query.id}" |
||||||
|
}, |
||||||
|
title: t(:button_delete) |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,48 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
|
||||||
|
#-- copyright |
||||||
|
# OpenProject is an open source project management software. |
||||||
|
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License version 3. |
||||||
|
# |
||||||
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||||
|
# Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License |
||||||
|
# as published by the Free Software Foundation; either version 2 |
||||||
|
# of the License, or (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
# |
||||||
|
# See COPYRIGHT and LICENSE files for more details. |
||||||
|
#++ |
||||||
|
|
||||||
|
module TeamPlanner |
||||||
|
class TableCell < ::TableCell |
||||||
|
options :current_user |
||||||
|
columns :name, :assignees, :created_at |
||||||
|
|
||||||
|
def sortable? |
||||||
|
false |
||||||
|
end |
||||||
|
|
||||||
|
def headers |
||||||
|
[ |
||||||
|
['name', { caption: I18n.t(:label_name) }], |
||||||
|
['assignees', { caption: I18n.t('team_planner.label_assignees') }], |
||||||
|
['created_at', { caption: I18n.t('attributes.created_at') }] |
||||||
|
] |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1 +1,16 @@ |
|||||||
<% html_title(t('team_planner.label_team_planner')) -%> |
<% html_title(t('team_planner.label_team_planner_plural')) -%> |
||||||
|
|
||||||
|
<%= toolbar title: t(:'team_planner.label_team_planner_plural') do %> |
||||||
|
<% if current_user.allowed_to?(:manage_team_planner, @project) %> |
||||||
|
<li class="toolbar-item"> |
||||||
|
<%= link_to new_project_team_planners_path(@project), |
||||||
|
class: 'button -alt-highlight', |
||||||
|
title: t(:button_create) do %> |
||||||
|
<%= op_icon('button--icon icon-add') %> |
||||||
|
<span class="button--text"><%= t(:button_create) %></span> |
||||||
|
<% end %> |
||||||
|
</li> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
|
||||||
|
<%= rails_cell ::TeamPlanner::TableCell, @views, current_user: current_user %> |
@ -0,0 +1 @@ |
|||||||
|
<% html_title(t('team_planner.label_team_planner')) -%> |
@ -1,6 +1,13 @@ |
|||||||
OpenProject::Application.routes.draw do |
OpenProject::Application.routes.draw do |
||||||
scope 'projects/:project_id', as: 'project' do |
scope 'projects/:project_id', as: 'project' do |
||||||
get '/team_planner/upsale', to: 'team_planner/team_planner#upsale', as: :team_planner_upsale |
resources :team_planners, |
||||||
get '/team_planner(/*state)', to: 'team_planner/team_planner#index', as: :team_planner |
controller: 'team_planner/team_planner', |
||||||
|
only: %i[index destroy], |
||||||
|
as: :team_planners do |
||||||
|
get :upsale, to: 'team_planner/team_planner#upsale', on: :collection, as: :upsale |
||||||
|
|
||||||
|
get '/new' => 'team_planner/team_planner#show', on: :collection, as: 'new' |
||||||
|
get '(/*state)' => 'team_planner/team_planner#show', on: :member, as: '' |
||||||
|
end |
||||||
end |
end |
||||||
end |
end |
||||||
|
@ -0,0 +1,108 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
|
||||||
|
#-- copyright |
||||||
|
# OpenProject is an open source project management software. |
||||||
|
# Copyright (C) 2012-2021 the OpenProject GmbH |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License version 3. |
||||||
|
# |
||||||
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||||
|
# Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License |
||||||
|
# as published by the Free Software Foundation; either version 2 |
||||||
|
# of the License, or (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
# |
||||||
|
# See COPYRIGHT and LICENSE files for more details. |
||||||
|
#++ |
||||||
|
|
||||||
|
require 'spec_helper' |
||||||
|
require_relative './shared_context' |
||||||
|
|
||||||
|
describe 'Team planner index', type: :feature, js: true, with_ee: %i[team_planner_view] do |
||||||
|
include_context 'with team planner full access' |
||||||
|
|
||||||
|
let(:current_user) { user } |
||||||
|
let(:query) { create :query, user: user, project: project, public: true } |
||||||
|
let(:team_plan) { create :view_team_planner, query: query } |
||||||
|
|
||||||
|
before do |
||||||
|
login_as current_user |
||||||
|
team_plan |
||||||
|
visit project_team_planners_path(project) |
||||||
|
end |
||||||
|
|
||||||
|
context 'with no view' do |
||||||
|
let(:team_plan) { nil } |
||||||
|
|
||||||
|
it 'shows an index action' do |
||||||
|
expect(page).to have_text 'There is currently nothing to display.' |
||||||
|
expect(page).to have_selector '.button', text: 'Create' |
||||||
|
end |
||||||
|
|
||||||
|
it 'can create an action through the sidebar' do |
||||||
|
click_on 'Create new planner' |
||||||
|
|
||||||
|
team_planner.expect_title |
||||||
|
|
||||||
|
# Also works from the frontend |
||||||
|
click_on 'Create new planner' |
||||||
|
|
||||||
|
team_planner.expect_no_toaster |
||||||
|
team_planner.expect_title |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context 'with an existing view' do |
||||||
|
it 'shows that view' do |
||||||
|
expect(page).to have_selector 'td', text: query.name |
||||||
|
expect(page).to have_selector "[data-qa-selector='team-planner-remove-#{query.id}']" |
||||||
|
end |
||||||
|
|
||||||
|
context 'with another user with limited access' do |
||||||
|
let(:current_user) do |
||||||
|
create :user, |
||||||
|
firstname: 'Bernd', |
||||||
|
member_in_project: project, |
||||||
|
member_with_permissions: %w[view_work_packages view_team_planner] |
||||||
|
end |
||||||
|
|
||||||
|
it 'does not show the create button' do |
||||||
|
expect(page).to have_selector 'td', text: query.name |
||||||
|
|
||||||
|
# Does not show the delete |
||||||
|
expect(page).to have_no_selector "[data-qa-selector='team-planner-remove-#{query.id}']" |
||||||
|
|
||||||
|
# Does not show the create button |
||||||
|
expect(page).to have_no_selector '.button', text: 'Create' |
||||||
|
end |
||||||
|
|
||||||
|
context 'when the view is non-public' do |
||||||
|
let(:query) { create :query, user: user, project: project, public: false } |
||||||
|
|
||||||
|
it 'does not show a non-public view' do |
||||||
|
expect(page).to have_text 'There is currently nothing to display.' |
||||||
|
expect(page).to have_no_selector 'td', text: query.name |
||||||
|
|
||||||
|
# Does not show the delete |
||||||
|
expect(page).to have_no_selector "[data-qa-selector='team-planner-remove-#{query.id}']" |
||||||
|
|
||||||
|
# Does not show the create button |
||||||
|
expect(page).to have_no_selector '.button', text: 'Create' |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,139 +0,0 @@ |
|||||||
#-- encoding: UTF-8 |
|
||||||
|
|
||||||
#-- copyright |
|
||||||
# OpenProject is an open source project management software. |
|
||||||
# Copyright (C) 2012-2021 the OpenProject GmbH |
|
||||||
# |
|
||||||
# This program is free software; you can redistribute it and/or |
|
||||||
# modify it under the terms of the GNU General Public License version 3. |
|
||||||
# |
|
||||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
|
||||||
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
||||||
# Copyright (C) 2010-2013 the ChiliProject Team |
|
||||||
# |
|
||||||
# This program is free software; you can redistribute it and/or |
|
||||||
# modify it under the terms of the GNU General Public License |
|
||||||
# as published by the Free Software Foundation; either version 2 |
|
||||||
# of the License, or (at your option) any later version. |
|
||||||
# |
|
||||||
# This program is distributed in the hope that it will be useful, |
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
# GNU General Public License for more details. |
|
||||||
# |
|
||||||
# You should have received a copy of the GNU General Public License |
|
||||||
# along with this program; if not, write to the Free Software |
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
||||||
# |
|
||||||
# See COPYRIGHT and LICENSE files for more details. |
|
||||||
#++ |
|
||||||
|
|
||||||
require 'spec_helper' |
|
||||||
require_relative './shared_context' |
|
||||||
|
|
||||||
describe 'Team planner', type: :feature, js: true, with_ee: %i[team_planner_view] do |
|
||||||
include_context 'with team planner full access' |
|
||||||
|
|
||||||
# We need a default status |
|
||||||
shared_let(:default_status) { create :default_status } |
|
||||||
|
|
||||||
it 'redirects to the first active plan' do |
|
||||||
visit project_path(project) |
|
||||||
|
|
||||||
within '#main-menu' do |
|
||||||
click_link 'Team planner' |
|
||||||
end |
|
||||||
|
|
||||||
team_planner.expect_title |
|
||||||
team_planner.save_as 'Foobar' |
|
||||||
|
|
||||||
visit project_path(project) |
|
||||||
|
|
||||||
within '#main-menu' do |
|
||||||
click_link 'Team planner' |
|
||||||
end |
|
||||||
|
|
||||||
query = View.where(type: 'team_planner').last.query |
|
||||||
expect(query.name).to eq 'Foobar' |
|
||||||
|
|
||||||
expect(page).to have_current_path /query_id=#{query.id}/ |
|
||||||
end |
|
||||||
|
|
||||||
shared_examples 'loads a new team planner' do |
|
||||||
it do |
|
||||||
visit project_path(project) |
|
||||||
|
|
||||||
within '#main-menu' do |
|
||||||
click_link 'Team planner' |
|
||||||
end |
|
||||||
|
|
||||||
team_planner.expect_title |
|
||||||
expect(page).to have_no_current_path /query_id=#{query.id}/ |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
shared_examples 'loads the query view' do |
|
||||||
it do |
|
||||||
visit project_path(project) |
|
||||||
|
|
||||||
within '#main-menu' do |
|
||||||
click_link 'Team planner' |
|
||||||
end |
|
||||||
|
|
||||||
team_planner.expect_title query.name |
|
||||||
expect(page).to have_current_path /query_id=#{query.id}/ |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context 'with an existing saved plan' do |
|
||||||
shared_let(:other_user) { create :user } |
|
||||||
let!(:view) { create :view_team_planner, query: query } |
|
||||||
|
|
||||||
context 'when the query is from another user and private' do |
|
||||||
let!(:query) { create :query, user: other_user, project: project, public: false } |
|
||||||
|
|
||||||
it_behaves_like 'loads a new team planner' |
|
||||||
end |
|
||||||
|
|
||||||
context 'when the query is from another user and public' do |
|
||||||
let!(:query) { create :query, user: other_user, project: project, public: true } |
|
||||||
|
|
||||||
it_behaves_like 'loads the query view' |
|
||||||
end |
|
||||||
|
|
||||||
context 'when the query is from the same user and private' do |
|
||||||
let!(:query) { create :query, user: user, project: project, public: false } |
|
||||||
|
|
||||||
it_behaves_like 'loads the query view' |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context 'with an existing plan and creating a new one' do |
|
||||||
let!(:view) { create :view_team_planner, query: query } |
|
||||||
let!(:query) { create :query, user: user, project: project, public: true } |
|
||||||
|
|
||||||
it 'allows to reload with query props active' do |
|
||||||
team_planner.visit! |
|
||||||
|
|
||||||
team_planner.expect_assignee(user, present: false) |
|
||||||
|
|
||||||
click_on 'Create new planner' |
|
||||||
team_planner.expect_assignee(user, present: false) |
|
||||||
|
|
||||||
retry_block do |
|
||||||
team_planner.click_add_user |
|
||||||
page.find('[data-qa-selector="tp-add-assignee"] input') |
|
||||||
team_planner.select_user_to_add user.name |
|
||||||
end |
|
||||||
|
|
||||||
team_planner.expect_assignee(user) |
|
||||||
|
|
||||||
page.driver.refresh |
|
||||||
|
|
||||||
expect(page).to have_current_path /query_props=/ |
|
||||||
expect(page).to have_current_path /cview=/ |
|
||||||
|
|
||||||
team_planner.expect_assignee(user) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,56 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
|
||||||
|
#-- copyright |
||||||
|
# OpenProject is an open source project management software. |
||||||
|
# Copyright (C) 2012-2021 the OpenProject GmbH |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License version 3. |
||||||
|
# |
||||||
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||||
|
# Copyright (C) 2006-2013 Jean-Philippe Lang |
||||||
|
# Copyright (C) 2010-2013 the ChiliProject Team |
||||||
|
# |
||||||
|
# This program is free software; you can redistribute it and/or |
||||||
|
# modify it under the terms of the GNU General Public License |
||||||
|
# as published by the Free Software Foundation; either version 2 |
||||||
|
# of the License, or (at your option) any later version. |
||||||
|
# |
||||||
|
# This program is distributed in the hope that it will be useful, |
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
# GNU General Public License for more details. |
||||||
|
# |
||||||
|
# You should have received a copy of the GNU General Public License |
||||||
|
# along with this program; if not, write to the Free Software |
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||||
|
# |
||||||
|
# See COPYRIGHT and LICENSE files for more details. |
||||||
|
#++ |
||||||
|
|
||||||
|
require 'spec_helper' |
||||||
|
require_relative './shared_context' |
||||||
|
|
||||||
|
describe 'Team planner index', type: :feature, js: true do |
||||||
|
include_context 'with team planner full access' |
||||||
|
|
||||||
|
let(:current_user) { user } |
||||||
|
|
||||||
|
before do |
||||||
|
login_as current_user |
||||||
|
end |
||||||
|
|
||||||
|
it 'redirects routes to upsale' do |
||||||
|
visit project_team_planners_path(project) |
||||||
|
|
||||||
|
expect(page).to have_text 'Upgrade now' |
||||||
|
|
||||||
|
click_on 'Create new planner' |
||||||
|
|
||||||
|
expect(page).to have_text 'Upgrade now' |
||||||
|
|
||||||
|
visit project_team_planner_path(project, id: 'new') |
||||||
|
|
||||||
|
expect(page).to have_text 'Upgrade now' |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue