From 7d149e831fd4b5fa088277327a23109c4a0a7f5b Mon Sep 17 00:00:00 2001 From: woodjes Date: Wed, 21 Feb 2024 14:42:32 +0000 Subject: [PATCH 1/5] Add provenance and additional information to the data type section on logical flows #CTCTOWALTZ-3048 #6986 --- .../waltz/data/data_type/DataTypeDao.java | 11 + .../FlowClassificationDao.java | 9 + .../logical_flow/DataTypeDecoratorView.java | 23 +- .../FlowClassificationRulesView.java | 40 ++ waltz-ng/client/common/slick-grid-utils.js | 25 ++ .../DataTypeDecoratorNodeContent.svelte | 76 ++++ .../svelte/DataTypeDecoratorTreeNode.svelte | 91 +++++ .../DataTypeDecoratorTreeTooltip.svelte | 31 ++ ...velte => DataTypeDecoratorTreeView.svelte} | 28 +- .../common/svelte/DataTypeTreeNode.svelte | 7 +- waltz-ng/client/common/view-grid-utils.js | 64 +++ .../DataTypeDecoratorSection.svelte | 115 ++++-- .../DataTypeDecoratorViewGrid.svelte | 107 +++++ .../DataTypeDetailPanel.svelte | 367 ------------------ .../DataTypeOverviewPanel.svelte | 32 +- .../DataTypeDecoratorViewTable.svelte | 60 +++ .../DataTypeDetailContextPanel.svelte | 90 +++++ .../context-panel/DataTypeViewTable.svelte | 58 +++ .../FlowClassificationRuleViewTable.svelte | 70 ++++ .../data-type-decorator-section-store.js | 16 + .../data-type-decorator-view-grid-utils.js | 160 ++++++++ .../filters/AssessmentFilters.svelte | 96 +++++ .../filters/FlowClassificationFilters.svelte | 96 +++++ .../filters/FlowDecoratorFilters.svelte | 65 ++++ .../pages/view/logical-flow-view.js | 18 +- .../components/svelte/report-grid-service.js | 4 +- .../components/svelte/report-grid-utils.js | 2 +- .../AssessmentRatingService.java | 34 ++ .../data_type/DataTypeDecoratorService.java | 63 +-- .../service/data_type/DataTypeService.java | 8 + .../FlowClassificationRuleService.java | 19 + 31 files changed, 1400 insertions(+), 485 deletions(-) create mode 100644 waltz-model/src/main/java/org/finos/waltz/model/logical_flow/FlowClassificationRulesView.java create mode 100644 waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte create mode 100644 waltz-ng/client/common/svelte/DataTypeDecoratorTreeNode.svelte create mode 100644 waltz-ng/client/common/svelte/DataTypeDecoratorTreeTooltip.svelte rename waltz-ng/client/common/svelte/{DataTypeTreeView.svelte => DataTypeDecoratorTreeView.svelte} (55%) create mode 100644 waltz-ng/client/common/view-grid-utils.js create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte delete mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDetailPanel.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDecoratorViewTable.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeViewTable.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/FlowClassificationRuleViewTable.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-section-store.js create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/filters/AssessmentFilters.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte create mode 100644 waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowDecoratorFilters.svelte diff --git a/waltz-data/src/main/java/org/finos/waltz/data/data_type/DataTypeDao.java b/waltz-data/src/main/java/org/finos/waltz/data/data_type/DataTypeDao.java index a1ae3cc995..cccd7c77a8 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/data_type/DataTypeDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/data_type/DataTypeDao.java @@ -98,6 +98,17 @@ public List findByIdSelectorAsEntityReference(Select findByIdSelector(Select> selector) { + checkNotNull(selector, "selector cannot be null"); + + return dsl + .select(DATA_TYPE.asterisk()) + .from(DATA_TYPE) + .where(DATA_TYPE.ID.in(selector)) + .fetchSet(TO_DOMAIN); + } + + public DataType getByCode(String code) { checkNotEmpty(code, "Code cannot be null/empty"); return dsl diff --git a/waltz-data/src/main/java/org/finos/waltz/data/flow_classification_rule/FlowClassificationDao.java b/waltz-data/src/main/java/org/finos/waltz/data/flow_classification_rule/FlowClassificationDao.java index 41057f4661..b40feea2ed 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/flow_classification_rule/FlowClassificationDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/flow_classification_rule/FlowClassificationDao.java @@ -77,6 +77,15 @@ public FlowClassification getById(long id) { } + public Set findByIds(Set classificationRuleIds) { + return dsl + .select(FLOW_CLASSIFICATION.fields()) + .from(FLOW_CLASSIFICATION) + .where(FLOW_CLASSIFICATION.ID.in(classificationRuleIds)) + .fetchSet(TO_DOMAIN_MAPPER); + } + + public int remove(long id) { return dsl .delete(FLOW_CLASSIFICATION) diff --git a/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/DataTypeDecoratorView.java b/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/DataTypeDecoratorView.java index 5257fad49a..887b84a58d 100644 --- a/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/DataTypeDecoratorView.java +++ b/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/DataTypeDecoratorView.java @@ -20,11 +20,10 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 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.application.AssessmentsView; +import org.finos.waltz.model.datatype.DataType; import org.finos.waltz.model.datatype.DataTypeDecorator; -import org.finos.waltz.model.flow_classification_rule.FlowClassificationRule; -import org.finos.waltz.model.rating.RatingSchemeItem; +import org.finos.waltz.model.flow_classification.FlowClassification; import org.immutables.value.Value; import java.util.Set; @@ -33,15 +32,11 @@ @Value.Immutable @JsonSerialize(as = ImmutableDataTypeDecoratorView.class) @JsonDeserialize(as = ImmutableDataTypeDecoratorView.class) -public abstract class DataTypeDecoratorView { - - public abstract Set dataTypeDecorators(); - public abstract Set decoratorRatings(); - - public abstract Set primaryAssessmentDefinitions(); - - public abstract Set ratingSchemeItems(); - - public abstract Set flowClassificationRules(); +public interface DataTypeDecoratorView { + Set dataTypeDecorators(); + Set dataTypes(); + Set classifications(); + AssessmentsView primaryAssessments(); + FlowClassificationRulesView flowClassificationRules(); } diff --git a/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/FlowClassificationRulesView.java b/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/FlowClassificationRulesView.java new file mode 100644 index 0000000000..ee68ab7e1c --- /dev/null +++ b/waltz-model/src/main/java/org/finos/waltz/model/logical_flow/FlowClassificationRulesView.java @@ -0,0 +1,40 @@ +/* + * Waltz - Enterprise Architecture + * Copyright (C) 2016, 2017, 2018, 2019 Waltz open source project + * See README.md for more information + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific + * + */ + +package org.finos.waltz.model.logical_flow; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.finos.waltz.model.datatype.DataType; +import org.finos.waltz.model.flow_classification.FlowClassification; +import org.finos.waltz.model.flow_classification_rule.FlowClassificationRule; +import org.immutables.value.Value; + +import java.util.Set; + + +@Value.Immutable +@JsonSerialize(as = ImmutableFlowClassificationRulesView.class) +@JsonDeserialize(as = ImmutableFlowClassificationRulesView.class) +public interface FlowClassificationRulesView { + + Set flowClassificationRules(); + Set flowClassifications(); + Set dataTypes(); + +} diff --git a/waltz-ng/client/common/slick-grid-utils.js b/waltz-ng/client/common/slick-grid-utils.js index becbe46703..e0d86a6f7f 100644 --- a/waltz-ng/client/common/slick-grid-utils.js +++ b/waltz-ng/client/common/slick-grid-utils.js @@ -3,6 +3,7 @@ import EntityLink from "./svelte/EntityLink.svelte"; import {applicationKind} from "./services/enums/application-kind"; import {lifecyclePhase} from "./services/enums/lifecycle-phase"; import _ from "lodash"; +import {toLocalDate} from "./date-utils"; export function mkSortFn(sortCol, sortAsc = true) { @@ -39,6 +40,30 @@ export function mkExternalIdFormatter(valueProvider = d => d.externalId) { } +export function mkNameFormatter(valueProvider = d => d.name) { + return (row, cell, value, colDef, dataCtx) => { + const name = valueProvider(value, dataCtx); + return `${name}`; + } +} + +export function mkReadOnlyFormatter(valueProvider = d => d.isReadonly) { + return (row, cell, value, colDef, dataCtx) => { + const isReadonly = valueProvider(value, dataCtx); + if (isReadonly) { + return ``; + } + } +} + +export function mkLastUpdatedFormatter(dateProvider = d => d.lastUpdatedAt) { + return (row, cell, value, colDef, dataCtx) => { + const lastUpdatedAt = dateProvider(dataCtx); + return `${toLocalDate(lastUpdatedAt)}`; + } +} + + export function mkEnumFormatter(valueProvider, enums) { return (row, cell, value, colDef, dataCtx) => { diff --git a/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte b/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte new file mode 100644 index 0000000000..fa32584aba --- /dev/null +++ b/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte @@ -0,0 +1,76 @@ + + + + + + {#if node.deprecated} + + Deprecated + + {/if} + + {#if node.decorator?.flowClassification} + + {/if} + {#if node.decorator?.isReadonly} + + {/if} + + + + + + + \ No newline at end of file diff --git a/waltz-ng/client/common/svelte/DataTypeDecoratorTreeNode.svelte b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeNode.svelte new file mode 100644 index 0000000000..3fd3b45eb3 --- /dev/null +++ b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeNode.svelte @@ -0,0 +1,91 @@ + + +{#if !isRoot} + + +{/if} + +{#if expanded || node.isExpanded} +
    + {#each sortedNodes as childNode} +
  • + {#if childNode.children.length > 0} + + {:else} + + + {/if} +
  • + {/each} +
+{/if} + + \ No newline at end of file diff --git a/waltz-ng/client/common/svelte/DataTypeDecoratorTreeTooltip.svelte b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeTooltip.svelte new file mode 100644 index 0000000000..0f1b498555 --- /dev/null +++ b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeTooltip.svelte @@ -0,0 +1,31 @@ + + +{#if (dataType)} + {dataType.name} +
{dataType.code}
+ + {#if dataType.deprecated} +
+ + + + This data type is deprecated +
+ {/if} +{/if} +{#if decorator} +
+ +{/if} \ No newline at end of file diff --git a/waltz-ng/client/common/svelte/DataTypeTreeView.svelte b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeView.svelte similarity index 55% rename from waltz-ng/client/common/svelte/DataTypeTreeView.svelte rename to waltz-ng/client/common/svelte/DataTypeDecoratorTreeView.svelte index fffba17daa..16d1964d2c 100644 --- a/waltz-ng/client/common/svelte/DataTypeTreeView.svelte +++ b/waltz-ng/client/common/svelte/DataTypeDecoratorTreeView.svelte @@ -1,13 +1,14 @@ + $: { + if ($viewData) { + $enrichedDecorators = prepareData($viewData); + } + } + -
- - - - - - - -
- {#if selectedTab === Tabs.DATA_TYPES} - - {:else if selectedTab === Tabs.DETAIL} - - {/if} +
+
+
+ +
+
+
+ {#if activeMode === Modes.TREE} + + {:else if activeMode === Modes.TABLE} + + {/if} +
+ {#if $selectedDecorator || $selectedDataType} +
+ +
+ {/if}
+ + + diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte new file mode 100644 index 0000000000..fac7fd4618 --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte @@ -0,0 +1,107 @@ + + + +
+ {#if !_.isEmpty(tableData)} + + + +
+ +
+ +
+
+ + {:else} + There are no data type decorators associated to this flow + {/if} +
diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDetailPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDetailPanel.svelte deleted file mode 100644 index 0eae01cc1e..0000000000 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDetailPanel.svelte +++ /dev/null @@ -1,367 +0,0 @@ - - -
-
- {#if !_.isEmpty(tableData)} - - {#if !_.isEmpty(assessmentFilters)} -
- - Filters - - -
Use the assessment ratings to filter the logical flow decorators. Only ratings aligned to a data type decorator can be filtered upon
-
-
- {#each assessmentFilters as assessment} - - - - - - - - {#each assessment?.ratings as rating} - _.isEqual(r, { definitionId: assessment.definition.id, ratingId: rating.id}))} - on:click={() => selectRating(assessment.definition.id, rating.id)}> - - - {/each} - -
{assessment?.definition?.name} - - - -
- -
- {:else} - No decorators have been given a rating for a primary assessment - {/each} -
-
-
- {/if} - -
- -
-
- - - - - - {#each viewData?.primaryAssessmentDefinitions || [] as defn} - - {/each} - - - - {#each visibleRows as decorator} - {@const classification = _.get(classificationsByCode, decorator.rating)} - selectDecorator(decorator)} - class="clickable"> - - - {#each _.get(viewData, "primaryAssessmentDefinitions", []) as defn} - {@const assessmentRatings = _.get(decorator.ratingsByDefnId, [defn.id], [])} - - {/each} - - {/each} - -
Data TypeFlow Classification Rule{defn.name}
- {decorator.decoratorEntity.name} - - {#if !_.isEmpty(classification)} - - {/if} - -
- {#each assessmentRatings as rating} - - {/each} -
-
-
- {:else} - There are no data type decorators associated to this flow - {/if} -
- {#if selectedDecorator} -
-

- {selectedDecorator.decoratorEntity.name} - -

- - This mapping was last updated: - -
- {#if selectedDecorator.flowClassificationRule} - Flow Classification Rule - - - - - - - - - - - - - - - - - - - - - - -
Source - -
Scope - -
Data Type - -
Classification - -
- -
- {/if} -
- -
- {#if !_.isEmpty(selectedDecorator.ratingsByDefnId)} - Assessments - - - - - - - - - {#each _.keys(selectedDecorator.ratingsByDefnId) as defnId} - {@const ratings = _.get(selectedDecorator.ratingsByDefnId, defnId, [])} - - - - - {/each} - -
DefinitionRatings
- {_.get(definitionsById, [defnId, "name"], "Unknown")} - -
    - {#each ratings as assessmentRating} -
  • - -
  • - {/each} -
-
- {/if} -
-
- {/if} -
- - - \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte index 1b0a551d89..e8d2d3fa44 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte @@ -4,11 +4,12 @@ import {dataTypeDecoratorStore} from "../../../svelte-stores/data-type-decorator-store"; import {mkSelectionOptions} from "../../../common/selector-utils"; import _ from "lodash"; - import DataTypeTreeView from "../../../common/svelte/DataTypeTreeView.svelte"; + import DataTypeDecoratorTreeView from "../../../common/svelte/DataTypeDecoratorTreeView.svelte"; import Icon from "../../../common/svelte/Icon.svelte"; import {displayError} from "../../../common/error-utils"; import toasts from "../../../svelte-stores/toast-store"; import {logicalFlowStore} from "../../../svelte-stores/logical-flow-store"; + import {enrichedDecorators, selectedDecorator, selectedDataType} from "./data-type-decorator-section-store" export let primaryEntityReference; @@ -23,7 +24,6 @@ let activeMode = Modes.VIEW; let selectionOptions; let relatedDataTypesCall; - let selectedDataType; let permissionsCall; let workingDataTypes = []; @@ -31,7 +31,11 @@ let removedDataTypeIds = []; function onSelect(evt) { - selectedDataType = evt.detail; + const dataType = evt.detail; + const decorator = _.get(decoratorsByDataTypeId, dataType.id); + $selectedDecorator = decorator + $selectedDataType = dataType + console.log({evt, decorator, dataType}); } function cancelEdit() { @@ -78,7 +82,7 @@ } } - $: dataTypeDecorators = $relatedDataTypesCall?.data || []; + $: dataTypeDecorators = $enrichedDecorators || []; $: dataTypes = _.map(dataTypeDecorators, d => d.dataTypeId) $: decoratorsByDataTypeId = _.keyBy(dataTypeDecorators, d => d.dataTypeId); @@ -96,10 +100,11 @@
{#if activeMode === Modes.VIEW} -
- +
+
-
- -
- {#if selectedDataType} -

{selectedDataType.name}

-
- {selectedDataType.description} -
- {/if} -
-
{:else if activeMode === Modes.EDIT}
+ + import EntityLink from "../../../../common/svelte/EntityLink.svelte"; + import RatingIndicatorCell from "../../../../ratings/components/rating-indicator-cell/RatingIndicatorCell.svelte"; + import LastEdited from "../../../../common/svelte/LastEdited.svelte"; + import Icon from "../../../../common/svelte/Icon.svelte"; + + export let decorator; + + + + + + + + + + + + + + + + + + + + + + + + + + {#if decorator.isReadonly} + + + + + {/if} + +
Data Type + +
Classification + +
Last Updated + +
Provenance + {decorator.provenance} +
Read Only + This decorator cannot be edited in Waltz +
+ + + \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte new file mode 100644 index 0000000000..6239bd3f2a --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte @@ -0,0 +1,90 @@ + + +
+ + + +
+
+{#if $selectedDataType} +
+ Data Type + +
+{/if} + +{#if $selectedDecorator} +
+
+ +
+ Decorator + +
+ +
+ {#if $selectedDecorator.flowClassificationRule} + Flow Classification Rule + +
This is the flow classification rule driving the classification of the flow
+ {/if} +
+ +
+ {#if !_.isEmpty($selectedDecorator.assessmentRatings)} + Assessments + + + + + + + + + {#each $viewData.primaryAssessments.assessmentDefinitions as definition} + {@const ratings = _.get($selectedDecorator, mkDefinitionKey(definition), [])} + + + + + {/each} + +
DefinitionRatings
+ {definition.name} + +
    + {#each ratings as assessmentRating} +
  • + +
  • + {/each} +
+
+ {/if} +
+
+{/if} + diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeViewTable.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeViewTable.svelte new file mode 100644 index 0000000000..50cf7b665d --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeViewTable.svelte @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + {#if dataType.deprecated} + + + + + {/if} + +
Name + +
Code + {dataType.code}/> +
Description + +
Deprecated +
+ + + + This data type has been deprecated +
+
+ + \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/FlowClassificationRuleViewTable.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/FlowClassificationRuleViewTable.svelte new file mode 100644 index 0000000000..393817063d --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/FlowClassificationRuleViewTable.svelte @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source + +
Scope + +
Data Type + +
Classification + +
+ +
+ + + \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-section-store.js b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-section-store.js new file mode 100644 index 0000000000..06bfe7811f --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-section-store.js @@ -0,0 +1,16 @@ +import {writable} from "svelte/store"; +import _ from "lodash"; + +export const selectedDecorator = writable(null); +export const selectedDataType = writable(null); +export const viewData = writable(null); +export const enrichedDecorators = writable([]); +export const filters = writable([]); + + +export function updateFilters(filters, id, newFilter) { + return filters.update(filtersList => { + const withoutFilter = _.reject(filtersList, d => d.id === id); + return _.concat(withoutFilter, newFilter); + }) +} \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js new file mode 100644 index 0000000000..873bb1af46 --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js @@ -0,0 +1,160 @@ +import _ from "lodash"; +import { + mkLastUpdatedFormatter, + mkNameFormatter, + mkPrimaryAssessmentAndCategoryColumns, + mkRatingSchemeItemFormatter, + mkReadOnlyFormatter +} from "../../../common/slick-grid-utils"; +import {cmp, compareDates} from "../../../common/sort-utils"; +import {FilterKinds} from "../../../data-flow/components/svelte/flow-detail-tab/filters/filter-utils"; +import {mkDefinitionKey, prepareAssessmentsView, prepareFlowClassificationsView} from "../../../common/view-grid-utils"; + +const baseColumns = [ + { + id: "read_only", + name: "", + field: "isReadonly", + width: 60, + sortable: false, + formatter: mkReadOnlyFormatter(), + sortFn: (a, b) => cmp(a?.decoratorEntity.name, b?.decoratorEntity.name) + }, + { + id: "data_type", + name: "Data Type", + field: "decoratorEntity", + sortable: true, + formatter: mkNameFormatter(), + sortFn: (a, b) => cmp(a?.decoratorEntity.name, b?.decoratorEntity.name) + }, + { + id: "flow_classification_rating", + name: "Flow Classification", + field: "flowClassification", + sortable: true, + width: 180, + formatter: mkRatingSchemeItemFormatter(d => d.name, d => d), + sortFn: (a, b) => cmp(a?.flowClassification.name, b?.flowClassification.name) + } +]; + + +const lastUpdatedAndProvenanceColumns = [ + { + id: "last_updated_by", + name: "Last Updated By", + field: "lastUpdatedBy", + sortable: true, + width: 180, + sortFn: (a, b) => cmp(a?.decoratorEntity.name, b?.decoratorEntity.name) + }, + { + id: "last_updated_at", + name: "Last Updated At", + field: "lastUpdatedAt", + sortable: true, + width: 180, + formatter: mkLastUpdatedFormatter(), + sortFn: (a, b) => compareDates(a?.lastUpdatedAt, b?.lastUpdatedAt) + }, + { + id: "provenance", + name: "Provenance", + field: "provenance", + width: 180, + sortable: true, + sortFn: (a, b) => cmp(a?.provenance, b?.provenance) + } +]; + + +export function prepareData($viewData) { + + const enrichedPrimaryAssessments = prepareAssessmentsView($viewData.primaryAssessments); + const assessmentRatingsByDecoratorId = _.groupBy(enrichedPrimaryAssessments, d => d.assessmentRating.entityReference.id); + + const enrichedClassificationRules = prepareFlowClassificationsView($viewData.flowClassificationRules); + const flowClassificationRulesById = _.keyBy(enrichedClassificationRules, d => d.flowClassificationRule.id); + const classificationsByCode = _.keyBy($viewData.classifications, d => d.code); + + return _ + .chain($viewData.dataTypeDecorators) + .map(d => { + + const ratingsForDecorator = _.get(assessmentRatingsByDecoratorId, d.id, []); + const flowClassification = _.get(classificationsByCode, d.rating); + + const ratingsByDefnId = _ + .chain(ratingsForDecorator) + .reduce((acc, d) => { + const key = mkDefinitionKey(d.assessmentDefinition); + const values = acc[key] || []; + values.push(d); + acc[key] = values; + return acc; + }, + {}) + .value(); + + const flowClassificationRule = _.get(flowClassificationRulesById, d.flowClassificationRuleId); + + return Object.assign( + {}, + d, + { + ...ratingsByDefnId, + flowClassification, + flowClassificationRule, + assessmentRatings: ratingsForDecorator + }); + }) + .value(); +} + + +export function mkColumns(assessmentDefinitions = []) { + return _.concat( + baseColumns, + mkPrimaryAssessmentAndCategoryColumns(assessmentDefinitions, []), + lastUpdatedAndProvenanceColumns); +} + + +export function getAssessmentViewFilters(assessmentsView) { + + const ratingSchemeItemsById = _.keyBy(assessmentsView.ratingSchemeItems, d => d.id); + + const ratingsByDefinitionId = _ + .chain(assessmentsView.assessmentRatings) + .groupBy(r => r.assessmentDefinitionId) + .mapValues(v => _ + .chain(v) + .map(r => ratingSchemeItemsById[r.ratingId]) + .filter(d => d != null) + .uniq() + .sortBy(r => r.position, r => r.name) + .value()) + .value(); + + return _ + .chain(assessmentsView.assessmentDefinitions) + .map(d => Object.assign({}, {definition: d, ratings: _.get(ratingsByDefinitionId, d.id, [])})) + .filter(d => !_.isEmpty(d.ratings)) + .value(); +} + +export function mkClassificationViewFilter(id, desiredClassificationRatings = []) { + return { + id, + kind: FilterKinds.FLOW_CLASSIFICATION, + classifications: desiredClassificationRatings, + test: flowRow => _.isEmpty(desiredClassificationRatings) + ? true + : _.some( + flowRow.dataTypesForLogicalFlow, + x => _.some( + desiredClassificationRatings, + d => _.isEqual(d, x.rating))) + } +} \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/AssessmentFilters.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/AssessmentFilters.svelte new file mode 100644 index 0000000000..eafa06f5cc --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/AssessmentFilters.svelte @@ -0,0 +1,96 @@ + + +
+ Use the assessment ratings to filter the logical flows. Only ratings aligned to a flow can be filtered upon. +
+
+ {#each assessmentFilters as assessment} +
+ + + + + + + + {#each assessment?.ratings as rating} + selectRating(assessment.definition.id, rating.id)}> + + + {/each} + +
+ + {assessment?.definition?.name} + +
+ +
+
+ {:else} + No flows have been given a rating for a primary assessment + {/each} +
+ + \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte new file mode 100644 index 0000000000..7aaed557e1 --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte @@ -0,0 +1,96 @@ + + +
+ Filters the flows based upon their classification ratings. +
+
+ + + + + + + + + {#each _.orderBy(classifications, d => d.name) as fc} + selectClassification(fc)}> + + + + {/each} + +
+ Flow Classification + + {#if hasFilters} + + {/if} +
+ + + {fc.description} +
+
+ + \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowDecoratorFilters.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowDecoratorFilters.svelte new file mode 100644 index 0000000000..83d04d922d --- /dev/null +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowDecoratorFilters.svelte @@ -0,0 +1,65 @@ + + + +
+ + Filters + {#if !_.isEmpty($filters)} + + {/if} + + +
+ + Flow Classification + {#if !_.isEmpty(_.get(classificationFilter, ["classifications"], []))} + + + + {/if} + + +
+ +
+ + Assessments + {#if _.some($filters, d => d.kind === FilterKinds.ASSESSMENT)} + + + + {/if} + + +
+
+ + + \ No newline at end of file diff --git a/waltz-ng/client/logical-flow/pages/view/logical-flow-view.js b/waltz-ng/client/logical-flow/pages/view/logical-flow-view.js index 0cc9a09714..c20b9393fc 100644 --- a/waltz-ng/client/logical-flow/pages/view/logical-flow-view.js +++ b/waltz-ng/client/logical-flow/pages/view/logical-flow-view.js @@ -40,7 +40,8 @@ function controller($q, $state, $stateParams, $window, - serviceBroker) + serviceBroker, + historyStore) { const vm = initialiseData(this, initialState); @@ -57,7 +58,17 @@ function controller($q, .loadViewData( CORE_API.LogicalFlowStore.getById, [ flowId ]) - .then(r => vm.logicalFlow = r.data); + .then(r => vm.logicalFlow = r.data) + + + flowPromise + .then(r => { + historyStore.put( + `Logical Flow: ${vm.logicalFlow.source.name} to ${vm.logicalFlow.target.name}`, + "LOGICAL_DATA_FLOW", + "main.logical-flow.view", + { id: flowId }); + }); const permissionPromise = serviceBroker .loadViewData( @@ -134,7 +145,8 @@ controller.$inject = [ "$state", "$stateParams", "$window", - "ServiceBroker" + "ServiceBroker", + "HistoryStore" ]; diff --git a/waltz-ng/client/report-grid/components/svelte/report-grid-service.js b/waltz-ng/client/report-grid/components/svelte/report-grid-service.js index 8199cb1b5c..da32aaca00 100644 --- a/waltz-ng/client/report-grid/components/svelte/report-grid-service.js +++ b/waltz-ng/client/report-grid/components/svelte/report-grid-service.js @@ -5,7 +5,7 @@ import { combineColDefs, determineDefaultColumnOptions, mkRowFilter, - prepareTableData, + prepareData, refreshSummaries, sameColumnRef } from "./report-grid-utils"; @@ -38,7 +38,7 @@ function selectGrid(gridId, opts) { columnDefs.set(cols); userRole.set(d.data.userRole); hasDirtyColumns.set(false); - preparedTableData.set(prepareTableData(d.data.instance, cols)); + preparedTableData.set(prepareData(d.data.instance, cols)); return d.data; }); } diff --git a/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js b/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js index fbc30ab100..65ef49c4a6 100644 --- a/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js +++ b/waltz-ng/client/report-grid/components/svelte/report-grid-utils.js @@ -413,7 +413,7 @@ export function combineColDefs(definition) { } -export function prepareTableData(instance, columnDefs) { +export function prepareData(instance, columnDefs) { if (_.isEmpty(columnDefs)) { return []; diff --git a/waltz-service/src/main/java/org/finos/waltz/service/assessment_rating/AssessmentRatingService.java b/waltz-service/src/main/java/org/finos/waltz/service/assessment_rating/AssessmentRatingService.java index 02de0b081a..774e3e3f02 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/assessment_rating/AssessmentRatingService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/assessment_rating/AssessmentRatingService.java @@ -26,6 +26,8 @@ import org.finos.waltz.data.assessment_rating.AssessmentRatingDao; import org.finos.waltz.data.rating_scheme.RatingSchemeDAO; import org.finos.waltz.model.*; +import org.finos.waltz.model.application.AssessmentsView; +import org.finos.waltz.model.application.ImmutableAssessmentsView; import org.finos.waltz.model.assessment_definition.AssessmentDefinition; import org.finos.waltz.model.assessment_rating.*; import org.finos.waltz.model.changelog.ChangeLog; @@ -44,7 +46,9 @@ import static org.finos.waltz.common.Checks.checkNotNull; import static org.finos.waltz.common.MapUtilities.indexBy; import static org.finos.waltz.common.SetUtilities.asSet; +import static org.finos.waltz.common.SetUtilities.map; import static org.finos.waltz.model.EntityReference.mkRef; +import static org.finos.waltz.model.utils.IdUtilities.toIds; @Service public class AssessmentRatingService { @@ -440,4 +444,34 @@ public Set findRatingSummaryCounts(EntityKind tar public boolean hasMultiValuedAssessments(long assessmentDefinitionId) { return assessmentRatingDao.hasMultiValuedAssessments(assessmentDefinitionId); } + + public Set findBySelectorForDefinitions(GenericSelector genericSelector, + Set defIds) { + return assessmentRatingDao.findBySelectorForDefinitions(genericSelector, defIds); + } + + + public AssessmentsView getPrimaryAssessmentsViewForKindAndSelector(EntityKind entityKind, IdSelectionOptions opts) { + + Set primaryAssessmentDefs = assessmentDefinitionDao + .findPrimaryDefinitionsForKind( + EntityKind.LOGICAL_DATA_FLOW_DATA_TYPE_DECORATOR, + Optional.empty()); + + GenericSelector selector = genericSelectorFactory.applyForKind(entityKind, opts); + + Set assessmentRatings = findBySelectorForDefinitions( + selector, + toIds(primaryAssessmentDefs)); + + Set assessmentRatingSchemeItems = ratingSchemeDAO.findRatingSchemeItemsByIds( + map(assessmentRatings, AssessmentRating::ratingId)); + + return ImmutableAssessmentsView + .builder() + .assessmentDefinitions(primaryAssessmentDefs) + .assessmentRatings(assessmentRatings) + .ratingSchemeItems(assessmentRatingSchemeItems) + .build(); + } } \ No newline at end of file diff --git a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java index 581bb56927..10f18c28d8 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java @@ -24,26 +24,32 @@ import org.finos.waltz.data.logical_flow.LogicalFlowDao; import org.finos.waltz.data.logical_flow.LogicalFlowIdSelectorFactory; import org.finos.waltz.data.physical_specification.PhysicalSpecificationDao; -import org.finos.waltz.model.*; -import org.finos.waltz.model.assessment_definition.AssessmentDefinition; -import org.finos.waltz.model.assessment_rating.AssessmentRating; +import org.finos.waltz.model.EntityKind; +import org.finos.waltz.model.EntityReference; +import org.finos.waltz.model.HierarchyQueryScope; +import org.finos.waltz.model.IdSelectionOptions; +import org.finos.waltz.model.Operation; +import org.finos.waltz.model.Severity; +import org.finos.waltz.model.application.AssessmentsView; import org.finos.waltz.model.changelog.ImmutableChangeLog; +import org.finos.waltz.model.datatype.DataType; import org.finos.waltz.model.datatype.DataTypeDecorator; import org.finos.waltz.model.datatype.DataTypeUsageCharacteristics; import org.finos.waltz.model.datatype.ImmutableDataTypeDecorator; -import org.finos.waltz.model.flow_classification_rule.FlowClassificationRule; +import org.finos.waltz.model.flow_classification.FlowClassification; import org.finos.waltz.model.logical_flow.DataTypeDecoratorView; +import org.finos.waltz.model.logical_flow.FlowClassificationRulesView; import org.finos.waltz.model.logical_flow.ImmutableDataTypeDecoratorView; import org.finos.waltz.model.logical_flow.LogicalFlow; import org.finos.waltz.model.physical_specification.PhysicalSpecification; import org.finos.waltz.model.rating.AuthoritativenessRatingValue; -import org.finos.waltz.model.rating.RatingSchemeItem; import org.finos.waltz.service.assessment_definition.AssessmentDefinitionService; import org.finos.waltz.service.assessment_rating.AssessmentRatingService; import org.finos.waltz.service.changelog.ChangeLogService; import org.finos.waltz.service.data_flow_decorator.LogicalFlowDecoratorRatingsCalculator; import org.finos.waltz.service.data_flow_decorator.LogicalFlowDecoratorService; import org.finos.waltz.service.flow_classification_rule.FlowClassificationRuleService; +import org.finos.waltz.service.flow_classification_rule.FlowClassificationService; import org.finos.waltz.service.logical_flow.LogicalFlowService; import org.finos.waltz.service.physical_specification.PhysicalSpecificationService; import org.finos.waltz.service.rating_scheme.RatingSchemeService; @@ -54,16 +60,26 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import static java.lang.String.format; import static org.finos.waltz.common.Checks.checkNotNull; -import static org.finos.waltz.common.CollectionUtilities.*; +import static org.finos.waltz.common.CollectionUtilities.isEmpty; +import static org.finos.waltz.common.CollectionUtilities.notEmpty; import static org.finos.waltz.common.DateTimeUtilities.nowUtc; import static org.finos.waltz.common.ListUtilities.newArrayList; import static org.finos.waltz.common.SetUtilities.map; -import static org.finos.waltz.model.EntityKind.*; +import static org.finos.waltz.model.EntityKind.ACTOR; +import static org.finos.waltz.model.EntityKind.APPLICATION; +import static org.finos.waltz.model.EntityKind.DATA_TYPE; +import static org.finos.waltz.model.EntityKind.LOGICAL_DATA_FLOW; +import static org.finos.waltz.model.EntityKind.LOGICAL_DATA_FLOW_DATA_TYPE_DECORATOR; +import static org.finos.waltz.model.EntityKind.PHYSICAL_SPECIFICATION; import static org.finos.waltz.model.EntityReference.mkRef; import static org.finos.waltz.model.IdSelectionOptions.mkOpts; @@ -82,8 +98,7 @@ public class DataTypeDecoratorService { private final PhysicalSpecificationDao physicalSpecificationDao; private final PhysicalSpecificationService physicalSpecificationService; private final AssessmentRatingService assessmentRatingService; - private final AssessmentDefinitionService assessmentDefinitionService; - private final RatingSchemeService ratingSchemeService; + private final FlowClassificationService flowClassificationService; private final FlowClassificationRuleService flowClassificationRuleService; @@ -101,29 +116,30 @@ public DataTypeDecoratorService(ChangeLogService changeLogService, AssessmentRatingService assessmentRatingService, AssessmentDefinitionService assessmentDefinitionService, RatingSchemeService ratingSchemeService, + FlowClassificationService flowClassificationService, FlowClassificationRuleService flowClassificationRuleService) { checkNotNull(assessmentDefinitionService, "assessmentDefinitionService cannot be null"); checkNotNull(assessmentRatingService, "assessmentRatingService cannot be null"); checkNotNull(changeLogService, "changeLogService cannot be null"); + checkNotNull(flowClassificationService, "flowClassificationService cannot be null"); checkNotNull(flowClassificationRuleService, "flowClassificationRuleService cannot be null"); checkNotNull(logicalFlowDecoratorService, "logicalFlowDecoratorService cannot be null"); checkNotNull(physicalSpecificationService, "physicalSpecificationService cannot be null"); checkNotNull(ratingSchemeService, "ratingSchemeService cannot be null"); - this.assessmentDefinitionService = assessmentDefinitionService; this.assessmentRatingService = assessmentRatingService; this.changeLogService = changeLogService; this.dataTypeDecoratorDaoSelectorFactory = dataTypeDecoratorDaoSelectorFactory; this.dataTypeService = dataTypeService; this.dataTypeUsageService = dataTypeUsageService; + this.flowClassificationService = flowClassificationService; this.flowClassificationRuleService = flowClassificationRuleService; this.logicalFlowDao = logicalFlowDao; this.logicalFlowService = logicalFlowService; this.physicalSpecificationDao = physicalSpecificationDao; this.physicalSpecificationService = physicalSpecificationService; this.ratingsCalculator = ratingsCalculator; - this.ratingSchemeService = ratingSchemeService; } @@ -383,26 +399,21 @@ public Collection findDatatypeUsageCharacteristics */ public DataTypeDecoratorView getDecoratorView(EntityReference parentEntityRef) { + IdSelectionOptions selectionOptions = mkOpts(parentEntityRef); DataTypeDecoratorDao dao = dataTypeDecoratorDaoSelectorFactory.getDao(parentEntityRef.kind()); - EntityKind decoratorKind = getDecoratorKind(parentEntityRef.kind()); List decorators = dao.findByEntityId(parentEntityRef.id()); - - List decoratorAssessmentRatings = assessmentRatingService.findByTargetKindForRelatedSelector(decoratorKind, mkOpts(parentEntityRef)); - - Set primaryDefs = assessmentDefinitionService.findByPrimaryDefinitionsForKind(EntityKind.LOGICAL_DATA_FLOW_DATA_TYPE_DECORATOR, Optional.empty()); - - Set uniqueRatingIds = map(decoratorAssessmentRatings, AssessmentRating::ratingId); - Set ratings = ratingSchemeService.findRatingSchemeItemsByIds(uniqueRatingIds); - - Set flowClassificationRules = flowClassificationRuleService.findAppliedClassificationRulesForFlow(parentEntityRef.id()); + Set dataTypes = dataTypeService.findByIdSelector(selectionOptions); + AssessmentsView assessmentsView = assessmentRatingService.getPrimaryAssessmentsViewForKindAndSelector(LOGICAL_DATA_FLOW_DATA_TYPE_DECORATOR, selectionOptions); + FlowClassificationRulesView classificationRulesView = flowClassificationRuleService.getFlowClassificationsViewForFlow(parentEntityRef.id()); + Set classifications = flowClassificationService.findAll(); return ImmutableDataTypeDecoratorView.builder() .dataTypeDecorators(decorators) - .decoratorRatings(decoratorAssessmentRatings) - .primaryAssessmentDefinitions(primaryDefs) - .ratingSchemeItems(ratings) - .flowClassificationRules(flowClassificationRules) + .dataTypes(dataTypes) + .classifications(classifications) + .primaryAssessments(assessmentsView) + .flowClassificationRules(classificationRulesView) .build(); } diff --git a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeService.java b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeService.java index dd87af71e2..26798bf2a8 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeService.java @@ -19,11 +19,13 @@ package org.finos.waltz.service.data_type; import org.finos.waltz.data.data_type.DataTypeDao; +import org.finos.waltz.data.data_type.DataTypeIdSelectorFactory; import org.finos.waltz.data.data_type.search.DataTypeSearchDao; import org.finos.waltz.data.logical_flow.LogicalFlowDao; import org.finos.waltz.data.logical_flow.LogicalFlowIdSelectorFactory; import org.finos.waltz.model.EntityKind; import org.finos.waltz.model.EntityReference; +import org.finos.waltz.model.IdSelectionOptions; import org.finos.waltz.model.datatype.DataType; import org.finos.waltz.model.entity_search.EntitySearchOptions; import org.jooq.Record1; @@ -85,6 +87,12 @@ public List findByIdSelector(Select> selector) { return dataTypeDao.findByIdSelectorAsEntityReference(selector); } + public Set findByIdSelector(IdSelectionOptions options) { + DataTypeIdSelectorFactory dataTypeIdSelectorFactory = new DataTypeIdSelectorFactory(); + Select> selector = dataTypeIdSelectorFactory.apply(options); + return dataTypeDao.findByIdSelector(selector); + } + public Collection search(EntitySearchOptions options) { return searchDao.search(options); diff --git a/waltz-service/src/main/java/org/finos/waltz/service/flow_classification_rule/FlowClassificationRuleService.java b/waltz-service/src/main/java/org/finos/waltz/service/flow_classification_rule/FlowClassificationRuleService.java index 87e7eb7bda..17e849a2c6 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/flow_classification_rule/FlowClassificationRuleService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/flow_classification_rule/FlowClassificationRuleService.java @@ -18,6 +18,9 @@ package org.finos.waltz.service.flow_classification_rule; +import org.finos.waltz.model.logical_flow.FlowClassificationRulesView; +import org.finos.waltz.model.logical_flow.ImmutableFlowClassificationRulesView; +import org.finos.waltz.model.logical_flow.ImmutableFlowClassificationsView; import org.finos.waltz.schema.Tables; import org.finos.waltz.service.changelog.ChangeLogService; import org.finos.waltz.common.exception.NotFoundException; @@ -53,6 +56,7 @@ import java.util.Map; import java.util.Set; +import static org.finos.waltz.common.SetUtilities.map; import static org.finos.waltz.schema.tables.LogicalFlowDecorator.LOGICAL_FLOW_DECORATOR; import static java.lang.String.format; import static org.finos.waltz.common.Checks.checkNotNull; @@ -501,4 +505,19 @@ public Collection findCompanionDataTypeRules(long ruleId public Set findAppliedClassificationRulesForFlow(Long logicalFlowId) { return flowClassificationRuleDao.findAppliedClassificationRulesForFlow(logicalFlowId); } + + public FlowClassificationRulesView getFlowClassificationsViewForFlow(long flowId) { + + Set flowClassificationRules = findAppliedClassificationRulesForFlow(flowId); + Set classifications = flowClassificationDao.findByIds(map(flowClassificationRules, FlowClassificationRule::classificationId)); + + List dataTypes = dataTypeDao.findByIds(map(flowClassificationRules, FlowClassificationRule::dataTypeId)); + + return ImmutableFlowClassificationRulesView + .builder() + .flowClassificationRules(flowClassificationRules) + .flowClassifications(classifications) + .dataTypes(dataTypes) + .build(); + } } From 0eeb2e84b8a034c44766c46da7f5ce262c51ca4d Mon Sep 17 00:00:00 2001 From: woodjes Date: Wed, 21 Feb 2024 15:52:37 +0000 Subject: [PATCH 2/5] Add provenance and additional information to the data type section on logical flows #CTCTOWALTZ-3048 #6986 --- .../DataTypeDecoratorSection.svelte | 3 +++ .../DataTypeDecoratorViewGrid.svelte | 3 +-- .../DataTypeOverviewPanel.svelte | 9 ++++----- .../DataTypeDetailContextPanel.svelte | 2 +- .../data-type-decorator-view-grid-utils.js | 17 +---------------- .../filters/FlowClassificationFilters.svelte | 7 +++++++ .../data_type/DataTypeDecoratorService.java | 6 +++++- 7 files changed, 22 insertions(+), 25 deletions(-) diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorSection.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorSection.svelte index c3fc142ec1..09b7d269f9 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorSection.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorSection.svelte @@ -55,6 +55,9 @@ state={activeMode === Modes.TREE} onToggle={toggleView}/>
+
+ These are the data types currently aligned to this logical flow. You can toggle between a tabular and tree view of this information. Select a data type to see more information. +

{#if activeMode === Modes.TREE} diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte index fac7fd4618..130c22fbe3 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte @@ -60,7 +60,6 @@ if ($enrichedDecorators) { if (elem) { - initGrid(elem); } @@ -90,7 +89,7 @@ {#if !_.isEmpty(tableData)} + classifications={$viewData.classifications}/>
diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte index e8d2d3fa44..8afaa1fe74 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeOverviewPanel.svelte @@ -33,9 +33,8 @@ function onSelect(evt) { const dataType = evt.detail; const decorator = _.get(decoratorsByDataTypeId, dataType.id); - $selectedDecorator = decorator - $selectedDataType = dataType - console.log({evt, decorator, dataType}); + $selectedDecorator = decorator; + $selectedDataType = dataType; } function cancelEdit() { @@ -63,7 +62,7 @@ entityReference: primaryEntityReference, addedDataTypeIds, removedDataTypeIds, - } + }; dataTypeDecoratorStore.save(primaryEntityReference, cmd) .then(() => { @@ -83,7 +82,7 @@ } $: dataTypeDecorators = $enrichedDecorators || []; - $: dataTypes = _.map(dataTypeDecorators, d => d.dataTypeId) + $: dataTypes = _.map(dataTypeDecorators, d => d.dataTypeId); $: decoratorsByDataTypeId = _.keyBy(dataTypeDecorators, d => d.dataTypeId); diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte index 6239bd3f2a..a0d17199b9 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte @@ -49,7 +49,7 @@ {#if $selectedDecorator.flowClassificationRule} Flow Classification Rule -
This is the flow classification rule driving the classification of the flow
+
This is the rule that has driven the classification of the flow
{/if}
diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js index 873bb1af46..40f758ee59 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/data-type-decorator-view-grid-utils.js @@ -7,7 +7,6 @@ import { mkReadOnlyFormatter } from "../../../common/slick-grid-utils"; import {cmp, compareDates} from "../../../common/sort-utils"; -import {FilterKinds} from "../../../data-flow/components/svelte/flow-detail-tab/filters/filter-utils"; import {mkDefinitionKey, prepareAssessmentsView, prepareFlowClassificationsView} from "../../../common/view-grid-utils"; const baseColumns = [ @@ -25,6 +24,7 @@ const baseColumns = [ name: "Data Type", field: "decoratorEntity", sortable: true, + width: 180, formatter: mkNameFormatter(), sortFn: (a, b) => cmp(a?.decoratorEntity.name, b?.decoratorEntity.name) }, @@ -142,19 +142,4 @@ export function getAssessmentViewFilters(assessmentsView) { .map(d => Object.assign({}, {definition: d, ratings: _.get(ratingsByDefinitionId, d.id, [])})) .filter(d => !_.isEmpty(d.ratings)) .value(); -} - -export function mkClassificationViewFilter(id, desiredClassificationRatings = []) { - return { - id, - kind: FilterKinds.FLOW_CLASSIFICATION, - classifications: desiredClassificationRatings, - test: flowRow => _.isEmpty(desiredClassificationRatings) - ? true - : _.some( - flowRow.dataTypesForLogicalFlow, - x => _.some( - desiredClassificationRatings, - d => _.isEqual(d, x.rating))) - } } \ No newline at end of file diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte index 7aaed557e1..a0fc79f59d 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte @@ -8,6 +8,7 @@ import RatingIndicatorCell from "../../../../ratings/components/rating-indicator-cell/RatingIndicatorCell.svelte"; import {mkClassificationViewFilter} from "../../../../common/view-grid-utils"; import {updateFilters} from "../data-type-decorator-section-store"; + import NoData from "../../../../common/svelte/NoData.svelte"; export let classifications = []; export let filters; @@ -82,6 +83,12 @@ {fc.description} + {:else} + + + There are no classifications to filter over + + {/each} diff --git a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java index 10f18c28d8..eca69f837c 100644 --- a/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java +++ b/waltz-service/src/main/java/org/finos/waltz/service/data_type/DataTypeDecoratorService.java @@ -73,6 +73,7 @@ import static org.finos.waltz.common.CollectionUtilities.notEmpty; import static org.finos.waltz.common.DateTimeUtilities.nowUtc; import static org.finos.waltz.common.ListUtilities.newArrayList; +import static org.finos.waltz.common.SetUtilities.filter; import static org.finos.waltz.common.SetUtilities.map; import static org.finos.waltz.model.EntityKind.ACTOR; import static org.finos.waltz.model.EntityKind.APPLICATION; @@ -406,7 +407,10 @@ public DataTypeDecoratorView getDecoratorView(EntityReference parentEntityRef) { Set dataTypes = dataTypeService.findByIdSelector(selectionOptions); AssessmentsView assessmentsView = assessmentRatingService.getPrimaryAssessmentsViewForKindAndSelector(LOGICAL_DATA_FLOW_DATA_TYPE_DECORATOR, selectionOptions); FlowClassificationRulesView classificationRulesView = flowClassificationRuleService.getFlowClassificationsViewForFlow(parentEntityRef.id()); - Set classifications = flowClassificationService.findAll(); + Set ratings = map(decorators, d -> d.rating().orElse(null)); + Set classifications = filter( + flowClassificationService.findAll(), + d -> ratings.contains(AuthoritativenessRatingValue.ofNullable(d.code()).orElse(null))); return ImmutableDataTypeDecoratorView.builder() .dataTypeDecorators(decorators) From 7c49886d9a99a00bb38e3143f507717788c73808 Mon Sep 17 00:00:00 2001 From: woodjes Date: Wed, 21 Feb 2024 16:16:13 +0000 Subject: [PATCH 3/5] Add provenance and additional information to the data type section on logical flows #CTCTOWALTZ-3048 #6986 --- .../DataTypeDecoratorViewGrid.svelte | 2 +- .../filters/FlowClassificationFilters.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte index 130c22fbe3..458ebd82ea 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/DataTypeDecoratorViewGrid.svelte @@ -57,7 +57,7 @@ $:{ - if ($enrichedDecorators) { + if ($enrichedDecorators && $viewData) { if (elem) { initGrid(elem); diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte index a0fc79f59d..a220355a29 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/filters/FlowClassificationFilters.svelte @@ -85,7 +85,7 @@ {:else} - + There are no classifications to filter over From 581e5be907d718fe6004080d5f5533d7c7d71ad2 Mon Sep 17 00:00:00 2001 From: woodjes Date: Wed, 21 Feb 2024 16:25:33 +0000 Subject: [PATCH 4/5] Add provenance and additional information to the data type section on logical flows #CTCTOWALTZ-3048 #6986 --- .../client/common/svelte/DataTypeDecoratorNodeContent.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte b/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte index fa32584aba..b36d4214c0 100644 --- a/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte +++ b/waltz-ng/client/common/svelte/DataTypeDecoratorNodeContent.svelte @@ -30,8 +30,7 @@ class:unknown={node.unknown} class:deprecated={node.deprecated} disabled={isDisabled} - on:click={() => selectNode(node)} - title={node.description}> + on:click={() => selectNode(node)}> {#if multiSelect} {/if} From 441f56a6dc72b91947ae62ae7b21f5a9017fafb2 Mon Sep 17 00:00:00 2001 From: woodjes Date: Wed, 21 Feb 2024 17:39:12 +0000 Subject: [PATCH 5/5] Prevent flow classification rules showing where rating for flow is 'DISCOURAGED' #CTCTOWALTZ-3048 #6986 --- .../context-panel/DataTypeDetailContextPanel.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte index a0d17199b9..fe5c77f3a3 100644 --- a/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte +++ b/waltz-ng/client/data-types/components/data-type-decorator-section/context-panel/DataTypeDetailContextPanel.svelte @@ -46,7 +46,7 @@
- {#if $selectedDecorator.flowClassificationRule} + {#if $selectedDecorator.flowClassificationRule && $selectedDecorator.rating !== 'DISCOURAGED'} Flow Classification Rule
This is the rule that has driven the classification of the flow