Skip to content

Commit 7bec5f2

Browse files
committed
#12 Display custom field form in case details page
1 parent b9e5ab6 commit 7bec5f2

File tree

8 files changed

+261
-126
lines changed

8 files changed

+261
-126
lines changed

ui/app/scripts/controllers/case/CaseDetailsCtrl.js

+111-53
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
(function() {
22
'use strict';
33

4-
angular.module('theHiveControllers').controller('CaseDetailsCtrl',
5-
function($scope, $state, $uibModal, CaseTabsSrv, UserInfoSrv, PSearchSrv) {
4+
angular.module('theHiveControllers').controller('CaseDetailsCtrl', function($scope, $state, $uibModal, CaseTabsSrv, UserInfoSrv, PSearchSrv) {
65

7-
CaseTabsSrv.activateTab($state.current.data.tab);
6+
CaseTabsSrv.activateTab($state.current.data.tab);
87

9-
$scope.isDefined = false;
10-
$scope.state = {
11-
'editing': false,
12-
'isCollapsed': true
13-
};
8+
$scope.isDefined = false;
9+
$scope.state = {
10+
'editing': false,
11+
'isCollapsed': true
12+
};
1413

15-
$scope.attachments = PSearchSrv($scope.caseId, 'case_task_log', {
16-
scope: $scope,
17-
filter: {
18-
'_and': [{
14+
$scope.attachments = PSearchSrv($scope.caseId, 'case_task_log', {
15+
scope: $scope,
16+
filter: {
17+
'_and': [
18+
{
1919
'_not': {
2020
'status': 'Deleted'
2121
}
@@ -33,57 +33,115 @@
3333
}
3434
}
3535
}
36-
}]
37-
},
38-
pageSize: 100,
39-
nparent: 1
40-
});
41-
42-
$scope.hasNoMetrics = function(caze) {
43-
return !caze.metrics || _.keys(caze.metrics).length === 0 || caze.metrics.length === 0;
44-
};
45-
46-
$scope.addMetric = function(metric) {
47-
var modalInstance = $uibModal.open({
48-
scope: $scope,
49-
templateUrl: 'views/partials/case/case.add.metric.html',
50-
controller: 'CaseAddMetricConfirmCtrl',
51-
size: '',
52-
resolve: {
53-
metric: function() {
54-
return metric;
55-
}
5636
}
57-
});
37+
]
38+
},
39+
pageSize: 100,
40+
nparent: 1
41+
});
5842

59-
modalInstance.result.then(function() {
60-
if (!$scope.caze.metrics) {
61-
$scope.caze.metrics = {};
43+
$scope.hasNoMetrics = function(caze) {
44+
return !caze.metrics || _.keys(caze.metrics).length === 0 || caze.metrics.length === 0;
45+
};
46+
47+
$scope.addMetric = function(metric) {
48+
var modalInstance = $uibModal.open({
49+
scope: $scope,
50+
templateUrl: 'views/partials/case/case.add.metric.html',
51+
controller: 'CaseAddMetadataConfirmCtrl',
52+
size: '',
53+
resolve: {
54+
data: function() {
55+
return metric;
6256
}
63-
$scope.caze.metrics[metric.name] = null;
64-
$scope.updateField('metrics', $scope.caze.metrics);
65-
$scope.updateMetricsList();
66-
});
67-
};
68-
69-
$scope.openAttachment = function(attachment) {
70-
$state.go('app.case.tasks-item', {
71-
caseId: $scope.caze.id,
72-
itemId: attachment.case_task.id
73-
});
74-
};
57+
}
58+
});
59+
60+
modalInstance.result.then(function() {
61+
if (!$scope.caze.metrics) {
62+
$scope.caze.metrics = {};
63+
}
64+
$scope.caze.metrics[metric.name] = null;
65+
$scope.updateField('metrics', $scope.caze.metrics);
66+
$scope.updateMetricsList();
67+
});
68+
};
69+
70+
$scope.openAttachment = function(attachment) {
71+
$state.go('app.case.tasks-item', {
72+
caseId: $scope.caze.id,
73+
itemId: attachment.case_task.id
74+
});
75+
};
76+
});
77+
78+
angular.module('theHiveControllers').controller('CaseCustomFieldsCtrl', function($scope, $uibModal, CustomFieldsCacheSrv) {
79+
var getTemplateCustomFields = function(customFields) {
80+
var result = [];
81+
82+
result = _.pluck(_.sortBy(_.map(customFields, function(definition, name){
83+
return {
84+
name: name,
85+
order: definition.order
86+
}
87+
}), function(item){
88+
return item.order;
89+
}), 'name');
90+
91+
return result;
7592
}
76-
);
7793

78-
angular.module('theHiveControllers').controller('CaseAddMetricConfirmCtrl', function($scope, $uibModalInstance, metric) {
79-
$scope.metric = metric;
94+
$scope.getCustomFieldName = function(fieldDef) {
95+
return 'customFields.' + fieldDef.name + '.' + fieldDef.type;
96+
};
97+
98+
$scope.addCustomField = function(customField) {
99+
var modalInstance = $uibModal.open({
100+
scope: $scope,
101+
templateUrl: 'views/partials/case/case.add.field.html',
102+
controller: 'CaseAddMetadataConfirmCtrl',
103+
size: '',
104+
resolve: {
105+
data: function() {
106+
return customField;
107+
}
108+
}
109+
});
110+
111+
modalInstance.result.then(function() {
112+
var temp = $scope.caze.customFields || {};
113+
114+
temp[customField.name] = {};
115+
temp[customField.name][customField.type] = null;
116+
temp[customField.name].order = _.keys(temp).length;
117+
118+
$scope.caze.customFields = temp;
119+
120+
$scope.updateField('customFields.', $scope.caze.customFields);
121+
$scope.updateCustomFieldsList();
122+
});
123+
};
124+
125+
$scope.updateCustomFieldsList = function() {
126+
CustomFieldsCacheSrv.all().then(function(fields) {
127+
$scope.orderedFields = getTemplateCustomFields($scope.caze.customFields);
128+
$scope.allCustomFields = _.omit(fields, _.keys($scope.caze.customFields));
129+
$scope.customFieldsAvailable = _.keys($scope.allCustomFields).length > 0;
130+
});
131+
};
132+
133+
$scope.updateCustomFieldsList();
134+
});
135+
136+
angular.module('theHiveControllers').controller('CaseAddMetadataConfirmCtrl', function($scope, $uibModalInstance, data) {
137+
$scope.data = data;
80138

81139
$scope.cancel = function() {
82-
$uibModalInstance.dismiss(metric);
140+
$uibModalInstance.dismiss(data);
83141
};
84142

85143
$scope.confirm = function() {
86-
$uibModalInstance.close(metric);
144+
$uibModalInstance.close(data);
87145
};
88146
});
89147

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<div class="modal-header bg-primary">
2+
<h3 class="modal-title">Add custom field to Case #{{caze.caseId}}</h3>
3+
</div>
4+
<div class="modal-body">
5+
<div class="vpad20">
6+
You are about to add the <strong uib-tooltip="{{data.description}}">{{data.label}}</strong> custom field to the case <strong>#{{caze.caseId}}: {{caze.title}}</strong>
7+
<br/>
8+
<br/>
9+
Are you sure you want to continue ?
10+
</div>
11+
</div>
12+
<div class="modal-footer text-left">
13+
<button class="btn btn-default" ng-click="cancel()" type="button">Cancel</button>
14+
<button class="btn btn-primary pull-right" type="button" ng-click="confirm()">Confirm</button>
15+
</div>

ui/app/views/partials/case/case.add.metric.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ <h3 class="modal-title">Add metric to Case #{{caze.caseId}}</h3>
33
</div>
44
<div class="modal-body">
55
<div class="vpad20">
6-
You are about to add the <strong uib-tooltip="{{metric.description}}">{{metric.title}}</strong> metric to the case <strong>#{{caze.caseId}}: {{caze.title}}</strong>
6+
You are about to add the <strong uib-tooltip="{{data.description}}">{{data.title}}</strong> metric to the case <strong>#{{caze.caseId}}: {{caze.title}}</strong>
77
<br/>
88
<br/>
99
Are you sure you want to continue ?

ui/app/views/partials/case/case.details.html

+3-72
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ <h4 class="vpad10 text-primary">Basic information</h4>
7171
<updatable-tags on-update="updateField('tags', getTags(newValue))" value="caze.tags"></updatable-tags>
7272
</dd>
7373
</dl>
74-
7574
<dl class="dl-horizontal clear">
7675
<dt class="pull-left">Description</dt>
7776
<dd>
@@ -80,78 +79,10 @@ <h4 class="vpad10 text-primary">Basic information</h4>
8079
</dl>
8180
</div>
8281
<div class="col-md-5 case-metrics">
83-
<div class="case-links" ng-show="links.length > 0">
84-
<h4 class="vpad10 text-primary">Related cases</h4>
85-
86-
<div>
87-
<h5>Newest (<a href ui-sref="app.case.details({caseId:links[0].id})">Case # {{newestLink.caseId}} - {{newestLink.title}}</a>)</h5>
88-
<div>
89-
Created on <strong>{{newestLink.startDate | showDate:'YYYY-MM-DD'}}</strong>
90-
</div>
91-
<div>
92-
Shares <strong><ng-pluralize count="newestLink.linksCount" when="{'one': '1 observable', 'other': '{} observables'}"></ng-pluralize></strong>
93-
<strong ng-if="newestLink.iocCount > 0" class="text-danger">
94-
(<ng-pluralize count="newestLink.iocCount" when="{'0': 'No IOCs', 'one': '1 IOC', 'other': '{} IOCs'}"></ng-pluralize>)
95-
</strong>
96-
</div>
97-
<div>
98-
Tagged as <tag-list data="newestLink.tags"></tag-list>
99-
</div>
100-
<div class="hr-line-dashed"></div>
101-
</div>
102-
103-
<div ng-show="links.length > 1">
104-
<h5>Oldest (<a href ui-sref="app.case.details({caseId:oldestLink.id})">Case # {{oldestLink.caseId}} - {{oldestLink.title}}</a>)</h5>
105-
<div>
106-
Created on <strong>{{oldestLink.startDate | showDate:'YYYY-MM-DD'}}</strong>
107-
</div>
108-
<div>
109-
Shares
110-
<strong><ng-pluralize count="oldestLink.linksCount" when="{'one': '1 observable', 'other': '{} observables'}"></ng-pluralize></strong>
111-
<strong ng-if="oldestLink.iocCount > 0" class="text-danger">
112-
(<ng-pluralize count="oldestLink.iocCount" when="{'one': '1 IOC', 'other': '{} IOCs'}"></ng-pluralize>)
113-
</strong>
114-
</div>
115-
<div>
116-
Tagged as <tag-list data="oldestLink.tags"></tag-list>
117-
</div>
118-
<div class="hr-line-dashed"></div>
119-
</div>
120-
121-
<div class="mt-xs">
122-
<a href ui-sref="app.case.links({caseId:caze.id})">
123-
See all (<ng-pluralize count="links.length" when="{'one': '1 related case', 'other': '{} related cases'}"></ng-pluralize>)
124-
</a>
125-
</div>
126-
</div>
127-
<div class="case-metrics">
128-
<h4 class="vpad10 text-primary">
129-
Metrics
130-
<span uib-dropdown class="pull-right" ng-show="metricsAvailable">
131-
<a href class="dropdown-toggle" uib-dropdown-toggle>
132-
<i class="fa fa-plus"></i>
133-
Add metric
134-
<span class="caret"></span>
135-
</a>
136-
<ul class="dropdown-menu" uib-dropdown-menu>
137-
<li ng-repeat="(key, value) in allMetrics">
138-
<a ng-click="addMetric(value)">{{value.title}}</a>
139-
</li>
140-
</ul>
141-
</span>
142-
</h4>
143-
144-
<div ng-if="hasNoMetrics(caze)">
145-
<em>No metrics need to be set</em>
146-
</div>
14782

148-
<dl class="dl-horizontal clear" ng-repeat="(k,v) in caze.metrics">
149-
<dt class="pull-left" uib-tooltip="{{metricsCache[k].description}}">{{metricsCache[k].title}}</dt>
150-
<dd>
151-
<updatable-simple-text input-type="number" on-update="updateField('metrics.' + k, newValue)" value="caze.metrics[k]"></updatable-simple-text>
152-
</dd>
153-
</dl>
154-
</div>
83+
<ng-include src="'views/partials/case/details/custom.fields.html'"></ng-include>
84+
<ng-include src="'views/partials/case/details/metrics.html'"></ng-include>
85+
<ng-include src="'views/partials/case/details/related.cases.html'"></ng-include>
15586
</div>
15687
</div>
15788

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<div class="modal-header bg-primary">
2+
<h3 class="modal-title">Add metric to Case #{{caze.caseId}}</h3>
3+
</div>
4+
<div class="modal-body">
5+
<div class="vpad20">
6+
You are about to add the <strong uib-tooltip="{{metric.description}}">{{data.title}}</strong> metric to the case <strong>#{{caze.caseId}}: {{caze.title}}</strong>
7+
<br/>
8+
<br/>
9+
Are you sure you want to continue ?
10+
</div>
11+
</div>
12+
<div class="modal-footer text-left">
13+
<button class="btn btn-default" ng-click="cancel()" type="button">Cancel</button>
14+
<button class="btn btn-primary pull-right" type="button" ng-click="confirm()">Confirm</button>
15+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<div class="case-custom-fields" ng-controller="CaseCustomFieldsCtrl">
2+
<h4 class="vpad10 text-primary">
3+
Custom fields
4+
<span uib-dropdown class="pull-right" ng-show="customFieldsAvailable">
5+
<a href class="dropdown-toggle" uib-dropdown-toggle>
6+
<i class="fa fa-plus"></i>
7+
Add Custom field
8+
<span class="caret"></span>
9+
</a>
10+
<ul class="dropdown-menu" uib-dropdown-menu>
11+
<li ng-repeat="(key, value) in allCustomFields">
12+
<a ng-click="addCustomField(value)">{{value.label}}</a>
13+
</li>
14+
</ul>
15+
</span>
16+
</h4>
17+
18+
<div ng-if="!orderedFields || orderedFields.length === 0">
19+
<em>No custom fields need to be set</em>
20+
</div>
21+
22+
<dl class="dl-horizontal clear"
23+
ng-repeat="k in orderedFields"
24+
ng-init="fieldDef = customFieldsCache[k]; customFieldValue=caze.customFields[fieldDef.name][fieldDef.type];">
25+
<dt class="pull-left" uib-tooltip="{{fieldDef.description}}">{{fieldDef.label}}</dt>
26+
<dd ng-switch="fieldDef.type">
27+
<updatable-simple-text ng-switch-when="string"
28+
input-type="text"
29+
on-update="updateField(getCustomFieldName(fieldDef), newValue)"
30+
value="customFieldValue"></updatable-simple-text>
31+
32+
<updatable-date ng-switch-when="date"
33+
on-update="updateField(getCustomFieldName(fieldDef), newValue)"
34+
value="customFieldValue"></updatable-date>
35+
36+
<updatable-simple-text ng-switch-when="number"
37+
input-type="number"
38+
on-update="updateField(getCustomFieldName(fieldDef), newValue)"
39+
value="customFieldValue"></updatable-simple-text>
40+
41+
<span ng-switch-default>Not Editable</span>
42+
</dd>
43+
</dl>
44+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<div class="case-metrics">
2+
<h4 class="vpad10 text-primary">
3+
Metrics
4+
<span uib-dropdown class="pull-right" ng-show="metricsAvailable">
5+
<a href class="dropdown-toggle" uib-dropdown-toggle>
6+
<i class="fa fa-plus"></i>
7+
Add metric
8+
<span class="caret"></span>
9+
</a>
10+
<ul class="dropdown-menu" uib-dropdown-menu>
11+
<li ng-repeat="(key, value) in allMetrics">
12+
<a ng-click="addMetric(value)">{{value.title}}</a>
13+
</li>
14+
</ul>
15+
</span>
16+
</h4>
17+
18+
<div ng-if="hasNoMetrics(caze)">
19+
<em>No metrics need to be set</em>
20+
</div>
21+
22+
<dl class="dl-horizontal clear" ng-repeat="(k,v) in caze.metrics">
23+
<dt class="pull-left" uib-tooltip="{{metricsCache[k].description}}">{{metricsCache[k].title}}</dt>
24+
<dd>
25+
<updatable-simple-text input-type="number" on-update="updateField('metrics.' + k, newValue)" value="caze.metrics[k]"></updatable-simple-text>
26+
</dd>
27+
</dl>
28+
</div>

0 commit comments

Comments
 (0)