Skip to content

Commit

Permalink
Merge pull request #6850 from davidwatkins73/waltz-6830-fcr-table-ass…
Browse files Browse the repository at this point in the history
…essments

Flow Classification Rule table to show assessments
  • Loading branch information
jessica-woodland-scott-db authored Nov 13, 2023
2 parents 126fb44 + 86ecb3e commit 76b7c04
Show file tree
Hide file tree
Showing 13 changed files with 293 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.finos.waltz.data.measurable_rating;

import org.finos.waltz.data.JooqUtilities;
import org.finos.waltz.model.EntityKind;
import org.finos.waltz.model.EntityReference;
import org.finos.waltz.model.measurable_rating.ImmutablePrimaryRatingViewItem;
import org.finos.waltz.model.measurable_rating.PrimaryRatingViewItem;
import org.finos.waltz.schema.Tables;
import org.finos.waltz.schema.tables.Measurable;
import org.finos.waltz.schema.tables.MeasurableCategory;
import org.finos.waltz.schema.tables.MeasurableRating;
import org.finos.waltz.schema.tables.RatingSchemeItem;
import org.jooq.DSLContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Set;

import static org.finos.waltz.model.EntityReference.mkRef;
import static org.finos.waltz.schema.Tables.*;

@Repository
public class MeasurableRatingViewDao {

private static final MeasurableRating mr = MEASURABLE_RATING;
private static final Measurable m = MEASURABLE;
private static final RatingSchemeItem rsi = RATING_SCHEME_ITEM;
private static final MeasurableCategory mc = MEASURABLE_CATEGORY;

private final DSLContext dsl;

@Autowired
public MeasurableRatingViewDao(DSLContext dsl) {
this.dsl = dsl;
}


/**
* Given an application id will return a set of primary ratings.
* The {@link PrimaryRatingViewItem} is a lightweight object with
* just enough data for display purposes.
*
* @param appId the identifier of the app to return primary ratings
* @return a set of primary ratings, the set will be empty if there are no ratings or the app cannot be found
*/
public Set<PrimaryRatingViewItem> findPrimaryRatingsForApp(long appId) {
return dsl
.select(mc.ID,
mc.NAME,
mc.DESCRIPTION,
m.ID,
m.NAME,
m.DESCRIPTION,
rsi.NAME,
rsi.DESCRIPTION,
rsi.COLOR)
.from(mr)
.innerJoin(m).on(m.ID.eq(mr.MEASURABLE_ID))
.innerJoin(mc).on(mc.ID.eq(m.MEASURABLE_CATEGORY_ID))
.innerJoin(rsi).on(mr.RATING.eq(rsi.CODE)
.and(rsi.SCHEME_ID.eq(mc.RATING_SCHEME_ID)))
.where(mr.ENTITY_KIND.eq(EntityKind.APPLICATION.name())
.and(mr.ENTITY_ID.eq(appId)))
.fetchSet(r -> ImmutablePrimaryRatingViewItem
.builder()
.measurableCategory(mkRef(
EntityKind.MEASURABLE_CATEGORY,
r.get(mc.ID),
r.get(mc.NAME),
r.get(mc.DESCRIPTION)))
.measurable(mkRef(
EntityKind.MEASURABLE,
r.get(m.ID),
r.get(m.NAME),
r.get(m.DESCRIPTION)))
.ratingName(r.get(rsi.NAME))
.ratingDescription(r.get(rsi.DESCRIPTION))
.ratingColor(r.get(rsi.COLOR))
.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.finos.waltz.model.flow_classification_rule;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.finos.waltz.model.assessment_definition.AssessmentDefinition;
import org.finos.waltz.model.assessment_rating.AssessmentRating;
import org.finos.waltz.model.rating.RatingSchemeItem;
import org.immutables.value.Value;

import java.util.Set;

@Value.Immutable
@JsonSerialize(as = ImmutableFlowClassificationRuleView.class)
public abstract class FlowClassificationRuleView {

public abstract Set<FlowClassificationRule> flowClassificationRules();

public abstract Set<AssessmentRating> assessmentRatings();

public abstract Set<AssessmentDefinition> primaryAssessmentDefinitions();

public abstract Set<RatingSchemeItem> ratingSchemeItems();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.finos.waltz.model.measurable_rating;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.finos.waltz.model.EntityReference;
import org.finos.waltz.model.rating.RatingSchemeItem;
import org.immutables.value.Value;

@Value.Immutable
@JsonSerialize(as = ImmutablePrimaryRatingViewItem.class)
public abstract class PrimaryRatingViewItem {

public abstract EntityReference measurableCategory();
public abstract EntityReference measurable();
public abstract String ratingName();
public abstract String ratingDescription();
public abstract String ratingColor();

}
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ function controller(serviceBroker) {

serviceBroker
.loadViewData(
CORE_API.FlowClassificationRuleStore.findByApp,
[ vm.parentEntityRef.id ], {force: true})
CORE_API.FlowClassificationRuleStore.view,
[ mkSelectionOptions(vm.parentEntityRef) ], {force: true})
.then(r => {
vm.flowClassificationRules = r.data;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
id="wass-sources-tab-content">
<div class="waltz-panel-content">

<div ng-if="$ctrl.classificationRules.length > 0">
<div ng-if="$ctrl.classificationRules.flowClassificationRules.length > 0">
<waltz-flow-classification-rules-table rules="$ctrl.classificationRules"
parent-entity-ref="$ctrl.parentEntityRef">
</waltz-flow-classification-rules-table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,12 @@ function controller(serviceBroker) {

const loadFlowClassificationRules = () => {
vm.selectionOptions = mkSelector();
const selector = mkSelector();
serviceBroker
.loadViewData(
CORE_API.FlowClassificationRuleStore.findFlowClassificationRulesBySelector,
[selector])
CORE_API.FlowClassificationRuleStore.view,
[vm.selectionOptions])
.then(r => {
vm.classificationRules = r.data;
vm.classificationRules = r.data;
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
</waltz-static-panels>
<br>

<div ng-if="$ctrl.viewMode==='LIST'">
<waltz-flow-classification-rules-table rules="$ctrl.classificationRules"
<div ng-if="$ctrl.viewMode === 'LIST'">
<waltz-flow-classification-rules-table rules="$ctrl.flowClassificationRules"
on-select="$ctrl.onSelectRule">
</waltz-flow-classification-rules-table>
</div>


<div ng-if="$ctrl.viewMode==='DETAIL'">
<div ng-if="$ctrl.viewMode === 'DETAIL'">
<waltz-svelte-component component="$ctrl.FlowClassificationRuleDetail"
primary-entity-ref="$ctrl.parentEntityRef"
can-edit="$ctrl.canEdit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,28 @@ import FlowClassificationRuleDetail from "./FlowClassificationRuleDetail.svelte"
import FlowClassificationRuleEditor from "./FlowClassificationRuleEditor.svelte";
import {mode, selectedClassificationRule} from "./editingFlowClassificationRulesState";
import roles from "../../../user/system-roles";
import {mkRef} from "../../../common/entity-utils";
import {mkSelectionOptions} from "../../../common/selector-utils";

const bindings = {}

const initialState = {
viewMode: "LIST",
FlowClassificationRuleDetail,
FlowClassificationRuleEditor,
canEdit: false
canEdit: false,
view: null
};

function controller(serviceBroker, userService, $scope){

const loadFlowClassificationRules = () => {
serviceBroker
.loadViewData(CORE_API.FlowClassificationRuleStore.findAll, [], {force: true})
.then(r => vm.classificationRules = r.data);
.loadViewData(
CORE_API.FlowClassificationRuleStore.view,
[mkSelectionOptions(mkRef("ALL", 1))],
{force: true})
.then(r => vm.flowClassificationRules = r.data);
};

const vm = initialiseData(this, initialState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import template from "./flow-classification-rules-table.html";

const bindings = {
parentEntityRef: "<",
rules: "<",
rules: "<?",
onSelect: "<?"
};

Expand All @@ -45,7 +45,7 @@ function shouldShowConsumers(parentRef) {
}


function mkColumnDefs(parentRef) {
function mkColumnDefs(parentRef, assessmentDefinitions = []) {
const consumerCell = shouldShowConsumers(parentRef)
? {
field: "consumers",
Expand Down Expand Up @@ -103,12 +103,28 @@ function mkColumnDefs(parentRef) {
</div>`
};

const definitionCells = _.map(assessmentDefinitions, def => {
return {
field: `assessmentRatings.${def.id}`,
displayName: def.name,
toSearchTerm: d => _.get(d, ["assessmentRatings", def.id, "ratingSchemeItem", "name"], ""),
cellTemplate: `
<div class="ui-grid-cell-contents" ng-style="{'background-color': COL_FIELD.ratingSchemeItem.color}">
<span ng-bind="COL_FIELD.ratingSchemeItem.name"
title="{{COL_FIELD.rating.comment}}">
</span>
</div>
`
};
});

return _.compact([
mkEntityLabelGridCell("Data Type", "dataType", "none", "right"),
mkEntityLabelGridCell("Scope", "vantagePointReference", "left"),
mkEntityLabelGridCell("Subject", "subjectReference", "left", "right"),
consumerCell,
classificationCell,
...definitionCells,
notesCell
]);
}
Expand Down Expand Up @@ -142,8 +158,14 @@ function controller($q, $state, serviceBroker) {
function mkGridData() {
const dataTypesById = _.keyBy(vm.dataTypes, "id");

vm.columnDefs = mkColumnDefs(vm.parentEntityRef);
vm.gridData = _.map(vm.rules, d => {
const ratingSchemeItemsById = _.keyBy(vm.rules.ratingSchemeItems, d => d.id);
const ratingsByEntityId = _.chain(vm.rules.assessmentRatings)
.map(r => Object.assign({}, {rating: r, ratingSchemeItem: ratingSchemeItemsById[r.ratingId]}))
.groupBy(d => d.rating.entityReference.id)
.value();

vm.columnDefs = mkColumnDefs(vm.parentEntityRef, vm.rules.primaryAssessmentDefinitions);
vm.gridData = _.map(vm.rules.flowClassificationRules, d => {
return {
id: d.id,
subjectReference: d.subjectReference,
Expand All @@ -153,7 +175,8 @@ function controller($q, $state, serviceBroker) {
description: d.description,
classification: vm.classificationsById[d.classificationId],
consumers: vm.consumersByAuthSourceId[d.id] || [],
isReadonly: d.isReadonly
isReadonly: d.isReadonly,
assessmentRatings: _.keyBy(ratingsByEntityId[d.id] || [], r => r.rating.assessmentDefinitionId)
};
});
}
Expand Down Expand Up @@ -181,10 +204,6 @@ function controller($q, $state, serviceBroker) {
.then(mkGridData);
}

vm.$onInit = () => {
loadAll();
};

vm.$onChanges = () => {
if(vm.rules) {
loadAll();
Expand All @@ -194,8 +213,6 @@ function controller($q, $state, serviceBroker) {
vm.onSelect = (d) => $state.go(
"main.flow-classification-rule.view",
{ id: d.id });


}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ export function store($http, root) {
.get(`${BASE}/cleanup-orphans`)
.then(r => r.data);

const view = (selector) =>
$http
.post(`${BASE}/view`, selector)
.then(r => r.data);

return {
calculateConsumersForDataTypeIdSelector,
findByReference,
Expand All @@ -112,7 +117,8 @@ export function store($http, root) {
remove,
findDiscouragedSources,
findFlowClassificationRulesBySelector,
cleanupOrphans
cleanupOrphans,
view
};

}
Expand Down Expand Up @@ -187,4 +193,9 @@ export const FlowClassificationRuleStore_API = {
serviceFnName: "cleanupOrphans",
description: "cleanupOrphans"
},
view: {
serviceName,
serviceFnName: "view",
description: "gets all rules as a view object"
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ public Set<FlowClassificationRule> findClassificationRules(IdSelectionOptions op
customSelectionCriteria = Tables.FLOW_CLASSIFICATION_RULE.DATA_TYPE_ID.in(dataTypeSelector.selector())
.and(FlowClassificationRuleDao.SUPPLIER_APP.KIND.notIn(options.filters().omitApplicationKinds()));
break;
case APPLICATION:
case ACTOR:
customSelectionCriteria = Tables.FLOW_CLASSIFICATION_RULE.SUBJECT_ENTITY_KIND.eq(options.entityReference().kind().name())
.and(Tables.FLOW_CLASSIFICATION_RULE.SUBJECT_ENTITY_ID.eq(options.entityReference().id()))
.and(FlowClassificationRuleDao.SUPPLIER_APP.KIND.notIn(options.filters().omitApplicationKinds()));
break;
case ALL:
case APP_GROUP:
case FLOW_DIAGRAM:
Expand Down
Loading

0 comments on commit 76b7c04

Please sign in to comment.