From f3381c827e51a67db5f1292759c490cfa271e7b8 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 25 Oct 2013 10:18:34 +0200 Subject: [PATCH 01/14] Ensure there is a main item when the wiki page with the last main item is deleted (WIP) TODO open a dialogue where the user can select a wiki page for main menu item respawn - see 'change parent wiki page' --- app/models/wiki_menu_item.rb | 14 +++++++- app/models/wiki_page.rb | 4 +++ .../step_definitions/wiki_menu_item_steps.rb | 32 +++++++++++++++++++ features/wiki/wiki_index.feature | 4 --- .../wiki_menu_items/wiki_menu_items.feature | 19 +++++++++-- 5 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 features/step_definitions/wiki_menu_item_steps.rb diff --git a/app/models/wiki_menu_item.rb b/app/models/wiki_menu_item.rb index 3accc221b6..ac7c678eed 100644 --- a/app/models/wiki_menu_item.rb +++ b/app/models/wiki_menu_item.rb @@ -39,7 +39,7 @@ class WikiMenuItem < ActiveRecord::Base :order => 'id ASC'} } - attr_accessible :name, :title + attr_accessible :name, :title, :wiki_id validates_presence_of :title validates_format_of :title, :with => /\A[^,\.\/\?\;\|\:]*\z/ @@ -47,6 +47,8 @@ class WikiMenuItem < ActiveRecord::Base validates_presence_of :name + before_destroy :ensure_presence_of_another_main_item + def item_class title.dasherize end @@ -84,4 +86,14 @@ class WikiMenuItem < ActiveRecord::Base def is_sub_item? !parent_id.nil? end + + def is_only_main_item? + self.class.main_items(wiki.id) == [self] + end + + def ensure_presence_of_another_main_item + if is_only_main_item? && wiki_page = WikiPage.main_pages(wiki.id).reject{|page| page.title == title}.first + self.class.find_or_create_by_wiki_id_and_title(wiki.id, wiki_page.title, name: wiki_page.title) + end + end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index e6ac96ae48..4735c73044 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -67,6 +67,10 @@ class WikiPage < ActiveRecord::Base :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id" } + scope :main_pages, lambda {|wiki_id| + { conditions: {wiki_id: wiki_id, parent_id: nil} } + } + # Wiki pages that are protected by default DEFAULT_PROTECTED_PAGES = %w(sidebar) diff --git a/features/step_definitions/wiki_menu_item_steps.rb b/features/step_definitions/wiki_menu_item_steps.rb new file mode 100644 index 0000000000..1889992138 --- /dev/null +++ b/features/step_definitions/wiki_menu_item_steps.rb @@ -0,0 +1,32 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2013 the OpenProject Foundation (OPF) +# +# 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 doc/COPYRIGHT.rdoc for more details. +#++ + +Given /^the wiki menu item of the wiki page "(.*?)" of project "(.*?)" has been deleted$/ do |item_name, project_name| + project = Project.find_by_name project_name + WikiPage.where(title: item_name, wiki_id: project.wiki.id).first.delete_wiki_menu_item +end diff --git a/features/wiki/wiki_index.feature b/features/wiki/wiki_index.feature index a2321c029a..78816d1d4f 100644 --- a/features/wiki/wiki_index.feature +++ b/features/wiki/wiki_index.feature @@ -64,7 +64,3 @@ Feature: Viewing the wiki index page When I go to the wiki index page below the "ParentWikiPage" page of the project called "project1" Then I should see "Index by title" within "#content" And there should be no menu item selected - - - - diff --git a/features/wiki_menu_items/wiki_menu_items.feature b/features/wiki_menu_items/wiki_menu_items.feature index f14184a15c..80ad418a64 100644 --- a/features/wiki_menu_items/wiki_menu_items.feature +++ b/features/wiki_menu_items/wiki_menu_items.feature @@ -33,9 +33,10 @@ Feature: Wiki menu items | identifier | awesome-project | And there is a role "member" And the role "member" may have the following rights: - | view_wiki_pages | - | edit_wiki_pages | - | manage_wiki_menu | + | view_wiki_pages | + | edit_wiki_pages | + | delete_wiki_pages | + | manage_wiki_menu | And there is 1 user with the following: | login | bob | And the user "bob" is a "member" in the project "Awesome Project" @@ -116,3 +117,15 @@ Feature: Wiki menu items And I choose "Do not show this wikipage in project navigation" And I press "Save" Then I should not see "Wiki" within "#main-menu" + + @javascript + Scenario: When I delete the last wiki page with a menu item there should be a menu item Wiki linking to the wiki index page + Given the project "Awesome Project" has a wiki menu item with the following: + | title | AwesomePage | + | name | AwesomePage | + And the wiki menu item of the wiki page "Wiki" of project "Awesome Project" has been deleted + When I go to the wiki page "AwesomePage" for the project called "Awesome Project" + And I click on "More functions" + And I click on "Delete" + And I confirm popups + Then I should see "Wiki" within "#main-menu" From 44d66f4e68b6dec57cdce488b522b8a454e0eeca Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 25 Oct 2013 10:22:04 +0200 Subject: [PATCH 02/14] Make wiki_menu_items#update more readable --- app/controllers/wiki_menu_items_controller.rb | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index ee65450409..1c8704f133 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -58,18 +58,7 @@ class WikiMenuItemsController < ApplicationController @wiki_menu_item.parent_id = parent_wiki_menu_item elsif wiki_menu_setting == 'main_item' @wiki_menu_item.parent_id = nil - - if params[:wiki_menu_item][:new_wiki_page] == "1" - @wiki_menu_item.new_wiki_page = true - elsif params[:wiki_menu_item][:new_wiki_page] == "0" - @wiki_menu_item.new_wiki_page = false - end - - if params[:wiki_menu_item][:index_page] == "1" - @wiki_menu_item.index_page = true - elsif params[:wiki_menu_item][:index_page] == "0" - @wiki_menu_item.index_page = false - end + assign_wiki_menu_item_params @wiki_menu_item end end @@ -102,4 +91,18 @@ class WikiMenuItemsController < ApplicationController @page.nearest_parent_menu_item(:is_main_item => true).try :id end end + + def assign_wiki_menu_item_params(menu_item) + if params[:wiki_menu_item][:new_wiki_page] == "1" + menu_item.new_wiki_page = true + elsif params[:wiki_menu_item][:new_wiki_page] == "0" + menu_item.new_wiki_page = false + end + + if params[:wiki_menu_item][:index_page] == "1" + menu_item.index_page = true + elsif params[:wiki_menu_item][:index_page] == "0" + menu_item.index_page = false + end + end end From 222874af95b9ab5af50b0eb755d2133ecfeedb89 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Fri, 25 Oct 2013 13:19:29 +0200 Subject: [PATCH 03/14] Disable wiki module when last wiki page is destroyed --- app/models/project.rb | 6 ++++++ app/models/wiki_page.rb | 7 +++++++ spec/models/wiki_page_spec.rb | 31 +++++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index aec2b2fd15..628c2338d6 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -718,6 +718,12 @@ class Project < ActiveRecord::Base enabled_modules.collect(&:name) end + def disable_module(module_name) + if module_enabled? module_name + self.enabled_module_names = enabled_module_names - [module_name.to_s] + end + end + safe_attributes 'name', 'description', 'summary', diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 4735c73044..f04c161aec 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -75,6 +75,9 @@ class WikiPage < ActiveRecord::Base DEFAULT_PROTECTED_PAGES = %w(sidebar) after_destroy :delete_wiki_menu_item + after_destroy do |wiki_page| + wiki_page.wiki.project.disable_module(:wiki) if is_only_wiki_page? + end def check_and_mark_as_protected if new_record? && DEFAULT_PROTECTED_PAGES.include?(title.to_s.downcase) @@ -253,6 +256,10 @@ class WikiPage < ActiveRecord::Base def validate_same_project errors.add(:parent_title, :not_same_project) if parent && (parent.wiki_id != wiki_id) end + + def is_only_wiki_page? + wiki.pages.reject {|page| page == self}.empty? + end end class WikiDiff < Redmine::Helpers::Diff diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 110b8c41a0..70905b4667 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -29,9 +29,11 @@ require 'spec_helper' describe WikiPage do + let(:project) { FactoryGirl.create(:project).reload } # a wiki is created for project, but the object doesn't know of it (FIXME?) + let(:wiki) { project.wiki } + let(:wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } + describe '#nearest_parent_menu_item' do - let(:wiki_page) { FactoryGirl.create(:wiki_page) } - let(:wiki) { wiki_page.wiki } let!(:wiki_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => wiki_page.title) } let(:child_page) { FactoryGirl.create(:wiki_page, :parent => wiki_page, :wiki => wiki) } let!(:child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => child_page.title, :parent => wiki_page_wiki_menu_item) } @@ -50,4 +52,29 @@ describe WikiPage do end end end + + describe '#destroy' do + context 'when the only wiki page is destroyed' do + before do + wiki_page.destroy + project.reload + end + + it 'deactivates the wiki module' do + project.module_enabled?(:wiki).should be_false + end + end + + context 'when one of two wiki pages is destroyed' do + before do + another_wiki_page = FactoryGirl.create(:wiki_page, :wiki => wiki) + wiki_page.destroy + project.reload + end + + it 'does not deactivate the wiki module' do + project.module_enabled?(:wiki).should be_true + end + end + end end From 72693bdcc5f483ac0195b64ea89fd5c7689366fb Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 10:21:31 +0100 Subject: [PATCH 04/14] Redirect to projects#show after the last wiki page has been deleted --- app/controllers/wiki_controller.rb | 3 ++- spec/controllers/wiki_controller_spec.rb | 28 ++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 1aeb90c489..461715ba17 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -303,7 +303,8 @@ class WikiController < ApplicationController end end @page.destroy - redirect_to :action => 'index', :project_id => @project + + redirect_to @wiki.pages.any? ? {:action => 'index', :project_id => @project} : project_path(@project) end # Export wiki to a single html file diff --git a/spec/controllers/wiki_controller_spec.rb b/spec/controllers/wiki_controller_spec.rb index 0bddfd7808..fb5067216f 100644 --- a/spec/controllers/wiki_controller_spec.rb +++ b/spec/controllers/wiki_controller_spec.rb @@ -49,7 +49,7 @@ describe WikiController do # creating pages @existing_page = FactoryGirl.create(:wiki_page, :wiki_id => @project.wiki.id, - :title => 'ExisitingPage') + :title => 'ExistingPage') # creating page contents FactoryGirl.create(:wiki_content, :page_id => @existing_page.id, @@ -187,7 +187,31 @@ describe WikiController do end end end - end + + describe 'destroy' do + describe 'successful action' do + context 'when it is not the only wiki page' do + let(:wiki) { @project.wiki } + + before do + another_wiki_page = FactoryGirl.create :wiki_page, wiki: wiki + end + + it 'redirects to wiki#index' do + delete :destroy, project_id: @project, id: @existing_page + response.should redirect_to action: 'index', project_id: @project + end + end + + context 'when it is the only wiki page' do + it 'redirects to projects#show' do + delete :destroy, project_id: @project, id: @existing_page + response.should redirect_to project_path(@project) + end + end + end + end + end # describe 'actions' describe 'view related stuff' do render_views From d779e8bae802971d28dda2807572cc6f954a82b3 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 10:51:57 +0100 Subject: [PATCH 05/14] Destroy wiki after its last page has been deactivated and the wiki module has been successfully deactivated... ... This ensures a new menu item is spawned on reactivation of the wiki module. Moreover this is the raw state of a project without enabled wiki module. --- app/models/wiki_page.rb | 2 +- spec/models/wiki_page_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index f04c161aec..2c9360d0ac 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -76,7 +76,7 @@ class WikiPage < ActiveRecord::Base after_destroy :delete_wiki_menu_item after_destroy do |wiki_page| - wiki_page.wiki.project.disable_module(:wiki) if is_only_wiki_page? + wiki_page.wiki.project.disable_module(:wiki) and wiki_page.wiki.destroy if is_only_wiki_page? end def check_and_mark_as_protected diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 70905b4667..985c23fdeb 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -63,6 +63,10 @@ describe WikiPage do it 'deactivates the wiki module' do project.module_enabled?(:wiki).should be_false end + + it 'destroys the project wiki' do + project.wiki.should be_nil + end end context 'when one of two wiki pages is destroyed' do @@ -75,6 +79,10 @@ describe WikiPage do it 'does not deactivate the wiki module' do project.module_enabled?(:wiki).should be_true end + + it 'does not destroy the project wiki' do + project.wiki.should be_present + end end end end From 72c427dc597047777c4e38107a00b83fdd70f833 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 16:19:52 +0100 Subject: [PATCH 06/14] Add action for main wiki menu item replacement --- app/controllers/wiki_menu_items_controller.rb | 19 ++++++++ .../replace_main_menu_item.html.erb | 43 +++++++++++++++++++ config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/routes.rb | 2 + lib/redmine.rb | 1 + 6 files changed, 67 insertions(+) create mode 100644 app/views/wiki_menu_items/replace_main_menu_item.html.erb diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index 1c8704f133..5f009e74cb 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -72,6 +72,25 @@ class WikiMenuItemsController < ApplicationController end end + def replace_main_menu_item + wiki_page_title = params[:id] + @possible_wiki_pages = @project.wiki.pages.all(:include => :parent).reject{|page| page.title == wiki_page_title || page.menu_item.present? && page.menu_item.is_main_item?} + end + + def create_main_menu_item + page = WikiPage.find params[:wiki_page][:id] + wiki = @project.wiki + + menu_item = if item = page.menu_item + item.tap {|item| item.parent_id = nil} + else + wiki.wiki_menu_items.build(title: page.title, name: page.pretty_title) + end + menu_item.save + + redirect_to project_wiki_path(@project, wiki.start_page) + end + private def get_data_from_params(params) diff --git a/app/views/wiki_menu_items/replace_main_menu_item.html.erb b/app/views/wiki_menu_items/replace_main_menu_item.html.erb new file mode 100644 index 0000000000..68501fd4b2 --- /dev/null +++ b/app/views/wiki_menu_items/replace_main_menu_item.html.erb @@ -0,0 +1,43 @@ +<%#-- copyright +OpenProject is a project management system. +Copyright (C) 2012-2013 the OpenProject Foundation (OPF) + +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 doc/COPYRIGHT.rdoc for more details. + +++#%> + +

