Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[50953] Progress reporting for work package hierarchies: Change calculation and name of Work and Remaining work #14216

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def sym

def caption
I18n.t(:'activerecord.attributes.query.relations_of_type_column',
type: I18n.t(type[:sym_name]))
type: I18n.t(type[:sym_name]).capitalize)
end

def self.instances(_context = nil)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class FixDerivedWorkAndRemainingWorkValues < ActiveRecord::Migration[7.0]
def up
execute(update_derived_values_as_sum_of_self_and_descendants_sql)
end

def down
execute(update_derived_values_as_sum_of_descendants_sql)
execute(update_leaf_derived_values_to_null_sql)
end

def update_derived_values_as_sum_of_self_and_descendants_sql
<<~SQL.squish
WITH wp_derived AS (
SELECT
wph.ancestor_id AS id,
sum(wp.estimated_hours) AS estimated_hours_sum,
sum(wp.remaining_hours) AS remaining_hours_sum
FROM work_package_hierarchies wph
LEFT JOIN work_packages wp ON wph.descendant_id = wp.id
GROUP BY wph.ancestor_id
)
UPDATE
work_packages
SET
derived_estimated_hours = wp_derived.estimated_hours_sum,
derived_remaining_hours = wp_derived.remaining_hours_sum
FROM
wp_derived
WHERE work_packages.id = wp_derived.id
SQL
end

def update_derived_values_as_sum_of_descendants_sql
<<~SQL.squish
WITH wp_derived AS (
SELECT
wph.ancestor_id AS id,
sum(wp.estimated_hours) AS estimated_hours_sum,
sum(wp.remaining_hours) AS remaining_hours_sum
FROM work_package_hierarchies wph
LEFT JOIN work_packages wp ON wph.descendant_id = wp.id
WHERE wph.ancestor_id != wph.descendant_id
GROUP BY wph.ancestor_id
)
UPDATE
work_packages
SET
derived_estimated_hours = wp_derived.estimated_hours_sum,
derived_remaining_hours = wp_derived.remaining_hours_sum
FROM
wp_derived
WHERE work_packages.id = wp_derived.id
SQL
end

