mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
BUG/34971 Order of work packages in XLS, PDF, CSV export differs from order in OpenProject (#10719)
* Save the new queries when manually sorting the work packages * fixup! Save the new queries when manually sorting the work packages * fixup! Save the new queries when manually sorting the work packages
This commit is contained in:
@@ -64,6 +64,10 @@ export class QueryResource extends HalResource {
|
||||
|
||||
public sortBy:QuerySortByResource[];
|
||||
|
||||
public setSortBy(newSortBy:QuerySortByResource[]):void {
|
||||
this.sortBy = newSortBy;
|
||||
}
|
||||
|
||||
public filters:QueryFilterInstanceResource[];
|
||||
|
||||
public starred:boolean;
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ export class DragAndDropTransformer {
|
||||
// Save the query when switching to manual
|
||||
const query = this.querySpace.query.value;
|
||||
if (query && this.wpTableSortBy.switchToManualSorting(query)) {
|
||||
await this.wpListService.save(query);
|
||||
await this.wpListService.createOrSave(query);
|
||||
}
|
||||
} catch (e) {
|
||||
this.halNotification.handleRawError(e);
|
||||
|
||||
@@ -120,7 +120,7 @@ export class WorkPackagesGridComponent implements WorkPackageViewOutputs {
|
||||
public switchToManualSorting() {
|
||||
const query = this.querySpace.query.value;
|
||||
if (query && this.wpTableSortBy.switchToManualSorting(query)) {
|
||||
this.wpList.save(query);
|
||||
void this.wpList.createOrSave(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import { AuthorisationService } from 'core-app/core/model-auth/model-auth.servic
|
||||
import { StateService } from '@uirouter/core';
|
||||
import { IsolatedQuerySpace } from 'core-app/features/work-packages/directives/query-space/isolated-query-space';
|
||||
import { Injectable } from '@angular/core';
|
||||
import isPersistedResource from 'core-app/features/hal/helpers/is-persisted-resource';
|
||||
import { UrlParamsHelperService } from 'core-app/features/work-packages/components/wp-query/url-params-helper';
|
||||
import { ToastService } from 'core-app/shared/components/toaster/toast.service';
|
||||
import { I18nService } from 'core-app/core/i18n/i18n.service';
|
||||
@@ -333,6 +334,13 @@ export class WorkPackagesListService {
|
||||
return promise;
|
||||
}
|
||||
|
||||
public async createOrSave(query:QueryResource):Promise<unknown> {
|
||||
if (!isPersistedResource(query)) {
|
||||
return this.create(query, 'New manually sorted query');
|
||||
}
|
||||
return this.save(query);
|
||||
}
|
||||
|
||||
public toggleStarred(query:QueryResource):Promise<any> {
|
||||
const promise = this
|
||||
.apiV3Service
|
||||
|
||||
+2
-8
@@ -34,7 +34,6 @@ import { QueryResource } from 'core-app/features/hal/resources/query-resource';
|
||||
import { IsolatedQuerySpace } from 'core-app/features/work-packages/directives/query-space/isolated-query-space';
|
||||
import { States } from 'core-app/core/states/states.service';
|
||||
import { QuerySortByResource } from 'core-app/features/hal/resources/query-sort-by-resource';
|
||||
import isPersistedResource from 'core-app/features/hal/helpers/is-persisted-resource';
|
||||
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
|
||||
import { QueryColumn } from 'core-app/features/work-packages/components/wp-query/query-column';
|
||||
import { WorkPackageQueryStateService } from './wp-view-base.service';
|
||||
@@ -123,13 +122,8 @@ export class WorkPackageViewSortByService extends WorkPackageQueryStateService<Q
|
||||
public switchToManualSorting(query:QueryResource):boolean {
|
||||
const { manualSortObject } = this;
|
||||
if (manualSortObject && !this.isManualSortingMode) {
|
||||
if (query && isPersistedResource(query)) {
|
||||
// Save the query if it is persisted
|
||||
query.sortBy = [manualSortObject];
|
||||
return true;
|
||||
}
|
||||
// Query cannot be saved, just update the props for now
|
||||
this.update([manualSortObject]);
|
||||
query.setSortBy([manualSortObject]);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -36,44 +36,45 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
let(:type_task) { create :type_task }
|
||||
let(:type_bug) { create :type_bug }
|
||||
let(:project) { create(:project, types: [type_task, type_bug]) }
|
||||
let(:work_package_1) do
|
||||
create(:work_package, subject: 'WP1', project: project, type: type_task, created_at: Time.now)
|
||||
let(:work_package1) do
|
||||
create(:work_package, subject: 'WP1', project:, type: type_task, created_at: Time.zone.now)
|
||||
end
|
||||
let(:work_package_2) do
|
||||
let(:work_package2) do
|
||||
create(:work_package,
|
||||
subject: 'WP2',
|
||||
project: project,
|
||||
parent: work_package_1,
|
||||
project:,
|
||||
parent: work_package1,
|
||||
type: type_task,
|
||||
created_at: Time.now - 1.minutes)
|
||||
created_at: 1.minute.ago)
|
||||
end
|
||||
let(:work_package_3) do
|
||||
let(:work_package3) do
|
||||
create(:work_package,
|
||||
subject: 'WP3',
|
||||
project: project,
|
||||
parent: work_package_2,
|
||||
project:,
|
||||
parent: work_package2,
|
||||
type: type_bug,
|
||||
created_at: Time.now - 2.minutes)
|
||||
created_at: 2.minutes.ago)
|
||||
end
|
||||
let(:work_package_4) do
|
||||
let(:work_package4) do
|
||||
create(:work_package,
|
||||
subject: 'WP4',
|
||||
project: project,
|
||||
parent: work_package_3,
|
||||
project:,
|
||||
parent: work_package3,
|
||||
type: type_bug,
|
||||
created_at: Time.now - 3.minutes)
|
||||
created_at: 3.minutes.ago)
|
||||
end
|
||||
|
||||
let(:sort_by) { ::Components::WorkPackages::SortBy.new }
|
||||
let(:hierarchies) { ::Components::WorkPackages::Hierarchies.new }
|
||||
let(:dialog) { ::Components::ConfirmationDialog.new }
|
||||
let(:pagination) { ::Components::TablePagination.new }
|
||||
let(:display_representation) { ::Components::WorkPackages::DisplayRepresentation.new }
|
||||
|
||||
def expect_query_order(query, expected)
|
||||
retry_block do
|
||||
query.reload
|
||||
|
||||
# work_package_4 was not positioned
|
||||
# work_package4 was not positioned
|
||||
found = query.ordered_work_packages.pluck(:work_package_id)
|
||||
|
||||
raise "Backend order is incorrect: #{found} != #{expected}" unless found == expected
|
||||
@@ -83,10 +84,10 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
before do
|
||||
login_as(user)
|
||||
|
||||
work_package_1
|
||||
work_package_2
|
||||
work_package_3
|
||||
work_package_4
|
||||
work_package1
|
||||
work_package2
|
||||
work_package3
|
||||
work_package4
|
||||
end
|
||||
|
||||
describe 'hierarchy mode' do
|
||||
@@ -94,30 +95,27 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
wp_table.visit!
|
||||
|
||||
# Hierarchy enabled
|
||||
wp_table.expect_work_package_order(work_package_1, work_package_2, work_package_3, work_package_4)
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2, work_package_3)
|
||||
hierarchies.expect_leaf_at(work_package_4)
|
||||
wp_table.expect_work_package_order(work_package1, work_package2, work_package3, work_package4)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2, work_package3)
|
||||
hierarchies.expect_leaf_at(work_package4)
|
||||
end
|
||||
|
||||
it 'maintains the order until saved' do
|
||||
it 'maintains the order and automatically saves the query' do
|
||||
wp_table.drag_and_drop_work_package from: 3, to: 1
|
||||
loading_indicator_saveguard
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_4, work_package_3)
|
||||
|
||||
expect(page).to have_selector('.editable-toolbar-title--save')
|
||||
wp_table.save_as "My sorted query"
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package4, work_package3)
|
||||
|
||||
wp_table.expect_and_dismiss_toaster message: 'Successful creation.'
|
||||
|
||||
query = nil
|
||||
retry_block do
|
||||
query = Query.last
|
||||
raise "Query was not yet saved." unless query.name == 'My sorted query'
|
||||
raise "Query was not yet saved." unless query.name == 'New manually sorted query'
|
||||
end
|
||||
|
||||
# Expect sorted 1 and 2, the rest is not positioned
|
||||
expect_query_order(query, [work_package_1, work_package_4].map(&:id))
|
||||
expect_query_order(query, [work_package1, work_package4].map(&:id))
|
||||
|
||||
# Pagination information is shown but no per page options
|
||||
pagination.expect_range(1, 4, 4)
|
||||
@@ -128,72 +126,72 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
# Move up the hierarchy
|
||||
wp_table.drag_and_drop_work_package from: 3, to: 1
|
||||
loading_indicator_saveguard
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_3, work_package_4)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package3, work_package4)
|
||||
|
||||
# Keep after table refresh
|
||||
page.driver.browser.navigate.refresh
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_3, work_package_4)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package3, work_package4)
|
||||
end
|
||||
|
||||
it 'can drag an element completely out of the hierarchy' do
|
||||
# Move up the hierarchy
|
||||
wp_table.drag_and_drop_work_package from: 3, to: 0
|
||||
loading_indicator_saveguard
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_4)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package4)
|
||||
|
||||
# Expect WP has no parent
|
||||
wp_page = Pages::SplitWorkPackage.new(work_package_4)
|
||||
wp_page = Pages::SplitWorkPackage.new(work_package4)
|
||||
wp_page.visit!
|
||||
wp_page.expect_no_parent
|
||||
|
||||
# Keep after table refresh
|
||||
page.driver.browser.navigate.refresh
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_3, work_package_4)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package3, work_package4)
|
||||
wp_page.expect_no_parent
|
||||
end
|
||||
|
||||
context 'drag an element partly out of the hierarchy' do
|
||||
let(:work_package_5) do
|
||||
create(:work_package, subject: 'WP5', project: project, parent: work_package_1)
|
||||
context 'when dragging an element partly out of the hierarchy' do
|
||||
let(:work_package5) do
|
||||
create(:work_package, subject: 'WP5', project:, parent: work_package1)
|
||||
end
|
||||
let(:work_package_6) do
|
||||
create(:work_package, subject: 'WP6', project: project, parent: work_package_1)
|
||||
let(:work_package6) do
|
||||
create(:work_package, subject: 'WP6', project:, parent: work_package1)
|
||||
end
|
||||
|
||||
before do
|
||||
work_package_5
|
||||
work_package_6
|
||||
work_package_4.parent = work_package_2
|
||||
work_package_4.save!
|
||||
work_package5
|
||||
work_package6
|
||||
work_package4.parent = work_package2
|
||||
work_package4.save!
|
||||
wp_table.visit!
|
||||
|
||||
# Hierarchy enabled
|
||||
wp_table.expect_work_package_order(work_package_1,
|
||||
work_package_2,
|
||||
work_package_3,
|
||||
work_package_4,
|
||||
work_package_5,
|
||||
work_package_6)
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_3, work_package_4, work_package_5, work_package_6)
|
||||
wp_table.expect_work_package_order(work_package1,
|
||||
work_package2,
|
||||
work_package3,
|
||||
work_package4,
|
||||
work_package5,
|
||||
work_package6)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package3, work_package4, work_package5, work_package6)
|
||||
end
|
||||
|
||||
it 'move below a sibling of my parent' do
|
||||
wp_table.drag_and_drop_work_package from: 3, to: 5
|
||||
|
||||
loading_indicator_saveguard
|
||||
wp_table.expect_work_package_order(work_package_1,
|
||||
work_package_2,
|
||||
work_package_3,
|
||||
work_package_5,
|
||||
work_package_4,
|
||||
work_package_6)
|
||||
hierarchies.expect_hierarchy_at(work_package_1, work_package_2)
|
||||
hierarchies.expect_leaf_at(work_package_3, work_package_4, work_package_5, work_package_6)
|
||||
wp_table.expect_work_package_order(work_package1,
|
||||
work_package2,
|
||||
work_package3,
|
||||
work_package5,
|
||||
work_package4,
|
||||
work_package6)
|
||||
hierarchies.expect_hierarchy_at(work_package1, work_package2)
|
||||
hierarchies.expect_leaf_at(work_package3, work_package4, work_package5, work_package6)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -208,12 +206,12 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
|
||||
wp_table.save_as 'Type query'
|
||||
wp_table.expect_and_dismiss_toaster message: 'Successful creation.'
|
||||
|
||||
expect(page).to have_selector('.group--value', text: 'Task (2)')
|
||||
expect(page).to have_selector('.group--value', text: 'Bug (2)')
|
||||
end
|
||||
|
||||
it 'updates the work packages appropriately' do
|
||||
expect(page).to have_selector('.group--value', text: 'Task (2)')
|
||||
expect(page).to have_selector('.group--value', text: 'Bug (2)')
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 0, to: 3
|
||||
|
||||
expect(page).to have_selector('.group--value', text: 'Task (1)')
|
||||
@@ -221,6 +219,9 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
end
|
||||
|
||||
it 'dragging item with parent does not result in an error (Regression #30832)' do
|
||||
expect(page).to have_selector('.group--value', text: 'Task (2)')
|
||||
expect(page).to have_selector('.group--value', text: 'Bug (2)')
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
|
||||
expect(page).to have_selector('.group--value', text: 'Task (1)')
|
||||
@@ -233,7 +234,7 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
|
||||
describe 'with a saved query and positions increasing from zero' do
|
||||
let(:query) do
|
||||
create(:query, user: user, project: project, show_hierarchies: false).tap do |q|
|
||||
create(:query, user:, project:, show_hierarchies: false).tap do |q|
|
||||
q.sort_criteria = [[:manual_sorting, 'asc']]
|
||||
q.save!
|
||||
end
|
||||
@@ -242,15 +243,15 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
let!(:priority) { create :default_priority }
|
||||
|
||||
before do
|
||||
::OrderedWorkPackage.create(query: query, work_package: work_package_1, position: 0)
|
||||
::OrderedWorkPackage.create(query: query, work_package: work_package_2, position: 1)
|
||||
::OrderedWorkPackage.create(query: query, work_package: work_package_3, position: 2)
|
||||
::OrderedWorkPackage.create(query: query, work_package: work_package_4, position: 3)
|
||||
::OrderedWorkPackage.create(query:, work_package: work_package1, position: 0)
|
||||
::OrderedWorkPackage.create(query:, work_package: work_package2, position: 1)
|
||||
::OrderedWorkPackage.create(query:, work_package: work_package3, position: 2)
|
||||
::OrderedWorkPackage.create(query:, work_package: work_package4, position: 3)
|
||||
end
|
||||
|
||||
it 'can inline create a work package and it is positioned to the bottom (Regression #31078)' do
|
||||
wp_table.visit_query query
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4
|
||||
|
||||
wp_table.click_inline_create
|
||||
subject_field = wp_table.edit_field(nil, :subject)
|
||||
@@ -271,26 +272,26 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
|
||||
# Wait until the order was saved, this might take a few moments
|
||||
retry_block do
|
||||
order = ::OrderedWorkPackage.find_by(query: query, work_package: inline_created)
|
||||
order = ::OrderedWorkPackage.find_by(query:, work_package: inline_created)
|
||||
|
||||
unless order&.position == 8195
|
||||
raise "Expected order of #{inline_created.id} to be 8195. Was: #{order&.position}. Retrying"
|
||||
end
|
||||
end
|
||||
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4, inline_created
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4, inline_created
|
||||
|
||||
# Revisit the query
|
||||
wp_table.visit_query query
|
||||
|
||||
# Expect same order
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4, inline_created
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4, inline_created
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with a saved query that is NOT manually sorted' do
|
||||
let(:query) do
|
||||
create(:query, user: user, project: project, show_hierarchies: false).tap do |q|
|
||||
create(:query, user:, project:, show_hierarchies: false).tap do |q|
|
||||
q.sort_criteria = [[:id, 'asc']]
|
||||
q.save!
|
||||
end
|
||||
@@ -298,11 +299,11 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
|
||||
it 'can drag and drop and will save the query' do
|
||||
wp_table.visit_query query
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
|
||||
wp_table.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
|
||||
wp_table.expect_and_dismiss_toaster message: 'Successful update.'
|
||||
|
||||
@@ -323,26 +324,24 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
before do
|
||||
wp_table.visit!
|
||||
hierarchies.disable_via_header
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4
|
||||
end
|
||||
|
||||
it 'can sort table rows via DragNDrop' do
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
|
||||
wp_table.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
|
||||
wp_table.save_as 'Manual sorted query'
|
||||
wp_table.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
|
||||
wp_table.expect_and_dismiss_toaster message: 'Successful creation.'
|
||||
|
||||
query = Query.last
|
||||
expect(query.name).to eq 'Manual sorted query'
|
||||
expect(query.name).to eq 'New manually sorted query'
|
||||
|
||||
expect_query_order(query, [work_package_1.id, work_package_3.id, work_package_2.id])
|
||||
expect_query_order(query, [work_package1.id, work_package3.id, work_package2.id])
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 0, to: 2
|
||||
|
||||
expect_query_order(query, [work_package_3.id, work_package_1.id, work_package_2.id])
|
||||
expect_query_order(query, [work_package3.id, work_package1.id, work_package2.id])
|
||||
end
|
||||
|
||||
it 'saves the changed order in a previously saved query' do
|
||||
@@ -354,11 +353,11 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
|
||||
wp_table.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
|
||||
query = Query.last
|
||||
expect(query.name).to eq 'Manual sorted query'
|
||||
expect_query_order(query, [work_package_1.id, work_package_3.id, work_package_2.id])
|
||||
expect_query_order(query, [work_package1.id, work_package3.id, work_package2.id])
|
||||
|
||||
pagination.expect_range(1, 4, 4)
|
||||
pagination.expect_no_per_page_options
|
||||
@@ -367,7 +366,7 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
it 'does not loose the current order when switching to manual sorting' do
|
||||
# Sort by creation date
|
||||
sort_by.update_criteria 'Created on'
|
||||
wp_table.expect_work_package_order work_package_4, work_package_3, work_package_2, work_package_1
|
||||
wp_table.expect_work_package_order work_package4, work_package3, work_package2, work_package1
|
||||
|
||||
# Enable manual sorting
|
||||
sort_by.open_modal
|
||||
@@ -375,13 +374,13 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
sort_by.apply_changes
|
||||
|
||||
# Expect same order
|
||||
wp_table.expect_work_package_order work_package_4, work_package_3, work_package_2, work_package_1
|
||||
wp_table.expect_work_package_order work_package4, work_package3, work_package2, work_package1
|
||||
end
|
||||
|
||||
it 'shows a warning when switching from manual to automatic sorting' do
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
|
||||
wp_table.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
|
||||
# Try to sort by creation date
|
||||
sort_by.sort_via_header 'Subject'
|
||||
@@ -389,10 +388,10 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
# Shows a warning
|
||||
dialog.expect_open
|
||||
dialog.confirm
|
||||
wp_table.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package2, work_package3, work_package4
|
||||
end
|
||||
|
||||
context 'the gantt chart' do
|
||||
context 'when view is gantt chart' do
|
||||
let(:wp_timeline) { Pages::WorkPackagesTimeline.new(project) }
|
||||
|
||||
it 'reloads after drop' do
|
||||
@@ -400,11 +399,36 @@ describe 'Manual sorting of WP table', type: :feature, js: true do
|
||||
wp_timeline.expect_timeline!
|
||||
wp_timeline.expect_row_count(4)
|
||||
|
||||
wp_timeline.expect_work_package_order work_package_1, work_package_2, work_package_3, work_package_4
|
||||
wp_timeline.expect_work_package_order work_package1, work_package2, work_package3, work_package4
|
||||
|
||||
wp_table.drag_and_drop_work_package from: 1, to: 3
|
||||
wp_table.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
wp_timeline.expect_work_package_order work_package_1, work_package_3, work_package_2, work_package_4
|
||||
wp_table.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
wp_timeline.expect_work_package_order work_package1, work_package3, work_package2, work_package4
|
||||
end
|
||||
end
|
||||
|
||||
context 'when view is card' do
|
||||
let(:wp_card) { Pages::WorkPackageCards.new(project) }
|
||||
|
||||
before do
|
||||
display_representation.switch_to_card_layout
|
||||
loading_indicator_saveguard
|
||||
end
|
||||
|
||||
it 'can sort cards via DragNDrop' do
|
||||
wp_card.drag_and_drop_work_package from: 0, to: 3
|
||||
|
||||
wp_card.expect_work_package_order work_package2, work_package3, work_package4, work_package1
|
||||
|
||||
wp_card.expect_and_dismiss_toaster message: 'Successful creation.'
|
||||
|
||||
query = Query.last
|
||||
expect(query.name).to eq 'New manually sorted query'
|
||||
expect_query_order(query, [work_package2.id, work_package3.id, work_package4.id, work_package1.id])
|
||||
|
||||
wp_card.drag_and_drop_work_package from: 0, to: 2
|
||||
|
||||
expect_query_order(query, [work_package3.id, work_package4.id, work_package1.id, work_package2.id])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,14 +74,14 @@ module Pages
|
||||
Capybara.current_session.driver.is_a?(Capybara::Selenium::Driver)
|
||||
end
|
||||
|
||||
def set_items_per_page!(n)
|
||||
Setting.per_page_options = "#{n}, 50, 100"
|
||||
def set_items_per_page!(number)
|
||||
Setting.per_page_options = "#{number}, 50, 100"
|
||||
end
|
||||
|
||||
def expect_current_path(query_params = nil)
|
||||
uri = URI.parse(current_url)
|
||||
current_path = uri.path
|
||||
current_path += '?' + uri.query if uri.query
|
||||
current_path += "?#{uri.query}" if uri.query
|
||||
|
||||
expected_path = path
|
||||
expected_path += "?#{query_params}" if query_params
|
||||
@@ -102,9 +102,9 @@ module Pages
|
||||
end
|
||||
|
||||
def expect_and_dismiss_toaster(message:, type: :success)
|
||||
expect_toast(type: type, message: message)
|
||||
expect_toast(type:, message:)
|
||||
dismiss_toaster!
|
||||
expect_no_toaster(type: type, message: message)
|
||||
expect_no_toaster(type:, message:)
|
||||
end
|
||||
|
||||
def dismiss_toaster!
|
||||
@@ -123,6 +123,55 @@ module Pages
|
||||
end
|
||||
end
|
||||
|
||||
def drag_and_drop_list(from:, to:, elements:, handler:)
|
||||
# Wait a bit because drag & drop in selenium is easily offended
|
||||
sleep 1
|
||||
|
||||
list = page.all(elements)
|
||||
source = list[from]
|
||||
target = list[to]
|
||||
|
||||
scroll_to_element(source)
|
||||
source.hover
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(source.native)
|
||||
.click_and_hold(source.find(handler).native)
|
||||
.perform
|
||||
|
||||
## Hover over each item to be sure,
|
||||
# that the dragged element is reduced to the minimum height.
|
||||
# Thus we can afterwards drag to the correct position.
|
||||
list.each do |item|
|
||||
next if item == source
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(item.native)
|
||||
.perform
|
||||
end
|
||||
|
||||
sleep 2
|
||||
|
||||
scroll_to_element(target)
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(target.native)
|
||||
.release
|
||||
.perform
|
||||
|
||||
# Wait a bit because drag & drop in selenium is easily offended
|
||||
sleep 1
|
||||
end
|
||||
|
||||
def path
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -35,6 +35,7 @@ module Pages
|
||||
|
||||
def initialize(project = nil)
|
||||
@project = project
|
||||
super()
|
||||
end
|
||||
|
||||
def expect_work_package_listed(*work_packages)
|
||||
@@ -80,6 +81,10 @@ module Pages
|
||||
::Pages::SplitWorkPackage.new(work_package, project)
|
||||
end
|
||||
|
||||
def drag_and_drop_work_package(from:, to:)
|
||||
drag_and_drop_list(from:, to:, elements: 'wp-single-card', handler: '.op-wp-single-card--content')
|
||||
end
|
||||
|
||||
def select_work_package(work_package)
|
||||
card(work_package).click
|
||||
end
|
||||
|
||||
@@ -37,6 +37,7 @@ module Pages
|
||||
|
||||
def initialize(project = nil)
|
||||
@project = project
|
||||
super()
|
||||
end
|
||||
|
||||
def visit_query(query)
|
||||
@@ -75,9 +76,9 @@ module Pages
|
||||
end
|
||||
end
|
||||
|
||||
def expect_work_package_count(n)
|
||||
def expect_work_package_count(count)
|
||||
within(table_container) do
|
||||
expect(page).to have_selector(".wp--row", count: n, wait: 20)
|
||||
expect(page).to have_selector(".wp--row", count:, wait: 20)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -171,60 +172,15 @@ module Pages
|
||||
end
|
||||
|
||||
def drag_and_drop_work_package(from:, to:)
|
||||
# Wait a bit because drag & drop in selenium is easily offended
|
||||
sleep 1
|
||||
|
||||
rows = page.all('.wp-table--row')
|
||||
source = rows[from]
|
||||
target = rows[to]
|
||||
|
||||
scroll_to_element(source)
|
||||
source.hover
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(source.native)
|
||||
.click_and_hold(source.find('.wp-table--drag-and-drop-handle', visible: false).native)
|
||||
.perform
|
||||
|
||||
## Hover over each row to be sure,
|
||||
# that the dragged element is reduced to the minimum height.
|
||||
# Thus we can afterwards drag to the correct position.
|
||||
rows.each do |row|
|
||||
next if row == source
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(row.native)
|
||||
.perform
|
||||
end
|
||||
|
||||
sleep 2
|
||||
|
||||
scroll_to_element(target)
|
||||
|
||||
page
|
||||
.driver
|
||||
.browser
|
||||
.action
|
||||
.move_to(target.native)
|
||||
.release
|
||||
.perform
|
||||
|
||||
# Wait a bit because drag & drop in selenium is easily offended
|
||||
sleep 1
|
||||
drag_and_drop_list(from:, to:, elements: '.wp-table--row', handler: '.wp-table--drag-and-drop-handle')
|
||||
end
|
||||
|
||||
def row(work_package)
|
||||
table_container.find(row_selector(work_package))
|
||||
end
|
||||
|
||||
def row_selector(el)
|
||||
id = el.is_a?(WorkPackage) ? el.id.to_s : el.to_s
|
||||
def row_selector(elem)
|
||||
id = elem.is_a?(WorkPackage) ? elem.id.to_s : elem.to_s
|
||||
".wp-row-#{id}-table"
|
||||
end
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ class WorkPackageCards
|
||||
|
||||
def initialize(project = nil)
|
||||
@project = project
|
||||
super()
|
||||
end
|
||||
|
||||
def open_full_screen_by_doubleclick(work_package)
|
||||
|
||||
Reference in New Issue
Block a user