<%= t(:label_select_main_menu_item) %>

+ +<%= labelled_tabular_form_for :wiki_page, url: { action: 'create_main_menu_item' } do |f| %> +
+

+ <%= f.select :id, + "".html_safe + wiki_page_options_for_select(@possible_wiki_pages), + {label: WikiPage.human_attribute_name(:title) }, + {size: "#{@possible_wiki_pages.size + 1}", class: "main-menu-item-select"} %> +

+ +
+ <%= submit_tag t(:button_save) %> +<% end %> diff --git a/config/locales/de.yml b/config/locales/de.yml index a151b4a256..04220175de 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -601,6 +601,7 @@ de: label_calendar: "Kalender" label_calendar_show: "Kalender anzeigen" label_category: "Kategorie" + label_select_main_menu_item: Neuen Hauptmenüpunkt auwählen label_change_plural: "Änderungen" label_change_properties: "Eigenschaften ändern" label_change_status: "Statuswechsel" diff --git a/config/locales/en.yml b/config/locales/en.yml index 1daadea715..b716150df7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -596,6 +596,7 @@ en: label_calendar: "Calendar" label_calendar_show: "Show Calendar" label_category: "Category" + label_select_main_menu_item: Select new main menu item label_change_plural: "Changes" label_change_properties: "Change properties" label_change_status: "Change status" diff --git a/config/routes.rb b/config/routes.rb index e5cbbe50ec..eca557bdb3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -201,6 +201,8 @@ OpenProject::Application.routes.draw do post :protect post :add_attachment get :list_attachments + get :replace_main_menu_item, to: 'wiki_menu_items#replace_main_menu_item' + post :create_main_menu_item, to: 'wiki_menu_items#create_main_menu_item' end end # as routes for index and show are swapped diff --git a/lib/redmine.rb b/lib/redmine.rb index fb457f7eab..6b80a92b12 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -164,6 +164,7 @@ Redmine::AccessControl.map do |map| map.permission :delete_wiki_pages_attachments, {} map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member map.permission :list_attachments, {:wiki => :list_attachments}, :require => :member + map.permission :replace_main_wiki_menu_item, {:wiki_menu_items => [:replace_main_menu_item, :create_main_menu_item]}, :require => :member end map.project_module :repository do |map| From ca3ef3bb8e148038de58b5c25ffddc78dc731256 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 22:12:33 +0100 Subject: [PATCH 07/14] Deimplement automatic wiki main menu item restauration --- app/models/wiki_menu_item.rb | 8 -------- features/wiki_menu_items/wiki_menu_items.feature | 12 ------------ 2 files changed, 20 deletions(-) diff --git a/app/models/wiki_menu_item.rb b/app/models/wiki_menu_item.rb index ac7c678eed..c200de3412 100644 --- a/app/models/wiki_menu_item.rb +++ b/app/models/wiki_menu_item.rb @@ -47,8 +47,6 @@ class WikiMenuItem < ActiveRecord::Base validates_presence_of :name - before_destroy :ensure_presence_of_another_main_item - def item_class title.dasherize end @@ -90,10 +88,4 @@ class WikiMenuItem < ActiveRecord::Base def is_only_main_item? self.class.main_items(wiki.id) == [self] end - - def ensure_presence_of_another_main_item - if is_only_main_item? && wiki_page = WikiPage.main_pages(wiki.id).reject{|page| page.title == title}.first - self.class.find_or_create_by_wiki_id_and_title(wiki.id, wiki_page.title, name: wiki_page.title) - end - end end diff --git a/features/wiki_menu_items/wiki_menu_items.feature b/features/wiki_menu_items/wiki_menu_items.feature index 80ad418a64..e0fdcdce7b 100644 --- a/features/wiki_menu_items/wiki_menu_items.feature +++ b/features/wiki_menu_items/wiki_menu_items.feature @@ -117,15 +117,3 @@ Feature: Wiki menu items And I choose "Do not show this wikipage in project navigation" And I press "Save" Then I should not see "Wiki" within "#main-menu" - - @javascript - Scenario: When I delete the last wiki page with a menu item there should be a menu item Wiki linking to the wiki index page - Given the project "Awesome Project" has a wiki menu item with the following: - | title | AwesomePage | - | name | AwesomePage | - And the wiki menu item of the wiki page "Wiki" of project "Awesome Project" has been deleted - When I go to the wiki page "AwesomePage" for the project called "Awesome Project" - And I click on "More functions" - And I click on "Delete" - And I confirm popups - Then I should see "Wiki" within "#main-menu" From 352516aee9eece9a6cc6e12a0eb8b9a37f6ef87e Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 22:14:12 +0100 Subject: [PATCH 08/14] Integrate main wiki menu item replacement selection into page flow (WIP) TODO Add specs and happy path integration test --- app/controllers/wiki_menu_items_controller.rb | 37 +++++++++++++------ ...tml.erb => select_main_menu_item.html.erb} | 6 ++- config/routes.rb | 4 +- lib/redmine.rb | 2 +- 4 files changed, 32 insertions(+), 17 deletions(-) rename app/views/wiki_menu_items/{replace_main_menu_item.html.erb => select_main_menu_item.html.erb} (88%) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index 5f009e74cb..efd81e8ccf 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -48,7 +48,13 @@ class WikiMenuItemsController < ApplicationController get_data_from_params(params) if wiki_menu_setting == 'no_item' - @wiki_menu_item.destroy unless @wiki_menu_item.nil? + unless @wiki_menu_item.nil? + if @wiki_menu_item.is_only_main_item? + redirect_to(select_main_menu_item_project_wiki_path(@project, @page_title)) and return + else + @wiki_menu_item.destroy + end + end else @wiki_menu_item.wiki_id = @page.wiki.id @wiki_menu_item.name = params[:wiki_menu_item][:name] @@ -72,23 +78,19 @@ class WikiMenuItemsController < ApplicationController end end - def replace_main_menu_item + def select_main_menu_item wiki_page_title = params[:id] @possible_wiki_pages = @project.wiki.pages.all(:include => :parent).reject{|page| page.title == wiki_page_title || page.menu_item.present? && page.menu_item.is_main_item?} end - def create_main_menu_item - page = WikiPage.find params[:wiki_page][:id] - wiki = @project.wiki - - menu_item = if item = page.menu_item - item.tap {|item| item.parent_id = nil} - else - wiki.wiki_menu_items.build(title: page.title, name: page.pretty_title) + def replace_main_menu_item + if page = WikiPage.find(params[:wiki_page][:id]) + create_main_menu_item_for_wiki_page(page) end - menu_item.save - redirect_to project_wiki_path(@project, wiki.start_page) + page.menu_item.destroy + + redirect_to action: :edit, id: page.title end private @@ -124,4 +126,15 @@ class WikiMenuItemsController < ApplicationController menu_item.index_page = false end end + + def create_main_menu_item_for_wiki_page(page) + wiki = page.wiki + + menu_item = if item = page.menu_item + item.tap {|item| item.parent_id = nil} + else + wiki.wiki_menu_items.build(title: page.title, name: page.pretty_title) + end + menu_item.save + end end diff --git a/app/views/wiki_menu_items/replace_main_menu_item.html.erb b/app/views/wiki_menu_items/select_main_menu_item.html.erb similarity index 88% rename from app/views/wiki_menu_items/replace_main_menu_item.html.erb rename to app/views/wiki_menu_items/select_main_menu_item.html.erb index 68501fd4b2..a4d9f0eba1 100644 --- a/app/views/wiki_menu_items/replace_main_menu_item.html.erb +++ b/app/views/wiki_menu_items/select_main_menu_item.html.erb @@ -29,15 +29,17 @@ See doc/COPYRIGHT.rdoc for more details.

