diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index 2e1ae58c07c5..76f9a26d6066 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -777,7 +777,6 @@ en: required_outside_context: > Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated. - details_activity: "Project details activity" context: "Project context" click_to_switch_to_project: "Project: %{projectname}" confirm_template_load: "Switching the template will reload the page and you will lose all input to this form. Continue?" diff --git a/db/migrate/20241025072902_remove_project_details_widget.rb b/db/migrate/20241025072902_remove_project_details_widget.rb new file mode 100644 index 000000000000..352218ac0b3e --- /dev/null +++ b/db/migrate/20241025072902_remove_project_details_widget.rb @@ -0,0 +1,13 @@ +class RemoveProjectDetailsWidget < ActiveRecord::Migration[7.1] + def up + # The joining of the overview grids is not strictly necessary + # but it ensures that only widgets of overview grids are removed. + execute <<~SQL.squish + DELETE FROM grid_widgets + USING grids + WHERE grids.id = grid_widgets.grid_id + AND grids.type = 'Grids::Overview' + AND grid_widgets.identifier = 'project_details' + SQL + end +end diff --git a/docs/development/concepts/inline-editing/README.md b/docs/development/concepts/inline-editing/README.md index 3bf93fa68e88..4ee0323449b1 100644 --- a/docs/development/concepts/inline-editing/README.md +++ b/docs/development/concepts/inline-editing/README.md @@ -226,12 +226,9 @@ An example where this comes into play is the [`CustomText`](https://github.com/o - [`EditFieldComponent`](https://github.com/opf/openproject/tree/dev/frontend/src/app/shared/components/fields/edit/field-types) definitions containing all display fields and the service to instantiate them - [`EditingPortalService`](https://github.com/opf/openproject/tree/dev/frontend/src/app/shared/components/fields/edit/editing-portal/editing-portal-service.ts) service to create an edit field with event handling in code - [`WorkPackageFullViewComponent`](https://github.com/opf/openproject/blob/dev/frontend/src/app/features/work-packages/routing/wp-full-view/wp-full-view.html) Work package full view template that uses the `edit-form` attribute to create a form for the work package full view (as seen in the Gif above) -- [`ProjectDetailsComponent`](https://github.com/opf/openproject/blob/dev/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.html) Exemplary widget template that uses the form for project attributes ## Minimal example -The [`ProjectDetailsComponent`](https://github.com/opf/openproject/blob/dev/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.html) is a very isolated example showing how to use the edit-form together with `EditableAttributeField` component to show the actual inline-editable field. - On the example of a work package, this following code snippet would create an edit form for a given work package resource and an attribute for the `subject` attribute of that work package. ```html diff --git a/docs/system-admin-guide/attribute-help-texts/README.md b/docs/system-admin-guide/attribute-help-texts/README.md index 7ed9fe72a423..d3fddf0dc8e7 100644 --- a/docs/system-admin-guide/attribute-help-texts/README.md +++ b/docs/system-admin-guide/attribute-help-texts/README.md @@ -65,7 +65,7 @@ The Attribute help texts for work packages will be displayed in the [details vie ## Projects -The Attribute help texts for projects will be displayed in the Project details widget in the [Project overview](../../user-guide/project-overview/) (as in the first screenshot below) and in the [Project settings](../../user-guide/projects/project-settings/project-information/) (as in the second screenshot below). +The Attribute help texts for projects will be displayed in the [Project overview](../../user-guide/project-overview/) (as in the first screenshot below) and in the [Project settings](../../user-guide/projects/project-settings/project-information/) (as in the second screenshot below). They will help the users (e.g. the project managers) understand what kind of information to put in which fields. diff --git a/docs/user-guide/project-overview/README.md b/docs/user-guide/project-overview/README.md index 2aaf71482d41..23a7841f118f 100644 --- a/docs/user-guide/project-overview/README.md +++ b/docs/user-guide/project-overview/README.md @@ -143,19 +143,6 @@ The description can be added or changed in the [project settings](../projects/pr ![project description widget](image-20191112143652698.png) -### Project details widget - -> [!IMPORTANT] -> Project details widget was replaced by [Project attributes](#project-attributes) in [OpenProject 14.0](../../release-notes/14-0-0/) and will be removed in the future. - -The project details widget displays all custom fields for projects, e.g. project owner, project due date, project number, or any other custom field for this project. - -The custom fields can be adapted in the [project settings](../projects/project-settings/). As a system administrator you can [create new custom fields for projects](../../system-admin-guide/custom-fields/custom-fields-projects/). - -![project details widget](image-20191112144557906.png) - -New custom fields for projects can be created in the [system administration](../../system-admin-guide/). - ### Project status widget Add your project status as a widget to display at a glance whether your project is on track, off track or at risk. diff --git a/docs/user-guide/project-overview/image-20191112144557906.png b/docs/user-guide/project-overview/image-20191112144557906.png deleted file mode 100644 index 1096915752a6..000000000000 Binary files a/docs/user-guide/project-overview/image-20191112144557906.png and /dev/null differ diff --git a/frontend/src/app/shared/components/grids/openproject-grids.module.ts b/frontend/src/app/shared/components/grids/openproject-grids.module.ts index baeb77827491..b462966ea91e 100644 --- a/frontend/src/app/shared/components/grids/openproject-grids.module.ts +++ b/frontend/src/app/shared/components/grids/openproject-grids.module.ts @@ -64,12 +64,6 @@ import { WidgetHeaderComponent } from 'core-app/shared/components/grids/widgets/ import { WidgetWpOverviewComponent } from 'core-app/shared/components/grids/widgets/wp-overview/wp-overview.component'; import { WidgetCustomTextComponent } from 'core-app/shared/components/grids/widgets/custom-text/custom-text.component'; import { OpenprojectFieldsModule } from 'core-app/shared/components/fields/openproject-fields.module'; -import { - WidgetProjectDetailsComponent, -} from 'core-app/shared/components/grids/widgets/project-details/project-details.component'; -import { - WidgetProjectDetailsMenuComponent, -} from 'core-app/shared/components/grids/widgets/project-details/project-details-menu.component'; import { WidgetTimeEntriesProjectComponent, } from 'core-app/shared/components/grids/widgets/time-entries/project/time-entries-project.component'; @@ -89,7 +83,7 @@ import { } from './widgets/time-entries/current-user/configuration-modal/configuration.modal'; import { WidgetProjectFavoritesComponent, -} from "core-app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component"; +} from 'core-app/shared/components/grids/widgets/project-favorites/widget-project-favorites.component'; import { IconModule } from 'core-app/shared/components/icon/icon.module'; @NgModule({ @@ -130,7 +124,6 @@ import { IconModule } from 'core-app/shared/components/icon/icon.module'; WidgetWpTableQuerySpaceComponent, WidgetWpGraphComponent, WidgetProjectDescriptionComponent, - WidgetProjectDetailsComponent, WidgetProjectStatusComponent, WidgetSubprojectsComponent, WidgetProjectFavoritesComponent, @@ -138,7 +131,6 @@ import { IconModule } from 'core-app/shared/components/icon/icon.module'; WidgetTimeEntriesProjectComponent, // Widget menus - WidgetProjectDetailsMenuComponent, WidgetMenuComponent, WidgetWpTableMenuComponent, WidgetWpGraphMenuComponent, @@ -331,14 +323,6 @@ export function registerWidgets(injector:Injector) { }, }, }, - { - identifier: 'project_details', - component: WidgetProjectDetailsComponent, - title: i18n.t('js.grid.widgets.project_details.title'), - properties: { - name: i18n.t('js.grid.widgets.project_details.title'), - }, - }, { identifier: 'project_status', component: WidgetProjectStatusComponent, diff --git a/frontend/src/app/shared/components/grids/widgets/project-details/project-details-menu.component.ts b/frontend/src/app/shared/components/grids/widgets/project-details/project-details-menu.component.ts deleted file mode 100644 index 9ee573bdaef3..000000000000 --- a/frontend/src/app/shared/components/grids/widgets/project-details/project-details-menu.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -//-- copyright -// OpenProject is an open source project management software. -// Copyright (C) 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. -//++ - -import { - Component, - OnInit, -} from '@angular/core'; -import { - WidgetAbstractMenuComponent, -} from 'core-app/shared/components/grids/widgets/menu/widget-abstract-menu.component'; -import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op-context-menu.types'; -import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator'; -import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; -import { CurrentProjectService } from 'core-app/core/current-project/current-project.service'; -import { CurrentUserService } from 'core-app/core/current-user/current-user.service'; -import { take } from 'rxjs/operators'; -import { firstValueFrom } from 'rxjs'; - -@Component({ - selector: 'op-widget-project-details-menu', - templateUrl: '../menu/widget-menu.component.html', -}) -export class WidgetProjectDetailsMenuComponent extends WidgetAbstractMenuComponent implements OnInit { - @InjectField() pathHelper:PathHelperService; - - @InjectField() currentProject:CurrentProjectService; - - @InjectField() currentUser:CurrentUserService; - - private capabilityPromise:Promise; - - ngOnInit():void { - this.capabilityPromise = firstValueFrom( - this.currentUser - .hasCapabilities$('activities/read', this.currentProject.id) - .pipe(take(1)), - ); - } - - protected async buildItems():Promise { - const items = [ - this.removeItem, - ]; - if (await this.capabilityPromise) { - items.push(this.projectActivityLinkItem); - } - return items; - } - - protected get projectActivityLinkItem():OpContextMenuItem { - const projectActivityPath = this.pathHelper.projectActivityPath(this.currentProject.identifier as string); - return { - linkText: this.i18n.t('js.project.details_activity'), - href: `${projectActivityPath}?event_types[]=project_attributes`, - }; - } -} diff --git a/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.html b/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.html deleted file mode 100644 index 366d584c04d9..000000000000 --- a/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -
-

