Skip to content

Commit

Permalink
Merge pull request #6983 from deutschebank/db-contrib/waltz-6820-prim…
Browse files Browse the repository at this point in the history
…ary-ratings-to-app-overview

Db contrib/waltz 6820 primary ratings to app overview
  • Loading branch information
jessica-woodland-scott-db authored Feb 12, 2024
2 parents e76d107 + 86b15de commit 833d192
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,12 @@
<!-- Key People -->
<waltz-key-people-sub-section parent-entity-ref="$ctrl.parentEntityRef">
</waltz-key-people-sub-section>

<br>
<!-- Primary Ratings -->
<waltz-svelte-component component="$ctrl.PrimaryRatingOverviewSubSection"
parent-entity-ref="$ctrl.parentEntityRef">
</waltz-svelte-component>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import template from "./app-overview.html";
import {displayError} from "../../../common/error-utils";
import {enrichComplexitiesWithKind, findDefaultComplexityKind} from "../../../complexity/services/complexity-utilities";
import {mkSelectionOptions} from "../../../common/selector-utils";
import PrimaryRatingOverviewSubSection from "../../../measurable-rating/svelte/PrimaryRatingOverviewSubSection.svelte";

const bindings = {
parentEntityRef: "<"
Expand All @@ -43,7 +44,8 @@ const initialState = {
aliasEditor: false,
tagEditor: false
},
showAllAppGroups: false
showAllAppGroups: false,
PrimaryRatingOverviewSubSection
};


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<script>
import SubSection from "../../common/svelte/SubSection.svelte";
import {measurableRatingStore} from "../../svelte-stores/measurable-rating-store";
import {mkSelectionOptions} from "../../common/selector-utils";
import _ from "lodash";
import RatingIndicatorCell from "../../ratings/components/rating-indicator-cell/RatingIndicatorCell.svelte";
import Icon from "../../common/svelte/Icon.svelte";
import {activeSections} from "../../dynamic-section/section-store";
import {dynamicSections} from "../../dynamic-section/dynamic-section-definitions";
import Tooltip from "../../common/svelte/Tooltip.svelte";
import PrimaryRatingTooltipContent from "./PrimaryRatingTooltipContent.svelte";
export let parentEntityRef;
let primaryRatingsCall;
let measurablesById = {};
let categoriesById = {};
let ratingsById = {};
$: {
if(parentEntityRef) {
const opts = mkSelectionOptions(parentEntityRef);
primaryRatingsCall = measurableRatingStore.getPrimaryRatingsViewBySelector(opts);
}
}
$: primaryRatingsView = $primaryRatingsCall?.data;
$: {
if(primaryRatingsView){
measurablesById = _.keyBy(primaryRatingsView.measurables, d => d.id);
categoriesById = _.keyBy(primaryRatingsView.measurableCategories, d => d.id);
ratingsById = _.keyBy(primaryRatingsView.ratingSchemeItems, d => d.id);
}
}
$: ratingsRows = _
.chain(primaryRatingsView?.measurableRatings || [])
.map(d => {
const measurable = measurablesById[d?.measurableId];
const category = categoriesById[measurable?.categoryId];
const ratingSchemeItem = ratingsById[d.ratingId];
return {
rating: d,
measurable,
category,
ratingSchemeItem
}
})
.orderBy(["category.position", "category.name"])
.value();
function mkRatingTooltipProps(row) {
return {
rating: row.rating,
ratingSchemeItem: row.ratingSchemeItem,
measurable: row.measurable
}
}
</script>
<SubSection>
<div slot="header">
Primary Viewpoint Ratings
</div>
<div slot="content">
{#if !_.isEmpty(primaryRatingsView?.measurableRatings)}
<table class="waltz-field-table waltz-field-table-border" style="width: 100%">
<tbody>
{#each ratingsRows as rating}
<tr>
<td class="wft-label" style="padding: 3px; width: 30%">
{_.get(rating, ["category", "name"], "Unknown Category")}
</td>
<td style="padding: 3px 6px; width: 70%">
<Tooltip content={PrimaryRatingTooltipContent}
placement="left-start"
props={mkRatingTooltipProps(rating)}>
<svelte:fragment slot="target">
<RatingIndicatorCell {...rating.ratingSchemeItem}
showName={false}/>
{_.get(rating, ["measurable", "name"], "Unknown Measurable")}
</svelte:fragment>
</Tooltip>
</td>
</tr>
{/each}
</tbody>
</table>
{:else}
<div class="help-block">
<Icon name="info-circle"/> No primary ratings have been set for this application
</div>
{/if}
</div>
<div slot="controls">
<span class="small pull-right">
<button class="btn btn-skinny btn-sm"
on:click={() => activeSections.add(dynamicSections.measurableRatingAppSection)}>
More
</button>
</span>
</div>
</SubSection>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script>
import DescriptionFade from "../../common/svelte/DescriptionFade.svelte";
import RatingIndicatorCell from "../../ratings/components/rating-indicator-cell/RatingIndicatorCell.svelte";
export let rating;
export let ratingSchemeItem;
export let measurable;
</script>


{#if measurable}
<div>
<h4>{measurable.name}</h4>
<span class="text-muted">{measurable.externalId}</span>
<DescriptionFade text={measurable.description}/>
</div>
<hr>
{/if}

<div>
<RatingIndicatorCell {...ratingSchemeItem}
showName={true}/>
<div>
{ratingSchemeItem.description}
</div>
</div>

{#if rating.description}
<hr>
<div>
<div>
Rating Comment:
</div>
<DescriptionFade text={rating.description || ""}/>
</div>
{:else }
<br>
{/if}
11 changes: 10 additions & 1 deletion waltz-ng/client/svelte-stores/measurable-rating-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,20 @@ export function mkMeasurableRelationshipStore() {
null,
{force});

const getPrimaryRatingsViewBySelector = (options, force = false) => remote
.fetchViewData(
"POST",
"api/measurable-rating/primary-ratings/view",
options,
null,
{force});

return {
findByApplicationSelector,
getById,
getViewById,
getViewByCategoryAndSelector
getViewByCategoryAndSelector,
getPrimaryRatingsViewBySelector
};
}

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

import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static org.finos.waltz.common.CollectionUtilities.find;
import static org.finos.waltz.common.MapUtilities.indexBy;
import static org.finos.waltz.common.SetUtilities.asSet;
import static org.finos.waltz.common.SetUtilities.filter;
Expand Down Expand Up @@ -168,10 +167,12 @@ public MeasurableRatingCategoryView getViewForCategoryAndSelector(IdSelectionOpt
GenericSelector appSelector = GENERIC_SELECTOR_FACTORY.applyForKind(EntityKind.APPLICATION, idSelectionOptions);

List<Application> applications = applicationService.findByAppIdSelector(idSelectionOptions);
Collection<MeasurableCategory> allCategories = measurableCategoryService.findAll();

MeasurableCategory category = find(allCategories, d -> d.id().get() == categoryId)
.orElseThrow(() -> new IllegalArgumentException(format("Cannot find category with id: %s", categoryId)));
MeasurableCategory category = measurableCategoryService.getById(categoryId);

if(category == null) {
throw new IllegalArgumentException(format("Cannot find category with id: %s", categoryId));
}

List<MeasurableRating> ratings = measurableRatingService.findForCategoryAndSelector(appSelector.selector(), categoryId);
List<Measurable> measurables = measurableService.findByCategoryId(categoryId);
Expand All @@ -195,21 +196,7 @@ public MeasurableRatingCategoryView getViewForCategoryAndSelector(IdSelectionOpt

Set<MeasurableHierarchy> hierarchyForCategory = measurableService.findHierarchyForCategory(categoryId);

Set<MeasurableCategory> primaryCategories = allCategories
.stream()
.filter(MeasurableCategory::allowPrimaryRatings)
.collect(Collectors.toSet());

Set<MeasurableRating> primaryMeasurableRatings = measurableRatingService.findPrimaryRatingsForGenericSelector(appSelector);
List<Measurable> primaryMeasurables = measurableDao.findByMeasurableIdSelector(mkMeasurableIdSelector(primaryMeasurableRatings));
Set<RatingSchemeItem> primaryRatingSchemeItems = ratingSchemeDAO.findRatingSchemeItemsForSchemeIds(map(primaryCategories, MeasurableCategory::ratingSchemeId));

ImmutableMeasurableRatingsView primaryRatingsView = ImmutableMeasurableRatingsView.builder()
.measurableRatings(primaryMeasurableRatings)
.measurables(primaryMeasurables)
.measurableCategories(primaryCategories)
.ratingSchemeItems(primaryRatingSchemeItems)
.build();
ImmutableMeasurableRatingsView primaryRatingsView = getPrimaryRatingsView(appSelector);

ImmutableMeasurableRatingsView ratingsView = ImmutableMeasurableRatingsView
.builder()
Expand Down Expand Up @@ -250,6 +237,26 @@ public MeasurableRatingCategoryView getViewForCategoryAndSelector(IdSelectionOpt
.build();
}

public ImmutableMeasurableRatingsView getPrimaryRatingsView(GenericSelector appSelector) {

Set<MeasurableCategory> primaryCategories = measurableCategoryService.findAll()
.stream()
.filter(MeasurableCategory::allowPrimaryRatings)
.collect(Collectors.toSet());

Set<MeasurableRating> primaryMeasurableRatings = measurableRatingService.findPrimaryRatingsForGenericSelector(appSelector);
List<Measurable> primaryMeasurables = measurableDao.findByMeasurableIdSelector(mkMeasurableIdSelector(primaryMeasurableRatings));
Set<RatingSchemeItem> primaryRatingSchemeItems = ratingSchemeDAO.findRatingSchemeItemsForSchemeIds(map(primaryCategories, MeasurableCategory::ratingSchemeId));

return ImmutableMeasurableRatingsView.builder()
.measurableRatings(primaryMeasurableRatings)
.measurables(primaryMeasurables)
.measurableCategories(primaryCategories)
.ratingSchemeItems(primaryRatingSchemeItems)
.build();
}


private SelectConditionStep<Record1<Long>> mkMeasurableIdSelector(Set<MeasurableRating> primaryMeasurableRatings) {
return DSL
.select(MEASURABLE.ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
package org.finos.waltz.web.endpoints.api;

import org.finos.waltz.common.exception.InsufficientPrivelegeException;
import org.finos.waltz.data.GenericSelector;
import org.finos.waltz.data.GenericSelectorFactory;
import org.finos.waltz.model.EntityKind;
import org.finos.waltz.model.EntityReference;
import org.finos.waltz.model.IdSelectionOptions;
import org.finos.waltz.model.Operation;
import org.finos.waltz.model.UserTimestamp;
import org.finos.waltz.model.application.MeasurableRatingsView;
import org.finos.waltz.model.measurable_rating.ImmutableRemoveMeasurableRatingCommand;
import org.finos.waltz.model.measurable_rating.MeasurableRating;
import org.finos.waltz.model.measurable_rating.MeasurableRatingCategoryView;
Expand Down Expand Up @@ -104,6 +107,7 @@ public void register() {
String getViewByIdPath = mkPath(BASE_URL, "id", ":id", "view");
String findForEntityPath = mkPath(BASE_URL, "entity", ":kind", ":id");
String getViewForCategoryAndAppSelectorPath = mkPath(BASE_URL, "category", ":id", "view");
String getPrimaryRatingsViewForAppSelectorPath = mkPath(BASE_URL, "primary-ratings", "view");
String modifyMeasurableForEntityPath = mkPath(BASE_URL, "entity", ":kind", ":id", "measurable", ":measurableId");
String modifyCategoryForEntityPath = mkPath(BASE_URL, "entity", ":kind", ":id", "category", ":categoryId");
String findByMeasurableSelectorPath = mkPath(BASE_URL, "measurable-selector");
Expand Down Expand Up @@ -138,6 +142,13 @@ public void register() {
return time("viewForCatAndSelector", () -> measurableRatingViewService.getViewForCategoryAndSelector(idSelectionOptions, categoryId));
};

DatumRoute<MeasurableRatingsView> getPrimaryRatingsViewForAppSelectorRoute = (request, response) -> {
IdSelectionOptions idSelectionOptions = readIdSelectionOptionsFromBody(request);
GenericSelectorFactory selectorFactory = new GenericSelectorFactory();
GenericSelector genericSelector = selectorFactory.apply(idSelectionOptions);
return measurableRatingViewService.getPrimaryRatingsView(genericSelector);
};

ListRoute<MeasurableRating> findByCategoryRoute = (request, response)
-> measurableRatingService.findByCategory(getId(request));

Expand Down Expand Up @@ -168,6 +179,7 @@ public void register() {
postForList(saveRatingDescriptionPath, this::saveRatingDescriptionRoute);
postForList(saveRatingIsPrimaryPath, this::saveRatingIsPrimaryRoute);
postForDatum(getViewForCategoryAndAppSelectorPath, getViewByCategoryAndAppSelectorRoute);
postForDatum(getPrimaryRatingsViewForAppSelectorPath, getPrimaryRatingsViewForAppSelectorRoute);
}


Expand Down

0 comments on commit 833d192

Please sign in to comment.