<%= t(:label_select_main_menu_item) %>

-<%= labelled_tabular_form_for :wiki_page, url: { action: 'create_main_menu_item' } do |f| %> +<%= labelled_tabular_form_for :wiki_page, url: { action: 'replace_main_menu_item' } do |f| %>

<%= f.select :id, "".html_safe + wiki_page_options_for_select(@possible_wiki_pages), {label: WikiPage.human_attribute_name(:title) }, - {size: "#{@possible_wiki_pages.size + 1}", class: "main-menu-item-select"} %> + {size: "#{@possible_wiki_pages.size + 1}", class: 'main-menu-item-select'} %>

+ + <%= submit_tag t(:button_save) %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index eca557bdb3..0e9f51c71f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -201,8 +201,8 @@ OpenProject::Application.routes.draw do post :protect post :add_attachment get :list_attachments - get :replace_main_menu_item, to: 'wiki_menu_items#replace_main_menu_item' - post :create_main_menu_item, to: 'wiki_menu_items#create_main_menu_item' + get :select_main_menu_item, to: 'wiki_menu_items#select_main_menu_item' + post :replace_main_menu_item, to: 'wiki_menu_items#replace_main_menu_item' end end # as routes for index and show are swapped diff --git a/lib/redmine.rb b/lib/redmine.rb index 6b80a92b12..2e44f8f153 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -164,7 +164,7 @@ Redmine::AccessControl.map do |map| map.permission :delete_wiki_pages_attachments, {} map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member map.permission :list_attachments, {:wiki => :list_attachments}, :require => :member - map.permission :replace_main_wiki_menu_item, {:wiki_menu_items => [:replace_main_menu_item, :create_main_menu_item]}, :require => :member + map.permission :replace_main_wiki_menu_item, {:wiki_menu_items => [:select_main_menu_item, :replace_main_menu_item]}, :require => :member end map.project_module :repository do |map| From dafd8be24217308142f013aca3acfa7d213019eb Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Mon, 28 Oct 2013 22:14:54 +0100 Subject: [PATCH 09/14] Remove duplicate initialization of @project in wiki menu items controller ... already done by before filter --- app/controllers/wiki_menu_items_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index efd81e8ccf..6e3a26677d 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -96,7 +96,6 @@ class WikiMenuItemsController < ApplicationController private def get_data_from_params(params) - @project = Project.find(params[:project_id]) @page_title = params[:id] wiki_id = @project.wiki.id From e5d739425bef83b3b695464d73d34dd2c1bc4bf0 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 29 Oct 2013 08:44:19 +0100 Subject: [PATCH 10/14] Add controller specs for main wiki menu item replacement, fix action --- app/controllers/wiki_menu_items_controller.rb | 7 +- .../wiki_menu_items_controller_spec.rb | 64 +++++++++++++++---- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index 6e3a26677d..6cce8a399d 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -50,7 +50,7 @@ class WikiMenuItemsController < ApplicationController if wiki_menu_setting == 'no_item' unless @wiki_menu_item.nil? if @wiki_menu_item.is_only_main_item? - redirect_to(select_main_menu_item_project_wiki_path(@project, @page_title)) and return + redirect_to(select_main_menu_item_project_wiki_path(@project, @page.id)) and return else @wiki_menu_item.destroy end @@ -88,9 +88,10 @@ class WikiMenuItemsController < ApplicationController create_main_menu_item_for_wiki_page(page) end - page.menu_item.destroy + current_page = WikiPage.find params[:id] + current_page.menu_item.destroy - redirect_to action: :edit, id: page.title + redirect_to action: :edit, id: current_page.title end private diff --git a/spec/controllers/wiki_menu_items_controller_spec.rb b/spec/controllers/wiki_menu_items_controller_spec.rb index 445133d557..48b228a895 100644 --- a/spec/controllers/wiki_menu_items_controller_spec.rb +++ b/spec/controllers/wiki_menu_items_controller_spec.rb @@ -35,20 +35,8 @@ describe WikiMenuItemsController do let(:project) { FactoryGirl.create(:project).reload } # a wiki is created for project, but the object doesn't know of it (FIXME?) let(:wiki) { project.wiki } - # wiki pages let(:wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # first wiki page without child pages let!(:top_level_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => wiki_page.title) } - let(:another_wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # second wiki page with two child pages - let!(:another_wiki_page_top_level_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => another_wiki_page.title) } - - # child pages of another_wiki_page - let(:child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } - let!(:child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => child_page.title) } - let(:another_child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } - let!(:another_child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => another_child_page.title, :parent => top_level_wiki_menu_item) } - - let(:grand_child_page) { FactoryGirl.create(:wiki_page, :parent => child_page, :wiki => wiki) } - let!(:grand_child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => grand_child_page.title) } before :each do # log in user @@ -56,6 +44,19 @@ describe WikiMenuItemsController do end describe :edit do + # more wiki pages with menu items + let(:another_wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # second wiki page with two child pages + let!(:another_wiki_page_top_level_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => another_wiki_page.title) } + + # child pages of another_wiki_page + let(:child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } + let!(:child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => child_page.title) } + let(:another_child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } + let!(:another_child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => another_child_page.title, :parent => top_level_wiki_menu_item) } + + let(:grand_child_page) { FactoryGirl.create(:wiki_page, :parent => child_page, :wiki => wiki) } + let!(:grand_child_page_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => grand_child_page.title) } + context 'when no parent wiki menu item has been configured yet' do context 'and it is a child page' do before { get :edit, project_id: project.id, id: child_page.title } @@ -91,4 +92,43 @@ describe WikiMenuItemsController do end end end + + shared_context 'there is one more wiki page with a child page' do + let!(:another_wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # second wiki page with two child pages + let!(:child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } + end + + describe :select_main_menu_item do + include_context 'there is one more wiki page with a child page' + + before { get :select_main_menu_item, project_id: project, id: wiki_page.title } + subject { assigns['possible_wiki_pages'] } + + context 'when selecting a new wiki page to replace the current main menu item' do + it { should include another_wiki_page } + it { should include child_page } + it { should_not include wiki_page } + end + end + + describe :replace_main_menu_item do + include_context 'there is one more wiki page with a child page' + + let(:selected_page) { child_page } + + before do + post :replace_main_menu_item, project_id: project, + id: wiki_page.id, + wiki_page: { id: selected_page.id } + end + + it 'destroys the current wiki menu item' do + wiki_page.menu_item.should be_nil + end + + it 'creates a new main menu item for the selected wiki page' do + selected_page.menu_item.should be_present + selected_page.menu_item.parent.should be_nil + end + end end From cb10d35385c096f3fd2290538e9ac3cab4af51a8 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 29 Oct 2013 09:19:04 +0100 Subject: [PATCH 11/14] Transfer menu item option to new wiki menu item during replacement --- app/controllers/wiki_menu_items_controller.rb | 12 ++++++++---- spec/controllers/wiki_menu_items_controller_spec.rb | 13 +++++++++---- spec/factories/wiki_menu_item_factory.rb | 5 +++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index 6cce8a399d..0cecabb231 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -84,12 +84,14 @@ class WikiMenuItemsController < ApplicationController end def replace_main_menu_item + current_page = WikiPage.find params[:id] + current_menu_item = current_page.menu_item + if page = WikiPage.find(params[:wiki_page][:id]) - create_main_menu_item_for_wiki_page(page) + create_main_menu_item_for_wiki_page(page, current_menu_item.options) end - current_page = WikiPage.find params[:id] - current_page.menu_item.destroy + current_menu_item.destroy redirect_to action: :edit, id: current_page.title end @@ -127,7 +129,7 @@ class WikiMenuItemsController < ApplicationController end end - def create_main_menu_item_for_wiki_page(page) + def create_main_menu_item_for_wiki_page(page, options={}) wiki = page.wiki menu_item = if item = page.menu_item @@ -135,6 +137,8 @@ class WikiMenuItemsController < ApplicationController else wiki.wiki_menu_items.build(title: page.title, name: page.pretty_title) end + + menu_item.options = options menu_item.save end end diff --git a/spec/controllers/wiki_menu_items_controller_spec.rb b/spec/controllers/wiki_menu_items_controller_spec.rb index 48b228a895..cfe7814ace 100644 --- a/spec/controllers/wiki_menu_items_controller_spec.rb +++ b/spec/controllers/wiki_menu_items_controller_spec.rb @@ -36,7 +36,7 @@ describe WikiMenuItemsController do let(:wiki) { project.wiki } let(:wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # first wiki page without child pages - let!(:top_level_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :wiki => wiki, :title => wiki_page.title) } + let!(:top_level_wiki_menu_item) { FactoryGirl.create(:wiki_menu_item, :with_menu_item_options, :wiki => wiki, :title => wiki_page.title) } before :each do # log in user @@ -93,13 +93,13 @@ describe WikiMenuItemsController do end end - shared_context 'there is one more wiki page with a child page' do + shared_context 'when there is one more wiki page with a child page' do let!(:another_wiki_page) { FactoryGirl.create(:wiki_page, :wiki => wiki) } # second wiki page with two child pages let!(:child_page) { FactoryGirl.create(:wiki_page, :parent => another_wiki_page, :wiki => wiki) } end describe :select_main_menu_item do - include_context 'there is one more wiki page with a child page' + include_context 'when there is one more wiki page with a child page' before { get :select_main_menu_item, project_id: project, id: wiki_page.title } subject { assigns['possible_wiki_pages'] } @@ -112,9 +112,10 @@ describe WikiMenuItemsController do end describe :replace_main_menu_item do - include_context 'there is one more wiki page with a child page' + include_context 'when there is one more wiki page with a child page' let(:selected_page) { child_page } + let(:new_menu_item) { selected_page.menu_item } before do post :replace_main_menu_item, project_id: project, @@ -130,5 +131,9 @@ describe WikiMenuItemsController do selected_page.menu_item.should be_present selected_page.menu_item.parent.should be_nil end + + it 'transfers the menu item options to the selected wiki page' do + new_menu_item.options.should == { index_page: true, new_wiki_page: true } + end end end diff --git a/spec/factories/wiki_menu_item_factory.rb b/spec/factories/wiki_menu_item_factory.rb index 60d0f97681..58ff08be2d 100644 --- a/spec/factories/wiki_menu_item_factory.rb +++ b/spec/factories/wiki_menu_item_factory.rb @@ -32,5 +32,10 @@ FactoryGirl.define do sequence(:name) {|n| "Item No. #{n}" } sequence(:title) {|n| "Wiki Title #{n}" } + + trait :with_menu_item_options do + index_page true + new_wiki_page true + end end end From 1f07b9c21067cac59c12958a036d7285d36652f8 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 29 Oct 2013 09:19:37 +0100 Subject: [PATCH 12/14] Fix wiki menu item replacement in the case no new main item is selected --- app/controllers/wiki_menu_items_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/wiki_menu_items_controller.rb b/app/controllers/wiki_menu_items_controller.rb index 0cecabb231..867088f9f7 100644 --- a/app/controllers/wiki_menu_items_controller.rb +++ b/app/controllers/wiki_menu_items_controller.rb @@ -87,7 +87,7 @@ class WikiMenuItemsController < ApplicationController current_page = WikiPage.find params[:id] current_menu_item = current_page.menu_item - if page = WikiPage.find(params[:wiki_page][:id]) + if page = WikiPage.find_by_id(params[:wiki_page][:id]) create_main_menu_item_for_wiki_page(page, current_menu_item.options) end From 801cacf08f8b89a4fa69514e1a59d4860b3217d1 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 29 Oct 2013 10:02:47 +0100 Subject: [PATCH 13/14] Add integration test for main wiki menu item replacement --- .../select_main_menu_item.html.erb | 2 +- .../wiki_menu_items/wiki_menu_items.feature | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/views/wiki_menu_items/select_main_menu_item.html.erb b/app/views/wiki_menu_items/select_main_menu_item.html.erb index a4d9f0eba1..c88066ec66 100644 --- a/app/views/wiki_menu_items/select_main_menu_item.html.erb +++ b/app/views/wiki_menu_items/select_main_menu_item.html.erb @@ -35,7 +35,7 @@ See doc/COPYRIGHT.rdoc for more details. <%= f.select :id, "".html_safe + wiki_page_options_for_select(@possible_wiki_pages), {label: WikiPage.human_attribute_name(:title) }, - {size: "#{@possible_wiki_pages.size + 1}", class: 'main-menu-item-select'} %> + {size: "#{@possible_wiki_pages.size + 1}", id: 'main-menu-item-select'} %>