def update_leaf_derived_values_to_null_sql
<<~SQL.squish
UPDATE
work_packages
SET
derived_estimated_hours = NULL,
derived_remaining_hours = NULL
WHERE
id NOT IN (
SELECT ancestor_id
FROM work_package_hierarchies
WHERE generations > 0
)
SQL
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export class EstimatedTimeDisplayField extends DisplayField {
public renderSeparator(element:HTMLElement) {
const span = document.createElement('span');
span.classList.add('-separator');
span.textContent = '·';
span.ariaHidden = 'true';
element.appendChild(span);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@
width: 100%
text-align: center

// READ value of display fields in wiki macros

display-field
& .split-time-field
white-space: nowrap

.-separator
display: inline-block
width: 1rem
padding-left: 0.25rem
padding-right: 0.25rem
text-align: center


// READ value of edit fields
.inline-edit--display-field
display: inline-block
Expand Down Expand Up @@ -87,8 +101,7 @@
.-actual-value
@include wp-table--actual-time-values

.-separator::before
content: "·"
.-separator
display: inline-block
width: 1rem
padding-left: 0.25rem
Expand Down
2 changes: 2 additions & 0 deletions spec/factories/query_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
project
user factory: :user
include_subprojects { Setting.display_subprojects_work_packages? }
show_hierarchies { false }
display_sums { false }
sequence(:name) { |n| "Query #{n}" }

factory :public_query do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,26 @@

require 'spec_helper'

RSpec.describe 'Estimated hours display' do
let(:user) { create(:admin) }
let(:project) { create(:project) }

let(:hierarchy) { [] }

let!(:work_packages) do
build_work_package_hierarchy(
hierarchy,
:subject,
:estimated_hours,
shared_attributes: {
project:
}
)
RSpec.describe 'Estimated hours display', :js do
shared_let(:project) { create(:project) }
shared_let(:user) { create(:admin) }
shared_let(:wiki_page) { create(:wiki_page, wiki: project.wiki) }
shared_let(:query) do
create(:query,
project:,
user:,
show_hierarchies: true,
column_names: %i[id subject estimated_hours])
end

let(:parent) { work_packages.first }
let(:child) { work_packages.last }

let!(:query) do
query = build(:query, user:, project:)
query.column_names = %w[id subject estimated_hours]

query.save!
query
before_all do
set_factory_default(:project, project)
set_factory_default(:project_with_types, project)
set_factory_default(:user, user)
end

let(:wp_table) { Pages::WorkPackagesTable.new project }
let(:editor) { Components::WysiwygEditor.new }

before do
WorkPackages::UpdateAncestorsService
Expand All @@ -66,165 +57,89 @@
login_as(user)
end

context "with both work and derived work" do
let(:hierarchy) do
[
{
["Parent", 1] => [
["Child", 3]
]
}
]
end

it 'work package index', :js do
shared_examples 'estimated time display' do |expected_text:|
it 'work package index' do
wp_table.visit_query query
wp_table.expect_work_package_listed child

wp_table.expect_work_package_with_attributes(
parent, estimatedTime: "1 hΣ 4 h"
parent, estimatedTime: expected_text
)
end

it 'work package details', :js do
it 'work package details' do
visit work_package_path(parent.id)

expect(page).to have_content("Work\n1 hΣ 4 h")
expect(page).to have_content("Work\n#{expected_text}")
end
end

context "with just work" do
let(:hierarchy) do
[
{
["Parent", 1] => [
["Child", 0]
]
}
]
end
it 'wiki page workPackageValue:id:estimatedTime macro' do
visit edit_project_wiki_path(project, wiki_page.id)

it 'work package index', :js do
wp_table.visit_query query
wp_table.expect_work_package_listed child
editor.set_markdown("workPackageValue:#{parent.id}:estimatedTime")
click_on 'Save'

wp_table.expect_work_package_with_attributes(
parent, subject: parent.subject, estimatedTime: "1 h"
)
expect(page).to have_css('.wiki-content', text: expected_text)
end
end

it 'work package details', :js do
visit work_package_path(parent.id)
context "with both work and derived work" do
let_work_packages(<<~TABLE)
hierarchy | work |
parent | 1h |
child | 3h |
TABLE

expect(page).to have_content("Work\n1 h")
end
include_examples 'estimated time display', expected_text: '1 h·Σ 4 h'
end

context "with just derived work with (parent work 0 h)" do
let(:hierarchy) do
[
{
["Parent", 0] => [
["Child", 3]
]
}
]
end

it 'work package index', :js do
wp_table.visit_query query
wp_table.expect_work_package_listed child
context "with just work" do
let_work_packages(<<~TABLE)
hierarchy | work |
parent | 1h |
child | 0h |
TABLE

wp_table.expect_work_package_with_attributes(
parent, subject: parent.subject, estimatedTime: "0 hΣ 3 h"
)
end
include_examples 'estimated time display', expected_text: '1 h'
end

it 'work package details', :js do
visit work_package_path(parent.id)
context "with just derived work with (parent work 0 h)" do
let_work_packages(<<~TABLE)
hierarchy | work |
parent | 0h |
child | 3h |
TABLE

expect(page).to have_content("Work\n0 hΣ 3 h")
end
include_examples 'estimated time display', expected_text: '0 h·Σ 3 h'
end

context "with just derived work (parent work unset)" do
let(:hierarchy) do
[
{
["Parent", nil] => [
["Child", 3]
]
}
]
end

it 'work package index', :js do
wp_table.visit_query query
wp_table.expect_work_package_listed child

wp_table.expect_work_package_with_attributes(
parent, subject: parent.subject, estimatedTime: "-Σ 3 h"
)
end

it 'work package details', :js do
visit work_package_path(parent.id)
let_work_packages(<<~TABLE)
hierarchy | work |
parent | |
child | 3h |
TABLE

expect(page).to have_content("Work\n-Σ 3 h")
end
include_examples 'estimated time display', expected_text: '-·Σ 3 h'
end

context "with neither work nor derived work (both 0 h)" do
let(:hierarchy) do
[
{
["Parent", 0] => [
["Child", 0]
]
}
]
end

it 'work package index', :js do
wp_table.visit_query query
wp_table.expect_work_package_listed child
let_work_packages(<<~TABLE)
hierarchy | work |
parent | 0h |
child | 0h |
TABLE

wp_table.expect_work_package_with_attributes(
parent, subject: parent.subject, estimatedTime: "0 h"
)
end

it 'work package details', :js do
visit work_package_path(parent.id)

expect(page).to have_content("Work\n0 h")
end
include_examples 'estimated time display', expected_text: '0 h'
end

context "with neither work nor derived work (both unset)" do
let(:hierarchy) do
[
{
["Parent", nil] => [
["Child", nil]
]
}
]
end

it 'work package index', :js do
wp_table.visit_query query
wp_table.expect_work_package_listed child
let_work_packages(<<~TABLE)
hierarchy | work |
parent | |
child | |
TABLE

wp_table.expect_work_package_with_attributes(
parent, subject: parent.subject, estimatedTime: "-"
)
end

it 'work package details', :js do
visit work_package_path(parent.id)

expect(page).to have_content("Work\n-")
end
include_examples 'estimated time display', expected_text: '-'
end
end
Loading
Loading