diff --git a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts index 1facc15598..0f24e83452 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts @@ -214,7 +214,7 @@ export class HierarchyRenderPass extends TableRenderPass { const hierarchyGroup = `.__hierarchy-group-${parentId}`; // Insert into table - const target = jQuery(this.tableBody).find(`${hierarchyRoot},${hierarchyGroup}`).last() + const target = jQuery(this.tableBody).find(`${hierarchyRoot},${hierarchyGroup}`).last(); target.after(el); // Mark as rendered at the given position @@ -224,6 +224,7 @@ export class HierarchyRenderPass extends TableRenderPass { classIdentifier: rowClass(workPackage.id), hidden: hidden }); + this.rendered[workPackage.id] = true; // Insert into timeline const timelineRow = this.buildTimelineRow(workPackage); diff --git a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts index fc88439aec..afe690764c 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/hierarchy/single-hierarchy-row-builder.ts @@ -41,16 +41,17 @@ export class SingleHierarchyRowBuilder extends RowRefreshBuilder { * Refresh a single row after structural changes. * Remembers and re-adds the hierarchy indicator if neccessary. */ - public refreshRow(row: WorkPackageTableRow, editForm: WorkPackageEditForm | undefined):[HTMLElement, boolean] { + public refreshRow(row: WorkPackageTableRow, editForm: WorkPackageEditForm | undefined):[HTMLElement, boolean]|null { // Remove any old hierarchy - const [newRow, hidden] = super.refreshRow(row, editForm); + const result = super.refreshRow(row, editForm); - if (newRow) { + if (result !== null) { + const [newRow, _hidden] = result; jQuery(newRow).find(`.wp-table--hierarchy-span`).remove(); this.appendHierarchyIndicator(row.object, newRow); } - return [newRow, hidden]; + return result; } /** diff --git a/frontend/app/components/wp-fast-table/builders/modes/rows-builder.ts b/frontend/app/components/wp-fast-table/builders/modes/rows-builder.ts index 9fdb6e5c1d..1b70a49084 100644 --- a/frontend/app/components/wp-fast-table/builders/modes/rows-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/modes/rows-builder.ts @@ -31,7 +31,7 @@ export abstract class RowsBuilder { * Refresh a single row after structural changes. * Will perform dirty checking for when a work package is currently being edited. */ - public refreshRow(row:WorkPackageTableRow):[HTMLElement, boolean] { + public refreshRow(row:WorkPackageTableRow):[HTMLElement, boolean]|null { let editing = this.states.editing.get(row.workPackageId).value; return this.refreshBuilder.refreshRow(row, editing); } diff --git a/frontend/app/components/wp-fast-table/builders/rows/row-refresh-builder.ts b/frontend/app/components/wp-fast-table/builders/rows/row-refresh-builder.ts index 1505817c2b..758589395f 100644 --- a/frontend/app/components/wp-fast-table/builders/rows/row-refresh-builder.ts +++ b/frontend/app/components/wp-fast-table/builders/rows/row-refresh-builder.ts @@ -4,18 +4,20 @@ import {locateRow} from "../../helpers/wp-table-row-helpers"; import {WorkPackageTableRow} from "../../wp-table.interfaces"; import {wpCellTdClassName} from "../cell-builder"; import {SingleRowBuilder} from "./single-row-builder"; +import {debugLog} from '../../../../helpers/debug_output'; export class RowRefreshBuilder extends SingleRowBuilder { /** * Refresh a row that is currently being edited, that is, some edit fields may be open */ - public refreshRow(row: WorkPackageTableRow, editForm: WorkPackageEditForm | undefined):[HTMLElement, boolean] { + public refreshRow(row: WorkPackageTableRow, editForm: WorkPackageEditForm | undefined):[HTMLElement, boolean] | null { // Get the row for the WP if refreshing existing const rowElement = row.element || locateRow(row.workPackageId); if (!rowElement) { - throw new Error(`Trying to refresh row for ${row.workPackageId} that is not in the table`); + debugLog(`Trying to refresh row for ${row.workPackageId} that is not in the table`); + return null; } // Iterate all columns, reattaching or rendering new columns diff --git a/frontend/app/components/wp-fast-table/wp-fast-table.ts b/frontend/app/components/wp-fast-table/wp-fast-table.ts index 12d0ef0a4d..f6df469e19 100644 --- a/frontend/app/components/wp-fast-table/wp-fast-table.ts +++ b/frontend/app/components/wp-fast-table/wp-fast-table.ts @@ -96,9 +96,10 @@ export class WorkPackageTable { public refreshRow(row:WorkPackageTableRow) { // Find the row we want to replace let oldRow = row.element || locateRow(row.workPackageId); - let [newRow, hidden] = this.rowBuilder.refreshRow(row); + let result = this.rowBuilder.refreshRow(row); - if (newRow && oldRow && oldRow.parentNode) { + if (result !== null && oldRow && oldRow.parentNode) { + let [newRow, _hidden] = result; oldRow.parentNode.replaceChild(newRow, oldRow); row.element = newRow; this.rowIndex[row.workPackageId] = row; diff --git a/spec/features/work_packages/details/details_relations_spec.rb b/spec/features/work_packages/details/details_relations_spec.rb index 6399acfb54..7e105456c3 100644 --- a/spec/features/work_packages/details/details_relations_spec.rb +++ b/spec/features/work_packages/details/details_relations_spec.rb @@ -84,14 +84,14 @@ describe 'Work package relations tab', js: true, selenium: true do end describe 'as admin' do - let!(:parent) { FactoryGirl.create(:work_package, project: project) } - let!(:child) { FactoryGirl.create(:work_package, project: project) } - let!(:child2) { FactoryGirl.create(:work_package, project: project, subject: 'Something new') } + let!(:parent) { FactoryGirl.create(:work_package, project: project) } + let!(:child) { FactoryGirl.create(:work_package, project: project) } + let!(:child2) { FactoryGirl.create(:work_package, project: project, subject: 'Something new') } it 'allows to mange hierarchy' do # Shows link parent link expect(page).to have_selector('#hierarchy--add-parent') - find('.wp-inline-create--add-link', + find('.work-packages--details .wp-inline-create--add-link', text: I18n.t('js.relation_buttons.add_parent')).click # Add parent @@ -99,14 +99,14 @@ describe 'Work package relations tab', js: true, selenium: true do ## # Add child #1 - find('.wp-inline-create--add-link', + find('.work-packages--details .wp-inline-create--add-link', text: I18n.t('js.relation_buttons.add_existing_child')).click add_hierarchy('.wp-relations--child-form', child.id, child.subject) ## # Add child #2 - find('.wp-inline-create--add-link', + find('.work-packages--details .wp-inline-create--add-link', text: I18n.t('js.relation_buttons.add_existing_child')).click add_hierarchy('.wp-relations--child-form', child2.subject, child2.subject) @@ -208,7 +208,7 @@ describe 'Work package relations tab', js: true, selenium: true do it 'should be able to link parent and children' do # Shows link parent link expect(page).to have_selector('#hierarchy--add-parent') - find('.wp-inline-create--add-link', + find('.work-packages--details .wp-inline-create--add-link', text: I18n.t('js.relation_buttons.add_parent')).click # Add parent @@ -216,7 +216,7 @@ describe 'Work package relations tab', js: true, selenium: true do ## # Add child - find('.wp-inline-create--add-link', + find('.work-packages--details .wp-inline-create--add-link', text: I18n.t('js.relation_buttons.add_existing_child')).click add_hierarchy('.wp-relations--child-form', child.id, child.subject)