diff --git a/features/wiki_menu_items/wiki_menu_items.feature b/features/wiki_menu_items/wiki_menu_items.feature index e0fdcdce7b..a3afdbfc6a 100644 --- a/features/wiki_menu_items/wiki_menu_items.feature +++ b/features/wiki_menu_items/wiki_menu_items.feature @@ -33,10 +33,11 @@ Feature: Wiki menu items | identifier | awesome-project | And there is a role "member" And the role "member" may have the following rights: - | view_wiki_pages | - | edit_wiki_pages | - | delete_wiki_pages | - | manage_wiki_menu | + | view_wiki_pages | + | edit_wiki_pages | + | delete_wiki_pages | + | manage_wiki_menu | + | replace_main_wiki_menu_item | And there is 1 user with the following: | login | bob | And the user "bob" is a "member" in the project "Awesome Project" @@ -117,3 +118,19 @@ Feature: Wiki menu items And I choose "Do not show this wikipage in project navigation" And I press "Save" Then I should not see "Wiki" within "#main-menu" + + @javascript + Scenario: When I delete the last wiki page with a menu item I can select a new menu item and the menu item is replaced + Given the project "Awesome Project" has a wiki menu item with the following: + | title | AwesomePage | + | name | AwesomePage | + And the wiki menu item of the wiki page "Wiki" of project "Awesome Project" has been deleted + When I go to the wiki page "AwesomePage" for the project called "Awesome Project" + And I click on "More functions" + And I click on "Configure menu item" + And I choose "Do not show this wikipage in project navigation" + And I press "Save" + And I select "Wiki" from "main-menu-item-select" + And I press "Save" + Then I should not see "AwesomePage" within "#main-menu" + Then I should see "Wiki" within "#main-menu" From d9fac1dc22126e6907f0d859e1e24b4f8879994e Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Tue, 29 Oct 2013 10:46:15 +0100 Subject: [PATCH 14/14] Merge permissions concerning wiki menu item management --- features/wiki_menu_items/wiki_menu_items.feature | 13 ++++++------- lib/redmine.rb | 3 +-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/features/wiki_menu_items/wiki_menu_items.feature b/features/wiki_menu_items/wiki_menu_items.feature index a3afdbfc6a..70b8d84633 100644 --- a/features/wiki_menu_items/wiki_menu_items.feature +++ b/features/wiki_menu_items/wiki_menu_items.feature @@ -29,15 +29,14 @@ Feature: Wiki menu items Background: Given there is 1 project with the following: - | name | Awesome Project | - | identifier | awesome-project | + | name | Awesome Project | + | identifier | awesome-project | And there is a role "member" And the role "member" may have the following rights: - | view_wiki_pages | - | edit_wiki_pages | - | delete_wiki_pages | - | manage_wiki_menu | - | replace_main_wiki_menu_item | + | view_wiki_pages | + | edit_wiki_pages | + | delete_wiki_pages | + | manage_wiki_menu | And there is 1 user with the following: | login | bob | And the user "bob" is a "member" in the project "Awesome Project" diff --git a/lib/redmine.rb b/lib/redmine.rb index 2e44f8f153..9b88ea11b7 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -152,7 +152,7 @@ Redmine::AccessControl.map do |map| map.project_module :wiki do |map| map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member - map.permission :manage_wiki_menu, {:wiki_menu_items => [:edit, :update]}, :require => :member + map.permission :manage_wiki_menu, {:wiki_menu_items => [:edit, :update, :select_main_menu_item, :replace_main_menu_item]}, :require => :member map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member map.permission :change_wiki_parent_page, {:wiki => [:edit_parent_page, :update_parent_page]}, :require => :member @@ -164,7 +164,6 @@ Redmine::AccessControl.map do |map| map.permission :delete_wiki_pages_attachments, {} map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member map.permission :list_attachments, {:wiki => :list_attachments}, :require => :member - map.permission :replace_main_wiki_menu_item, {:wiki_menu_items => [:select_main_menu_item, :replace_main_menu_item]}, :require => :member end map.project_module :repository do |map|