From c551263d3d783adf49e99f77c021ff241c663f4b Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Tue, 5 Aug 2025 14:49:41 +0200 Subject: [PATCH 01/18] fix: Correctly chose color in target score value #1570 --- .../components/key-result-form/key-result-form.component.ts | 3 +-- frontend/src/app/shared/custom/scoring/scoring.component.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.ts b/frontend/src/app/components/key-result-form/key-result-form.component.ts index e74692809f..888f07e203 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.ts @@ -6,7 +6,6 @@ import { KeyResultMetric } from '../../shared/types/model/key-result-metric'; import { KeyResultOrdinal } from '../../shared/types/model/key-result-ordinal'; import { filter, map, Observable, of, startWith, switchMap } from 'rxjs'; import { UserService } from '../../services/user.service'; -import { ActionService } from '../../services/action.service'; import { actionListToItemList, formInputCheck } from '../../shared/common'; import { initFormGroupFromItem, Item } from '../action-plan/action-plan.component'; @@ -29,7 +28,7 @@ export class KeyResultFormComponent implements OnInit, AfterContentInit { @Input() keyResult?: KeyResult; - constructor(public userService: UserService, public actionService: ActionService) { + constructor(public userService: UserService) { } ngOnInit(): void { diff --git a/frontend/src/app/shared/custom/scoring/scoring.component.ts b/frontend/src/app/shared/custom/scoring/scoring.component.ts index 550d62d2aa..88fe58f042 100644 --- a/frontend/src/app/shared/custom/scoring/scoring.component.ts +++ b/frontend/src/app/shared/custom/scoring/scoring.component.ts @@ -111,8 +111,7 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { calculatePercentageMetric() { if (this.keyResult.lastCheckIn !== null) { - const keyResultMetric: KeyResultMetricMin = this.castToMetric(); - const percentage = calculateCurrentPercentage(keyResultMetric); + const percentage = Math.round(calculateCurrentPercentage(this.castToMetric())); this.labelPercentage = of(percentage); if (percentage < 30) { this.stretched = false; From 3ff91bdbeb76cca183b96a8253ec6a1dc816a868 Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Thu, 7 Aug 2025 17:16:39 +0200 Subject: [PATCH 02/18] fix(api): Add commit- and targetGoal to Overview and KeyResult #1570 --- .../okr/dto/keyresult/KeyResultMetricDto.java | 6 +-- .../overview/OverviewKeyResultMetricDto.java | 5 +- .../ch/puzzle/okr/mapper/OverviewMapper.java | 3 +- .../keyresult/KeyResultMetricMapper.java | 4 ++ .../okr/models/keyresult/KeyResultMetric.java | 42 ++++++++++++++-- .../puzzle/okr/models/overview/Overview.java | 48 ++++++++++++------- .../resources/db/migration/V3_6_1__test.sql | 3 ++ .../V3_6_2__addMetricKeyResultGoals.sql | 34 +++++++++++++ .../key-result-dialog.component.ts | 7 ++- 9 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V3_6_1__test.sql create mode 100644 backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql diff --git a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java index 0841a1ffca..f38866fe94 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java @@ -8,9 +8,9 @@ @JsonDeserialize(as = KeyResultMetricDto.class) public record KeyResultMetricDto(Long id, int version, String keyResultType, String title, String description, - Double baseline, Double stretchGoal, UnitDto unit, KeyResultUserDto owner, KeyResultObjectiveDto objective, - KeyResultLastCheckInMetricDto lastCheckIn, LocalDateTime createdOn, LocalDateTime modifiedOn, - boolean isWriteable, List actionList) implements KeyResultDto { + Double baseline, Double commitGoal, Double targetGoal, Double stretchGoal, UnitDto unit, KeyResultUserDto owner, + KeyResultObjectiveDto objective, KeyResultLastCheckInMetricDto lastCheckIn, LocalDateTime createdOn, + LocalDateTime modifiedOn, boolean isWriteable, List actionList) implements KeyResultDto { @Override public List getActionList() { return actionList; diff --git a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java index 2b397339ad..78c6961952 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java @@ -1,5 +1,6 @@ package ch.puzzle.okr.dto.overview; -public record OverviewKeyResultMetricDto(Long id, String title, String keyResultType, String unit, Double baseline, - Double stretchGoal, OverviewLastCheckInMetricDto lastCheckIn) implements OverviewKeyResultDto { +public record OverviewKeyResultMetricDto(Long id, String title, String keyResultType, Double baseline, + Double commitGoal, Double targetGoal, Double stretchGoal, + OverviewLastCheckInMetricDto lastCheckIn) implements OverviewKeyResultDto { } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java index 7f0ef5b198..0427d15fb0 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java @@ -103,8 +103,9 @@ private OverviewKeyResultMetricDto createKeyResultMetricDto(Overview overview) { return new OverviewKeyResultMetricDto(overview.getOverviewId().getKeyResultId(), overview.getKeyResultTitle(), overview.getKeyResultType(), - overview.getUnit(), overview.getBaseline(), + overview.getCommitGoal(), + overview.getTargetGoal(), overview.getStretchGoal(), lastCheckIn); } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java index 5ed8adf55e..dd6364884d 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java @@ -63,6 +63,8 @@ public KeyResultDto toDto(KeyResultMetric keyResult, List actionList) { keyResult.getTitle(), // keyResult.getDescription(), // keyResult.getBaseline(), // + keyResult.getCommitGoal(), + keyResult.getTargetGoal(), keyResult.getStretchGoal(), // unitMapper.toDto(keyResult.getUnit()), // ownerDto, @@ -79,6 +81,8 @@ public KeyResult toKeyResultMetric(KeyResultMetricDto keyResultMetricDto) { .builder() // .withBaseline(keyResultMetricDto.baseline()) // .withStretchGoal(keyResultMetricDto.stretchGoal()) // + .withCommitGoal(keyResultMetricDto.commitGoal()) // + .withTargetGoal(keyResultMetricDto.targetGoal()) // .withUnit(unitBusinessService.findUnitByName(keyResultMetricDto.unit().unitName())) .withId(keyResultMetricDto.id()) // .withVersion(keyResultMetricDto.version()) // diff --git a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java index a0a1ca4b34..e59b496459 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java +++ b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java @@ -14,6 +14,10 @@ public class KeyResultMetric extends KeyResult { @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double baseline; + private Double commitGoal; + + private Double targetGoal; + @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double stretchGoal; @@ -33,6 +37,22 @@ public Double getStretchGoal() { return stretchGoal; } + public Double getCommitGoal() { + return commitGoal; + } + + public void setCommitGoal(Double commitGoal) { + this.commitGoal = commitGoal; + } + + public Double getTargetGoal() { + return targetGoal; + } + + public void setTargetGoal(Double targetGoal) { + this.targetGoal = targetGoal; + } + public void setStretchGoal(Double stretchGoal) { this.stretchGoal = stretchGoal; } @@ -54,6 +74,8 @@ public boolean equals(Object o) { if (o instanceof KeyResultMetric keyResultMetric) { return super.equals(o) && Objects.equals(baseline, keyResultMetric.baseline) && Objects.equals(stretchGoal, keyResultMetric.stretchGoal) + && Objects.equals(commitGoal, keyResultMetric.commitGoal) + && Objects.equals(targetGoal, keyResultMetric.targetGoal) && Objects.equals(unit, keyResultMetric.unit); } return false; @@ -61,24 +83,28 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), baseline, stretchGoal, unit); + return Objects.hash(super.hashCode(), baseline, commitGoal, targetGoal, stretchGoal, unit); } @Override public String toString() { - return super.toString() + "KeyResultMetric{" + "baseline=" + baseline + ", stretchGoal=" + stretchGoal - + ", unit='" + unit + '\'' + '}'; + return "KeyResultMetric{" + "baseline=" + baseline + ", commitGoal=" + commitGoal + ", targetGoal=" + targetGoal + + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; } private KeyResultMetric(Builder builder) { super(builder); setBaseline(builder.baseline); + setCommitGoal(builder.commitGoal); + setTargetGoal(builder.targetGoal); setStretchGoal(builder.stretchGoal); setUnit(builder.unit); } public static class Builder extends KeyResult.Builder { private Double baseline; + private Double commitGoal; + private Double targetGoal; private Double stretchGoal; private Unit unit; @@ -105,6 +131,16 @@ public Builder withUnit(Unit unit) { return this; } + public Builder withCommitGoal(Double commitGoal) { + this.commitGoal = commitGoal; + return this; + } + + public Builder withTargetGoal(Double targetGoal) { + this.targetGoal = targetGoal; + return this; + } + @Override public KeyResult build() { return new KeyResultMetric(this); diff --git a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java index 8f45505807..859ac7c6f7 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java +++ b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java @@ -23,8 +23,9 @@ public class Overview implements WriteableInterface { private String keyResultTitle; private String keyResultType; private Double baseline; + private Double commitGoal; + private Double targetGoal; private Double stretchGoal; - private String unit; private String commitZone; private String targetZone; private String stretchZone; @@ -54,8 +55,9 @@ private Overview(Builder builder) { keyResultTitle = builder.keyResultTitle; keyResultType = builder.keyResultType; baseline = builder.baseline; + commitGoal = builder.commitGoal; + targetGoal = builder.targetGoal; stretchGoal = builder.stretchGoal; - unit = builder.unit; commitZone = builder.commitZone; targetZone = builder.targetZone; stretchZone = builder.stretchZone; @@ -113,10 +115,6 @@ public Double getStretchGoal() { return stretchGoal; } - public String getUnit() { - return unit; - } - public String getCommitZone() { return commitZone; } @@ -145,6 +143,14 @@ public LocalDateTime getCheckInCreatedOn() { return checkInCreatedOn; } + public Double getCommitGoal() { + return commitGoal; + } + + public Double getTargetGoal() { + return targetGoal; + } + @Override public boolean isWriteable() { return writeable; @@ -165,15 +171,15 @@ public void setBacklogQuarter(boolean backlogQuarter) { @Override public String toString() { - return "Overview{" + "overviewId=" + overviewId + ", teamVersion='" + teamVersion + ", teamName='" + teamName - + '\'' + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState + return "Overview{" + "overviewId=" + overviewId + ", teamName='" + teamName + '\'' + ", teamVersion=" + + teamVersion + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState + ", objectiveCreatedOn=" + objectiveCreatedOn + ", quarterId=" + quarterId + ", quarterLabel='" + quarterLabel + '\'' + ", keyResultTitle='" + keyResultTitle + '\'' + ", keyResultType='" - + keyResultType + '\'' + ", baseline=" + baseline + ", stretchGoal=" + stretchGoal + ", unit='" + unit - + '\'' + ", commitZone='" + commitZone + '\'' + ", targetZone='" + targetZone + '\'' + ", stretchZone='" - + stretchZone + '\'' + ", checkInValue=" + checkInValue + ", checkInZone='" + checkInZone + '\'' - + ", confidence=" + confidence + ", createdOn=" + checkInCreatedOn + ", writeable=" + writeable + '\'' - + '}'; + + keyResultType + '\'' + ", baseline=" + baseline + ", commitGoal=" + commitGoal + ", targetGoal=" + + targetGoal + ", stretchGoal=" + stretchGoal + ", commitZone='" + commitZone + '\'' + ", targetZone='" + + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + ", checkInValue=" + checkInValue + + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + confidence + ", checkInCreatedOn=" + + checkInCreatedOn + ", writeable=" + writeable + ", backlogQuarter=" + backlogQuarter + '}'; } public static final class Builder { @@ -188,8 +194,9 @@ public static final class Builder { private String keyResultTitle; private String keyResultType; private Double baseline; + private Double commitGoal; + private Double targetGoal; private Double stretchGoal; - private String unit; private String commitZone; private String targetZone; private String stretchZone; @@ -260,13 +267,18 @@ public Builder withBaseline(Double baseline) { return this; } - public Builder withStretchGoal(Double stretchGoal) { - this.stretchGoal = stretchGoal; + public Builder withCommitGoal(Double commitGoal) { + this.commitGoal = commitGoal; + return this; + } + + public Builder withTargetGoal(Double targetGoal) { + this.targetGoal = targetGoal; return this; } - public Builder withUnit(String unit) { - this.unit = unit; + public Builder withStretchGoal(Double stretchGoal) { + this.stretchGoal = stretchGoal; return this; } diff --git a/backend/src/main/resources/db/migration/V3_6_1__test.sql b/backend/src/main/resources/db/migration/V3_6_1__test.sql new file mode 100644 index 0000000000..622c2fb5f5 --- /dev/null +++ b/backend/src/main/resources/db/migration/V3_6_1__test.sql @@ -0,0 +1,3 @@ +ALTER TABLE key_result + add column if not exists commit_goal double precision, + add column if not exists target_goal double precision; diff --git a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql new file mode 100644 index 0000000000..9444059b99 --- /dev/null +++ b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql @@ -0,0 +1,34 @@ +DROP VIEW IF EXISTS OVERVIEW RESTRICT ; +CREATE VIEW OVERVIEW AS +SELECT tq.team_id AS "team_id", + tq.team_version AS "team_version", + tq.name AS "team_name", + tq.quater_id AS "quarter_id", + tq.label AS "quarter_label", + coalesce(o.id, -1) AS "objective_id", + o.title AS "objective_title", + o.state AS "objective_state", + o.created_on AS "objective_created_on", + coalesce(kr.id, -1) AS "key_result_id", + kr.title AS "key_result_title", + kr.key_result_type AS "key_result_type", + kr.baseline, + kr.commit_goal, + kr.target_goal, + kr.stretch_goal, + kr.commit_zone, + kr.target_zone, + kr.stretch_zone, + coalesce(c.id, -1) AS "check_in_id", + c.value_metric AS "check_in_value", + c.zone AS "check_in_zone", + c.confidence, + c.created_on AS "check_in_created_on" +FROM (select t.id as team_id, t.version as team_version, t.name, q.id as quater_id, q.label + from team t, + quarter q) tq + LEFT JOIN OBJECTIVE O ON TQ.TEAM_ID = O.TEAM_ID AND TQ.QUATER_ID = O.QUARTER_ID + LEFT JOIN KEY_RESULT KR ON O.ID = KR.OBJECTIVE_ID + LEFT JOIN CHECK_IN C ON KR.ID = C.KEY_RESULT_ID AND C.MODIFIED_ON = (SELECT MAX(CC.MODIFIED_ON) + FROM CHECK_IN CC + WHERE CC.KEY_RESULT_ID = C.KEY_RESULT_ID); \ No newline at end of file diff --git a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts index 197cf7c7aa..bd2426785c 100644 --- a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts +++ b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts @@ -47,15 +47,20 @@ export class KeyResultDialogComponent implements OnInit { } saveKeyResult(openNewDialog = false) { + const roundToTwoDecimals = (num: number) => parseFloat(num.toFixed(2)); this.deletedItems.subscribe((e: any[]) => e.forEach((elem: any) => this.actionService.deleteAction(elem.id) .subscribe())); this.keyResultForm.controls['metric'].enable(); this.keyResultForm.controls['ordinal'].enable(); let keyResult: KeyResultDto = this.keyResultForm.value; + const values = this.keyResultForm.get('metric')?.value; + const num: number = (values.stretchGoal - values.baseline) * 0.3 + values.baseline; keyResult.actionList = itemListToActionList(this.keyResultForm.getRawValue().actionList, this.data.keyResult?.id || null); + const commit = { commitGoal: roundToTwoDecimals(num) }; if (this.isMetricKeyResult()) { keyResult = { ...keyResult, - ...this.keyResultForm.get('metric')?.value } as KeyResultMetricDto; + ...this.keyResultForm.get('metric')?.value, + ...commit } as KeyResultMetricDto; } else { keyResult = { ...keyResult, ...this.keyResultForm.get('ordinal')?.value } as KeyResultOrdinalDto; From d3cc49b704f98be696474925dcfa8c0b07132473 Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Fri, 8 Aug 2025 10:44:34 +0200 Subject: [PATCH 03/18] feat: Add Calculation commitGoal and targetGoal #1570 --- .../db/migration/V3_6_1__addMetricGoalsToKeyResult.sql | 9 +++++++++ backend/src/main/resources/db/migration/V3_6_1__test.sql | 3 --- ...sql => V3_6_2__addMetricKeyResultGoalsToOverview.sql} | 0 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql delete mode 100644 backend/src/main/resources/db/migration/V3_6_1__test.sql rename backend/src/main/resources/db/migration/{V3_6_2__addMetricKeyResultGoals.sql => V3_6_2__addMetricKeyResultGoalsToOverview.sql} (100%) diff --git a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql new file mode 100644 index 0000000000..71baff6e05 --- /dev/null +++ b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql @@ -0,0 +1,9 @@ +ALTER TABLE key_result + ADD COLUMN IF NOT EXISTS commit_goal DOUBLE PRECISION, + add COLUMN IF NOT EXISTS target_goal DOUBLE PRECISION; + +UPDATE key_result +SET commit_goal = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), + target_goal = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.7 + COALESCE(baseline, 0))::numeric, 2) +WHERE commit_goal IS NULL + AND target_goal IS NULL; diff --git a/backend/src/main/resources/db/migration/V3_6_1__test.sql b/backend/src/main/resources/db/migration/V3_6_1__test.sql deleted file mode 100644 index 622c2fb5f5..0000000000 --- a/backend/src/main/resources/db/migration/V3_6_1__test.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE key_result - add column if not exists commit_goal double precision, - add column if not exists target_goal double precision; diff --git a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql similarity index 100% rename from backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoals.sql rename to backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql From b452f1891d0776919086aaf4f16586d6516421f8 Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Mon, 11 Aug 2025 09:00:15 +0200 Subject: [PATCH 04/18] style: Rename commitGoal and targetGoal --- .../okr/dto/keyresult/KeyResultMetricDto.java | 7 +-- .../overview/OverviewKeyResultMetricDto.java | 2 +- .../ch/puzzle/okr/mapper/OverviewMapper.java | 4 +- .../keyresult/KeyResultMetricMapper.java | 8 ++-- .../okr/models/keyresult/KeyResultMetric.java | 46 +++++++++---------- .../puzzle/okr/models/overview/Overview.java | 39 ++++++++-------- .../V3_6_1__addMetricGoalsToKeyResult.sql | 12 ++--- ...6_2__addMetricKeyResultGoalsToOverview.sql | 4 +- .../okr/controller/OverviewControllerIT.java | 5 -- .../keyresult/helper/TestDataConstants.java | 2 + .../keyresult/helper/TestDataDtoHelper.java | 4 +- .../puzzle/okr/test/KeyResultTestHelpers.java | 4 +- 12 files changed, 70 insertions(+), 67 deletions(-) diff --git a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java index f38866fe94..4314a36ae5 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java @@ -8,9 +8,10 @@ @JsonDeserialize(as = KeyResultMetricDto.class) public record KeyResultMetricDto(Long id, int version, String keyResultType, String title, String description, - Double baseline, Double commitGoal, Double targetGoal, Double stretchGoal, UnitDto unit, KeyResultUserDto owner, - KeyResultObjectiveDto objective, KeyResultLastCheckInMetricDto lastCheckIn, LocalDateTime createdOn, - LocalDateTime modifiedOn, boolean isWriteable, List actionList) implements KeyResultDto { + Double baseline, Double wordingCommitValue, Double wordingTargetValue, Double stretchGoal, UnitDto unit, + KeyResultUserDto owner, KeyResultObjectiveDto objective, KeyResultLastCheckInMetricDto lastCheckIn, + LocalDateTime createdOn, LocalDateTime modifiedOn, boolean isWriteable, + List actionList) implements KeyResultDto { @Override public List getActionList() { return actionList; diff --git a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java index 78c6961952..502dee595e 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java @@ -1,6 +1,6 @@ package ch.puzzle.okr.dto.overview; public record OverviewKeyResultMetricDto(Long id, String title, String keyResultType, Double baseline, - Double commitGoal, Double targetGoal, Double stretchGoal, + Double wordingCommitValue, Double wordingTargetValue, Double stretchGoal, OverviewLastCheckInMetricDto lastCheckIn) implements OverviewKeyResultDto { } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java index 0427d15fb0..91a929087b 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java @@ -104,8 +104,8 @@ private OverviewKeyResultMetricDto createKeyResultMetricDto(Overview overview) { overview.getKeyResultTitle(), overview.getKeyResultType(), overview.getBaseline(), - overview.getCommitGoal(), - overview.getTargetGoal(), + overview.getWordingCommitValue(), + overview.getWordingTargetValue(), overview.getStretchGoal(), lastCheckIn); } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java index dd6364884d..98714bb2a4 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java @@ -63,8 +63,8 @@ public KeyResultDto toDto(KeyResultMetric keyResult, List actionList) { keyResult.getTitle(), // keyResult.getDescription(), // keyResult.getBaseline(), // - keyResult.getCommitGoal(), - keyResult.getTargetGoal(), + keyResult.getWordingCommitValue(), + keyResult.getWordingTargetValue(), keyResult.getStretchGoal(), // unitMapper.toDto(keyResult.getUnit()), // ownerDto, @@ -81,8 +81,8 @@ public KeyResult toKeyResultMetric(KeyResultMetricDto keyResultMetricDto) { .builder() // .withBaseline(keyResultMetricDto.baseline()) // .withStretchGoal(keyResultMetricDto.stretchGoal()) // - .withCommitGoal(keyResultMetricDto.commitGoal()) // - .withTargetGoal(keyResultMetricDto.targetGoal()) // + .withWordingCommitValue(keyResultMetricDto.wordingCommitValue()) // + .withWordingTargetValue(keyResultMetricDto.wordingTargetValue()) // .withUnit(unitBusinessService.findUnitByName(keyResultMetricDto.unit().unitName())) .withId(keyResultMetricDto.id()) // .withVersion(keyResultMetricDto.version()) // diff --git a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java index e59b496459..e2300c3412 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java +++ b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java @@ -14,9 +14,9 @@ public class KeyResultMetric extends KeyResult { @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double baseline; - private Double commitGoal; + private Double wordingCommitValue; - private Double targetGoal; + private Double wordingTargetValue; @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double stretchGoal; @@ -37,20 +37,20 @@ public Double getStretchGoal() { return stretchGoal; } - public Double getCommitGoal() { - return commitGoal; + public Double getWordingCommitValue() { + return wordingCommitValue; } - public void setCommitGoal(Double commitGoal) { - this.commitGoal = commitGoal; + public void setWordingCommitValue(Double wordingCommitValue) { + this.wordingCommitValue = wordingCommitValue; } - public Double getTargetGoal() { - return targetGoal; + public Double getWordingTargetValue() { + return wordingTargetValue; } - public void setTargetGoal(Double targetGoal) { - this.targetGoal = targetGoal; + public void setWordingTargetValue(Double wordingTargetValue) { + this.wordingTargetValue = wordingTargetValue; } public void setStretchGoal(Double stretchGoal) { @@ -74,8 +74,8 @@ public boolean equals(Object o) { if (o instanceof KeyResultMetric keyResultMetric) { return super.equals(o) && Objects.equals(baseline, keyResultMetric.baseline) && Objects.equals(stretchGoal, keyResultMetric.stretchGoal) - && Objects.equals(commitGoal, keyResultMetric.commitGoal) - && Objects.equals(targetGoal, keyResultMetric.targetGoal) + && Objects.equals(wordingCommitValue, keyResultMetric.wordingCommitValue) + && Objects.equals(wordingTargetValue, keyResultMetric.wordingTargetValue) && Objects.equals(unit, keyResultMetric.unit); } return false; @@ -83,28 +83,28 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), baseline, commitGoal, targetGoal, stretchGoal, unit); + return Objects.hash(super.hashCode(), baseline, wordingCommitValue, wordingTargetValue, stretchGoal, unit); } @Override public String toString() { - return "KeyResultMetric{" + "baseline=" + baseline + ", commitGoal=" + commitGoal + ", targetGoal=" + targetGoal - + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; + return "KeyResultMetric{" + "baseline=" + baseline + ", wordingCommitValue=" + wordingCommitValue + + ", wordingTargetValue=" + wordingTargetValue + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; } private KeyResultMetric(Builder builder) { super(builder); setBaseline(builder.baseline); - setCommitGoal(builder.commitGoal); - setTargetGoal(builder.targetGoal); + setWordingCommitValue(builder.wordingCommitValue); + setWordingTargetValue(builder.wordingTargetValue); setStretchGoal(builder.stretchGoal); setUnit(builder.unit); } public static class Builder extends KeyResult.Builder { private Double baseline; - private Double commitGoal; - private Double targetGoal; + private Double wordingCommitValue; + private Double wordingTargetValue; private Double stretchGoal; private Unit unit; @@ -131,13 +131,13 @@ public Builder withUnit(Unit unit) { return this; } - public Builder withCommitGoal(Double commitGoal) { - this.commitGoal = commitGoal; + public Builder withWordingCommitValue(Double wordingCommitValue) { + this.wordingCommitValue = wordingCommitValue; return this; } - public Builder withTargetGoal(Double targetGoal) { - this.targetGoal = targetGoal; + public Builder withWordingTargetValue(Double wordingTargetValue) { + this.wordingTargetValue = wordingTargetValue; return this; } diff --git a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java index 859ac7c6f7..68004b42ce 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java +++ b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java @@ -23,8 +23,8 @@ public class Overview implements WriteableInterface { private String keyResultTitle; private String keyResultType; private Double baseline; - private Double commitGoal; - private Double targetGoal; + private Double wordingCommitValue; + private Double wordingTargetValue; private Double stretchGoal; private String commitZone; private String targetZone; @@ -55,8 +55,8 @@ private Overview(Builder builder) { keyResultTitle = builder.keyResultTitle; keyResultType = builder.keyResultType; baseline = builder.baseline; - commitGoal = builder.commitGoal; - targetGoal = builder.targetGoal; + wordingCommitValue = builder.wordingCommitValue; + wordingTargetValue = builder.wordingTargetValue; stretchGoal = builder.stretchGoal; commitZone = builder.commitZone; targetZone = builder.targetZone; @@ -143,12 +143,12 @@ public LocalDateTime getCheckInCreatedOn() { return checkInCreatedOn; } - public Double getCommitGoal() { - return commitGoal; + public Double getWordingCommitValue() { + return wordingCommitValue; } - public Double getTargetGoal() { - return targetGoal; + public Double getWordingTargetValue() { + return wordingTargetValue; } @Override @@ -175,11 +175,12 @@ public String toString() { + teamVersion + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState + ", objectiveCreatedOn=" + objectiveCreatedOn + ", quarterId=" + quarterId + ", quarterLabel='" + quarterLabel + '\'' + ", keyResultTitle='" + keyResultTitle + '\'' + ", keyResultType='" - + keyResultType + '\'' + ", baseline=" + baseline + ", commitGoal=" + commitGoal + ", targetGoal=" - + targetGoal + ", stretchGoal=" + stretchGoal + ", commitZone='" + commitZone + '\'' + ", targetZone='" - + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + ", checkInValue=" + checkInValue - + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + confidence + ", checkInCreatedOn=" - + checkInCreatedOn + ", writeable=" + writeable + ", backlogQuarter=" + backlogQuarter + '}'; + + keyResultType + '\'' + ", baseline=" + baseline + ", wordingCommitValue=" + wordingCommitValue + + ", wordingTargetValue=" + wordingTargetValue + ", stretchGoal=" + stretchGoal + ", commitZone='" + + commitZone + '\'' + ", targetZone='" + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + + ", checkInValue=" + checkInValue + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + + confidence + ", checkInCreatedOn=" + checkInCreatedOn + ", writeable=" + writeable + + ", backlogQuarter=" + backlogQuarter + '}'; } public static final class Builder { @@ -194,8 +195,8 @@ public static final class Builder { private String keyResultTitle; private String keyResultType; private Double baseline; - private Double commitGoal; - private Double targetGoal; + private Double wordingCommitValue; + private Double wordingTargetValue; private Double stretchGoal; private String commitZone; private String targetZone; @@ -267,13 +268,13 @@ public Builder withBaseline(Double baseline) { return this; } - public Builder withCommitGoal(Double commitGoal) { - this.commitGoal = commitGoal; + public Builder withWordingCommitValue(Double wordingCommitValue) { + this.wordingCommitValue = wordingCommitValue; return this; } - public Builder withTargetGoal(Double targetGoal) { - this.targetGoal = targetGoal; + public Builder withWordingTargetValue(Double wordingTargetValue) { + this.wordingTargetValue = wordingTargetValue; return this; } diff --git a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql index 71baff6e05..cdd558c8be 100644 --- a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql +++ b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql @@ -1,9 +1,9 @@ ALTER TABLE key_result - ADD COLUMN IF NOT EXISTS commit_goal DOUBLE PRECISION, - add COLUMN IF NOT EXISTS target_goal DOUBLE PRECISION; + ADD COLUMN IF NOT EXISTS wording_commit_value DOUBLE PRECISION, + add COLUMN IF NOT EXISTS wording_target_value DOUBLE PRECISION; UPDATE key_result -SET commit_goal = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), - target_goal = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.7 + COALESCE(baseline, 0))::numeric, 2) -WHERE commit_goal IS NULL - AND target_goal IS NULL; +SET wording_commit_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), + wording_target_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.7 + COALESCE(baseline, 0))::numeric, 2) +WHERE wording_commit_value IS NULL + AND wording_target_value IS NULL; diff --git a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql index 9444059b99..6fcab09763 100644 --- a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql +++ b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql @@ -13,8 +13,8 @@ SELECT tq.team_id AS "team_id", kr.title AS "key_result_title", kr.key_result_type AS "key_result_type", kr.baseline, - kr.commit_goal, - kr.target_goal, + kr.wording_commit_value, + kr.wording_target_value, kr.stretch_goal, kr.commit_zone, kr.target_zone, diff --git a/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java b/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java index 4f7acfe7d3..2611586cd2 100644 --- a/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java +++ b/backend/src/test/java/ch/puzzle/okr/controller/OverviewControllerIT.java @@ -63,7 +63,6 @@ class OverviewControllerIT { .withQuarterLabel(QUARTER_LABEL) .withKeyResultTitle(DESCRIPTION) .withKeyResultType(KEY_RESULT_TYPE_METRIC) - .withUnit(CHF) .withBaseline(5.0) .withStretchGoal(20.0) .withCheckInValue(15.0) @@ -80,7 +79,6 @@ class OverviewControllerIT { .withQuarterLabel(QUARTER_LABEL) .withKeyResultTitle(DESCRIPTION) .withKeyResultType(KEY_RESULT_TYPE_METRIC) - .withUnit(EUR) .withBaseline(5.0) .withStretchGoal(20.0) .withCheckInValue(15.0) @@ -98,7 +96,6 @@ class OverviewControllerIT { .withQuarterLabel(QUARTER_LABEL) .withKeyResultTitle(DESCRIPTION) .withKeyResultType(KEY_RESULT_TYPE_METRIC) - .withUnit(CHF) .withBaseline(5.0) .withStretchGoal(20.0) .withCheckInValue(15.0) @@ -115,7 +112,6 @@ class OverviewControllerIT { .withQuarterLabel(QUARTER_LABEL) .withKeyResultTitle(DESCRIPTION) .withKeyResultType(KEY_RESULT_TYPE_METRIC) - .withUnit(FTE) .withBaseline(5.0) .withStretchGoal(20.0) .withCheckInValue(15.0) @@ -133,7 +129,6 @@ class OverviewControllerIT { .withQuarterLabel(QUARTER_LABEL) .withKeyResultTitle(DESCRIPTION) .withKeyResultType(KEY_RESULT_TYPE_METRIC) - .withUnit(EUR) .withBaseline(5.0) .withStretchGoal(20.0) .withCheckInValue(15.0) diff --git a/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataConstants.java b/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataConstants.java index 50bf3bd6b8..657f8ab503 100644 --- a/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataConstants.java +++ b/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataConstants.java @@ -38,6 +38,8 @@ public class TestDataConstants { public static final String KEY_RESULT_TITLE = "keyresult title"; public static final String KEY_RESULT_DESCRIPTION = "keyresult description"; public static final double KEY_RESULT_BASELINE = 55D; + public static final double KEY_RESULT_COMMIT_GOAL = 62.5D; + public static final double KEY_RESULT_TARGET_GOAL = 72.5D; public static final double KEY_RESULT_STRETCH_GOAL = 80D; public static final Unit KEY_RESULT_UNIT = TestHelper.NUMBER_UNIT; diff --git a/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataDtoHelper.java b/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataDtoHelper.java index 4bf310acf0..34e64c164a 100644 --- a/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataDtoHelper.java +++ b/backend/src/test/java/ch/puzzle/okr/mapper/keyresult/helper/TestDataDtoHelper.java @@ -69,7 +69,9 @@ public static KeyResultLastCheckInOrdinalDto lastCheckInOrdinalDto() { KEY_RESULT_TYPE_METRIC, // KEY_RESULT_TITLE, // KEY_RESULT_DESCRIPTION, // - KEY_RESULT_BASELINE, // + KEY_RESULT_BASELINE, + KEY_RESULT_COMMIT_GOAL, + KEY_RESULT_TARGET_GOAL, // KEY_RESULT_STRETCH_GOAL, // KEY_RESULT_UNIT_DTO, // ownerDto, // diff --git a/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java b/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java index b0525cfae0..95a527004e 100644 --- a/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java +++ b/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java @@ -384,7 +384,9 @@ public class KeyResultTestHelpers { TITLE, DESCRIPTION, 1.0, - 5.0, + 3.0, + 7.0, + 10.0, KEY_RESULT_UNIT_DTO, keyResultUserDto, keyResultObjectiveDto, From f596351738eddd5393f5825ba32bfccbfd2fbe77 Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Mon, 11 Aug 2025 16:00:40 +0200 Subject: [PATCH 05/18] fix: Rename commit- targetGoal in frontend and revise calculation logic #1570 --- .../key-result-dialog.component.ts | 12 ++++----- .../key-result-form.component.ts | 2 +- .../key-result-type.component.html | 6 ++--- .../key-result-type.component.ts | 27 +++++++++++-------- .../src/app/services/key-result.service.ts | 2 +- frontend/src/app/shared/constant-library.ts | 5 +++- .../custom/scoring/scoring.component.ts | 21 ++++++++------- .../types/DTOs/key-result-metric-dto.ts | 2 ++ .../types/model/key-result-metric-min.ts | 2 ++ .../shared/types/model/key-result-metric.ts | 2 ++ 10 files changed, 48 insertions(+), 33 deletions(-) diff --git a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts index bd2426785c..4f84fabe57 100644 --- a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts +++ b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts @@ -47,24 +47,24 @@ export class KeyResultDialogComponent implements OnInit { } saveKeyResult(openNewDialog = false) { - const roundToTwoDecimals = (num: number) => parseFloat(num.toFixed(2)); this.deletedItems.subscribe((e: any[]) => e.forEach((elem: any) => this.actionService.deleteAction(elem.id) .subscribe())); this.keyResultForm.controls['metric'].enable(); this.keyResultForm.controls['ordinal'].enable(); + let keyResult: KeyResultDto = this.keyResultForm.value; - const values = this.keyResultForm.get('metric')?.value; - const num: number = (values.stretchGoal - values.baseline) * 0.3 + values.baseline; + keyResult.actionList = itemListToActionList(this.keyResultForm.getRawValue().actionList, this.data.keyResult?.id || null); - const commit = { commitGoal: roundToTwoDecimals(num) }; + if (this.isMetricKeyResult()) { keyResult = { ...keyResult, - ...this.keyResultForm.get('metric')?.value, - ...commit } as KeyResultMetricDto; + ...this.keyResultForm.get('metric')?.value } as KeyResultMetricDto; } else { keyResult = { ...keyResult, ...this.keyResultForm.get('ordinal')?.value } as KeyResultOrdinalDto; } + + console.log(this.keyResultForm.get('metric')?.value); keyResult.objective = this.data.objective; keyResult.id = this.data.keyResult?.id; keyResult.version = this.data.keyResult?.version; diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.ts b/frontend/src/app/components/key-result-form/key-result-form.component.ts index 888f07e203..9a613c7af8 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.ts @@ -70,7 +70,7 @@ export class KeyResultFormComponent implements OnInit, AfterContentInit { } addNewItem(item?: Item) { - (this.keyResultForm.get('actionList') as FormArray) + (this.keyResultForm.get('actionLis0.9t') as FormArray) ?.push(initFormGroupFromItem(item)); } diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.html b/frontend/src/app/components/key-result-type/key-result-type.component.html index 7655bc3dc1..c41e6d97f8 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.html +++ b/frontend/src/app/components/key-result-type/key-result-type.component.html @@ -133,11 +133,11 @@ - + diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index 2643320340..df91846f13 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -13,14 +13,14 @@ import { ManageUnitsDialogComponent } from '../manage-units-dialog/manage-units- export enum KeyResultMetricField { BASELINE, - TARGET_GOAL, + WORDING_TARGET_VALUE, STRETCH_GOAL, NONE } export interface MetricValue { baseline: number; - targetGoal: number; + wordingTargetValue: number; stretchGoal: number; } @@ -91,7 +91,8 @@ export class KeyResultTypeComponent implements AfterContentInit { formGroupValue = { ...formGroupValue, ...fieldValue }; return { baseline: +formGroupValue.baseline, - targetGoal: +formGroupValue.targetGoal, + wordingTargetValue: +formGroupValue.wordingTargetValue, + wordingCommitValue: +formGroupValue.wordingCommitValue, stretchGoal: +formGroupValue.stretchGoal } as MetricValue; } @@ -99,11 +100,12 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (changed) { case KeyResultMetricField.STRETCH_GOAL: case KeyResultMetricField.BASELINE: { - return this.calculateValueForField(values, KeyResultMetricField.TARGET_GOAL); + return this.calculateValueForField(values, KeyResultMetricField.WORDING_TARGET_VALUE); } - case KeyResultMetricField.TARGET_GOAL: { + case KeyResultMetricField.WORDING_TARGET_VALUE: { return this.calculateValueForField(values, KeyResultMetricField.STRETCH_GOAL); } + case KeyResultMetricField.NONE: { return {}; } @@ -115,15 +117,18 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (field) { case KeyResultMetricField.BASELINE: { - return { baseline: roundToTwoDecimals((values.targetGoal - values.stretchGoal * 0.7) / 0.3) }; + return { baseline: roundToTwoDecimals((values.wordingTargetValue - values.stretchGoal * 0.7) / 0.3), + wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } - case KeyResultMetricField.TARGET_GOAL: { - return { targetGoal: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline) }; + case KeyResultMetricField.WORDING_TARGET_VALUE: { + return { wordingTargetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline), + wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.STRETCH_GOAL: { - return { stretchGoal: roundToTwoDecimals((values.targetGoal - values.baseline) / 0.7 + values.baseline) }; + return { stretchGoal: roundToTwoDecimals((values.wordingTargetValue - values.baseline) / 0.7 + values.baseline), + wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.NONE: { @@ -149,8 +154,8 @@ export class KeyResultTypeComponent implements AfterContentInit { formGroupMetric?.get('baseline')?.valueChanges .subscribe((value: any) => this.updateMetricValue(KeyResultMetricField.BASELINE, { baseline: value })); - formGroupMetric?.get('targetGoal')?.valueChanges - .subscribe((value) => this.updateMetricValue(KeyResultMetricField.TARGET_GOAL, { targetGoal: value })); + formGroupMetric?.get('wordingTargetValue')?.valueChanges + .subscribe((value) => this.updateMetricValue(KeyResultMetricField.WORDING_TARGET_VALUE, { wordingTargetValue: value })); formGroupMetric?.get('stretchGoal')?.valueChanges .subscribe((value) => this.updateMetricValue(KeyResultMetricField.STRETCH_GOAL, { stretchGoal: value })); diff --git a/frontend/src/app/services/key-result.service.ts b/frontend/src/app/services/key-result.service.ts index 7523e38cc3..fc875f502a 100644 --- a/frontend/src/app/services/key-result.service.ts +++ b/frontend/src/app/services/key-result.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import { Injectable } from '@angular/core'; Object; import { HttpClient } from '@angular/common/http'; import { KeyResult } from '../shared/types/model/key-result'; import { map, Observable } from 'rxjs'; diff --git a/frontend/src/app/shared/constant-library.ts b/frontend/src/app/shared/constant-library.ts index 6ada396ef3..6d5ce0974d 100644 --- a/frontend/src/app/shared/constant-library.ts +++ b/frontend/src/app/shared/constant-library.ts @@ -104,7 +104,10 @@ export function getKeyResultForm(): FormGroup { baseline: new FormControl(0, [Validators.required, numberValidator(), Validators.maxLength(20)]), - targetGoal: new FormControl(0, [Validators.required, + wordingCommitValue: new FormControl(0, [Validators.required, + numberValidator(), + Validators.maxLength(20)]), + wordingTargetValue: new FormControl(0, [Validators.required, numberValidator(), Validators.maxLength(20)]), stretchGoal: new FormControl(0, [Validators.required, diff --git a/frontend/src/app/shared/custom/scoring/scoring.component.ts b/frontend/src/app/shared/custom/scoring/scoring.component.ts index 88fe58f042..8ae6d0b0c6 100644 --- a/frontend/src/app/shared/custom/scoring/scoring.component.ts +++ b/frontend/src/app/shared/custom/scoring/scoring.component.ts @@ -12,7 +12,7 @@ import { } from '@angular/core'; import { Zone } from '../../types/enums/zone'; import { KeyResultMetricMin } from '../../types/model/key-result-metric-min'; -import { Observable, of } from 'rxjs'; +import { Observable } from 'rxjs'; import { calculateCurrentPercentage } from '../../common'; import { KeyResultOrdinalMin } from '../../types/model/key-result-ordinal-min'; import { CheckInOrdinalMin } from '../../types/model/check-in-ordinal-min'; @@ -111,21 +111,22 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { calculatePercentageMetric() { if (this.keyResult.lastCheckIn !== null) { - const percentage = Math.round(calculateCurrentPercentage(this.castToMetric())); - this.labelPercentage = of(percentage); - if (percentage < 30) { + const keyResult = this.keyResult as KeyResultMetricMin; + const lastCheckIn = keyResult.lastCheckIn?.value!; + + if (lastCheckIn < keyResult.wordingCommitValue) { this.stretched = false; - this.failPercent = 100 / 30 * percentage; - } else if (percentage < 70) { + this.failPercent = (lastCheckIn - keyResult.baseline) / (keyResult.wordingCommitValue - keyResult.baseline) * 100; + } else if (lastCheckIn < keyResult.wordingTargetValue) { this.stretched = false; this.failPercent = 100; - this.commitPercent = 100 / 40 * (percentage - 30); - } else if (percentage < 100) { + this.commitPercent = (lastCheckIn - keyResult.wordingCommitValue) / (keyResult.wordingTargetValue - keyResult.wordingCommitValue) * 100; + } else if (lastCheckIn < keyResult.stretchGoal) { this.stretched = false; this.failPercent = 100; this.commitPercent = 100; - this.targetPercent = 100 / 30 * (percentage - 70); - } else if (percentage >= 100) { + this.targetPercent = (lastCheckIn - keyResult.wordingTargetValue) / (keyResult.stretchGoal - keyResult.wordingTargetValue) * 100; + } else if (lastCheckIn >= keyResult.stretchGoal) { this.stretched = true; } } diff --git a/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts b/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts index 4bbcda4ff4..d270396dee 100644 --- a/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts +++ b/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts @@ -3,5 +3,7 @@ import { KeyResultDto } from './key-result-dto'; export interface KeyResultMetricDto extends KeyResultDto { unit: string | null; baseline: number | null; + wordingCommitValue: number | null; + wordingTargetValue: number | null; stretchGoal: number | null; } diff --git a/frontend/src/app/shared/types/model/key-result-metric-min.ts b/frontend/src/app/shared/types/model/key-result-metric-min.ts index 8cd09bea6d..fbc314b87d 100644 --- a/frontend/src/app/shared/types/model/key-result-metric-min.ts +++ b/frontend/src/app/shared/types/model/key-result-metric-min.ts @@ -4,6 +4,8 @@ import { Unit } from '../enums/unit'; export interface KeyResultMetricMin extends KeyResultMin { baseline: number; + wordingCommitValue: number; + wordingTargetValue: number; stretchGoal: number; unit: Unit; lastCheckIn: CheckInMetricMin | null; diff --git a/frontend/src/app/shared/types/model/key-result-metric.ts b/frontend/src/app/shared/types/model/key-result-metric.ts index 924a9f9896..6e79f98795 100644 --- a/frontend/src/app/shared/types/model/key-result-metric.ts +++ b/frontend/src/app/shared/types/model/key-result-metric.ts @@ -5,6 +5,8 @@ import { Unit } from '../enums/unit'; export interface KeyResultMetric extends KeyResult { lastCheckIn: CheckInMetric | null; baseline: number; + wordingCommitValue: number; + wordingTargetValue: number; stretchGoal: number; unit: Unit; } From 8eb1b0e2f1daa3ff76114ed27e1f67f825b51f6b Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Tue, 12 Aug 2025 08:46:57 +0200 Subject: [PATCH 06/18] test: Remove unit from builder #1570 --- .../src/test/java/ch/puzzle/okr/mapper/OverviewMapperTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/src/test/java/ch/puzzle/okr/mapper/OverviewMapperTest.java b/backend/src/test/java/ch/puzzle/okr/mapper/OverviewMapperTest.java index c394e63f8e..51ee05e715 100644 --- a/backend/src/test/java/ch/puzzle/okr/mapper/OverviewMapperTest.java +++ b/backend/src/test/java/ch/puzzle/okr/mapper/OverviewMapperTest.java @@ -179,7 +179,6 @@ void shouldReturnOneElementWhenToDtoIsCalledWithMultipleObjectivesKeyResultsAndC .withKeyResultType(KEY_RESULT_TYPE_METRIC) .withBaseline(20.0) .withStretchGoal(37.0) - .withUnit("TCHF") .withCheckInValue(27.5) .build(), Overview.Builder From 992d7693fd26acff2496bc7c910d3af89850d6f1 Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Tue, 12 Aug 2025 15:59:36 +0200 Subject: [PATCH 07/18] test: Update integration and unit tests and a bit of formatting --- .../V1_0_0__current-db-schema-for-testing.sql | 6 ++++-- .../db/migration/V3_6_1__addMetricGoalsToKeyResult.sql | 2 +- .../okr/service/business/KeyResultBusinessServiceIT.java | 6 ++++-- .../test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java | 2 +- .../key-result-dialog/key-result-dialog.component.ts | 5 ----- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql b/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql index 5f560db8ba..edb133b8ee 100644 --- a/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql +++ b/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql @@ -107,6 +107,8 @@ create table if not exists key_result commit_zone varchar(1024), target_zone varchar(1024), stretch_zone varchar(1024), + wording_commit_value DOUBLE PRECISION, + wording_target_value DOUBLE PRECISION, primary key (id), constraint fk4ba6rgbr8mrkc8vvyqd5il4v9 foreign key (created_by_id) references person, @@ -187,7 +189,8 @@ SELECT TQ.TEAM_ID AS "TEAM_ID", COALESCE(KR.ID, -1) AS "KEY_RESULT_ID", KR.TITLE AS "KEY_RESULT_TITLE", KR.KEY_RESULT_TYPE AS "KEY_RESULT_TYPE", - U.unit_name as "UNIT", + KR.WORDING_COMMIT_VALUE, + KR.WORDING_TARGET_VALUE, KR.BASELINE, KR.STRETCH_GOAL, KR.COMMIT_ZONE, @@ -203,7 +206,6 @@ FROM (SELECT T.ID AS TEAM_ID, T.VERSION AS TEAM_VERSION, T.NAME, Q.ID AS QUARTER QUARTER Q) TQ LEFT JOIN OBJECTIVE O ON TQ.TEAM_ID = O.TEAM_ID AND TQ.QUARTER_ID = O.QUARTER_ID LEFT JOIN KEY_RESULT KR ON O.ID = KR.OBJECTIVE_ID - LEFT JOIN unit U ON U.ID = KR.unit_id LEFT JOIN CHECK_IN C ON KR.ID = C.KEY_RESULT_ID AND C.MODIFIED_ON = (SELECT MAX(CC.MODIFIED_ON) FROM CHECK_IN CC WHERE CC.KEY_RESULT_ID = C.KEY_RESULT_ID); diff --git a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql index cdd558c8be..889cc85962 100644 --- a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql +++ b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql @@ -1,6 +1,6 @@ ALTER TABLE key_result ADD COLUMN IF NOT EXISTS wording_commit_value DOUBLE PRECISION, - add COLUMN IF NOT EXISTS wording_target_value DOUBLE PRECISION; + ADD COLUMN IF NOT EXISTS wording_target_value DOUBLE PRECISION; UPDATE key_result SET wording_commit_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), diff --git a/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java index b2c14d4e8c..0eefd1a2fd 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java @@ -64,8 +64,10 @@ class KeyResultBusinessServiceIT { private KeyResult createKeyResultMetric(Long id) { return KeyResultMetric.Builder .builder() - .withBaseline(3.0) - .withStretchGoal(5.0) + .withBaseline(0.0) + .withStretchGoal(10.0) + .withWordingTargetValue(7.0) + .withWordingCommitValue(3.0) .withUnit(this.UNIT) .withId(id) .withTitle("Title") diff --git a/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java b/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java index 95a527004e..1eca51c1dc 100644 --- a/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java +++ b/backend/src/test/java/ch/puzzle/okr/test/KeyResultTestHelpers.java @@ -28,7 +28,7 @@ public class KeyResultTestHelpers { public static final Number OBJECTIVE_ID = 1; public static final Number LAST_CHECK_IN_ID = 1; public static final Double BASELINE_VALUE = 1.0; - public static final Double STRETCH_GOAL_VALUE = 5.0; + public static final Double STRETCH_GOAL_VALUE = 10.0; public static final String TARGET_ZONE = "Ein Baum"; public static final String STRETCH_ZONE = "Ein Wald"; public static final String QUARTER_LABEL = "GJ 22/23-Q4"; diff --git a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts index 4f84fabe57..197cf7c7aa 100644 --- a/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts +++ b/frontend/src/app/components/key-result-dialog/key-result-dialog.component.ts @@ -51,11 +51,8 @@ export class KeyResultDialogComponent implements OnInit { .subscribe())); this.keyResultForm.controls['metric'].enable(); this.keyResultForm.controls['ordinal'].enable(); - let keyResult: KeyResultDto = this.keyResultForm.value; - keyResult.actionList = itemListToActionList(this.keyResultForm.getRawValue().actionList, this.data.keyResult?.id || null); - if (this.isMetricKeyResult()) { keyResult = { ...keyResult, ...this.keyResultForm.get('metric')?.value } as KeyResultMetricDto; @@ -63,8 +60,6 @@ export class KeyResultDialogComponent implements OnInit { keyResult = { ...keyResult, ...this.keyResultForm.get('ordinal')?.value } as KeyResultOrdinalDto; } - - console.log(this.keyResultForm.get('metric')?.value); keyResult.objective = this.data.objective; keyResult.id = this.data.keyResult?.id; keyResult.version = this.data.keyResult?.version; From 66428b95d857cb55b8d9d5b08477104809d69830 Mon Sep 17 00:00:00 2001 From: Nevio Di Gennaro Date: Wed, 13 Aug 2025 09:46:26 +0200 Subject: [PATCH 08/18] test: fix frontend unit tests #1570 --- .../key-result-form.component.spec.ts | 2 + .../key-result-type.component.spec.ts | 72 +++++++++---------- .../key-result-type.component.ts | 9 +-- .../src/app/services/key-result.service.ts | 2 +- frontend/src/app/shared/test-data.ts | 10 +++ 5 files changed, 52 insertions(+), 43 deletions(-) diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts index 3214dba519..b72d3b37d6 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts @@ -157,6 +157,8 @@ describe('KeyResultFormComponent', () => { lastCheckIn: null, actionList: [], stretchGoal: 25, + wordingCommitValue: 9.6, + wordingTargetValue: 18.4, unit: UNIT_CHF, createdOn: new Date(), modifiedOn: new Date(), diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts index 4b82dedd3a..b3827888fe 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts @@ -214,19 +214,19 @@ describe('KeyResultTypeComponent', () => { }); it.each([[{ baseline: 0, - targetGoal: 0, + wordingTargetValue: 0, stretchGoal: 5 }, KeyResultMetricField.BASELINE, - KeyResultMetricField.TARGET_GOAL], + KeyResultMetricField.WORDING_TARGET_VALUE], [{ baseline: 0, - targetGoal: 0, + wordingTargetValue: 0, stretchGoal: 5 }, KeyResultMetricField.STRETCH_GOAL, - KeyResultMetricField.TARGET_GOAL], + KeyResultMetricField.WORDING_TARGET_VALUE], [{ baseline: 0, - targetGoal: 0, + wordingTargetValue: 0, stretchGoal: 5 }, - KeyResultMetricField.TARGET_GOAL, + KeyResultMetricField.WORDING_TARGET_VALUE, KeyResultMetricField.STRETCH_GOAL]])('Should call calculateValueForField with the correct enum', (values: MetricValue, changed: KeyResultMetricField, result: KeyResultMetricField) => { const spyInstance = jest.spyOn(component, 'calculateValueForField'); @@ -237,89 +237,89 @@ describe('KeyResultTypeComponent', () => { it.each([ [{ baseline: NaN, - targetGoal: 8.5, + wordingTargetValue: 8.5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, { baseline: 5 }], [{ baseline: NaN, - targetGoal: 6.5, + wordingTargetValue: 6.5, stretchGoal: 5 }, KeyResultMetricField.BASELINE, { baseline: 10 }], [{ baseline: NaN, - targetGoal: -8.5, + wordingTargetValue: -8.5, stretchGoal: -10 }, KeyResultMetricField.BASELINE, { baseline: -5 }], [{ baseline: NaN, - targetGoal: -6.5, + wordingTargetValue: -6.5, stretchGoal: -5 }, KeyResultMetricField.BASELINE, { baseline: -10 }], [{ baseline: NaN, - targetGoal: 2, + wordingTargetValue: 2, stretchGoal: 5 }, KeyResultMetricField.BASELINE, { baseline: -5 }], [{ baseline: NaN, - targetGoal: 5, + wordingTargetValue: 5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, { baseline: -6.67 }], [{ baseline: 5, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: 10 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: 8.5 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: 8.5 }], [{ baseline: 10, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: 5 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: 6.5 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: 6.5 }], [{ baseline: -5, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: -10 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: -8.5 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: -8.5 }], [{ baseline: -10, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: -5 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: -6.5 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: -6.5 }], [{ baseline: -5, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: 5 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: 2 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: 2 }], [{ baseline: 0, - targetGoal: NaN, + wordingTargetValue: NaN, stretchGoal: 5.34 }, - KeyResultMetricField.TARGET_GOAL, - { targetGoal: 3.74 }], + KeyResultMetricField.WORDING_TARGET_VALUE, + { wordingTargetValue: 3.74 }], [{ baseline: 5, - targetGoal: 8.5, + wordingTargetValue: 8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 10 }], [{ baseline: 10, - targetGoal: 6.5, + wordingTargetValue: 6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 5 }], [{ baseline: -5, - targetGoal: -8.5, + wordingTargetValue: -8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: -10 }], [{ baseline: -10, - targetGoal: -6.5, + wordingTargetValue: -6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: -5 }], [{ baseline: -5, - targetGoal: 2, + wordingTargetValue: 2, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 5 }] @@ -338,7 +338,7 @@ describe('KeyResultTypeComponent', () => { .toEqual(0); expect(getValueOfForm(component.keyResultForm, ['metric', - 'targetGoal'])) + 'wordingTargetValue'])) .toEqual(0); expect(getValueOfForm(component.keyResultForm, ['metric', diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index df91846f13..0d4f5c58d5 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -117,18 +117,15 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (field) { case KeyResultMetricField.BASELINE: { - return { baseline: roundToTwoDecimals((values.wordingTargetValue - values.stretchGoal * 0.7) / 0.3), - wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; + return { baseline: roundToTwoDecimals((values.wordingTargetValue - values.stretchGoal * 0.7) / 0.3) }; } case KeyResultMetricField.WORDING_TARGET_VALUE: { - return { wordingTargetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline), - wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; + return { wordingTargetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline) }; } case KeyResultMetricField.STRETCH_GOAL: { - return { stretchGoal: roundToTwoDecimals((values.wordingTargetValue - values.baseline) / 0.7 + values.baseline), - wordingCommitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; + return { stretchGoal: roundToTwoDecimals((values.wordingTargetValue - values.baseline) / 0.7 + values.baseline) }; } case KeyResultMetricField.NONE: { diff --git a/frontend/src/app/services/key-result.service.ts b/frontend/src/app/services/key-result.service.ts index fc875f502a..7523e38cc3 100644 --- a/frontend/src/app/services/key-result.service.ts +++ b/frontend/src/app/services/key-result.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; Object; +import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { KeyResult } from '../shared/types/model/key-result'; import { map, Observable } from 'rxjs'; diff --git a/frontend/src/app/shared/test-data.ts b/frontend/src/app/shared/test-data.ts index 83120392c2..226e763d37 100644 --- a/frontend/src/app/shared/test-data.ts +++ b/frontend/src/app/shared/test-data.ts @@ -220,6 +220,8 @@ export const keyResultMetricMin: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 10.0, stretchGoal: 25.0, + wordingCommitValue: 10, + wordingTargetValue: 20, lastCheckIn: checkInMetric, type: 'keyResult' } as KeyResultMetricMin; @@ -232,6 +234,8 @@ export const keyResultMetricMinScoring: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 25.0, stretchGoal: 75.0, + wordingCommitValue: 10, + wordingTargetValue: 20, lastCheckIn: { id: 800, version: 1, @@ -255,6 +259,8 @@ export const keyResultMetricMinScoringInversion: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 50.0, stretchGoal: 0.0, + wordingCommitValue: 10, + wordingTargetValue: 20, lastCheckIn: { id: 800, version: 1, @@ -579,6 +585,8 @@ export const keyResultMetric: KeyResultMetric = { description: 'Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', baseline: 30, stretchGoal: 100, + wordingCommitValue: 10, + wordingTargetValue: 20, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', @@ -616,6 +624,8 @@ export const keyResultActions: KeyResultMetric = { description: 'Puzzle ITC hat schöne Büros, wo es alles hat.', baseline: 10, stretchGoal: 30, + wordingCommitValue: 10, + wordingTargetValue: 20, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', From f29211710ee83373241031725a00ea5dbd33f30f Mon Sep 17 00:00:00 2001 From: Nevio Di Gennaro Date: Wed, 13 Aug 2025 09:55:48 +0200 Subject: [PATCH 09/18] test: calculate correct commitvalues and targetvalues for test data #1570 --- frontend/src/app/shared/test-data.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/shared/test-data.ts b/frontend/src/app/shared/test-data.ts index 226e763d37..5a78faee77 100644 --- a/frontend/src/app/shared/test-data.ts +++ b/frontend/src/app/shared/test-data.ts @@ -220,8 +220,8 @@ export const keyResultMetricMin: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 10.0, stretchGoal: 25.0, - wordingCommitValue: 10, - wordingTargetValue: 20, + wordingCommitValue: 14.5, + wordingTargetValue: 20.5, lastCheckIn: checkInMetric, type: 'keyResult' } as KeyResultMetricMin; @@ -234,8 +234,8 @@ export const keyResultMetricMinScoring: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 25.0, stretchGoal: 75.0, - wordingCommitValue: 10, - wordingTargetValue: 20, + wordingCommitValue: 40, + wordingTargetValue: 60, lastCheckIn: { id: 800, version: 1, @@ -259,8 +259,8 @@ export const keyResultMetricMinScoringInversion: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 50.0, stretchGoal: 0.0, - wordingCommitValue: 10, - wordingTargetValue: 20, + wordingCommitValue: 35, + wordingTargetValue: 15, lastCheckIn: { id: 800, version: 1, @@ -585,8 +585,8 @@ export const keyResultMetric: KeyResultMetric = { description: 'Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', baseline: 30, stretchGoal: 100, - wordingCommitValue: 10, - wordingTargetValue: 20, + wordingCommitValue: 51, + wordingTargetValue: 79, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', @@ -624,8 +624,8 @@ export const keyResultActions: KeyResultMetric = { description: 'Puzzle ITC hat schöne Büros, wo es alles hat.', baseline: 10, stretchGoal: 30, - wordingCommitValue: 10, - wordingTargetValue: 20, + wordingCommitValue: 16, + wordingTargetValue: 24, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', From 9ef92460c8f2cb48d2607a0259eea24948012e38 Mon Sep 17 00:00:00 2001 From: Nevio Di Gennaro Date: Wed, 13 Aug 2025 10:34:39 +0200 Subject: [PATCH 10/18] test: Fix some of the e2e tests #1570 --- frontend/cypress/e2e/tab.cy.ts | 1 + .../app/components/key-result-form/key-result-form.component.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/cypress/e2e/tab.cy.ts b/frontend/cypress/e2e/tab.cy.ts index c7a86c9f66..d8cd0122b3 100644 --- a/frontend/cypress/e2e/tab.cy.ts +++ b/frontend/cypress/e2e/tab.cy.ts @@ -173,6 +173,7 @@ describe('tabbing workflows', () => { tabAndCheck('stretch-goal'); tabAndCheck('owner-input'); tabAndCheck('description-input'); + tabAndCheck('manage-units'); tabAndCheck('action-input'); tabAndCheck('add-action-plan-line', 'Weitere Action hinzufügen'); tabAndCheck('ordinal-tab', 'Ordinal'); diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.ts b/frontend/src/app/components/key-result-form/key-result-form.component.ts index 9a613c7af8..888f07e203 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.ts @@ -70,7 +70,7 @@ export class KeyResultFormComponent implements OnInit, AfterContentInit { } addNewItem(item?: Item) { - (this.keyResultForm.get('actionLis0.9t') as FormArray) + (this.keyResultForm.get('actionList') as FormArray) ?.push(initFormGroupFromItem(item)); } From 75ca89aebd065d1e657dbc7fc83ebc94f76c0fbb Mon Sep 17 00:00:00 2001 From: Nevio Di Gennaro Date: Wed, 13 Aug 2025 13:20:29 +0200 Subject: [PATCH 11/18] test: Update testdata #1570 --- .../h2-db/data-test-h2/V100_0_0__TestData.sql | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql b/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql index f23e94d906..b15c42cb04 100644 --- a/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql +++ b/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql @@ -115,23 +115,23 @@ values (4, 1, '', '2023-07-25 08:17:51.309958', 66, 'Build a company culture tha 1, 2, 6, 'ONGOING', null, '2023-07-25 08:39:28.175703'); INSERT INTO key_result (id, version, baseline, description, modified_on, stretch_goal, title, created_by_id, - objective_id, owner_id, key_result_type, created_on, unit_id, commit_zone, target_zone, stretch_zone) -VALUES (10,1, 465, '', '2023-07-25 08:23:02.273028', 60, 'Im Durchschnitt soll die Lautstärke 60dB nicht überschreiten', 1, 5, 1, 'metric', '2023-07-25 08:23:02.273028', 1, null, null, null), - (8,1, 213425, '', '2023-07-25 08:19:44.351252', 80, 'High employee satisfaction scores (80%+) throughout the year.', 1, 4, 1, 'metric', '2023-07-25 08:19:44.351252', 1, null, null, null), - (7,1, 84, '', '2023-07-25 08:19:13.569300', 4, 'Monthly town halls between our people and leadership teams over the next four months.', 1, 4, 1, 'metric', '2023-07-25 08:19:13.569300', 1, null, null, null), - (6,1, 5, '', '2023-07-25 08:18:44.087674', 1, 'New structure that rewards funny guys and innovation before the end of Q1.', 1, 4, 1, 'metric', '2023-07-25 08:18:44.087674', 1, null, null, null), - (15,1, 0, 'asf', '2023-07-25 08:40:49.412684', 1, ' Lorem ipsum dolor sit amet', 1, 9, 1, 'metric', '2023-07-25 08:40:49.412684', 1, null, null, null), - (5,1, null, '', '2023-07-25 08:16:24.466383', null, 'Kundenzufriedenheitsumfrage soll mindestens einmal pro 2 Wochen durchgeführt werden. ', 1, 3, 1, 'ordinal', '2023-07-25 08:16:24.466383', 1, 'Fisch', 'Hai', 'MEG'), - (12,1, 0, '', '2023-07-25 08:28:45.110759', 80, 'Wir wollen bereits nach Q1 rund 80% des Redesigns vom OKR-Tool abgeschlossen haben. ', 1, 6, 1, 'metric', '2023-07-25 08:28:45.110759', 1, null, null, null), - (4,1, null, '', '2023-07-25 08:15:18.244565', null, 'Antwortzeit für Supportanfragen um 33% verkürzen.', 1, 3, 1, 'ordinal', '2023-07-25 08:15:18.244565', 1, 'Pflanze', 'Baum', 'Wald'), - (13,1, 43, '', '2023-07-25 08:29:57.709926', 15, 'Jedes Woche wird ein Kuchen vom BBT für Puzzle Organisiert', 1, 6, 1, 'metric', '2023-07-25 08:29:57.709926', 1, null, null, null), - (3,1, 0, '', '2023-07-25 08:14:31.964115', 25, 'Steigern der URS um 25%', 1, 3, 1, 'metric', '2023-07-25 08:14:31.964115', 1, null, null, null), - (14,1, 0, '', '2023-07-25 08:31:39.249943', 20, 'Das BBT hilft den Membern 20% mehr beim Töggelen', 1, 6, 1, 'metric', '2023-07-25 08:31:39.249943', 1, null, null, null), - (16,1, 200, '', '2023-07-25 08:41:24.592007', 1, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.', 1, 9, 1, 'metric', '2023-07-25 08:41:24.592007', 1, null, null, null), - (19,1, 50, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', '2023-07-25 08:42:56.407125', 1, 'nsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At ', 1, 8, 1, 'metric', '2023-07-25 08:42:56.407125', 1, null, null, null), - (17,1, 525, 'asdf', '2023-07-25 08:41:52.844903', 20000000, 'vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', 1, 9, 1, 'metric', '2023-07-25 08:41:52.844903', 1, null, null, null), - (9,1, 100, '', '2023-07-25 08:48:45.825328', 80, 'Die Member des BBT reduzieren Ihre Lautstärke um 20%', 1, 5, 1, 'metric', '2023-07-25 08:48:45.825328', 1, null, null, null), - (18,1, 0, 'consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', '2023-07-25 08:42:24.779721', 1, 'Lorem', 1, 8, 1, 'metric', '2023-07-25 08:42:24.779721', 1, null, null, null); + objective_id, owner_id, key_result_type, created_on, unit_id, commit_zone, target_zone, stretch_zone, wording_commit_value, wording_target_value) +VALUES (10,1, 465, '', '2023-07-25 08:23:02.273028', 60, 'Im Durchschnitt soll die Lautstärke 60dB nicht überschreiten', 1, 5, 1, 'metric', '2023-07-25 08:23:02.273028', 1, null, null, null, 321, 186), + (8,1, 213425, '', '2023-07-25 08:19:44.351252', 80, 'High employee satisfaction scores (80%+) throughout the year.', 1, 4, 1, 'metric', '2023-07-25 08:19:44.351252', 1, null, null, null, 149303.5, 71550.5), + (7,1, 84, '', '2023-07-25 08:19:13.569300', 4, 'Monthly town halls between our people and leadership teams over the next four months.', 1, 4, 1, 'metric', '2023-07-25 08:19:13.569300', 1, null, null, null, 60.0, 28.0), + (6,1, 5, '', '2023-07-25 08:18:44.087674', 1, 'New structure that rewards funny guys and innovation before the end of Q1.', 1, 4, 1, 'metric', '2023-07-25 08:18:44.087674', 1, null, null, null, 3.8, 2.2), + (15,1, 0, 'asf', '2023-07-25 08:40:49.412684', 1, ' Lorem ipsum dolor sit amet', 1, 9, 1, 'metric', '2023-07-25 08:40:49.412684', 1, null, null, null, 0.3, 0.7), + (5,1, null, '', '2023-07-25 08:16:24.466383', null, 'Kundenzufriedenheitsumfrage soll mindestens einmal pro 2 Wochen durchgeführt werden. ', 1, 3, 1, 'ordinal', '2023-07-25 08:16:24.466383', 1, 'Fisch', 'Hai', 'MEG',null,null), + (12,1, 0, '', '2023-07-25 08:28:45.110759', 80, 'Wir wollen bereits nach Q1 rund 80% des Redesigns vom OKR-Tool abgeschlossen haben. ', 1, 6, 1, 'metric', '2023-07-25 08:28:45.110759', 1, null, null, null, 24.0, 56.0), + (4,1, null, '', '2023-07-25 08:15:18.244565', null, 'Antwortzeit für Supportanfragen um 33% verkürzen.', 1, 3, 1, 'ordinal', '2023-07-25 08:15:18.244565', 1, 'Pflanze', 'Baum', 'Wald',null,null), + (13,1, 43, '', '2023-07-25 08:29:57.709926', 15, 'Jedes Woche wird ein Kuchen vom BBT für Puzzle Organisiert', 1, 6, 1, 'metric', '2023-07-25 08:29:57.709926', 1, null, null, null, 35.6, 22.4), + (3,1, 0, '', '2023-07-25 08:14:31.964115', 25, 'Steigern der URS um 25%', 1, 3, 1, 'metric', '2023-07-25 08:14:31.964115', 1, null, null, null, 7.5, 17.5), + (14,1, 0, '', '2023-07-25 08:31:39.249943', 20, 'Das BBT hilft den Membern 20% mehr beim Töggelen', 1, 6, 1, 'metric', '2023-07-25 08:31:39.249943', 1, null, null, null, 6.0, 14.0), + (16,1, 200, '', '2023-07-25 08:41:24.592007', 1, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.', 1, 9, 1, 'metric', '2023-07-25 08:41:24.592007', 1, null, null, null, 140.3, 80.7), + (19,1, 50, 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', '2023-07-25 08:42:56.407125', 1, 'nsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At ', 1, 8, 1, 'metric', '2023-07-25 08:42:56.407125', 1, null, null, null, 35.3, 15.7), + (17,1, 525, 'asdf', '2023-07-25 08:41:52.844903', 20000000, 'vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', 1, 9, 1, 'metric', '2023-07-25 08:41:52.844903', 1, null, null, null, 6000000.08, 14000000.08), + (9,1, 100, '', '2023-07-25 08:48:45.825328', 80, 'Die Member des BBT reduzieren Ihre Lautstärke um 20%', 1, 5, 1, 'metric', '2023-07-25 08:48:45.825328', 1, null, null, null, 94.0, 86.0), + (18,1, 0, 'consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lore', '2023-07-25 08:42:24.779721', 1, 'Lorem', 1, 8, 1, 'metric', '2023-07-25 08:42:24.779721', 1, null, null, null, 0.3, 0.7); From 62a29fd226d61e32c3b2131851b91ea2137c83fc Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Fri, 15 Aug 2025 09:57:46 +0200 Subject: [PATCH 12/18] refactor: Rename wordingCommitValue and wordingTargetValue #1570 --- .../okr/dto/keyresult/KeyResultMetricDto.java | 2 +- .../overview/OverviewKeyResultMetricDto.java | 2 +- .../ch/puzzle/okr/mapper/OverviewMapper.java | 4 +- .../keyresult/KeyResultMetricMapper.java | 8 +-- .../okr/models/keyresult/KeyResultMetric.java | 46 ++++++------ .../puzzle/okr/models/overview/Overview.java | 32 ++++----- .../h2-db/data-test-h2/V100_0_0__TestData.sql | 2 +- .../V1_0_0__current-db-schema-for-testing.sql | 8 +-- .../V3_6_1__addMetricGoalsToKeyResult.sql | 12 ++-- ...6_2__addMetricKeyResultGoalsToOverview.sql | 4 +- .../business/KeyResultBusinessServiceIT.java | 4 +- .../key-result-form.component.spec.ts | 4 +- .../key-result-type.component.html | 6 +- .../key-result-type.component.spec.ts | 72 +++++++++---------- .../key-result-type.component.ts | 24 +++---- frontend/src/app/shared/constant-library.ts | 4 +- .../custom/scoring/scoring.component.ts | 10 +-- frontend/src/app/shared/test-data.ts | 20 +++--- .../types/DTOs/key-result-metric-dto.ts | 4 +- .../types/model/key-result-metric-min.ts | 4 +- .../shared/types/model/key-result-metric.ts | 4 +- 21 files changed, 138 insertions(+), 138 deletions(-) diff --git a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java index 4314a36ae5..24b87194e4 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/keyresult/KeyResultMetricDto.java @@ -8,7 +8,7 @@ @JsonDeserialize(as = KeyResultMetricDto.class) public record KeyResultMetricDto(Long id, int version, String keyResultType, String title, String description, - Double baseline, Double wordingCommitValue, Double wordingTargetValue, Double stretchGoal, UnitDto unit, + Double baseline, Double commitValue, Double targetValue, Double stretchGoal, UnitDto unit, KeyResultUserDto owner, KeyResultObjectiveDto objective, KeyResultLastCheckInMetricDto lastCheckIn, LocalDateTime createdOn, LocalDateTime modifiedOn, boolean isWriteable, List actionList) implements KeyResultDto { diff --git a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java index 502dee595e..f49c2630ee 100644 --- a/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java +++ b/backend/src/main/java/ch/puzzle/okr/dto/overview/OverviewKeyResultMetricDto.java @@ -1,6 +1,6 @@ package ch.puzzle.okr.dto.overview; public record OverviewKeyResultMetricDto(Long id, String title, String keyResultType, Double baseline, - Double wordingCommitValue, Double wordingTargetValue, Double stretchGoal, + Double commitValue, Double targetValue, Double stretchGoal, OverviewLastCheckInMetricDto lastCheckIn) implements OverviewKeyResultDto { } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java index 91a929087b..ace81adfc9 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/OverviewMapper.java @@ -104,8 +104,8 @@ private OverviewKeyResultMetricDto createKeyResultMetricDto(Overview overview) { overview.getKeyResultTitle(), overview.getKeyResultType(), overview.getBaseline(), - overview.getWordingCommitValue(), - overview.getWordingTargetValue(), + overview.getCommitValue(), + overview.getTargetValue(), overview.getStretchGoal(), lastCheckIn); } diff --git a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java index 98714bb2a4..1d5f9d5f10 100644 --- a/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java +++ b/backend/src/main/java/ch/puzzle/okr/mapper/keyresult/KeyResultMetricMapper.java @@ -63,8 +63,8 @@ public KeyResultDto toDto(KeyResultMetric keyResult, List actionList) { keyResult.getTitle(), // keyResult.getDescription(), // keyResult.getBaseline(), // - keyResult.getWordingCommitValue(), - keyResult.getWordingTargetValue(), + keyResult.getCommitValue(), + keyResult.getTargetValue(), keyResult.getStretchGoal(), // unitMapper.toDto(keyResult.getUnit()), // ownerDto, @@ -81,8 +81,8 @@ public KeyResult toKeyResultMetric(KeyResultMetricDto keyResultMetricDto) { .builder() // .withBaseline(keyResultMetricDto.baseline()) // .withStretchGoal(keyResultMetricDto.stretchGoal()) // - .withWordingCommitValue(keyResultMetricDto.wordingCommitValue()) // - .withWordingTargetValue(keyResultMetricDto.wordingTargetValue()) // + .withCommitValue(keyResultMetricDto.commitValue()) // + .withTargetValue(keyResultMetricDto.targetValue()) // .withUnit(unitBusinessService.findUnitByName(keyResultMetricDto.unit().unitName())) .withId(keyResultMetricDto.id()) // .withVersion(keyResultMetricDto.version()) // diff --git a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java index e2300c3412..886da7fe73 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java +++ b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java @@ -14,9 +14,9 @@ public class KeyResultMetric extends KeyResult { @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double baseline; - private Double wordingCommitValue; + private Double commitValue; - private Double wordingTargetValue; + private Double targetValue; @NotNull(message = MessageKey.ATTRIBUTE_NOT_NULL) private Double stretchGoal; @@ -37,20 +37,20 @@ public Double getStretchGoal() { return stretchGoal; } - public Double getWordingCommitValue() { - return wordingCommitValue; + public Double getCommitValue() { + return commitValue; } - public void setWordingCommitValue(Double wordingCommitValue) { - this.wordingCommitValue = wordingCommitValue; + public void setCommitValue(Double commitValue) { + this.commitValue = commitValue; } - public Double getWordingTargetValue() { - return wordingTargetValue; + public Double getTargetValue() { + return targetValue; } - public void setWordingTargetValue(Double wordingTargetValue) { - this.wordingTargetValue = wordingTargetValue; + public void setTargetValue(Double targetValue) { + this.targetValue = targetValue; } public void setStretchGoal(Double stretchGoal) { @@ -74,8 +74,8 @@ public boolean equals(Object o) { if (o instanceof KeyResultMetric keyResultMetric) { return super.equals(o) && Objects.equals(baseline, keyResultMetric.baseline) && Objects.equals(stretchGoal, keyResultMetric.stretchGoal) - && Objects.equals(wordingCommitValue, keyResultMetric.wordingCommitValue) - && Objects.equals(wordingTargetValue, keyResultMetric.wordingTargetValue) + && Objects.equals(commitValue, keyResultMetric.commitValue) + && Objects.equals(targetValue, keyResultMetric.targetValue) && Objects.equals(unit, keyResultMetric.unit); } return false; @@ -83,28 +83,28 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), baseline, wordingCommitValue, wordingTargetValue, stretchGoal, unit); + return Objects.hash(super.hashCode(), baseline, commitValue, targetValue, stretchGoal, unit); } @Override public String toString() { - return "KeyResultMetric{" + "baseline=" + baseline + ", wordingCommitValue=" + wordingCommitValue - + ", wordingTargetValue=" + wordingTargetValue + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; + return "KeyResultMetric{" + "baseline=" + baseline + ", commitValue=" + commitValue + + ", targetValue=" + targetValue + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; } private KeyResultMetric(Builder builder) { super(builder); setBaseline(builder.baseline); - setWordingCommitValue(builder.wordingCommitValue); - setWordingTargetValue(builder.wordingTargetValue); + setCommitValue(builder.commitValue); + setTargetValue(builder.targetValue); setStretchGoal(builder.stretchGoal); setUnit(builder.unit); } public static class Builder extends KeyResult.Builder { private Double baseline; - private Double wordingCommitValue; - private Double wordingTargetValue; + private Double commitValue; + private Double targetValue; private Double stretchGoal; private Unit unit; @@ -131,13 +131,13 @@ public Builder withUnit(Unit unit) { return this; } - public Builder withWordingCommitValue(Double wordingCommitValue) { - this.wordingCommitValue = wordingCommitValue; + public Builder withCommitValue(Double commitValue) { + this.commitValue = commitValue; return this; } - public Builder withWordingTargetValue(Double wordingTargetValue) { - this.wordingTargetValue = wordingTargetValue; + public Builder withTargetValue(Double targetValue) { + this.targetValue = targetValue; return this; } diff --git a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java index 68004b42ce..9919081963 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java +++ b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java @@ -23,8 +23,8 @@ public class Overview implements WriteableInterface { private String keyResultTitle; private String keyResultType; private Double baseline; - private Double wordingCommitValue; - private Double wordingTargetValue; + private Double commitValue; + private Double targetValue; private Double stretchGoal; private String commitZone; private String targetZone; @@ -55,8 +55,8 @@ private Overview(Builder builder) { keyResultTitle = builder.keyResultTitle; keyResultType = builder.keyResultType; baseline = builder.baseline; - wordingCommitValue = builder.wordingCommitValue; - wordingTargetValue = builder.wordingTargetValue; + commitValue = builder.commitValue; + targetValue = builder.targetValue; stretchGoal = builder.stretchGoal; commitZone = builder.commitZone; targetZone = builder.targetZone; @@ -143,12 +143,12 @@ public LocalDateTime getCheckInCreatedOn() { return checkInCreatedOn; } - public Double getWordingCommitValue() { - return wordingCommitValue; + public Double getCommitValue() { + return commitValue; } - public Double getWordingTargetValue() { - return wordingTargetValue; + public Double getTargetValue() { + return targetValue; } @Override @@ -175,8 +175,8 @@ public String toString() { + teamVersion + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState + ", objectiveCreatedOn=" + objectiveCreatedOn + ", quarterId=" + quarterId + ", quarterLabel='" + quarterLabel + '\'' + ", keyResultTitle='" + keyResultTitle + '\'' + ", keyResultType='" - + keyResultType + '\'' + ", baseline=" + baseline + ", wordingCommitValue=" + wordingCommitValue - + ", wordingTargetValue=" + wordingTargetValue + ", stretchGoal=" + stretchGoal + ", commitZone='" + + keyResultType + '\'' + ", baseline=" + baseline + ", commitValue=" + commitValue + + ", targetValue=" + targetValue + ", stretchGoal=" + stretchGoal + ", commitZone='" + commitZone + '\'' + ", targetZone='" + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + ", checkInValue=" + checkInValue + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + confidence + ", checkInCreatedOn=" + checkInCreatedOn + ", writeable=" + writeable @@ -195,8 +195,8 @@ public static final class Builder { private String keyResultTitle; private String keyResultType; private Double baseline; - private Double wordingCommitValue; - private Double wordingTargetValue; + private Double commitValue; + private Double targetValue; private Double stretchGoal; private String commitZone; private String targetZone; @@ -268,13 +268,13 @@ public Builder withBaseline(Double baseline) { return this; } - public Builder withWordingCommitValue(Double wordingCommitValue) { - this.wordingCommitValue = wordingCommitValue; + public Builder withCommitValue(Double commitValue) { + this.commitValue = commitValue; return this; } - public Builder withWordingTargetValue(Double wordingTargetValue) { - this.wordingTargetValue = wordingTargetValue; + public Builder withTargetValue(Double targetValue) { + this.targetValue = targetValue; return this; } diff --git a/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql b/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql index b15c42cb04..caa1279de3 100644 --- a/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql +++ b/backend/src/main/resources/db/h2-db/data-test-h2/V100_0_0__TestData.sql @@ -115,7 +115,7 @@ values (4, 1, '', '2023-07-25 08:17:51.309958', 66, 'Build a company culture tha 1, 2, 6, 'ONGOING', null, '2023-07-25 08:39:28.175703'); INSERT INTO key_result (id, version, baseline, description, modified_on, stretch_goal, title, created_by_id, - objective_id, owner_id, key_result_type, created_on, unit_id, commit_zone, target_zone, stretch_zone, wording_commit_value, wording_target_value) + objective_id, owner_id, key_result_type, created_on, unit_id, commit_zone, target_zone, stretch_zone, commit_value, target_value) VALUES (10,1, 465, '', '2023-07-25 08:23:02.273028', 60, 'Im Durchschnitt soll die Lautstärke 60dB nicht überschreiten', 1, 5, 1, 'metric', '2023-07-25 08:23:02.273028', 1, null, null, null, 321, 186), (8,1, 213425, '', '2023-07-25 08:19:44.351252', 80, 'High employee satisfaction scores (80%+) throughout the year.', 1, 4, 1, 'metric', '2023-07-25 08:19:44.351252', 1, null, null, null, 149303.5, 71550.5), (7,1, 84, '', '2023-07-25 08:19:13.569300', 4, 'Monthly town halls between our people and leadership teams over the next four months.', 1, 4, 1, 'metric', '2023-07-25 08:19:13.569300', 1, null, null, null, 60.0, 28.0), diff --git a/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql b/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql index edb133b8ee..921dade574 100644 --- a/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql +++ b/backend/src/main/resources/db/h2-db/database-h2-schema/V1_0_0__current-db-schema-for-testing.sql @@ -107,8 +107,8 @@ create table if not exists key_result commit_zone varchar(1024), target_zone varchar(1024), stretch_zone varchar(1024), - wording_commit_value DOUBLE PRECISION, - wording_target_value DOUBLE PRECISION, + commit_value DOUBLE PRECISION, + target_value DOUBLE PRECISION, primary key (id), constraint fk4ba6rgbr8mrkc8vvyqd5il4v9 foreign key (created_by_id) references person, @@ -189,8 +189,8 @@ SELECT TQ.TEAM_ID AS "TEAM_ID", COALESCE(KR.ID, -1) AS "KEY_RESULT_ID", KR.TITLE AS "KEY_RESULT_TITLE", KR.KEY_RESULT_TYPE AS "KEY_RESULT_TYPE", - KR.WORDING_COMMIT_VALUE, - KR.WORDING_TARGET_VALUE, + KR.COMMIT_VALUE, + KR.TARGET_VALUE, KR.BASELINE, KR.STRETCH_GOAL, KR.COMMIT_ZONE, diff --git a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql index 889cc85962..8c9abcc11f 100644 --- a/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql +++ b/backend/src/main/resources/db/migration/V3_6_1__addMetricGoalsToKeyResult.sql @@ -1,9 +1,9 @@ ALTER TABLE key_result - ADD COLUMN IF NOT EXISTS wording_commit_value DOUBLE PRECISION, - ADD COLUMN IF NOT EXISTS wording_target_value DOUBLE PRECISION; + ADD COLUMN IF NOT EXISTS commit_value DOUBLE PRECISION, + ADD COLUMN IF NOT EXISTS target_value DOUBLE PRECISION; UPDATE key_result -SET wording_commit_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), - wording_target_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.7 + COALESCE(baseline, 0))::numeric, 2) -WHERE wording_commit_value IS NULL - AND wording_target_value IS NULL; +SET commit_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.3 + COALESCE(baseline, 0))::numeric, 2), + target_value = ROUND(((COALESCE(stretch_goal, 0) - COALESCE(baseline, 0)) * 0.7 + COALESCE(baseline, 0))::numeric, 2) +WHERE commit_value IS NULL + AND target_value IS NULL; diff --git a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql index 6fcab09763..fccf23fb8c 100644 --- a/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql +++ b/backend/src/main/resources/db/migration/V3_6_2__addMetricKeyResultGoalsToOverview.sql @@ -13,8 +13,8 @@ SELECT tq.team_id AS "team_id", kr.title AS "key_result_title", kr.key_result_type AS "key_result_type", kr.baseline, - kr.wording_commit_value, - kr.wording_target_value, + kr.commit_value, + kr.target_value, kr.stretch_goal, kr.commit_zone, kr.target_zone, diff --git a/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java b/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java index 0eefd1a2fd..a6ff808db5 100644 --- a/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java +++ b/backend/src/test/java/ch/puzzle/okr/service/business/KeyResultBusinessServiceIT.java @@ -66,8 +66,8 @@ private KeyResult createKeyResultMetric(Long id) { .builder() .withBaseline(0.0) .withStretchGoal(10.0) - .withWordingTargetValue(7.0) - .withWordingCommitValue(3.0) + .withTargetValue(7.0) + .withCommitValue(3.0) .withUnit(this.UNIT) .withId(id) .withTitle("Title") diff --git a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts index b72d3b37d6..a8dd410ff5 100644 --- a/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts +++ b/frontend/src/app/components/key-result-form/key-result-form.component.spec.ts @@ -157,8 +157,8 @@ describe('KeyResultFormComponent', () => { lastCheckIn: null, actionList: [], stretchGoal: 25, - wordingCommitValue: 9.6, - wordingTargetValue: 18.4, + commitValue: 9.6, + targetValue: 18.4, unit: UNIT_CHF, createdOn: new Date(), modifiedOn: new Date(), diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.html b/frontend/src/app/components/key-result-type/key-result-type.component.html index c41e6d97f8..8142a63694 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.html +++ b/frontend/src/app/components/key-result-type/key-result-type.component.html @@ -133,11 +133,11 @@ - + diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts index b3827888fe..01cdf32344 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts @@ -214,19 +214,19 @@ describe('KeyResultTypeComponent', () => { }); it.each([[{ baseline: 0, - wordingTargetValue: 0, + targetValue: 0, stretchGoal: 5 }, KeyResultMetricField.BASELINE, - KeyResultMetricField.WORDING_TARGET_VALUE], + KeyResultMetricField.TARGET_VALUE], [{ baseline: 0, - wordingTargetValue: 0, + targetValue: 0, stretchGoal: 5 }, KeyResultMetricField.STRETCH_GOAL, - KeyResultMetricField.WORDING_TARGET_VALUE], + KeyResultMetricField.TARGET_VALUE], [{ baseline: 0, - wordingTargetValue: 0, + targetValue: 0, stretchGoal: 5 }, - KeyResultMetricField.WORDING_TARGET_VALUE, + KeyResultMetricField.TARGET_VALUE, KeyResultMetricField.STRETCH_GOAL]])('Should call calculateValueForField with the correct enum', (values: MetricValue, changed: KeyResultMetricField, result: KeyResultMetricField) => { const spyInstance = jest.spyOn(component, 'calculateValueForField'); @@ -237,89 +237,89 @@ describe('KeyResultTypeComponent', () => { it.each([ [{ baseline: NaN, - wordingTargetValue: 8.5, + targetValue: 8.5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, { baseline: 5 }], [{ baseline: NaN, - wordingTargetValue: 6.5, + targetValue: 6.5, stretchGoal: 5 }, KeyResultMetricField.BASELINE, { baseline: 10 }], [{ baseline: NaN, - wordingTargetValue: -8.5, + targetValue: -8.5, stretchGoal: -10 }, KeyResultMetricField.BASELINE, { baseline: -5 }], [{ baseline: NaN, - wordingTargetValue: -6.5, + targetValue: -6.5, stretchGoal: -5 }, KeyResultMetricField.BASELINE, { baseline: -10 }], [{ baseline: NaN, - wordingTargetValue: 2, + targetValue: 2, stretchGoal: 5 }, KeyResultMetricField.BASELINE, { baseline: -5 }], [{ baseline: NaN, - wordingTargetValue: 5, + targetValue: 5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, { baseline: -6.67 }], [{ baseline: 5, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: 10 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: 8.5 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: 8.5 }], [{ baseline: 10, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: 5 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: 6.5 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: 6.5 }], [{ baseline: -5, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: -10 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: -8.5 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: -8.5 }], [{ baseline: -10, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: -5 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: -6.5 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: -6.5 }], [{ baseline: -5, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: 5 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: 2 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: 2 }], [{ baseline: 0, - wordingTargetValue: NaN, + targetValue: NaN, stretchGoal: 5.34 }, - KeyResultMetricField.WORDING_TARGET_VALUE, - { wordingTargetValue: 3.74 }], + KeyResultMetricField.TARGET_VALUE, + { targetValue: 3.74 }], [{ baseline: 5, - wordingTargetValue: 8.5, + targetValue: 8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 10 }], [{ baseline: 10, - wordingTargetValue: 6.5, + targetValue: 6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 5 }], [{ baseline: -5, - wordingTargetValue: -8.5, + targetValue: -8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: -10 }], [{ baseline: -10, - wordingTargetValue: -6.5, + targetValue: -6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: -5 }], [{ baseline: -5, - wordingTargetValue: 2, + targetValue: 2, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, { stretchGoal: 5 }] @@ -338,7 +338,7 @@ describe('KeyResultTypeComponent', () => { .toEqual(0); expect(getValueOfForm(component.keyResultForm, ['metric', - 'wordingTargetValue'])) + 'targetValue'])) .toEqual(0); expect(getValueOfForm(component.keyResultForm, ['metric', diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index 0d4f5c58d5..bb68b74475 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -13,14 +13,14 @@ import { ManageUnitsDialogComponent } from '../manage-units-dialog/manage-units- export enum KeyResultMetricField { BASELINE, - WORDING_TARGET_VALUE, + TARGET_VALUE, STRETCH_GOAL, NONE } export interface MetricValue { baseline: number; - wordingTargetValue: number; + targetValue: number; stretchGoal: number; } @@ -91,8 +91,8 @@ export class KeyResultTypeComponent implements AfterContentInit { formGroupValue = { ...formGroupValue, ...fieldValue }; return { baseline: +formGroupValue.baseline, - wordingTargetValue: +formGroupValue.wordingTargetValue, - wordingCommitValue: +formGroupValue.wordingCommitValue, + targetValue: +formGroupValue.targetValue, + commitValue: +formGroupValue.commitValue, stretchGoal: +formGroupValue.stretchGoal } as MetricValue; } @@ -100,9 +100,9 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (changed) { case KeyResultMetricField.STRETCH_GOAL: case KeyResultMetricField.BASELINE: { - return this.calculateValueForField(values, KeyResultMetricField.WORDING_TARGET_VALUE); + return this.calculateValueForField(values, KeyResultMetricField.TARGET_VALUE); } - case KeyResultMetricField.WORDING_TARGET_VALUE: { + case KeyResultMetricField.TARGET_VALUE: { return this.calculateValueForField(values, KeyResultMetricField.STRETCH_GOAL); } @@ -117,15 +117,15 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (field) { case KeyResultMetricField.BASELINE: { - return { baseline: roundToTwoDecimals((values.wordingTargetValue - values.stretchGoal * 0.7) / 0.3) }; + return { baseline: roundToTwoDecimals((values.targetValue - values.stretchGoal * 0.7) / 0.3) }; } - case KeyResultMetricField.WORDING_TARGET_VALUE: { - return { wordingTargetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline) }; + case KeyResultMetricField.TARGET_VALUE: { + return { targetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline) }; } case KeyResultMetricField.STRETCH_GOAL: { - return { stretchGoal: roundToTwoDecimals((values.wordingTargetValue - values.baseline) / 0.7 + values.baseline) }; + return { stretchGoal: roundToTwoDecimals((values.targetValue - values.baseline) / 0.7 + values.baseline) }; } case KeyResultMetricField.NONE: { @@ -151,8 +151,8 @@ export class KeyResultTypeComponent implements AfterContentInit { formGroupMetric?.get('baseline')?.valueChanges .subscribe((value: any) => this.updateMetricValue(KeyResultMetricField.BASELINE, { baseline: value })); - formGroupMetric?.get('wordingTargetValue')?.valueChanges - .subscribe((value) => this.updateMetricValue(KeyResultMetricField.WORDING_TARGET_VALUE, { wordingTargetValue: value })); + formGroupMetric?.get('targetValue')?.valueChanges + .subscribe((value) => this.updateMetricValue(KeyResultMetricField.TARGET_VALUE, { targetValue: value })); formGroupMetric?.get('stretchGoal')?.valueChanges .subscribe((value) => this.updateMetricValue(KeyResultMetricField.STRETCH_GOAL, { stretchGoal: value })); diff --git a/frontend/src/app/shared/constant-library.ts b/frontend/src/app/shared/constant-library.ts index 6d5ce0974d..b744cb9868 100644 --- a/frontend/src/app/shared/constant-library.ts +++ b/frontend/src/app/shared/constant-library.ts @@ -104,10 +104,10 @@ export function getKeyResultForm(): FormGroup { baseline: new FormControl(0, [Validators.required, numberValidator(), Validators.maxLength(20)]), - wordingCommitValue: new FormControl(0, [Validators.required, + commitValue: new FormControl(0, [Validators.required, numberValidator(), Validators.maxLength(20)]), - wordingTargetValue: new FormControl(0, [Validators.required, + targetValue: new FormControl(0, [Validators.required, numberValidator(), Validators.maxLength(20)]), stretchGoal: new FormControl(0, [Validators.required, diff --git a/frontend/src/app/shared/custom/scoring/scoring.component.ts b/frontend/src/app/shared/custom/scoring/scoring.component.ts index 8ae6d0b0c6..7f4058f7a3 100644 --- a/frontend/src/app/shared/custom/scoring/scoring.component.ts +++ b/frontend/src/app/shared/custom/scoring/scoring.component.ts @@ -114,18 +114,18 @@ export class ScoringComponent implements OnInit, AfterViewInit, OnChanges { const keyResult = this.keyResult as KeyResultMetricMin; const lastCheckIn = keyResult.lastCheckIn?.value!; - if (lastCheckIn < keyResult.wordingCommitValue) { + if (lastCheckIn < keyResult.commitValue) { this.stretched = false; - this.failPercent = (lastCheckIn - keyResult.baseline) / (keyResult.wordingCommitValue - keyResult.baseline) * 100; - } else if (lastCheckIn < keyResult.wordingTargetValue) { + this.failPercent = (lastCheckIn - keyResult.baseline) / (keyResult.commitValue - keyResult.baseline) * 100; + } else if (lastCheckIn < keyResult.targetValue) { this.stretched = false; this.failPercent = 100; - this.commitPercent = (lastCheckIn - keyResult.wordingCommitValue) / (keyResult.wordingTargetValue - keyResult.wordingCommitValue) * 100; + this.commitPercent = (lastCheckIn - keyResult.commitValue) / (keyResult.targetValue - keyResult.commitValue) * 100; } else if (lastCheckIn < keyResult.stretchGoal) { this.stretched = false; this.failPercent = 100; this.commitPercent = 100; - this.targetPercent = (lastCheckIn - keyResult.wordingTargetValue) / (keyResult.stretchGoal - keyResult.wordingTargetValue) * 100; + this.targetPercent = (lastCheckIn - keyResult.targetValue) / (keyResult.stretchGoal - keyResult.targetValue) * 100; } else if (lastCheckIn >= keyResult.stretchGoal) { this.stretched = true; } diff --git a/frontend/src/app/shared/test-data.ts b/frontend/src/app/shared/test-data.ts index 5a78faee77..d486478407 100644 --- a/frontend/src/app/shared/test-data.ts +++ b/frontend/src/app/shared/test-data.ts @@ -220,8 +220,8 @@ export const keyResultMetricMin: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 10.0, stretchGoal: 25.0, - wordingCommitValue: 14.5, - wordingTargetValue: 20.5, + commitValue: 14.5, + targetValue: 20.5, lastCheckIn: checkInMetric, type: 'keyResult' } as KeyResultMetricMin; @@ -234,8 +234,8 @@ export const keyResultMetricMinScoring: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 25.0, stretchGoal: 75.0, - wordingCommitValue: 40, - wordingTargetValue: 60, + commitValue: 40, + targetValue: 60, lastCheckIn: { id: 800, version: 1, @@ -259,8 +259,8 @@ export const keyResultMetricMinScoringInversion: KeyResultMetricMin = { unit: UNIT_PERCENT, baseline: 50.0, stretchGoal: 0.0, - wordingCommitValue: 35, - wordingTargetValue: 15, + commitValue: 35, + targetValue: 15, lastCheckIn: { id: 800, version: 1, @@ -585,8 +585,8 @@ export const keyResultMetric: KeyResultMetric = { description: 'Puzzle ITC erledigt die IT-Aufträge für 100% aller Unternehmen.', baseline: 30, stretchGoal: 100, - wordingCommitValue: 51, - wordingTargetValue: 79, + commitValue: 51, + targetValue: 79, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', @@ -624,8 +624,8 @@ export const keyResultActions: KeyResultMetric = { description: 'Puzzle ITC hat schöne Büros, wo es alles hat.', baseline: 10, stretchGoal: 30, - wordingCommitValue: 16, - wordingTargetValue: 24, + commitValue: 16, + targetValue: 24, unit: UNIT_PERCENT, owner: users[3], keyResultType: 'metric', diff --git a/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts b/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts index d270396dee..b71960161c 100644 --- a/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts +++ b/frontend/src/app/shared/types/DTOs/key-result-metric-dto.ts @@ -3,7 +3,7 @@ import { KeyResultDto } from './key-result-dto'; export interface KeyResultMetricDto extends KeyResultDto { unit: string | null; baseline: number | null; - wordingCommitValue: number | null; - wordingTargetValue: number | null; + commitValue: number | null; + targetValue: number | null; stretchGoal: number | null; } diff --git a/frontend/src/app/shared/types/model/key-result-metric-min.ts b/frontend/src/app/shared/types/model/key-result-metric-min.ts index fbc314b87d..04f60fd6c1 100644 --- a/frontend/src/app/shared/types/model/key-result-metric-min.ts +++ b/frontend/src/app/shared/types/model/key-result-metric-min.ts @@ -4,8 +4,8 @@ import { Unit } from '../enums/unit'; export interface KeyResultMetricMin extends KeyResultMin { baseline: number; - wordingCommitValue: number; - wordingTargetValue: number; + commitValue: number; + targetValue: number; stretchGoal: number; unit: Unit; lastCheckIn: CheckInMetricMin | null; diff --git a/frontend/src/app/shared/types/model/key-result-metric.ts b/frontend/src/app/shared/types/model/key-result-metric.ts index 6e79f98795..10eb587fa8 100644 --- a/frontend/src/app/shared/types/model/key-result-metric.ts +++ b/frontend/src/app/shared/types/model/key-result-metric.ts @@ -5,8 +5,8 @@ import { Unit } from '../enums/unit'; export interface KeyResultMetric extends KeyResult { lastCheckIn: CheckInMetric | null; baseline: number; - wordingCommitValue: number; - wordingTargetValue: number; + commitValue: number; + targetValue: number; stretchGoal: number; unit: Unit; } From bfaff1b6d53d309cd7a23d55ed38976380ff9d53 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 15 Aug 2025 11:39:27 +0200 Subject: [PATCH 13/18] fix(frontend): Fix updating of commitValue when creating new key-results #1570 --- .../key-result-type/key-result-type.component.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index bb68b74475..f358f0dfea 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -117,15 +117,18 @@ export class KeyResultTypeComponent implements AfterContentInit { switch (field) { case KeyResultMetricField.BASELINE: { - return { baseline: roundToTwoDecimals((values.targetValue - values.stretchGoal * 0.7) / 0.3) }; + return { baseline: roundToTwoDecimals((values.targetValue - values.stretchGoal * 0.7) / 0.3), + commitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.TARGET_VALUE: { - return { targetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline) }; + return { targetValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.7 + values.baseline), + commitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.STRETCH_GOAL: { - return { stretchGoal: roundToTwoDecimals((values.targetValue - values.baseline) / 0.7 + values.baseline) }; + return { stretchGoal: roundToTwoDecimals((values.targetValue - values.baseline) / 0.7 + values.baseline), + commitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.NONE: { From bd7841ee7849e889962bea568086a48886312c98 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 15 Aug 2025 11:44:24 +0200 Subject: [PATCH 14/18] style(backend): Format backend #1570 --- .../puzzle/okr/models/keyresult/KeyResultMetric.java | 4 ++-- .../java/ch/puzzle/okr/models/overview/Overview.java | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java index 886da7fe73..b8f6139898 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java +++ b/backend/src/main/java/ch/puzzle/okr/models/keyresult/KeyResultMetric.java @@ -88,8 +88,8 @@ public int hashCode() { @Override public String toString() { - return "KeyResultMetric{" + "baseline=" + baseline + ", commitValue=" + commitValue - + ", targetValue=" + targetValue + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; + return "KeyResultMetric{" + "baseline=" + baseline + ", commitValue=" + commitValue + ", targetValue=" + + targetValue + ", stretchGoal=" + stretchGoal + ", unit=" + unit + '}'; } private KeyResultMetric(Builder builder) { diff --git a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java index 9919081963..a538aeee02 100644 --- a/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java +++ b/backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java @@ -175,12 +175,11 @@ public String toString() { + teamVersion + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState + ", objectiveCreatedOn=" + objectiveCreatedOn + ", quarterId=" + quarterId + ", quarterLabel='" + quarterLabel + '\'' + ", keyResultTitle='" + keyResultTitle + '\'' + ", keyResultType='" - + keyResultType + '\'' + ", baseline=" + baseline + ", commitValue=" + commitValue - + ", targetValue=" + targetValue + ", stretchGoal=" + stretchGoal + ", commitZone='" - + commitZone + '\'' + ", targetZone='" + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' - + ", checkInValue=" + checkInValue + ", checkInZone='" + checkInZone + '\'' + ", confidence=" - + confidence + ", checkInCreatedOn=" + checkInCreatedOn + ", writeable=" + writeable - + ", backlogQuarter=" + backlogQuarter + '}'; + + keyResultType + '\'' + ", baseline=" + baseline + ", commitValue=" + commitValue + ", targetValue=" + + targetValue + ", stretchGoal=" + stretchGoal + ", commitZone='" + commitZone + '\'' + ", targetZone='" + + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + ", checkInValue=" + checkInValue + + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + confidence + ", checkInCreatedOn=" + + checkInCreatedOn + ", writeable=" + writeable + ", backlogQuarter=" + backlogQuarter + '}'; } public static final class Builder { From 459932f14d584184bbfb2ba8ba6eda9602c41865 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 15 Aug 2025 15:23:49 +0200 Subject: [PATCH 15/18] test(frontend): Extend failing test to match new changes #1570 --- .../key-result-type.component.spec.ts | 51 ++++++++++++------- .../key-result-type.component.ts | 11 ++-- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts index 01cdf32344..937724ad25 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.spec.ts @@ -240,89 +240,106 @@ describe('KeyResultTypeComponent', () => { targetValue: 8.5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, - { baseline: 5 }], + { baseline: 5, + commitValue: 6.5 }], [{ baseline: NaN, targetValue: 6.5, stretchGoal: 5 }, KeyResultMetricField.BASELINE, - { baseline: 10 }], + { baseline: 10, + commitValue: 8.5 }], [{ baseline: NaN, targetValue: -8.5, stretchGoal: -10 }, KeyResultMetricField.BASELINE, - { baseline: -5 }], + { baseline: -5, + commitValue: -6.5 }], [{ baseline: NaN, targetValue: -6.5, stretchGoal: -5 }, KeyResultMetricField.BASELINE, - { baseline: -10 }], + { baseline: -10, + commitValue: -8.5 }], [{ baseline: NaN, targetValue: 2, stretchGoal: 5 }, KeyResultMetricField.BASELINE, - { baseline: -5 }], + { baseline: -5, + commitValue: -2 }], [{ baseline: NaN, targetValue: 5, stretchGoal: 10 }, KeyResultMetricField.BASELINE, - { baseline: -6.67 }], + { baseline: -6.67, + commitValue: -1.67 }], [{ baseline: 5, targetValue: NaN, stretchGoal: 10 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: 8.5 }], + { targetValue: 8.5, + commitValue: 6.5 }], [{ baseline: 10, targetValue: NaN, stretchGoal: 5 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: 6.5 }], + { targetValue: 6.5, + commitValue: 8.5 }], [{ baseline: -5, targetValue: NaN, stretchGoal: -10 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: -8.5 }], + { targetValue: -8.5, + commitValue: -6.5 }], [{ baseline: -10, targetValue: NaN, stretchGoal: -5 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: -6.5 }], + { targetValue: -6.5, + commitValue: -8.5 }], [{ baseline: -5, targetValue: NaN, stretchGoal: 5 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: 2 }], + { targetValue: 2, + commitValue: -2 }], [{ baseline: 0, targetValue: NaN, stretchGoal: 5.34 }, KeyResultMetricField.TARGET_VALUE, - { targetValue: 3.74 }], + { targetValue: 3.74, + commitValue: 1.6 }], [{ baseline: 5, targetValue: 8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, - { stretchGoal: 10 }], + { stretchGoal: 10, + commitValue: 6.5 }], [{ baseline: 10, targetValue: 6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, - { stretchGoal: 5 }], + { stretchGoal: 5, + commitValue: 8.5 }], [{ baseline: -5, targetValue: -8.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, - { stretchGoal: -10 }], + { stretchGoal: -10, + commitValue: -6.5 }], [{ baseline: -10, targetValue: -6.5, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, - { stretchGoal: -5 }], + { stretchGoal: -5, + commitValue: -8.5 }], [{ baseline: -5, targetValue: 2, stretchGoal: NaN }, KeyResultMetricField.STRETCH_GOAL, - { stretchGoal: 5 }] + { stretchGoal: 5, + commitValue: -2 }] ])('calculateValueForField should calculate correct', (values: MetricValue, targetField: KeyResultMetricField, result: any) => { expect(component.calculateValueForField(values, targetField)) .toEqual(result); diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index f358f0dfea..17a8ee56ed 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -114,11 +114,13 @@ export class KeyResultTypeComponent implements AfterContentInit { calculateValueForField(values: MetricValue, field: KeyResultMetricField) { const roundToTwoDecimals = (num: number) => parseFloat(num.toFixed(2)); + const calculatedField: any = {}; switch (field) { case KeyResultMetricField.BASELINE: { - return { baseline: roundToTwoDecimals((values.targetValue - values.stretchGoal * 0.7) / 0.3), - commitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; + const baseline = roundToTwoDecimals((values.targetValue - values.stretchGoal * 0.7) / 0.3); + return { baseline: baseline, + commitValue: roundToTwoDecimals((values.stretchGoal - baseline) * 0.3 + baseline) }; } case KeyResultMetricField.TARGET_VALUE: { @@ -127,8 +129,9 @@ export class KeyResultTypeComponent implements AfterContentInit { } case KeyResultMetricField.STRETCH_GOAL: { - return { stretchGoal: roundToTwoDecimals((values.targetValue - values.baseline) / 0.7 + values.baseline), - commitValue: roundToTwoDecimals((values.stretchGoal - values.baseline) * 0.3 + values.baseline) }; + const stretchGoal = roundToTwoDecimals((values.targetValue - values.baseline) / 0.7 + values.baseline); + return { stretchGoal: stretchGoal, + commitValue: roundToTwoDecimals((stretchGoal - values.baseline) * 0.3 + values.baseline) }; } case KeyResultMetricField.NONE: { From c4d7573094eb38ed0778b8a886f9b0b0a2ee5598 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 15 Aug 2025 15:29:40 +0200 Subject: [PATCH 16/18] refactor: Remove unnecessary variable #1570 --- .../app/components/key-result-type/key-result-type.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/components/key-result-type/key-result-type.component.ts b/frontend/src/app/components/key-result-type/key-result-type.component.ts index 17a8ee56ed..dde26c1fb0 100644 --- a/frontend/src/app/components/key-result-type/key-result-type.component.ts +++ b/frontend/src/app/components/key-result-type/key-result-type.component.ts @@ -114,7 +114,6 @@ export class KeyResultTypeComponent implements AfterContentInit { calculateValueForField(values: MetricValue, field: KeyResultMetricField) { const roundToTwoDecimals = (num: number) => parseFloat(num.toFixed(2)); - const calculatedField: any = {}; switch (field) { case KeyResultMetricField.BASELINE: { From eac26518b8afc86bd5898f1cb09c9bd20989cb1e Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Tue, 19 Aug 2025 09:15:01 +0200 Subject: [PATCH 17/18] test: Create small backup #1570 --- frontend/cypress/e2e/scoring.cy.ts | 110 ++++++++++++++---- frontend/cypress/support/commands.ts | 10 +- frontend/cypress/support/component.ts | 4 +- .../cypress/support/helper/scoringSupport.ts | 80 ++++++++++++- 4 files changed, 172 insertions(+), 32 deletions(-) diff --git a/frontend/cypress/e2e/scoring.cy.ts b/frontend/cypress/e2e/scoring.cy.ts index 48374da764..1eed4421a1 100644 --- a/frontend/cypress/e2e/scoring.cy.ts +++ b/frontend/cypress/e2e/scoring.cy.ts @@ -1,5 +1,5 @@ import * as users from '../fixtures/users.json'; -import { getPercentageMetric, getPercentageOrdinal } from 'cypress/support/helper/scoringSupport'; +import { CheckInValue, getPercentageMetric, getPercentageOrdinal } from 'cypress/support/helper/scoringSupport'; import CyOverviewPage from '../support/helper/dom-helper/pages/overviewPage'; import KeyResultDetailPage from '../support/helper/dom-helper/pages/keyResultDetailPage'; import { UNIT_PERCENT } from '../../src/app/shared/test-data'; @@ -15,29 +15,58 @@ describe('okr scoring', () => { }); [ - [0, + [ + 0, + 30, + 70, 100, - 10], - [0, + 10 + ], + [ + 0, + 30, + 70, 100, - 31], - [0, + 31 + ], + [ + 0, + 30, + 70, 100, - 71], - [0, + 71 + ], + [ + 0, + 30, + 70, 100, - 100] - ].forEach(([baseline, + 100 + ] + ].forEach(([ + baseline, + commitValue, + targetValue, stretchGoal, - value]) => { + value + ]) => { it('should display correct value on scoring component after creating metric check-in', () => { setupMetricKr( `Metric kr with check-in value ${value}`, baseline, stretchGoal, value ); + Cypress.env('param', `Metric kr with check-in value ${value}`); const percentage = getPercentageMetric(baseline, stretchGoal, value); - cy.validateScoring(false, percentage); + const keyResult: CheckInValue = { + baseline: baseline, + commitValue: commitValue, + targetValue: targetValue, + stretchGoal: stretchGoal, + lastCheckIn: value + }; + + cy.validateScoringMetric(false, keyResult, percentage); cy.get('.key-result-detail-attribute-show') .contains('Aktuell') .parent() @@ -46,27 +75,48 @@ describe('okr scoring', () => { .and('not.equal', 'rgb(186, 56, 56)'); keyResultDetailPage.close(); - cy.validateScoring(true, percentage); + cy.validateScoringMetric(true, keyResult, percentage); overviewPage .getKeyResultByName(`Metric kr with check-in value ${value}`) .not(':contains(*[class="scoring-error-badge"])'); + deleteKeyResultToDefault(`Metric kr with check-in value ${value}`, keyResultDetailPage); }); }); - [[0, + [[ + 0, + 30, + 70, 100, - -1], - [200, + -1 + ], + [ + 200, + 170, + 130, 100, - 250]].forEach(([baseline, + 250 + ]].forEach(([ + baseline, + commitValue, + targetValue, stretchGoal, - value]) => { - it('show indicator that value is negative', () => { + value + ]) => { + it.only('show indicator that value is negative', () => { setupMetricKr( `Check indicator with value ${value}`, baseline, stretchGoal, value ); - cy.validateScoring(false, 0); + Cypress.env('param', `Check indicator with value ${value}`); + const keyResult: CheckInValue = { + baseline: baseline, + commitValue: commitValue, + targetValue: targetValue, + stretchGoal: stretchGoal, + lastCheckIn: value + }; + cy.validateScoringMetric(false, keyResult, 0); cy.get('.key-result-detail-attribute-show') .contains('Aktuell') .parent() @@ -75,10 +125,11 @@ describe('okr scoring', () => { .and('equal', 'rgb(186, 56, 56)'); keyResultDetailPage.close(); - cy.validateScoring(true, 0); + cy.validateScoringMetric(true, keyResult, 0); overviewPage.getKeyResultByName(`Check indicator with value ${value}`) .get('.scoring-error-badge'); + deleteKeyResultToDefault(`Check indicator with value ${value}`, keyResultDetailPage); }); }); @@ -89,6 +140,7 @@ describe('okr scoring', () => { ['stretch'] ].forEach(([zoneName]) => { it('should create ordinal checkin and validate value of scoring component', () => { + Cypress.env('param', 'Ordinal scoring keyresult'); overviewPage .addKeyResult() .fillKeyResultTitle('Ordinal scoring keyresult') @@ -106,13 +158,25 @@ describe('okr scoring', () => { .fillCheckInInitiatives('Testmassnahmen') .submit(); const percentage = getPercentageOrdinal(zoneName); - cy.validateScoring(false, percentage); + cy.validateScoringOrdinal(false, percentage); keyResultDetailPage.close(); - cy.validateScoring(true, percentage); + cy.validateScoringOrdinal(true, percentage); + deleteKeyResultToDefault('Ordinal scoring keyresult', keyResultDetailPage); }); }); }); +function deleteKeyResultToDefault(keyResultName: string, keyResultDetailPage: KeyResultDetailPage) { + console.log(keyResultName); + keyResultDetailPage + .visit(keyResultName) + .editKeyResult() + .deleteKeyResult() + .checkForContentOnDialog('Key Result löschen') + .checkForContentOnDialog('Möchtest du dieses Key Result wirklich löschen? Zugehörige Check-ins werden dadurch ebenfalls gelöscht!') + .submit(); +} + function setupMetricKr( name: string, baseline: number, stretchGoal: number, value: number ) { diff --git a/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts index 8877963ee4..5a0dada483 100644 --- a/frontend/cypress/support/commands.ts +++ b/frontend/cypress/support/commands.ts @@ -1,4 +1,4 @@ -import { validateScoring } from './helper/scoringSupport'; +import { CheckInValue, validateScoringMetric, validateScoringOrdinal } from './helper/scoringSupport'; import { keyCodeDefinitions } from 'cypress-real-events/keyCodeDefinitions'; import { pressUntilContains, doUntilSelector } from './helper/utils'; import Chainable = Cypress.Chainable; @@ -71,8 +71,12 @@ Cypress.Commands.add('getZone', (zone: string, onOverview: boolean) => { return (onOverview ? cy.focused() : cy.getByTestId('side-panel')).findByTestId(zone); }); -Cypress.Commands.add('validateScoring', (isOverview: boolean, percentage: number) => { - validateScoring(isOverview, percentage); +Cypress.Commands.add('validateScoringMetric', (isOverview: boolean, keyResult: CheckInValue, percentage: number) => { + validateScoringMetric(isOverview, keyResult, percentage); +}); + +Cypress.Commands.add('validateScoringOrdinal', (isOverview: boolean, percentage: number) => { + validateScoringOrdinal(isOverview, percentage); }); Cypress.Commands.add('buttonShouldBePrimary', (buttonId: string) => { diff --git a/frontend/cypress/support/component.ts b/frontend/cypress/support/component.ts index caf1fad3da..ea753e1a85 100644 --- a/frontend/cypress/support/component.ts +++ b/frontend/cypress/support/component.ts @@ -1,5 +1,6 @@ import './commands'; import { keyCodeDefinitions } from 'cypress-real-events/keyCodeDefinitions'; +import { CheckInValue } from './helper/scoringSupport'; declare global { export namespace Cypress { @@ -15,7 +16,8 @@ declare global { tabForwardUntil(selector: string, limit?: number): void; tabBackwardUntil(selector: string, limit?: number): void; getZone(zone: string, onOverview: boolean): Chainable; - validateScoring(isOverview: boolean, percentage: number): Chainable; + validateScoringMetric(isOverview: boolean, keyResult: CheckInValue, percentage: number): Chainable; + validateScoringOrdinal(isOverview: boolean, percentage: number): Chainable; } } } diff --git a/frontend/cypress/support/helper/scoringSupport.ts b/frontend/cypress/support/helper/scoringSupport.ts index cfa2c75aca..b8bcba4a16 100644 --- a/frontend/cypress/support/helper/scoringSupport.ts +++ b/frontend/cypress/support/helper/scoringSupport.ts @@ -6,9 +6,31 @@ interface ScoringValue { targetPercent: number; } -export function validateScoring(isOverview: boolean, percentage: number) { - const rgbCode = colorFromPercentage(percentage); - const scoringValue = scoringValueFromPercentage(percentage); +export interface CheckInValue { + baseline: number; + commitValue: number; + targetValue: number; + stretchGoal: number; + lastCheckIn: number; +} +export function validateScoringMetric(isOverview: boolean, keyResult: CheckInValue, percentage: number) { + const rgbCode = colorFromPercentageMetric(keyResult); + const scoringValue = scoringValueFromPercentageMetric(keyResult, percentage); + + if (percentage >= 100) { + cy.getZone('stretch', isOverview) + .should('have.attr', 'src') + .should('include', 'star-filled-icon.svg'); + } + + validateScoring( + isOverview, rgbCode, scoringValue, percentage + ); +} + +export function validateScoringOrdinal(isOverview: boolean, percentage: number) { + const rgbCode = colorFromPercentageOrdinal(percentage); + const scoringValue = scoringValueFromPercentageOrdinal(percentage); if (percentage >= 100) { cy.getZone('stretch', isOverview) @@ -16,6 +38,14 @@ export function validateScoring(isOverview: boolean, percentage: number) { .should('include', 'star-filled-icon.svg'); } + validateScoring( + isOverview, rgbCode, scoringValue, percentage + ); +} + +export function validateScoring( + isOverview: boolean, rgbCode: string, scoringValue: ScoringValue, percentage: number +) { validateScoringWidth('fail', scoringValue.failPercent, isOverview); validateScoringWidth('commit', scoringValue.commitPercent, isOverview); validateScoringWidth('target', scoringValue.targetPercent, isOverview); @@ -85,7 +115,7 @@ function checkVisibilityOfScoringComponent(isOverview: boolean, displayProperty: .should('equal', displayProperty); } -function colorFromPercentage(percentage: number) { +function colorFromPercentageOrdinal(percentage: number) { switch (true) { case percentage >= 100: return 'rgba(0, 0, 0, 0)'; @@ -98,7 +128,7 @@ function colorFromPercentage(percentage: number) { } } -function scoringValueFromPercentage(percentage: number): ScoringValue { +function scoringValueFromPercentageOrdinal(percentage: number): ScoringValue { switch (true) { case percentage >= 100: return { @@ -126,3 +156,43 @@ function scoringValueFromPercentage(percentage: number): ScoringValue { }; } } + +function colorFromPercentageMetric(keyResult: CheckInValue) { + if (keyResult.lastCheckIn < keyResult.commitValue) { + return 'rgb(186, 56, 56)'; + } else if (keyResult.lastCheckIn < keyResult.targetValue) { + return 'rgb(255, 214, 0)'; + } else if (keyResult.lastCheckIn < keyResult.stretchGoal) { + return 'rgb(30, 138, 41)'; + } else if (keyResult.lastCheckIn >= keyResult.stretchGoal) { + return 'rgba(0, 0, 0, 0)'; + } +} + +function scoringValueFromPercentageMetric(keyResult: CheckInValue, percentage: number): ScoringValue { + if (keyResult.lastCheckIn < keyResult.commitValue) { + return { + failPercent: percentage * (100 / 30), + commitPercent: -1, + targetPercent: -1 + }; + } else if (keyResult.lastCheckIn < keyResult.targetValue) { + return { + failPercent: 100, + commitPercent: (percentage - 30) * (100 / 40), + targetPercent: -1 + }; + } else if (keyResult.lastCheckIn < keyResult.stretchGoal) { + return { + failPercent: 100, + commitPercent: 100, + targetPercent: (percentage - 70) * (100 / 30) + }; + } else if (keyResult.lastCheckIn >= keyResult.stretchGoal) { + return { + failPercent: 0, + commitPercent: 0, + targetPercent: 0 + }; + } +} From a26033f70e7914c5f16d088b3f2a717dbf3944cd Mon Sep 17 00:00:00 2001 From: Livio Canobbio Date: Tue, 19 Aug 2025 11:23:28 +0200 Subject: [PATCH 18/18] test: add clean-up function #1570 --- frontend/cypress/e2e/scoring.cy.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/frontend/cypress/e2e/scoring.cy.ts b/frontend/cypress/e2e/scoring.cy.ts index 1eed4421a1..84330c3078 100644 --- a/frontend/cypress/e2e/scoring.cy.ts +++ b/frontend/cypress/e2e/scoring.cy.ts @@ -56,7 +56,6 @@ describe('okr scoring', () => { `Metric kr with check-in value ${value}`, baseline, stretchGoal, value ); - Cypress.env('param', `Metric kr with check-in value ${value}`); const percentage = getPercentageMetric(baseline, stretchGoal, value); const keyResult: CheckInValue = { baseline: baseline, @@ -80,7 +79,7 @@ describe('okr scoring', () => { overviewPage .getKeyResultByName(`Metric kr with check-in value ${value}`) .not(':contains(*[class="scoring-error-badge"])'); - deleteKeyResultToDefault(`Metric kr with check-in value ${value}`, keyResultDetailPage); + deleteKeyResult(`Metric kr with check-in value ${value}`, keyResultDetailPage); }); }); @@ -104,11 +103,10 @@ describe('okr scoring', () => { stretchGoal, value ]) => { - it.only('show indicator that value is negative', () => { + it('show indicator that value is negative', () => { setupMetricKr( `Check indicator with value ${value}`, baseline, stretchGoal, value ); - Cypress.env('param', `Check indicator with value ${value}`); const keyResult: CheckInValue = { baseline: baseline, commitValue: commitValue, @@ -125,11 +123,10 @@ describe('okr scoring', () => { .and('equal', 'rgb(186, 56, 56)'); keyResultDetailPage.close(); - cy.validateScoringMetric(true, keyResult, 0); overviewPage.getKeyResultByName(`Check indicator with value ${value}`) .get('.scoring-error-badge'); - deleteKeyResultToDefault(`Check indicator with value ${value}`, keyResultDetailPage); + deleteKeyResult(`Check indicator with value ${value}`, keyResultDetailPage); }); }); @@ -140,7 +137,6 @@ describe('okr scoring', () => { ['stretch'] ].forEach(([zoneName]) => { it('should create ordinal checkin and validate value of scoring component', () => { - Cypress.env('param', 'Ordinal scoring keyresult'); overviewPage .addKeyResult() .fillKeyResultTitle('Ordinal scoring keyresult') @@ -161,13 +157,12 @@ describe('okr scoring', () => { cy.validateScoringOrdinal(false, percentage); keyResultDetailPage.close(); cy.validateScoringOrdinal(true, percentage); - deleteKeyResultToDefault('Ordinal scoring keyresult', keyResultDetailPage); + deleteKeyResult('Ordinal scoring keyresult', keyResultDetailPage); }); }); }); -function deleteKeyResultToDefault(keyResultName: string, keyResultDetailPage: KeyResultDetailPage) { - console.log(keyResultName); +function deleteKeyResult(keyResultName: string, keyResultDetailPage: KeyResultDetailPage) { keyResultDetailPage .visit(keyResultName) .editKeyResult() @@ -175,6 +170,7 @@ function deleteKeyResultToDefault(keyResultName: string, keyResultDetailPage: Ke .checkForContentOnDialog('Key Result löschen') .checkForContentOnDialog('Möchtest du dieses Key Result wirklich löschen? Zugehörige Check-ins werden dadurch ebenfalls gelöscht!') .submit(); + keyResultDetailPage.close(); } function setupMetricKr(