Skip to content

Commit

Permalink
Primary Measurable Ratings
Browse files Browse the repository at this point in the history
- updated the ratings browser
- TODO: browser for measurables

#CTCTOWALTZ-2746
finos#6635
  • Loading branch information
db-waltz committed Jun 20, 2023
1 parent ae85ebf commit c10cd18
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,19 @@ public List<Tally<Long>> tallyByMeasurableCategoryId(long categoryId) {
}


public List<MeasurableRatingTally> statsByAppSelector(Select<Record1<Long>> selector) {
public List<MeasurableRatingTally> statsByAppSelector(Select<Record1<Long>> selector,
boolean primaryOnly) {
Condition primaryCond = MEASURABLE_CATEGORY.ALLOW_PRIMARY_RATINGS.isFalse()
.or(MEASURABLE_RATING.IS_PRIMARY.eq(primaryOnly));

return dsl
.select(MEASURABLE_RATING.MEASURABLE_ID, MEASURABLE_RATING.RATING, DSL.count())
.from(MEASURABLE_RATING)
.innerJoin(MEASURABLE).on(MEASURABLE.ID.eq(MEASURABLE_RATING.MEASURABLE_ID))
.innerJoin(MEASURABLE_CATEGORY).on(MEASURABLE_CATEGORY.ID.eq(MEASURABLE.MEASURABLE_CATEGORY_ID))
.where(dsl.renderInlined(MEASURABLE_RATING.ENTITY_KIND.eq(EntityKind.APPLICATION.name())
.and(MEASURABLE_RATING.ENTITY_ID.in(selector))))
.and(primaryCond)
.groupBy(MEASURABLE_RATING.MEASURABLE_ID, MEASURABLE_RATING.RATING)
.fetch(TO_TALLY_MAPPER);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.finos.waltz.model.measurable_rating;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.finos.waltz.model.IdSelectionOptions;
import org.immutables.value.Value;

@Value.Immutable
@JsonDeserialize(as = ImmutableMeasurableRatingStatParams.class)
public abstract class MeasurableRatingStatParams {

public abstract IdSelectionOptions options();


@Value.Default
public boolean showPrimaryOnly() {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,30 @@

</div>
<div class="col-sm-6">
<div ng-if="$ctrl.activeCategory" style="padding-top: 8px">
<div ng-if="$ctrl.activeCategory">
<h4>
<waltz-icon name="{{$ctrl.activeCategory.icon}}"></waltz-icon>
<span ng-bind="$ctrl.activeCategory.name"></span>
</h4>

<p class="text-muted">
<waltz-markdown text="$ctrl.activeCategory.description"></waltz-markdown>
</p>

<waltz-warning ng-if="$ctrl.activeCategory.allowPrimaryRatings">
<message>This category supports Primary Ratings</message>
<content>
blah blah bah.
<waltz-toggle icon-on="star"
icon-off="star-o"
label-on="Showing only primary ratings"
label-off="Showing all ratings"
state="$ctrl.showPrimaryOnly"
on-toggle="$ctrl.onTogglePrimaryOnly(!$ctrl.showPrimaryOnly)">
</waltz-toggle>
Use the toggle below to filter the tree to only show ratings which have been flagged as
<i>Primary</i>
<div style="padding-top: 1em;">
<waltz-toggle icon-on="star"
icon-off="star-o"
label-on="Showing only primary ratings"
label-off="Showing all ratings"
state="$ctrl.showPrimaryOnly"
on-toggle="$ctrl.onTogglePrimaryOnly(!$ctrl.showPrimaryOnly)">
</waltz-toggle>
</div>
</content>
</waltz-warning>
<hr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {lastViewedMeasurableCategoryKey} from "../../../user";
const bindings = {
filters: "<",
parentEntityRef: "<",
onMeasurableCategorySelect: "<"
onMeasurableCategorySelect: "<?"
};


Expand All @@ -56,6 +56,7 @@ const initialState = {
},
selectedMeasurable: null,
onLoadDetail: () => log("onLoadDetail"),
onMeasurableCategorySelect: () => log("onMeasurableCategorySelect"),
showMore: false,
showPrimaryOnly: false
};
Expand Down Expand Up @@ -197,9 +198,9 @@ function log() {
}


function loadMeasurableRatingTallies(serviceBroker, selector, holder) {
function loadMeasurableRatingTallies(serviceBroker, params, holder) {
return serviceBroker
.loadViewData(CORE_API.MeasurableRatingStore.statsByAppSelector, [selector])
.loadViewData(CORE_API.MeasurableRatingStore.statsByAppSelector, [params])
.then(r => holder.ratingTallies = r.data);
}

Expand Down Expand Up @@ -256,38 +257,29 @@ function controller($q, serviceBroker) {
};

const loadBaseData = () => {
vm.selector = mkSelectionOptionsWithJoiningEntity(
vm.parentEntityRef,
undefined,
undefined,
vm.filters,
"APPLICATION"
);

return $q.all([
loadMeasurableCategories(serviceBroker, vm),
loadMeasurables(serviceBroker, vm.selector, vm),
loadRatingSchemes(serviceBroker, vm),
loadMeasurableRatingTallies(serviceBroker, vm.selector, vm),
loadApps(serviceBroker, vm.selector, vm),
loadLastViewedCategory(serviceBroker, vm),
]);
return $q
.all([
loadMeasurableCategories(serviceBroker, vm),
loadMeasurables(serviceBroker, vm.selector, vm),
loadRatingSchemes(serviceBroker, vm),
loadApps(serviceBroker, vm.selector, vm),
loadLastViewedCategory(serviceBroker, vm)
])
.then(loadRatings);
};


const loadRatings = () => {
clearDetail();

vm.selector = mkSelectionOptions(
vm.parentEntityRef,
undefined,
undefined,
vm.filters);
const statsParams = {
options: vm.selector,
showPrimaryOnly: vm.showPrimaryOnly
};

const promise = loadMeasurableRatingTallies(serviceBroker, statsParams, vm);

const promise = $q.all([
loadApps(serviceBroker, vm.selector, vm),
loadMeasurableRatingTallies(serviceBroker, vm.selector, vm),
]);

if(vm.visibility.ratingDetail) {
promise.then(() => vm.onSelect(vm.selectedMeasurable));
Expand All @@ -299,21 +291,35 @@ function controller($q, serviceBroker) {

const loadRatingDetail = () => {
clearDetail();
return vm.measurableRatingsDetail
? $q.resolve(vm.measurableRatingsDetail)
: serviceBroker
.execute(CORE_API.MeasurableRatingStore.findByAppSelector, [vm.selector])
.then(r => vm.measurableRatingsDetail = r.data);
return serviceBroker
.execute(CORE_API.MeasurableRatingStore.findByAppSelector, [vm.selector])
.then(r => {
const ratings = r.data;
vm.measurableRatingsDetail = vm.showPrimaryOnly
? _.filter(ratings, d => d.isPrimary === true)
: ratings;
return vm.measurableRatingsDetail;
});
};

function setupSelector() {
vm.selector = mkSelectionOptionsWithJoiningEntity(
vm.parentEntityRef,
undefined,
undefined,
vm.filters,
"APPLICATION"
);
}

vm.$onInit = () => {
loadBaseData()
.then(() => loadRatings());
setupSelector();
loadBaseData();
};


vm.$onChanges = (changes) => {
setupSelector();
if(vm.parentEntityRef && changes.filters) {
loadRatings();
}
Expand Down Expand Up @@ -384,6 +390,7 @@ function controller($q, serviceBroker) {
vm.onTogglePrimaryOnly = (showPrimaryOnly) => {
console.log("onTogglePrimaryOnly", {showPrimaryOnly});
vm.showPrimaryOnly = showPrimaryOnly;
loadRatings();
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ function initialiseRatingTalliesMap(ratingTallies = [], measurables = []) {
: {};

acc[m.id] = {
measurableId: m.id,
direct: _.clone(summaryObj),
compound: _.clone(summaryObj),
compound: _.clone(summaryObj)
};
return acc;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,34 @@ function controller(serviceBroker) {

const prepareData = () => {
if (_.isEmpty(vm.measurables) ||
_.isEmpty(vm.ratingTallies) ||
// _.isEmpty(vm.ratingTallies) ||
_.isEmpty(vm.categories) ||
_.isEmpty(vm.ratingSchemesById)) {

if (_.isEmpty(vm.ratingTallies)) {
vm.ratingsMap = {};
}
} else {
const tabs = prepareTabs(vm.categories, vm.measurables, vm.ratingSchemesById);
vm.ratingsMap = mkRatingTalliesMap(vm.ratingTallies, vm.measurables);
vm.maxTotal = findMaxTotal(vm.ratingsMap);

const unusedMeasurables = _
.chain(vm.ratingsMap)
.values()
.filter(d => _.get(d, ["compound", "total"], 0) === 0)
.map(d => d.measurableId)
.value();

const tabs = prepareTabs(
vm.categories,
_.reject(vm.measurables, m => _.includes(unusedMeasurables, m.id)),
vm.ratingSchemesById);

const lastViewedCategory = _.find(tabs, t => t.category.id === vm.lastViewedCategoryId);
const tab = lastViewedCategory || findFirstNonEmptyTab(tabs);

vm.tabs = tabs;

vm.ratingsMap = mkRatingTalliesMap(vm.ratingTallies, vm.measurables);
vm.maxTotal = findMaxTotal(vm.ratingsMap);

if (!vm.visibility.tab) {
// no tab selected, select the first
vm.visibility.tab = _.get(tab, ["category", "id"]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h4>Implicit Relationships</h4>
to applications aligned to this viewpoint.
</p>
<div class="row"
ng-if="$ctrl.relatedMeasurables.length < 2">
ng-if="$ctrl.relatedMeasurables.length === 1">
<div class="col-sm-12">
<waltz-no-data>
<message>
Expand All @@ -44,8 +44,7 @@ <h4>Implicit Relationships</h4>
ng-if="$ctrl.relatedMeasurables.length > 1">
<div class="col-sm-12">
<waltz-measurable-ratings-browser-tree-panel parent-entity-ref="$ctrl.parentEntityRef"
filters="$ctrl.filters"
on-measurable-category-select="$ctrl.onCategorySelect">
filters="$ctrl.filters">
</waltz-measurable-ratings-browser-tree-panel>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function controller($q, serviceBroker) {
return;
}

// QUESTION: can we do this without making the full call? Only used to hide/show implicit measurables
const selectionOptions = mkSelectionOptions(vm.parentEntityRef);

const measurablesPromise = serviceBroker
Expand All @@ -90,10 +91,6 @@ function controller($q, serviceBroker) {
.then(() => vm.relatedMeasurables = calcRelatedMeasurables(vm.stats, vm.measurables));

};

vm.onCategorySelect = (category) => {
vm.activeCategory = category;
};
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ function store($http, baseApiUrl) {
.then(d => d.data);
};

const statsByAppSelector = (options) => {
checkIsIdSelector(options);
const statsByAppSelector = (params) => {
checkIsIdSelector(params.options);
return $http
.post(`${baseUrl}/stats-by/app-selector`, options)
.post(`${baseUrl}/stats-by/app-selector`, params)
.then(d => d.data);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package org.finos.waltz.service.measurable_rating;

import org.finos.waltz.model.measurable_rating.MeasurableRatingStatParams;
import org.finos.waltz.service.changelog.ChangeLogService;
import org.finos.waltz.service.rating_scheme.RatingSchemeService;
import org.finos.waltz.common.DateTimeUtilities;
Expand Down Expand Up @@ -206,10 +207,12 @@ public Collection<MeasurableRatingTally> statsForRelatedMeasurable(IdSelectionOp
}


public List<MeasurableRatingTally> statsByAppSelector(IdSelectionOptions options) {
checkNotNull(options, "options cannot be null");
Select<Record1<Long>> selector = applicationIdSelectorFactory.apply(options);
return measurableRatingDao.statsByAppSelector(selector);
public List<MeasurableRatingTally> statsByAppSelector(MeasurableRatingStatParams params) {
checkNotNull(params, "params cannot be null");
Select<Record1<Long>> selector = applicationIdSelectorFactory.apply(params.options());
return measurableRatingDao.statsByAppSelector(
selector,
params.showPrimaryOnly());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public void register() {
-> measurableRatingService.tallyByMeasurableCategoryId(getId(request));

ListRoute<MeasurableRatingTally> statsByAppSelectorRoute = (request, response)
-> measurableRatingService.statsByAppSelector(readIdSelectionOptionsFromBody(request));
-> measurableRatingService.statsByAppSelector(readBody(request, MeasurableRatingStatParams.class));

ListRoute<MeasurableRatingTally> statsForRelatedMeasurableRoute = (request, response)
-> measurableRatingService.statsForRelatedMeasurable(readIdSelectionOptionsFromBody(request));
Expand Down

0 comments on commit c10cd18

Please sign in to comment.