Skip to content

Commit

Permalink
Merge pull request #140 in WALTZ/waltz from WALTZ/waltz-jws:CTCTOWALT…
Browse files Browse the repository at this point in the history
…Z-2451-report-grids-support-app-groups-5962 to db-feature/waltz-5962-report-grids-app-group-columns

* commit '3d3abdf08dabaf9de4e0f2fa2a75b1144564e75f':
  Removing comment
  Pull out method for determining query
  App group columns for CIs
  Extractor supports app group columns
  Org unit select
  Allow addition of app group columns to grid
  Report grids can display group involvement
  • Loading branch information
MarkGuerriero committed Mar 17, 2022
2 parents ae40295 + 3d3abdf commit 32b7faf
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@


import org.finos.waltz.common.DateTimeUtilities;
import org.finos.waltz.common.SetUtilities;
import org.finos.waltz.data.GenericSelector;
import org.finos.waltz.data.InlineSelectFieldFactory;
import org.finos.waltz.model.EntityKind;
Expand All @@ -39,6 +38,7 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.util.Comparator;
import java.util.*;
import java.util.function.Function;
Expand All @@ -50,11 +50,11 @@
import static java.util.Collections.emptySet;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.*;
import static org.finos.waltz.common.DateTimeUtilities.toLocalDate;
import static org.finos.waltz.common.DateTimeUtilities.toLocalDateTime;
import static org.finos.waltz.common.ListUtilities.newArrayList;
import static org.finos.waltz.common.MapUtilities.groupBy;
import static org.finos.waltz.common.SetUtilities.map;
import static org.finos.waltz.common.SetUtilities.union;
import static org.finos.waltz.common.SetUtilities.*;
import static org.finos.waltz.common.StringUtilities.join;
import static org.finos.waltz.model.EntityReference.mkRef;
import static org.finos.waltz.model.survey.SurveyInstanceStatus.APPROVED;
Expand Down Expand Up @@ -83,10 +83,14 @@ public class ReportGridDao {
private final org.finos.waltz.schema.tables.InvolvementKind ik = INVOLVEMENT_KIND.as("ik");
private final org.finos.waltz.schema.tables.Person p = Tables.PERSON.as("p");
private final org.finos.waltz.schema.tables.SurveyQuestion sq = SURVEY_QUESTION.as("sq");
private final org.finos.waltz.schema.tables.ApplicationGroup ag = APPLICATION_GROUP.as("ag");
private final org.finos.waltz.schema.tables.ApplicationGroupEntry age = APPLICATION_GROUP_ENTRY.as("age");
private final org.finos.waltz.schema.tables.ApplicationGroupOuEntry agoe = APPLICATION_GROUP_OU_ENTRY.as("agoe");
private final org.finos.waltz.schema.tables.EntityFieldReference efr = ENTITY_FIELD_REFERENCE.as("efr");
private final org.finos.waltz.schema.tables.SurveyTemplate st = SURVEY_TEMPLATE.as("st");
private final org.finos.waltz.schema.tables.Application a = APPLICATION.as("a");
private final org.finos.waltz.schema.tables.ChangeInitiative ci = CHANGE_INITIATIVE.as("ci");
private final org.finos.waltz.schema.tables.EntityRelationship er = ENTITY_RELATIONSHIP.as("er");

private static final Field<String> ENTITY_NAME_FIELD = InlineSelectFieldFactory.mkNameField(
SURVEY_QUESTION_RESPONSE.ENTITY_RESPONSE_ID,
Expand Down Expand Up @@ -258,6 +262,14 @@ private List<ReportGridColumnDefinition> getColumnDefinitions(Condition conditio
sq.HELP_TEXT,
condition);

SelectConditionStep<Record13<String, String, Long, String, String, Integer, String, String, Long, String, String, String, String>> appGroupColumns = mkColumnDefinitionQuery(
EntityKind.APP_GROUP,
ag,
ag.ID,
ag.NAME,
ag.DESCRIPTION,
condition);

SelectConditionStep<Record13<String, String, Long, String, String, Integer, String, String, Long, String, String, String, String>> surveyMetaColumns = mkColumnDefinitionQuery(
EntityKind.SURVEY_TEMPLATE,
st,
Expand Down Expand Up @@ -287,6 +299,7 @@ private List<ReportGridColumnDefinition> getColumnDefinitions(Condition conditio
.unionAll(costKindColumns)
.unionAll(involvementKindColumns)
.unionAll(surveyQuestionColumns)
.unionAll(appGroupColumns)
.unionAll(surveyMetaColumns)
.unionAll(applicationMetaColumns)
.unionAll(changeInitiativeMetaColumns)
Expand Down Expand Up @@ -405,6 +418,10 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
colsByKind.getOrDefault(EntityKind.SURVEY_QUESTION, emptySet()),
cd -> cd.columnEntityId());

Set<Long> requiredAppGroupIds = map(
colsByKind.getOrDefault(EntityKind.APP_GROUP, emptySet()),
cd -> cd.columnEntityId());


// COMPLEX GRID DEFS

Expand Down Expand Up @@ -443,13 +460,118 @@ private Set<ReportGridCell> findCellDataByGridCondition(Condition gridCondition,
fetchCostData(genericSelector, requiredCostKinds),
fetchInvolvementData(genericSelector, requiredInvolvementKinds),
fetchSurveyQuestionResponseData(genericSelector, requiredSurveyQuestionIds),
fetchAppGroupData(genericSelector, requiredAppGroupIds),
fetchSurveyFieldReferenceData(genericSelector, requiredSurveyTemplateIds),
fetchApplicationFieldReferenceData(genericSelector, requiredApplicationColumns),
fetchChangeInitiativeFieldReferenceData(genericSelector, requiredChangeInitiativeColumns));
}
}


private Set<ReportGridCell> fetchAppGroupData(GenericSelector genericSelector,
Set<Long> requiredAppGroupIds) {
if (requiredAppGroupIds.size() == 0) {
return emptySet();
} else {

SelectOrderByStep<Record3<Long, Long, Timestamp>> appGroupInfoSelect = determineAppGroupQuery(genericSelector, requiredAppGroupIds);

return dsl
.fetch(appGroupInfoSelect)
.stream()
.map(r -> {
Long subjectId = r.get("subject_id", Long.class);
Timestamp created_at = r.get("created_at", Timestamp.class);

return ImmutableReportGridCell
.builder()
.subjectId(subjectId)
.columnEntityId(r.get(ag.ID))
.columnEntityKind(EntityKind.APP_GROUP)
.text("Y")
.comment(format("Created at: %s", toLocalDate(created_at).toString()))
.entityFieldReferenceId(null)
.build();
})
.collect(toSet());
}
}


private SelectOrderByStep<Record3<Long, Long, Timestamp>> determineAppGroupQuery(GenericSelector selector, Set<Long> requiredAppGroupIds) {

switch (selector.kind()) {
case APPLICATION:
return mkApplicationAppGroupSelect(selector, requiredAppGroupIds);
case CHANGE_INITIATIVE:
return mkChangeInitiativeAppGroupSelect(selector, requiredAppGroupIds);
default:
throw new UnsupportedOperationException("Cannot return app group selector for kind: " + selector.kind().name());
}

}


private SelectOrderByStep<Record3<Long, Long, Timestamp>> mkChangeInitiativeAppGroupSelect(GenericSelector selector, Set<Long> requiredAppGroupIds) {

SelectConditionStep<Record3<Long, Long, Timestamp>> groupASelect = dsl
.select(ci.ID.as("subject_id"),
ag.ID,
er.LAST_UPDATED_AT.as("created_at"))
.from(ag)
.innerJoin(er).on(ag.ID.eq(er.ID_A))
.innerJoin(ci).on(er.ID_B.eq(ci.ID))
.where(er.KIND_A.eq(EntityKind.APP_GROUP.name())
.and(er.KIND_B.eq(EntityKind.CHANGE_INITIATIVE.name())))
.and(ci.ID.in(selector.selector()))
.and(ag.ID.in(requiredAppGroupIds));

SelectConditionStep<Record3<Long, Long, Timestamp>> groupBSelect = dsl
.select(ci.ID.as("subject_id"),
ag.ID,
er.LAST_UPDATED_AT.as("created_at"))
.from(ag)
.innerJoin(er).on(ag.ID.eq(er.ID_B))
.innerJoin(ci).on(er.ID_A.eq(ci.ID))
.where(er.KIND_B.eq(EntityKind.APP_GROUP.name())
.and(er.KIND_A.eq(EntityKind.CHANGE_INITIATIVE.name())))
.and(ci.ID.in(selector.selector()))
.and(ag.ID.in(requiredAppGroupIds));


return groupASelect.union(groupBSelect);
}


private SelectOrderByStep<Record3<Long, Long, Timestamp>> mkApplicationAppGroupSelect(GenericSelector selector, Set<Long> requiredAppGroupIds) {

SelectConditionStep<Record3<Long, Long, Timestamp>> directSelect = DSL
.select(
age.APPLICATION_ID.as("subject_id"),
ag.ID,
age.CREATED_AT.as("created_at"))
.from(ag)
.innerJoin(age).on(ag.ID.eq(age.GROUP_ID))
.where(age.APPLICATION_ID.in(selector.selector()))
.and(ag.ID.in(requiredAppGroupIds));

SelectConditionStep<Record3<Long, Long, Timestamp>> indirectSelect = DSL
.select(
a.ID.as("subject_id"),
ag.ID,
agoe.CREATED_AT.as("created_at"))
.from(ag)
.innerJoin(agoe).on(ag.ID.eq(agoe.GROUP_ID))
.innerJoin(eh).on(agoe.ORG_UNIT_ID.eq(eh.ANCESTOR_ID)
.and(eh.KIND.eq(EntityKind.ORG_UNIT.name())))
.innerJoin(a).on(eh.ID.eq(a.ORGANISATIONAL_UNIT_ID))
.where(a.ID.in(selector.selector()))
.and(ag.ID.in(requiredAppGroupIds));

return directSelect.union(indirectSelect);
}


public Set<ReportGridCell> fetchApplicationFieldReferenceData(GenericSelector selector,
Set<Tuple2<ReportGridColumnDefinition, EntityFieldReference>> requiredApplicationColumns) {

Expand Down Expand Up @@ -625,7 +747,7 @@ private Set<ReportGridCell> fetchInvolvementData(GenericSelector selector,
if (requiredInvolvementKinds.size() == 0) {
return emptySet();
} else {
return SetUtilities.fromCollection(dsl
return fromCollection(dsl
.select(
inv.ENTITY_ID,
inv.KIND_ID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
.wgrc-involvement-cell {
background-color: #e0ffe1;
}

.wgrc-survey-question-cell {
background-color: #fff59d;
}

.wgrc-app-group-cell {
background-color: #d1dbff;
}

.wgrc-no-data-cell {
background-color: #f7f9f9;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
let canBeAdded;
function onSelect(d) {
const column = {
columnEntityId: d.columnEntityId,
columnEntityKind: d.columnEntityKind,
Expand All @@ -39,6 +40,10 @@
position: 0
};
if (_.some($columnDefs, c => sameColumnRef(column, c))) {
return;
}
const newList = _.concat(
$columnDefs,
column);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
entity.SURVEY_QUESTION,
entity.ASSESSMENT_DEFINITION,
entity.MEASURABLE,
entity.APP_GROUP,
entity.SURVEY_INSTANCE,
entity.APPLICATION,
entity.CHANGE_INITIATIVE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script>
import Icon from "../../../../common/svelte/Icon.svelte";
import EntitySearchSelector from "../../../../common/svelte/EntitySearchSelector.svelte";
export let onSelect = () => console.log("Selecting involvement kind");
export let selectionFilter = () => true;
function onSelectGroup(e) {
if (e.detail == null) {
return;
}
const column = {
columnEntityId: e.detail.id,
columnEntityKind: e.detail.kind,
entityFieldReference: null,
columnName: e.detail.name,
displayName: null
}
onSelect(column);
}
$: canBeAdded = (d) => {
if (d === null) {
return true;
} else {
const column = {
columnEntityId: d.id,
columnEntityKind: d.kind,
entityFieldReference: null,
columnName: d.name,
displayName: null
}
return selectionFilter(column);
}
}
</script>

<div class="help-block small">
<Icon name="info-circle"/>
Select an app group using the search below.
</div>
<br>
<EntitySearchSelector on:select={onSelectGroup}
placeholder="Search for app group"
entityKinds={['APP_GROUP']}
selectionFilter={canBeAdded}>
</EntitySearchSelector>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import SurveyInstanceFieldPicker from "./SurveyInstanceFieldPicker.svelte";
import ApplicationFieldPicker from "./ApplicationFieldPicker.svelte";
import ChangeInitiativeFieldPicker from "./ChangeInitiativeFieldPicker.svelte";
import AppGroupPicker from "./AppGroupPicker.svelte";
export let onSelect = (d) => console.log("Selecting an entity", d);
export let onDeselect = (d) => console.log("Deselecting an entity", d);
Expand All @@ -32,6 +33,8 @@
return ApplicationFieldPicker;
case "CHANGE_INITIATIVE":
return ChangeInitiativeFieldPicker;
case "APP_GROUP":
return AppGroupPicker;
default:
throw "Cannot find picker for kind: " + entityKind;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export function prepareColumnDefs(gridData) {
case "SURVEY_TEMPLATE":
case "APPLICATION":
case "CHANGE_INITIATIVE":
case "APP_GROUP":
case "SURVEY_QUESTION":
return {
allowSummary: false,
Expand All @@ -187,6 +188,7 @@ export function prepareColumnDefs(gridData) {
popover-placement="left"
ng-class="{'wgrc-involvement-cell': COL_FIELD.text && ${c.columnEntityKind === "INVOLVEMENT_KIND"},
'wgrc-survey-question-cell': COL_FIELD.text && ${c.columnEntityKind === "SURVEY_QUESTION"},
'wgrc-app-group-cell': COL_FIELD.text && ${c.columnEntityKind === "APP_GROUP"},
'wgrc-no-data-cell': !COL_FIELD.text}"
ng-style="{
'border-bottom-right-radius': COL_FIELD.comment ? '15% 50%' : 0,
Expand Down Expand Up @@ -294,6 +296,7 @@ export function prepareTableData(gridData) {
case "SURVEY_TEMPLATE":
case "APPLICATION":
case "CHANGE_INITIATIVE":
case "APP_GROUP":
case "SURVEY_QUESTION":
return {
text: x.text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ private Object getValueFromReportCell(Map<Long, RatingSchemeItem> ratingsById,
case APPLICATION:
case CHANGE_INITIATIVE:
case SURVEY_QUESTION:
case APP_GROUP:
return Optional.ofNullable(reportGridCell.text()).orElse("-");
case MEASURABLE:
case ASSESSMENT_DEFINITION:
Expand Down

0 comments on commit 32b7faf

Please sign in to comment.