diff --git a/app/controllers/homescreen_controller.rb b/app/controllers/homescreen_controller.rb index c3abcbffcd..42f4244a04 100644 --- a/app/controllers/homescreen_controller.rb +++ b/app/controllers/homescreen_controller.rb @@ -37,7 +37,7 @@ class HomescreenController < ApplicationController @news = News.latest(count: 3) @announcement = Announcement.active_and_current - @homescreen = OpenProject::Homescreen + @homescreen = OpenProject::Static::Homescreen end def robots diff --git a/app/helpers/homescreen_helper.rb b/app/helpers/homescreen_helper.rb index 124227a406..ffe57286e2 100644 --- a/app/helpers/homescreen_helper.rb +++ b/app/helpers/homescreen_helper.rb @@ -47,4 +47,16 @@ module HomescreenHelper avatar.presence || content_tag(:span, '', class: 'icon-context icon-user') end + + ## + # Render a static link defined in OpenProject::Static::Links + def static_link_to(key) + link = OpenProject::Static::Links.links[key] + label = I18n.t(link[:label]) + + link_to label, + link[:href], + title: label, + target: '_blank' + end end diff --git a/app/views/homescreen/blocks/_community.html.erb b/app/views/homescreen/blocks/_community.html.erb index aad404fce1..2e581a2cc0 100644 --- a/app/views/homescreen/blocks/_community.html.erb +++ b/app/views/homescreen/blocks/_community.html.erb @@ -5,18 +5,10 @@ diff --git a/config/initializers/homescreen.rb b/config/initializers/homescreen.rb index 7b498d30f4..f991767dcc 100644 --- a/config/initializers/homescreen.rb +++ b/config/initializers/homescreen.rb @@ -27,9 +27,10 @@ # See doc/COPYRIGHT.rdoc for more details. #++ -require 'open_project/homescreen' +require 'open_project/static/homescreen' +require 'open_project/static/links' -OpenProject::Homescreen.manage :blocks do |blocks| +OpenProject::Static::Homescreen.manage :blocks do |blocks| blocks.push( { partial: 'welcome', if: Proc.new { Setting.welcome_on_homescreen? && !Setting.welcome_text.empty? } }, @@ -46,32 +47,34 @@ OpenProject::Homescreen.manage :blocks do |blocks| ) end -OpenProject::Homescreen.manage :links do |links| +OpenProject::Static::Homescreen.manage :links do |links| + static_links = OpenProject::Static::Links.links + links.push( { label: :user_guides, icon: 'icon-context icon-rename', - url: 'https://www.openproject.org/help/user-guides/' + url: static_links[:user_guides][:href] }, { label: :faq, icon: 'icon-context icon-faq', - url: 'https://www.openproject.org/help/faq/' + url: static_links[:faq][:href] }, { label: :glossary, icon: 'icon-context icon-glossar', - url: 'https://www.openproject.org/help/user-guides/glossary/' + url: static_links[:glossary][:href] }, { label: :shortcuts, icon: 'icon-context icon-shortcuts', - url: 'https://www.openproject.org/help/user-guides/keyboard-shortcuts-access-keys/' + url: static_links[:shortcuts][:href] }, { - label: :forums, + label: :boards, icon: 'icon-context icon-forums', - url: 'https://community.openproject.org/projects/openproject/boards' + url: static_links[:boards][:href] } ) end diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index 65fdfdf2ad..70faf94a69 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -56,7 +56,7 @@ Redmine::MenuManager.map :top_menu do |menu| (User.current.logged? || !Setting.login_required?) && User.current.allowed_to?(:view_time_entries, nil, global: true) } - menu.push :help, OpenProject::Info.help_url, + menu.push :help, OpenProject::Static::Links.help_link, last: true, caption: '', html: { accesskey: OpenProject::AccessKeys.key_for(:help), diff --git a/doc/CONFIGURATION.md b/doc/CONFIGURATION.md index 27af0aa8f2..6e6dd159a7 100644 --- a/doc/CONFIGURATION.md +++ b/doc/CONFIGURATION.md @@ -79,6 +79,7 @@ storage config above like this: * `database_cipher_key` (default: nil) * `scm_git_command` (default: 'git') * `scm_subversion_command` (default: 'svn') +* `force_help_link` (default: nil) * `session_store`: `active_record_store`, `cache_store`, or `cookie_store` (default: cache_store) * [`omniauth_direct_login_provider`](#omniauth-direct-login-provider) (default: nil) * [`disable_password_login`](#disable-password-login) (default: false) @@ -167,6 +168,11 @@ In the case of fog you only have to configure everything under `fog`, however. D to `fog` just yet. Instead leave it as `file`. This is because the current attachments storage is used as the source for the migration. +### Overriding the help link + +You can override the default help menu of OpenProject by specifying a `force_help_link` option to +the configuration. This value is used for the href of the help link, and the default dropdown is removed. + ### hidden menu items *default: {}* diff --git a/lib/open_project/configuration.rb b/lib/open_project/configuration.rb index 992fd1f5f1..1077ce21fb 100644 --- a/lib/open_project/configuration.rb +++ b/lib/open_project/configuration.rb @@ -43,6 +43,7 @@ module OpenProject 'autologin_cookie_path' => '/', 'autologin_cookie_secure' => false, 'database_cipher_key' => nil, + 'force_help_link' => nil, 'scm_git_command' => nil, 'scm_subversion_command' => nil, 'disable_browser_cache' => true, diff --git a/lib/open_project/info.rb b/lib/open_project/info.rb index 0f87f08284..d20b1a1a26 100644 --- a/lib/open_project/info.rb +++ b/lib/open_project/info.rb @@ -34,10 +34,6 @@ module OpenProject def url; Setting.software_url end - def help_url - 'https://www.openproject.org/help' - end - def versioned_name; "#{app_name} #{OpenProject::VERSION.to_semver}" end # Creates the url string to a specific Redmine issue diff --git a/lib/open_project/homescreen.rb b/lib/open_project/static/homescreen.rb similarity index 67% rename from lib/open_project/homescreen.rb rename to lib/open_project/static/homescreen.rb index 7e0b3030f9..5aafedfbf6 100644 --- a/lib/open_project/homescreen.rb +++ b/lib/open_project/static/homescreen.rb @@ -28,29 +28,31 @@ #++ module OpenProject - module Homescreen - class << self - ## - # Access a defined item on the homescreen - # By default, this will likely be :blocks and :links, - # however plugins may define their own blocks and - # render them in the call_hook. - def [](item) - homescreen[item] - end + module Static + module Homescreen + class << self + ## + # Access a defined item on the homescreen + # By default, this will likely be :blocks and :links, + # however plugins may define their own blocks and + # render them in the call_hook. + def [](item) + homescreen[item] + end - ## - # Manage the given content for this item, - # yielding it. - def manage(item, default = []) - homescreen[item] ||= default - yield homescreen[item] - end + ## + # Manage the given content for this item, + # yielding it. + def manage(item, default = []) + homescreen[item] ||= default + yield homescreen[item] + end - private + private - def homescreen - @content ||= {} + def homescreen + @content ||= {} + end end end end diff --git a/lib/open_project/static/links.rb b/lib/open_project/static/links.rb new file mode 100644 index 0000000000..d92a567261 --- /dev/null +++ b/lib/open_project/static/links.rb @@ -0,0 +1,98 @@ +#-- encoding: UTF-8 +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 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. +#++ + +module OpenProject + module Static + module Links + class << self + + def help_link_overridden? + OpenProject::Configuration.force_help_link.present? + end + + def help_link + OpenProject::Configuration.force_help_link.presence || links[:user_guides] + end + + def links + { + user_guides: { + href: 'https://www.openproject.org/help/user-guides', + label: 'homescreen.links.user_guides' + }, + faq: { + href: 'https://www.openproject.org/help/faq', + label: 'homescreen.links.faq' + }, + glossary: { + href: 'https://www.openproject.org/help/user-guides/glossary/', + label: 'homescreen.links.glossary' + }, + shortcuts: { + href: 'https://www.openproject.org/help/user-guides/keyboard-shortcuts-access-keys/', + label: 'homescreen.links.shortcuts' + }, + boards: { + href: 'https://community.openproject.com/projects/openproject/boards', + label: 'homescreen.links.boards' + }, + professional_support: { + href: 'https://www.openproject.org/professional-services/', + label: :label_professional_support + }, + blog: { + href: 'https://www.openproject.org/blog', + label: 'homescreen.links.blog' + }, + release_notes: { + href: 'https://www.openproject.org/open-source/release-notes/', + label: :label_release_notes + }, + report_bug: { + href: 'https://www.openproject.org/open-source/report-bug/', + label: :label_report_bug + }, + roadmap: { + href: 'https://community.openproject.org/projects/openproject/roadmap', + label: :label_development_roadmap + }, + crowdin: { + href: 'https://crowdin.com/projects/opf', + label: :label_add_edit_translations + }, + api_docs: { + href: 'https://www.openproject.org/api', + label: :label_api_documentation + }, + } + end + end + end + end +end diff --git a/lib/redmine/menu_manager/help_menu_helper.rb b/lib/redmine/menu_manager/help_menu_helper.rb new file mode 100644 index 0000000000..66a8801127 --- /dev/null +++ b/lib/redmine/menu_manager/help_menu_helper.rb @@ -0,0 +1,98 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 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. +#++ + +require 'concerns/omniauth_login' +require 'open_project/static/links' + +module Redmine::MenuManager::HelpMenuHelper + def render_help_top_menu_node(item = help_menu_item) + if OpenProject::Static::Links.help_link_overridden? + render_menu_node(item) + else + render_help_dropdown + end + end + + def render_help_dropdown + link_to_help_pop_up = link_to '', '', + class: 'icon-help1', + aria: { haspopup: 'true' } + + result = ''.html_safe + render_drop_down_menu_node(link_to_help_pop_up, class: 'drop-down hidden-for-mobile') do + content_tag :ul, style: 'display:none', class: 'drop-down--help' do + render_help_and_support result + render_additional_resources result + end + end + end + + private + + def render_help_and_support(result) + result << content_tag(:li) do + content_tag :span, l('top_menu.help_and_support'), + class: 'drop-down--help-headline', + title: l('top_menu.help_and_support') + end + result << static_link_item(:user_guides) + result << static_link_item(:faq) + result << content_tag(:li) do + link_to l('homescreen.links.shortcuts'), + '', + title: l('homescreen.links.shortcuts'), + onClick: 'modalHelperInstance.createModal(\'/help/keyboard_shortcuts\');' + end + result << static_link_item(:boards) + result << static_link_item(:professional_support) + + end + + def render_additional_resources(result) + result << content_tag(:li) do + content_tag :span, + l('top_menu.additional_resources'), + class: 'drop-down--help-headline', + title: l('top_menu.additional_resources') + end + result << static_link_item(:blog) + result << static_link_item(:release_notes) + result << static_link_item(:report_bug) + result << static_link_item(:roadmap) + result << static_link_item(:crowdin) + result << static_link_item(:api_docs) + end + + def static_link_item(key) + link = OpenProject::Static::Links.links[key] + label = I18n.t(link[:label]) + content_tag(:li) do + link_to label, link[:href], title: label + end + end +end diff --git a/lib/redmine/menu_manager/top_menu_helper.rb b/lib/redmine/menu_manager/top_menu_helper.rb index 577ac3ac92..e5c5a54b0a 100644 --- a/lib/redmine/menu_manager/top_menu_helper.rb +++ b/lib/redmine/menu_manager/top_menu_helper.rb @@ -29,6 +29,7 @@ require 'concerns/omniauth_login' module Redmine::MenuManager::TopMenuHelper + include HelpMenuHelper def render_top_menu_left content_tag :ul, id: 'account-nav-left', class: 'menu_root account-nav hidden-for-mobile' do [render_main_top_menu_nodes, @@ -151,63 +152,6 @@ module Redmine::MenuManager::TopMenuHelper id: 'more-menu' end - def render_help_top_menu_node(item = help_menu_item) - link_to_help_pop_up = link_to '', '', - class: 'icon-help1', - aria: { haspopup: 'true' } - - result = ''.html_safe - - render_drop_down_menu_node(link_to_help_pop_up, class: 'drop-down hidden-for-mobile') do - content_tag :ul, style: 'display:none', class: 'drop-down--help' do - result << content_tag(:li) do - content_tag(:span, l('top_menu.help_and_support'), class: 'drop-down--help-headline', title: l('top_menu.help_and_support')) - end - result << content_tag(:li) do - link_to l('homescreen.links.user_guides'), 'https://www.openproject.org/help/user-guides', title: l('homescreen.links.user_guides') - end - result << content_tag(:li) do - link_to l('homescreen.links.faq'), 'https://www.openproject.org/help/faq', title: l('homescreen.links.faq') - end - result << content_tag(:li) do - link_to l('homescreen.links.shortcuts'), '', title: l('homescreen.links.shortcuts'), onClick: 'modalHelperInstance.createModal(\'/help/keyboard_shortcuts\');' - end - result << content_tag(:li) do - link_to l('homescreen.links.boards'), 'https://community.openproject.com/projects/openproject/boards', title: l('homescreen.links.boards') - end - result << content_tag(:li) do - link_to l(:label_professional_support), 'https://www.openproject.org/professional-services/', title: l(:label_professional_support) - end - result << content_tag(:hr, '', class: 'form--separator') - - - result << content_tag(:li) do - content_tag(:span, l('top_menu.additional_resources'), class: 'drop-down--help-headline', title: l('top_menu.additional_resources')) - end - result << content_tag(:li) do - link_to l('homescreen.links.blog'), 'https://www.openproject.org/blog', title: l('homescreen.links.blog') - end - result << content_tag(:li) do - link_to l(:label_release_notes), 'https://www.openproject.org/open-source/release-notes/', title: l(:label_release_notes) - end - result << content_tag(:li) do - link_to l(:label_report_bug), 'https://www.openproject.org/open-source/report-bug/', title: l(:label_report_bug) - end - result << content_tag(:li) do - link_to l(:label_development_roadmap), 'https://community.openproject.org/projects/openproject/roadmap', title: l(:label_development_roadmap) - end - result << content_tag(:li) do - link_to l(:label_add_edit_translations), 'https://crowdin.com/projects/opf', title: l(:label_add_edit_translations) - end - result << content_tag(:li) do - link_to l(:label_api_documentation), 'https://www.openproject.org/api', title: l(:label_api_documentation) - end - - result - end - end - end - def render_main_top_menu_nodes(items = main_top_menu_items) items.map { |item| render_menu_node(item) diff --git a/spec/features/menu_items/help_menu_spec.rb b/spec/features/menu_items/help_menu_spec.rb new file mode 100644 index 0000000000..6f5ad2ce02 --- /dev/null +++ b/spec/features/menu_items/help_menu_spec.rb @@ -0,0 +1,62 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 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. +#++ + +require 'spec_helper' + +feature 'Help menu items' do + let(:user) { FactoryGirl.create :admin } + let(:help_item) { find('.icon-help1') } + + before do + login_as user + end + + describe 'When force_help_link is not set', js: true do + it 'renders a dropdown' do + visit home_path + + help_item.click + expect(page).to have_selector('.drop-down--help li', + text: I18n.t('homescreen.links.user_guides')) + end + end + + describe 'When force_help_link is set' do + let(:custom_url) { 'https://mycustomurl.example.org' } + before do + allow(OpenProject::Configuration).to receive(:force_help_link) + .and_return custom_url + end + it 'renders a link' do + visit home_path + + expect(help_item[:href]).to eq(custom_url) + expect(page).to have_no_selector('.drop-down--help', visible: false) + end + end +end diff --git a/spec_legacy/unit/lib/redmine/menu_manager/mapper_spec.rb b/spec_legacy/unit/lib/redmine/menu_manager/mapper_spec.rb index 15ca89b6cb..477322e250 100644 --- a/spec_legacy/unit/lib/redmine/menu_manager/mapper_spec.rb +++ b/spec_legacy/unit/lib/redmine/menu_manager/mapper_spec.rb @@ -170,9 +170,9 @@ describe Redmine::MenuManager::Mapper do specify 'deleting all items' do # Exposed by deleting :last items Redmine::MenuManager.map :test_menu do |menu| - menu.push :not_last, OpenProject::Info.help_url + menu.push :not_last, OpenProject::Static::Links.help_link menu.push :administration, { controller: 'projects', action: 'show' }, last: true - menu.push :help, OpenProject::Info.help_url, last: true + menu.push :help, OpenProject::Static::Links.help_link, last: true end expect {