Skip to content

Commit b0e79a1

Browse files
Merge pull request #6745 from davidwatkins73/waltz-6706-dt2
Data Type section on measurables
2 parents d756f81 + 1aca1b2 commit b0e79a1

9 files changed

Lines changed: 321 additions & 189 deletions

File tree

waltz-ng/client/assessments/components/info-tile/AssessmentWidget.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
}
7777
7878
$: assessmentCounts = $assessmentSummaryCall?.data;
79-
$: displayedDefinition = _.find(assessmentCounts, d => d.definitionId === selectedDefinition.id);
79+
$: displayedDefinition = _.find(assessmentCounts, d => d.definitionId === selectedDefinition?.id);
8080
$: availableDefinitions = _.map(assessmentCounts, d => d.definitionId);
8181
8282
$: graphData = _

waltz-ng/client/common/svelte/DataTypeTreeNode.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
4141
</script>
4242

43-
4443
{#if !isRoot}
4544
<button class="btn btn-plain"
4645
on:click={toggleExpanded}>
@@ -55,7 +54,8 @@
5554
class:unknown={node.unknown}
5655
class:deprecated={node.deprecated}
5756
disabled={calcDisabled(selectionFilter, node)}
58-
on:click={() => selectNode(node)}>
57+
on:click={() => selectNode(node)}
58+
title={node.description}>
5959
{#if multiSelect}
6060
<Icon name={calcCheckIcon(selectionFilter, node)}/>
6161
{/if}
@@ -83,7 +83,8 @@
8383
class:unknown={childNode.unknown}
8484
class:deprecated={childNode.deprecated}
8585
disabled={!nonConcreteSelectable && !childNode.concrete}
86-
on:click={() => selectNode(childNode)}>
86+
on:click={() => selectNode(childNode)}
87+
title={childNode.description}>
8788
<span class="no-wrap">
8889
{#if multiSelect}
8990
<Icon name={calcCheckIcon(selectionFilter, childNode)}/>
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
<script>
2+
import _ from "lodash";
3+
import {dataTypeStore} from "../../../svelte-stores/data-type-store";
4+
import {buildHierarchies, reduceToSelectedNodesOnly} from "../../../common/hierarchy-utils";
5+
import DataTypeTreeNode from "../../../common/svelte/DataTypeTreeNode.svelte";
6+
import DataTypeTreeSelector from "../../../common/svelte/DataTypeTreeSelector.svelte";
7+
import {entityRelationshipStore} from "../../../svelte-stores/entity-relationship-store";
8+
import {mkRel} from "../../../common/relationship-utils";
9+
import {toEntityRef} from "../../../common/entity-utils";
10+
import {onMount} from "svelte";
11+
import toasts from "../../../svelte-stores/toast-store";
12+
import {displayError} from "../../../common/error-utils";
13+
import NoData from "../../../common/svelte/NoData.svelte";
14+
import Markdown from "../../../common/svelte/Markdown.svelte";
15+
import EntityLink from "../../../common/svelte/EntityLink.svelte";
16+
import SubSection from "../../../common/svelte/SubSection.svelte";
17+
import {userStore} from "../../../svelte-stores/user-store";
18+
import {getEditRoleForEntityKind} from "../../../common/role-utils";
19+
import {entity} from "../../../common/services/enums/entity";
20+
21+
22+
const Modes = {
23+
EDIT: "EDIT",
24+
VIEW: "VIEW"
25+
};
26+
27+
const root = {};
28+
29+
export let primaryEntityReference;
30+
31+
let dataTypesCall = dataTypeStore.findAll();
32+
let selected = [];
33+
let mode = Modes.VIEW;
34+
let viewHierarchy = [];
35+
let focusedType = null;
36+
let canEdit = false;
37+
38+
let currentDataTypesCall = null;
39+
let userCall = null;
40+
41+
let restrictedEntities = [entity.MEASURABLE.key]; // Determines which parent pages the permissions check applies to
42+
43+
function reload() {
44+
currentDataTypesCall = entityRelationshipStore.findForEntity(
45+
primaryEntityReference,
46+
"SOURCE",
47+
["RELATES_TO"],
48+
true);
49+
}
50+
51+
onMount(() => {
52+
reload();
53+
userCall = userStore.load();
54+
});
55+
56+
function onFocus(evt) {
57+
focusedType = evt.detail;
58+
}
59+
60+
function onSelect(evt) {
61+
const dt = evt.detail;
62+
const alreadySelected = _.includes(selected, dt.id);
63+
64+
const remoteCall = alreadySelected
65+
? entityRelationshipStore.remove
66+
: entityRelationshipStore.create;
67+
68+
const rel = mkRel(
69+
primaryEntityReference,
70+
"RELATES_TO",
71+
toEntityRef(evt.detail));
72+
73+
const msgAction = alreadySelected
74+
? "removed"
75+
: "added";
76+
77+
remoteCall(rel)
78+
.then(() => {
79+
toasts.success(`Successfully ${msgAction} data type: ${dt.name}`);
80+
})
81+
.catch(err => {
82+
displayError(`Failed ${msgAction} data type: ${dt.name}`, err);
83+
})
84+
.finally(reload);
85+
}
86+
87+
$: selected = _
88+
.chain($currentDataTypesCall?.data)
89+
.filter(d => d.b.kind === "DATA_TYPE")
90+
.map(d => d.b.id)
91+
.value();
92+
93+
$: viewHierarchy = buildHierarchies(reduceToSelectedNodesOnly(dataTypes, selected));
94+
95+
$: selectionFilter = (d) => ! _.includes(selected, d.id);
96+
$: dataTypes = $dataTypesCall.data;
97+
98+
$: user = $userCall?.data;
99+
100+
$: requiredRole = getEditRoleForEntityKind(primaryEntityReference.kind, entity.DATA_TYPE.key);
101+
$: hasEditRoleForKind = _.includes(user?.roles, requiredRole);
102+
103+
$: canEdit = !_.includes(restrictedEntities, primaryEntityReference.kind) || hasEditRoleForKind;
104+
105+
</script>
106+
107+
{#if mode === Modes.VIEW}
108+
109+
<h4>Associated Data Types <small>View</small></h4>
110+
<div class="help-block">
111+
The tree below shows the set of data types which have been related to this entity.
112+
</div>
113+
114+
{#if viewHierarchy.length === 0}
115+
<NoData>
116+
There are <strong>no data types</strong> associated with this entity
117+
</NoData>
118+
{:else}
119+
<div class="row">
120+
<div class="col-md-7">
121+
<DataTypeTreeNode isRoot={true}
122+
node={root}
123+
childNodes={viewHierarchy}
124+
expanded={selected}
125+
on:select={onFocus}/>
126+
</div>
127+
<div class="col-md-5">
128+
{#if focusedType}
129+
<SubSection>
130+
<div slot="header">
131+
<span>{focusedType.name}</span>
132+
</div>
133+
<div slot="content">
134+
<div class="focused-type-content">
135+
<Markdown text={focusedType.description}/>
136+
</div>
137+
</div>
138+
<div slot="controls">
139+
<div class="focused-type-controls">
140+
More about: <EntityLink ref={focusedType}/>
141+
</div>
142+
</div>
143+
</SubSection>
144+
{/if}
145+
</div>
146+
</div>
147+
148+
{/if}
149+
150+
{#if canEdit}
151+
<div class="actions">
152+
<button class="btn btn-primary btn-sm"
153+
on:click={() => mode = Modes.EDIT}>
154+
Edit
155+
</button>
156+
</div>
157+
{/if}
158+
159+
{:else if mode === Modes.EDIT}
160+
161+
<h4>Associated Data Types <small>Edit</small></h4>
162+
163+
<div class="help-block">
164+
Use the tree below to edit the set of data types which have been related to this entity.
165+
As you toggle, the data will be automatically saved.
166+
</div>
167+
168+
<DataTypeTreeSelector multiSelect={true}
169+
nonConcreteSelectable={false}
170+
selectionFilter={selectionFilter}
171+
on:select={onSelect}/>
172+
173+
<div class="actions">
174+
<button class="btn-skinny"
175+
on:click={() => mode = Modes.VIEW}>
176+
&laquo; Back to view
177+
</button>
178+
</div>
179+
{/if}
180+
181+
182+
<style>
183+
.actions {
184+
padding-top: 1em;
185+
}
186+
187+
.focused-type-content {
188+
padding-left: 1em;
189+
}
190+
191+
.focused-type-controls {
192+
float: right;
193+
padding-right: 1em;
194+
}
195+
</style>

waltz-ng/client/data-types/components/related-data-types-section/related-data-types-section.html

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -17,91 +17,7 @@
1717
-->
1818

1919
<div>
20-
<waltz-section-actions>
21-
<button class="btn btn-xs btn-primary clickable"
22-
ng-if="!$ctrl.visibility.picker"
23-
ng-click="$ctrl.onShowPicker()">
24-
Edit
25-
</button>
26-
<button class="btn btn-xs btn-primary clickable"
27-
ng-if="$ctrl.visibility.picker"
28-
ng-click="$ctrl.onShowPicker()">
29-
View
30-
</button>
31-
</waltz-section-actions>
32-
33-
34-
<!-- VIEW -->
35-
<div class="row"
36-
ng-if="!$ctrl.visibility.picker">
37-
<div class="col-md-12" ng-if="$ctrl.relatedDataTypes.length > 0">
38-
<waltz-data-type-usage-tree used="$ctrl.relatedDataTypes">
39-
</waltz-data-type-usage-tree>
40-
</div>
41-
<div class="col-md-12" ng-if="$ctrl.relatedDataTypes.length === 0">
42-
<waltz-no-data>
43-
<message>
44-
<strong>No Data Types</strong>
45-
have been related
46-
</message>
47-
</waltz-no-data>
48-
</div>
49-
</div>
50-
51-
<!-- EDIT -->
52-
<div class="row"
53-
ng-if="$ctrl.visibility.picker">
54-
<div class="col-sm-5">
55-
<ul class="list-unstyled">
56-
<li ng-repeat="dataType in $ctrl.relatedDataTypes">
57-
58-
<waltz-entity-link entity-ref="dataType"
59-
ng-if="!$ctrl.visibility.picker">
60-
</waltz-entity-link>
61-
<waltz-entity-icon-label entity-ref="dataType"
62-
class="clickable"
63-
ng-click="$ctrl.onSelectDataType(dataType)"
64-
ng-if="$ctrl.visibility.picker">
65-
</waltz-entity-icon-label>
66-
</li>
67-
</ul>
68-
69-
<waltz-no-data ng-if="$ctrl.relatedDataTypes.length === 0">
70-
<message>
71-
<strong>No Data Types</strong>
72-
have been related
73-
</message>
74-
</waltz-no-data>
75-
</div>
76-
<div class="col-sm-7">
77-
<div style="border-left: 1px solid #eee; padding-left: 1em">
78-
<h4>Edit related Data Type</h4>
79-
80-
<waltz-tree-picker items="$ctrl.dataTypes"
81-
on-select="$ctrl.onSelectDataType">
82-
</waltz-tree-picker>
83-
84-
<br>
85-
86-
<button class="btn btn-sm"
87-
ng-class="{
88-
'btn-danger' : $ctrl.editMode === 'REMOVE',
89-
'btn-success' : $ctrl.editMode === 'ADD'
90-
}"
91-
ng-if="$ctrl.selectedDataType"
92-
ng-click="$ctrl.onAction()">
93-
<span ng-bind="$ctrl.editMode === 'REMOVE' ? 'Remove' : 'Add'">
94-
</span>
95-
<span ng-bind="$ctrl.selectedDataType.name">
96-
</span>
97-
</button>
98-
99-
<a class="clickable"
100-
ng-click="$ctrl.onShowPicker()">
101-
Cancel
102-
</a>
103-
</div>
104-
</div>
105-
</div>
106-
20+
<waltz-svelte-component component="$ctrl.RelatedDataTypesSection"
21+
primary-entity-reference="$ctrl.parentEntityRef">
22+
</waltz-svelte-component>
10723
</div>

0 commit comments

Comments
 (0)