diff --git a/waltz-data/src/main/java/org/finos/waltz/data/datatype_decorator/LogicalFlowDecoratorDao.java b/waltz-data/src/main/java/org/finos/waltz/data/datatype_decorator/LogicalFlowDecoratorDao.java index a27aa818c0..329ecb34de 100644 --- a/waltz-data/src/main/java/org/finos/waltz/data/datatype_decorator/LogicalFlowDecoratorDao.java +++ b/waltz-data/src/main/java/org/finos/waltz/data/datatype_decorator/LogicalFlowDecoratorDao.java @@ -305,6 +305,8 @@ public List findDatatypeUsageCharacteristics(Entit .select( LOGICAL_FLOW_DECORATOR.DECORATOR_ENTITY_ID, LOGICAL_FLOW_DECORATOR.IS_READONLY, + LOGICAL_FLOW_DECORATOR.LAST_UPDATED_BY, + LOGICAL_FLOW_DECORATOR.PROVENANCE, numberOfFlowsSharingDatatype) .from(LOGICAL_FLOW) .innerJoin(LOGICAL_FLOW_DECORATOR).on(LOGICAL_FLOW.ID.eq(LOGICAL_FLOW_DECORATOR.LOGICAL_FLOW_ID) @@ -315,22 +317,58 @@ public List findDatatypeUsageCharacteristics(Entit .leftJoin(PHYSICAL_SPEC_DATA_TYPE).on(PHYSICAL_FLOW.SPECIFICATION_ID.eq(PHYSICAL_SPEC_DATA_TYPE.SPECIFICATION_ID) .and(PHYSICAL_SPEC_DATA_TYPE.DATA_TYPE_ID.eq(LOGICAL_FLOW_DECORATOR.DECORATOR_ENTITY_ID))) .where(LOGICAL_FLOW.ID.eq(ref.id())) - .groupBy(LOGICAL_FLOW_DECORATOR.DECORATOR_ENTITY_ID, LOGICAL_FLOW_DECORATOR.IS_READONLY) + .groupBy(LOGICAL_FLOW_DECORATOR.DECORATOR_ENTITY_ID, LOGICAL_FLOW_DECORATOR.IS_READONLY, LOGICAL_FLOW_DECORATOR.LAST_UPDATED_BY, LOGICAL_FLOW_DECORATOR.PROVENANCE) .fetch(r -> { int usageCount = r.get(numberOfFlowsSharingDatatype); + boolean noUsages = usageCount == 0; + boolean isReadOnly = r.get(LOGICAL_FLOW_DECORATOR.IS_READONLY); + String provenance = r.get(LOGICAL_FLOW_DECORATOR.PROVENANCE); + String lastUpdatedBy = r.get(LOGICAL_FLOW_DECORATOR.LAST_UPDATED_BY); return ImmutableDataTypeUsageCharacteristics.builder() .dataTypeId(r.get(LOGICAL_FLOW_DECORATOR.DECORATOR_ENTITY_ID)) - .warningMessageForViewers(usageCount == 0 - ? "Warning: None of the underlying physical flows reference this data type." - : null) - .warningMessageForEditors(usageCount > 0 - ? format("Cannot be removed as used in %d physical flows. These must be removed first.", usageCount) - : null) - .isRemovable(usageCount == 0) + .warningMessageForViewers(mkViewerWarningMessage(noUsages, isReadOnly, lastUpdatedBy, provenance)) + .warningMessageForEditors(mkEditorWarningMessage(usageCount, isReadOnly, lastUpdatedBy, provenance)) + .isRemovable(noUsages && !isReadOnly) .build(); }); } + private String mkEditorWarningMessage(int usageCount, + boolean isReadOnly, + String lastUpdatedBy, + String provenance) { + + StringBuilder buff = new StringBuilder(); + if (usageCount > 0 || isReadOnly) { + buff.append("Warning:\n"); + } + if (usageCount > 0) { + buff.append(format("- Cannot be removed as used in %d physical flows. The data type mappings on these must be removed first\n", usageCount)); + } + if (isReadOnly) { + buff.append(format("- Marked as readonly - %s / %s\n", lastUpdatedBy, provenance)); + } + return buff.toString(); + } + + + private String mkViewerWarningMessage(boolean noUsages, + boolean isReadOnly, + String lastUpdatedBy, + String provenance) { + StringBuilder buff = new StringBuilder(); + if (noUsages || isReadOnly) { + buff.append("Warning:\n"); + } + if (noUsages) { + buff.append("- None of the underlying physical flows reference this data type\n"); + } + if (isReadOnly) { + buff.append(format("- Marked as readonly - %s / %s\n", lastUpdatedBy, provenance)); + } + return buff.toString(); + } + public int updateRatingsByCondition(AuthoritativenessRatingValue rating, Condition condition) { return dsl diff --git a/waltz-ng/client/common/svelte/DataTypeNodeTooltipContent.svelte b/waltz-ng/client/common/svelte/DataTypeNodeTooltipContent.svelte index b72059d80b..9709c5ecc1 100644 --- a/waltz-ng/client/common/svelte/DataTypeNodeTooltipContent.svelte +++ b/waltz-ng/client/common/svelte/DataTypeNodeTooltipContent.svelte @@ -108,7 +108,7 @@ style="vertical-align: middle" size="xl"/> - {usageCharacteristics.warningMessageForEditors} + {/if} @@ -120,7 +120,7 @@ style="vertical-align: middle" size="xl"/> - {usageCharacteristics.warningMessageForViewers} + {/if} diff --git a/waltz-ng/client/common/svelte/DataTypeTreeNode.svelte b/waltz-ng/client/common/svelte/DataTypeTreeNode.svelte index 6804a1467e..66ec3c1cad 100644 --- a/waltz-ng/client/common/svelte/DataTypeTreeNode.svelte +++ b/waltz-ng/client/common/svelte/DataTypeTreeNode.svelte @@ -38,12 +38,16 @@ function calcDisabled(filterFn, n) { const isUnchecked = filterFn(n); - return isUnchecked // should be allowed to deselect non-concrete + const cannotCheck = isUnchecked // should be allowed to deselect non-concrete && ((!nonConcreteSelectable && !n.concrete) || n.unknown); + + const cannotUncheck = ! _.get(n, ["usageCharacteristics", "isRemovable"], true); + + return cannotCheck || cannotUncheck; } function mkTooltipProps(node) { - return node; + return Object.assign({}, node, {isEditMode: multiSelect}); } @@ -82,6 +86,7 @@ {/if} {#if node.usageCharacteristics} {/if} @@ -138,6 +143,7 @@ {/if} {#if childNode.usageCharacteristics} {/if} @@ -185,5 +191,4 @@ margin-left: 0; } - \ No newline at end of file diff --git a/waltz-ng/client/common/svelte/UsageCharacteristicsDecorator.svelte b/waltz-ng/client/common/svelte/UsageCharacteristicsDecorator.svelte index b4ff108c05..913b5db23c 100644 --- a/waltz-ng/client/common/svelte/UsageCharacteristicsDecorator.svelte +++ b/waltz-ng/client/common/svelte/UsageCharacteristicsDecorator.svelte @@ -7,24 +7,42 @@ export let isConcrete; export let isEditMode = false; - + $: isEditable = usageCharacteristics?.isRemovable; + $: isReadonly = ! isEditable; + $: hasViewerMessage = !_.isEmpty(usageCharacteristics.warningMessageForViewers); + $: hasEditorMessage = !_.isEmpty(usageCharacteristics.warningMessageForEditors); + $: hasMapping= !_.isEmpty(usageCharacteristics); + + -{#if !isConcrete && !_.isEmpty(usageCharacteristics)} +{#if !isConcrete && hasMapping} {/if} -{#if isEditMode && !_.isEmpty(usageCharacteristics.warningMessageForEditors)} +{#if isEditMode && hasEditorMessage} {/if} -{#if !isEditMode && !_.isEmpty(usageCharacteristics.warningMessageForViewers)} +{#if !isEditMode && hasViewerMessage} +{/if} +{#if !isEditMode && isReadonly && hasViewerMessage} + + + +{/if} +{#if isEditMode && isReadonly} + + + {/if} \ No newline at end of file