diff --git a/Gemfile.lock b/Gemfile.lock index 27b0088c99a..81c3deb9032 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,6 +68,11 @@ PATH specs: budgets (1.0.0) +PATH + remote: modules/calendar + specs: + openproject-calendar (1.0.0) + PATH remote: modules/costs specs: @@ -1040,6 +1045,7 @@ DEPENDENCIES openproject-backlogs! openproject-bim! openproject-boards! + openproject-calendar! openproject-documents! openproject-github_integration! openproject-job_status! diff --git a/Gemfile.modules b/Gemfile.modules index 9e169fb2a59..fccc77bbe19 100644 --- a/Gemfile.modules +++ b/Gemfile.modules @@ -45,6 +45,7 @@ group :opf_plugins do gem 'overviews', path: 'modules/overviews' gem 'budgets', path: 'modules/budgets' gem 'openproject-team_planner', path: 'modules/team_planner' + gem 'openproject-calendar', path: 'modules/calendar' gem 'openproject-bim', path: 'modules/bim' end diff --git a/app/views/homescreen/robots.text.erb b/app/views/homescreen/robots.text.erb index 0fd806c6e9a..7d7964f3a86 100644 --- a/app/views/homescreen/robots.text.erb +++ b/app/views/homescreen/robots.text.erb @@ -34,5 +34,5 @@ Disallow: <%= project_work_packages_path(p) %> Disallow: <%= project_activity_index_path(p) %> <% end -%> <% end %> -Disallow: /work_packages/calendar +Disallow: /calendar Disallow: /activity diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index ba246258659..970a6e5913c 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -436,11 +436,6 @@ Redmine::MenuManager.map :project_menu do |menu| last: true, caption: :label_all_open_wps - menu.push :calendar, - { controller: '/work_packages/calendars', action: 'index' }, - caption: :label_calendar, - icon: 'icon2 icon-calendar' - menu.push :news, { controller: '/news', action: 'index' }, caption: :label_news_plural, diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index f2ce2eca6f1..c63509b9333 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -344,10 +344,5 @@ OpenProject::AccessControl.map do |map| require: :loggedin end - map.project_module :calendar, dependencies: :work_package_tracking do |cal| - cal.permission :view_calendar, - 'work_packages/calendars': [:index] - end - map.project_module :activity end diff --git a/config/initializers/register_views.rb b/config/initializers/register_views.rb index f0877b2bd1d..78ec3178fc9 100644 --- a/config/initializers/register_views.rb +++ b/config/initializers/register_views.rb @@ -29,5 +29,3 @@ require Rails.root.join('config/constants/views') Constants::Views.add :WorkPackagesTable -Constants::Views.add :WorkPackagesCalendar, - contract_strategy: 'Views::CalendarStrategy' diff --git a/config/locales/en.yml b/config/locales/en.yml index 714af0c086f..5f584ab763e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2266,7 +2266,6 @@ en: permission_select_custom_fields: "Select custom fields" permission_select_project_modules: "Select project modules" permission_manage_types: "Select types" - permission_view_calendar: "View calendar" permission_view_changesets: "View repository revisions in OpenProject" permission_view_commit_author_statistics: "View commit author statistics" permission_view_work_package_watchers: "View watchers list" @@ -2306,7 +2305,6 @@ en: project_module_activity: "Activity" project_module_forums: "Forums" - project_module_calendar: "Calendar" project_module_work_package_tracking: "Work package tracking" project_module_news: "News" project_module_repository: "Repository" diff --git a/config/routes.rb b/config/routes.rb index ae61d328a42..3b17d48e57d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -256,10 +256,6 @@ OpenProject::Application.routes.draw do # work as a catchall for everything under /wiki get 'wiki' => 'wiki#show' - namespace :work_packages do - resources :calendar, controller: 'calendars', only: [:index] - end - resources :work_packages, only: [] do collection do get '/report/:detail' => 'work_packages/reports#report_details' @@ -437,7 +433,6 @@ OpenProject::Application.routes.draw do namespace :work_packages do match 'auto_complete' => 'auto_completes#index', via: %i[get post] - resources :calendar, controller: 'calendars', only: [:index] resource :bulk, controller: 'bulk', only: %i[edit update destroy] # FIXME: this is kind of evil!! We need to remove this soonest and # cover the functionality. Route is being used in work-package-service.js:331 diff --git a/frontend/src/app/core/path-helper/path-helper.service.ts b/frontend/src/app/core/path-helper/path-helper.service.ts index 6de6548a6a9..5469dee1c71 100644 --- a/frontend/src/app/core/path-helper/path-helper.service.ts +++ b/frontend/src/app/core/path-helper/path-helper.service.ts @@ -133,7 +133,7 @@ export class PathHelperService { } public projectCalendarPath(projectId:string) { - return `${this.projectPath(projectId)}/work_packages/calendar`; + return `${this.projectPath(projectId)}/calendar`; } public projectMembershipsPath(projectId:string) { diff --git a/modules/backlogs/lib/open_project/backlogs/engine.rb b/modules/backlogs/lib/open_project/backlogs/engine.rb index 7bf439e86d0..e6f472d0406 100644 --- a/modules/backlogs/lib/open_project/backlogs/engine.rb +++ b/modules/backlogs/lib/open_project/backlogs/engine.rb @@ -106,7 +106,7 @@ module OpenProject::Backlogs :backlogs, { controller: '/rb_master_backlogs', action: :index }, caption: :project_module_backlogs, - before: :calendar, + after: :work_packages, icon: 'icon2 icon-backlogs' menu :project_menu, diff --git a/app/contracts/views/calendar_strategy.rb b/modules/calendar/app/contracts/calendar/views/contract_strategy.rb similarity index 100% rename from app/contracts/views/calendar_strategy.rb rename to modules/calendar/app/contracts/calendar/views/contract_strategy.rb diff --git a/modules/calendar/app/controllers/calendar/base_controller.rb b/modules/calendar/app/controllers/calendar/base_controller.rb new file mode 100644 index 00000000000..ff321058951 --- /dev/null +++ b/modules/calendar/app/controllers/calendar/base_controller.rb @@ -0,0 +1,4 @@ +module ::Calendar + class BaseController < ::ApplicationController + end +end diff --git a/app/controllers/work_packages/calendars_controller.rb b/modules/calendar/app/controllers/calendar/calendar_controller.rb similarity index 86% rename from app/controllers/work_packages/calendars_controller.rb rename to modules/calendar/app/controllers/calendar/calendar_controller.rb index 034b79b088a..90ed55cae7b 100644 --- a/app/controllers/work_packages/calendars_controller.rb +++ b/modules/calendar/app/controllers/calendar/calendar_controller.rb @@ -28,11 +28,13 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class WorkPackages::CalendarsController < ApplicationController - menu_item :calendar - before_action :find_optional_project +module ::Calendar + class CalendarController < ApplicationController + menu_item :calendar + before_action :find_optional_project - def index - render layout: 'angular/angular' + def index + render layout: 'angular/angular' + end end end diff --git a/modules/calendar/app/views/calendar/calendar/_menu.html.erb b/modules/calendar/app/views/calendar/calendar/_menu.html.erb new file mode 100644 index 00000000000..ec11d4d16b2 --- /dev/null +++ b/modules/calendar/app/views/calendar/calendar/_menu.html.erb @@ -0,0 +1,9 @@ + <%= + angular_component_tag 'op-view-select', + inputs: { + projectId: (@project ? @project.id.to_s : ''), + menuItems: [parent_name, name], + baseRoute: 'work-packages.calendar', + viewType: 'WorkPackagesCalendar', + } + %> diff --git a/app/views/work_packages/calendars/index.html.erb b/modules/calendar/app/views/calendar/calendar/index.html.erb similarity index 100% rename from app/views/work_packages/calendars/index.html.erb rename to modules/calendar/app/views/calendar/calendar/index.html.erb diff --git a/modules/calendar/config/locales/en.yml b/modules/calendar/config/locales/en.yml new file mode 100644 index 00000000000..9bbe445e37a --- /dev/null +++ b/modules/calendar/config/locales/en.yml @@ -0,0 +1,4 @@ +# English strings go here +en: + permission_view_calendar: "View calendar" + project_module_calendar_view: "Calendar" diff --git a/modules/calendar/config/routes.rb b/modules/calendar/config/routes.rb new file mode 100644 index 00000000000..40ef4fb1974 --- /dev/null +++ b/modules/calendar/config/routes.rb @@ -0,0 +1,7 @@ +OpenProject::Application.routes.draw do + scope 'projects/:project_id', as: 'project' do + resources :calendar, controller: 'calendar/calendar', only: [:index] + end + + resources :calendar, controller: 'calendar/calendar', only: [:index] +end diff --git a/modules/calendar/lib/open_project/calendar.rb b/modules/calendar/lib/open_project/calendar.rb new file mode 100644 index 00000000000..73a0c190f8f --- /dev/null +++ b/modules/calendar/lib/open_project/calendar.rb @@ -0,0 +1,33 @@ +#-- 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. +#++ + +module OpenProject + module Calendar + require 'open_project/calendar/engine' + end +end diff --git a/modules/calendar/lib/open_project/calendar/engine.rb b/modules/calendar/lib/open_project/calendar/engine.rb new file mode 100644 index 00000000000..d5f05e0879a --- /dev/null +++ b/modules/calendar/lib/open_project/calendar/engine.rb @@ -0,0 +1,54 @@ +# OpenProject Calendar module +# +# Copyright (C) 2021 OpenProject GmbH +# +# 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. + +module OpenProject::Calendar + class Engine < ::Rails::Engine + engine_name :openproject_calendar + + include OpenProject::Plugins::ActsAsOpEngine + + register 'openproject-calendar', + author_url: 'https://www.openproject.org', + bundled: true, + settings: {}, + name: 'OpenProject Calendar' do + project_module :calendar_view, dependencies: :work_package_tracking do + permission :view_calendar, + { 'calendar/calendar': %i[index] } + end + + menu :project_menu, + :calendar_view, + { controller: '/calendar/calendar', action: 'index' }, + caption: :label_calendar, + icon: 'icon2 icon-calendar', + after: :work_packages + + menu :project_menu, + :calendar_menu, + { controller: '/calendar/calendar', action: 'index' }, + parent: :calendar_view, + partial: 'calendar/calendar/menu', + last: true, + caption: :label_calendar + end + + add_view :WorkPackagesCalendar, + contract_strategy: 'Calendar::Views::ContractStrategy' + end +end diff --git a/modules/calendar/lib/openproject-calendar.rb b/modules/calendar/lib/openproject-calendar.rb new file mode 100644 index 00000000000..39ee5b24567 --- /dev/null +++ b/modules/calendar/lib/openproject-calendar.rb @@ -0,0 +1 @@ +require 'open_project/calendar' diff --git a/modules/calendar/openproject-calendar.gemspec b/modules/calendar/openproject-calendar.gemspec new file mode 100644 index 00000000000..3fe40b68fc1 --- /dev/null +++ b/modules/calendar/openproject-calendar.gemspec @@ -0,0 +1,13 @@ +# encoding: UTF-8 + +Gem::Specification.new do |s| + s.name = 'openproject-calendar' + s.version = '1.0.0' + s.authors = 'OpenProject GmbH' + s.email = 'info@openproject.com' + s.summary = 'OpenProject Calendar' + s.description = 'Provides calendar views' + s.license = 'GPLv3' + + s.files = Dir['{app,config,db,lib}/**/*'] +end diff --git a/spec/controllers/work_packages/calendars_controller_spec.rb b/modules/calendar/spec/controllers/calendar_controller_spec.rb similarity index 91% rename from spec/controllers/work_packages/calendars_controller_spec.rb rename to modules/calendar/spec/controllers/calendar_controller_spec.rb index 7a6c10307f2..977b97a034e 100644 --- a/spec/controllers/work_packages/calendars_controller_spec.rb +++ b/modules/calendar/spec/controllers/calendar_controller_spec.rb @@ -28,7 +28,7 @@ require 'spec_helper' -describe WorkPackages::CalendarsController, type: :controller do +describe Calendar::CalendarController, type: :controller do let(:project) do FactoryBot.build_stubbed(:project).tap do |p| allow(Project) @@ -42,7 +42,7 @@ describe WorkPackages::CalendarsController, type: :controller do FactoryBot.build_stubbed(:user).tap do |user| allow(user) .to receive(:allowed_to?) do |permission, p, global:| - permission[:controller] == 'work_packages/calendars' && + permission[:controller] == '/calendar/calendar' && permission[:action] == 'index' && (p.nil? || p == project) end @@ -57,7 +57,7 @@ describe WorkPackages::CalendarsController, type: :controller do it { is_expected.to be_successful } - it { is_expected.to render_template('work_packages/calendars/index') } + it { is_expected.to render_template('calendar/calendar/index') } end context 'cross-project' do diff --git a/spec/features/calendars/calendars_spec.rb b/modules/calendar/spec/features/calendars_spec.rb similarity index 100% rename from spec/features/calendars/calendars_spec.rb rename to modules/calendar/spec/features/calendars_spec.rb diff --git a/spec/routing/work_package/calendars_routing_spec.rb b/modules/calendar/spec/routing/calendar_routing_spec.rb similarity index 64% rename from spec/routing/work_package/calendars_routing_spec.rb rename to modules/calendar/spec/routing/calendar_routing_spec.rb index 03d94ac9252..b74f40eea2f 100644 --- a/spec/routing/work_package/calendars_routing_spec.rb +++ b/modules/calendar/spec/routing/calendar_routing_spec.rb @@ -28,15 +28,15 @@ require 'spec_helper' -describe WorkPackages::CalendarsController, type: :routing do - it 'should connect GET /work_packages/calendar to work_package/calendar#index' do - expect(get('/work_packages/calendar')).to route_to(controller: 'work_packages/calendars', - action: 'index') +describe Calendar::CalendarController, type: :routing do + it 'should connect GET /calendar to calendar#index' do + expect(get('/calendar')).to route_to(controller: 'calendar/calendar', + action: 'index') end - it 'should connect GET /project/1/work_packages/calendar to work_package/calendar#index' do - expect(get('/projects/1/work_packages/calendar')).to route_to(controller: 'work_packages/calendars', - action: 'index', - project_id: '1') + it 'should connect GET /project/1/calendar to calendar#index' do + expect(get('/projects/1/calendar')).to route_to(controller: 'calendar/calendar', + action: 'index', + project_id: '1') end end diff --git a/modules/reporting/spec/features/menu_spec.rb b/modules/reporting/spec/features/menu_spec.rb index cf068e59602..f8d5c7192f2 100644 --- a/modules/reporting/spec/features/menu_spec.rb +++ b/modules/reporting/spec/features/menu_spec.rb @@ -50,7 +50,7 @@ describe 'project menu', type: :feature do # `url_for controller: 'cost_reports'` will yield different results ... # # when on `/projects/ponyo/work_packages`: `/projects/ponyo/cost_reports` (correct) - # when on `/projects/ponyo/work_packages/calendar`: `/work_packages/cost_reports?project_id=ponyo` + # when on `/projects/ponyo/calendar`: `/work_packages/cost_reports?project_id=ponyo` # # This is only relevant for project menu entries, not global ones (`project_id` param is nil)*. # Meaning that you have to make sure to force the absolute URL in a project menu entry @@ -80,7 +80,7 @@ describe 'project menu', type: :feature do end context "when on the project's calendar" do - let(:current_path) { '/projects/ponyo/work_packages/calendar' } + let(:current_path) { '/projects/ponyo/calendar' } it_behaves_like 'it leads to the project costs reports' end @@ -111,7 +111,7 @@ describe 'project menu', type: :feature do end context "when on the project's calendar" do - let(:current_path) { '/projects/ponyo/work_packages/calendar' } + let(:current_path) { '/projects/ponyo/calendar' } it_behaves_like 'it leads to the cost reports' end diff --git a/modules/team_planner/lib/open_project/team_planner/engine.rb b/modules/team_planner/lib/open_project/team_planner/engine.rb index f747caa9c16..e4a3fa20049 100644 --- a/modules/team_planner/lib/open_project/team_planner/engine.rb +++ b/modules/team_planner/lib/open_project/team_planner/engine.rb @@ -40,7 +40,7 @@ module OpenProject::TeamPlanner :team_planner_view, { controller: '/team_planner/team_planner', action: :index }, caption: :'team_planner.label_team_planner', - after: :backlogs, + after: :work_packages, icon: 'icon2 icon-calendar', badge: 'label_menu_badge.pre_alpha' diff --git a/spec/features/homescreen/robots_spec.rb b/spec/features/homescreen/robots_spec.rb index f359c11f392..e895cf209c2 100644 --- a/spec/features/homescreen/robots_spec.rb +++ b/spec/features/homescreen/robots_spec.rb @@ -36,7 +36,7 @@ describe 'robots.txt', type: :feature do end it 'disallows global paths and paths from public project' do - expect(page).to have_content('Disallow: /work_packages/calendar') + expect(page).to have_content('Disallow: /calendar') expect(page).to have_content('Disallow: /activity') expect(page).to have_content("Disallow: /projects/#{project.identifier}/repository")