- Project details have now moved to a column on the right edge of this page. -

-

- Starting with version 14.0, project attributes can be grouped in sections and enabled and disabled at a project level. Learn more -

- This widget can now be removed or replaced. It will be deleted in subsequent versions. -
diff --git a/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.ts b/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.ts deleted file mode 100644 index a0b0708b387d..000000000000 --- a/frontend/src/app/shared/components/grids/widgets/project-details/project-details.component.ts +++ /dev/null @@ -1,62 +0,0 @@ -//-- copyright -// OpenProject is an open source project management software. -// Copyright (C) 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. -//++ - -import { - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ElementRef, - Injector, - ViewChild, -} from '@angular/core'; -import { AbstractWidgetComponent } from 'core-app/shared/components/grids/widgets/abstract-widget.component'; -import { I18nService } from 'core-app/core/i18n/i18n.service'; -import { CurrentProjectService } from 'core-app/core/current-project/current-project.service'; -import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; - -@Component({ - templateUrl: './project-details.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class WidgetProjectDetailsComponent extends AbstractWidgetComponent { - @ViewChild('contentContainer', { static: true }) readonly contentContainer:ElementRef; - - constructor( - protected readonly i18n:I18nService, - protected readonly injector:Injector, - protected readonly apiV3Service:ApiV3Service, - protected readonly currentProject:CurrentProjectService, - protected readonly cdRef:ChangeDetectorRef, - ) { - super(i18n, injector); - } - - public get isEditable():boolean { - return false; - } -} diff --git a/modules/dashboards/spec/features/project_details_spec.rb b/modules/dashboards/spec/features/project_details_spec.rb deleted file mode 100644 index 6b1b4fc3a99c..000000000000 --- a/modules/dashboards/spec/features/project_details_spec.rb +++ /dev/null @@ -1,149 +0,0 @@ -#-- copyright -# OpenProject is an open source project management software. -# Copyright (C) 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 "../support/pages/dashboard" - -RSpec.describe "Project details widget on dashboard", :js do - let(:system_version) { create(:version, sharing: "system") } - - let!(:project) do - create(:project, members: { other_user => role }) - end - - let(:permissions) do - %i[view_dashboards - manage_dashboards] - end - - let(:editing_permissions) do - %i[view_dashboards - manage_dashboards - edit_project] - end - - let(:role) do - create(:project_role, permissions:) - end - - let(:read_only_user) do - create(:user, member_with_roles: { project => role }) - end - let(:editing_user) do - create(:user, - member_with_permissions: { project => editing_permissions }, - firstname: "Cool", - lastname: "Guy") - end - let(:other_user) do - create(:user, - firstname: "Other", - lastname: "User") - end - - let(:dashboard_page) do - Pages::Dashboard.new(project) - end - - def add_project_details_widget - dashboard_page.visit! - dashboard_page.add_widget(1, 1, :within, "Project details") - - dashboard_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") - end - - before do - login_as current_user - add_project_details_widget - end - - context "without editing permissions" do - let(:current_user) { read_only_user } - - it "displays the deprecated message" do - # As the user lacks the manage_public_queries and save_queries permission, no other widget is present - details_widget = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") - - within(details_widget.area) do - expect(page) - .to have_content("Project details have now moved to a column on the right edge of this page.") - expect(page).to have_content( - <<~TEXT.strip - Starting with version 14.0, project attributes can be grouped \ - in sections and enabled and disabled at a project level. - TEXT - ) - expect(page).to have_content( - <<~TEXT.strip - This widget can now be removed or replaced. \ - It will be deleted in subsequent versions. - TEXT - ) - end - end - end - - context "with editing permissions" do - let(:current_user) { editing_user } - - it "displays the deprecated message" do - # As the user lacks the manage_public_queries and save_queries permission, no other widget is present - details_widget = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") - - within(details_widget.area) do - expect(page) - .to have_content("Project details have now moved to a column on the right edge of this page.") - expect(page).to have_content( - <<~TEXT.strip - Starting with version 14.0, project attributes can be grouped \ - in sections and enabled and disabled at a project level. - TEXT - ) - expect(page).to have_content( - <<~TEXT.strip - This widget can now be removed or replaced. \ - It will be deleted in subsequent versions. - TEXT - ) - end - end - end - - context "when project has Activity module enabled" do - let(:current_user) { read_only_user } - - it 'has a "Project activity" entry in More menu linking to the project activity page' do - details_widget = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") - - details_widget.click_menu_item("Project details activity") - expect(page).to have_current_path(project_activity_index_path(project), ignore_query: true) - expect(page).to have_checked_field(id: "event_types_project_attributes") - end - end -end diff --git a/modules/grids/config/locales/js-en.yml b/modules/grids/config/locales/js-en.yml index ffa20d4f2683..dfa0eecf0af4 100644 --- a/modules/grids/config/locales/js-en.yml +++ b/modules/grids/config/locales/js-en.yml @@ -27,9 +27,6 @@ en: project_description: title: 'Project description' no_results: "No description has been written yet. One can be provided in the 'Project settings'." - project_details: - title: 'Project details' - no_results: 'No custom fields have been defined for projects.' project_status: title: 'Project status' not_started: 'Not started' diff --git a/modules/grids/lib/grids/configuration/in_project_base_registration.rb b/modules/grids/lib/grids/configuration/in_project_base_registration.rb index ad268e575937..647789e59b35 100644 --- a/modules/grids/lib/grids/configuration/in_project_base_registration.rb +++ b/modules/grids/lib/grids/configuration/in_project_base_registration.rb @@ -4,7 +4,6 @@ class InProjectBaseRegistration < ::Grids::Configuration::Registration "work_packages_graph", "project_description", "project_status", - "project_details", "subprojects", "work_packages_calendar", "work_packages_overview", diff --git a/modules/overviews/lib/overviews/grid_registration.rb b/modules/overviews/lib/overviews/grid_registration.rb index 04de8323cf25..cf811904030f 100644 --- a/modules/overviews/lib/overviews/grid_registration.rb +++ b/modules/overviews/lib/overviews/grid_registration.rb @@ -15,7 +15,7 @@ class GridRegistration < ::Grids::Configuration::InProjectBaseRegistration { identifier: "project_description", start_row: 1, - end_row: 2, + end_row: 3, start_column: 1, end_column: 2, options: { @@ -32,16 +32,6 @@ class GridRegistration < ::Grids::Configuration::InProjectBaseRegistration name: I18n.t("js.grid.widgets.project_status.title") } }, - { - identifier: "project_details", - start_row: 2, - end_row: 3, - start_column: 1, - end_column: 2, - options: { - name: I18n.t("js.grid.widgets.project_details.title") - } - }, { identifier: "work_packages_overview", start_row: 3, diff --git a/modules/overviews/spec/contracts/grids/create_contract_spec.rb b/modules/overviews/spec/contracts/grids/create_contract_spec.rb index 225ec352a45b..7e7c95b93db2 100644 --- a/modules/overviews/spec/contracts/grids/create_contract_spec.rb +++ b/modules/overviews/spec/contracts/grids/create_contract_spec.rb @@ -130,13 +130,13 @@ context "(widget added)" do before do grid.row_count = 4 - grid.widgets.build(identifier: "project_details", + grid.widgets.build(identifier: "project_description", start_row: 3, end_row: 4, start_column: 1, end_column: 3, options: { - name: I18n.t("js.grid.widgets.work_packages_overview.title") + name: I18n.t("js.grid.widgets.project_description.title") }) end diff --git a/modules/overviews/spec/features/managing_overview_page_spec.rb b/modules/overviews/spec/features/managing_overview_page_spec.rb index 001ff0292d7f..b05955516e07 100644 --- a/modules/overviews/spec/features/managing_overview_page_spec.rb +++ b/modules/overviews/spec/features/managing_overview_page_spec.rb @@ -73,18 +73,15 @@ it "renders the default view, allows altering and saving" do description_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") status_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(2)") - details_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(3)") - overview_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(4)") - members_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(5)") + overview_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(3)") + members_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(4)") description_area.expect_to_exist status_area.expect_to_exist - details_area.expect_to_exist overview_area.expect_to_exist members_area.expect_to_exist - description_area.expect_to_span(1, 1, 2, 2) + description_area.expect_to_span(1, 1, 3, 2) status_area.expect_to_span(1, 2, 2, 3) - details_area.expect_to_span(2, 1, 3, 2) overview_area.expect_to_span(3, 1, 4, 3) members_area.expect_to_span(2, 2, 3, 3) @@ -107,7 +104,7 @@ overview_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") - table_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(6)") + table_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(5)") table_area.expect_to_span(1, 1, 2, 2) # A useless resizing shows no message and does not alter the size @@ -138,11 +135,12 @@ overview_page.visit! ## Because of the added column and the resizing the other widgets have moved down + # For unknown, undesired reasons, the project description no longer spans two rows. + # This happens when resizing the table area. description_area.expect_to_span(2, 1, 3, 2) - status_area.expect_to_span(2, 2, 4, 3) - details_area.expect_to_span(3, 1, 4, 2) - overview_area.expect_to_span(5, 1, 6, 3) - members_area.expect_to_span(4, 2, 5, 3) + status_area.expect_to_span(2, 2, 3, 3) + overview_area.expect_to_span(4, 1, 5, 3) + members_area.expect_to_span(3, 2, 4, 3) table_area.expect_to_span(1, 1, 2, 3) end end diff --git a/spec/migrations/remove_project_details_widget_spec.rb b/spec/migrations/remove_project_details_widget_spec.rb new file mode 100644 index 000000000000..26dc85fcda39 --- /dev/null +++ b/spec/migrations/remove_project_details_widget_spec.rb @@ -0,0 +1,62 @@ +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2010-2024 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 Rails.root.join("db/migrate/20241025072902_remove_project_details_widget.rb") + +RSpec.describe RemoveProjectDetailsWidget, type: :model do + subject do + ActiveRecord::Migration.suppress_messages do + described_class + .new + .tap { _1.migrate(:up) } + end + end + + let!(:overview) do + create(:overview) do |o| + create(:grid_widget, grid: o, identifier: "widget_a", start_row: 1, end_row: 2, start_column: 1, end_column: 2) + create(:grid_widget, grid: o, identifier: "widget_b", start_row: 1, end_row: 2, start_column: 2, end_column: 3) + create(:grid_widget, grid: o, identifier: "project_details", start_row: 2, end_row: 3, start_column: 1, end_column: 2) + create(:grid_widget, grid: o, identifier: "widget_c", start_row: 2, end_row: 3, start_column: 2, end_column: 3) + create(:grid_widget, grid: o, identifier: "widget_d", start_row: 3, end_row: 4, start_column: 1, end_column: 2) + create(:grid_widget, grid: o, identifier: "widget_1", start_row: 4, end_row: 4, start_column: 2, end_column: 3) + end + end + + it "removes only the project_details widget", :aggregate_failures do + subject + + expect(Grids::Widget.where(identifier: "project_details")).not_to exist + expect(Grids::Widget.where(identifier: "widget_a", start_row: 1, end_row: 2, start_column: 1, end_column: 2)).to exist + expect(Grids::Widget.where(identifier: "widget_b", start_row: 1, end_row: 2, start_column: 2, end_column: 3)).to exist + expect(Grids::Widget.where(identifier: "widget_c", start_row: 2, end_row: 3, start_column: 2, end_column: 3)).to exist + expect(Grids::Widget.where(identifier: "widget_d", start_row: 3, end_row: 4, start_column: 1, end_column: 2)).to exist + expect(Grids::Widget.where(identifier: "widget_1", start_row: 4, end_row: 4, start_column: 2, end_column: 3)).to exist + end +end