rsanchez
2014-10-16 4d18a46ee3ada751517f9bf767d5057a3bf5eb9e
#2021 feature - Added Pack management (in Beta) 
8 files modified
changed files
securis/src/main/java/net/curisit/securis/db/Pack.java patch | view | blame | history
securis/src/main/resources/db/schema.sql patch | view | blame | history
securis/src/main/resources/static/admin.html patch | view | blame | history
securis/src/main/resources/static/js/admin.js patch | view | blame | history
securis/src/main/resources/static/js/licenses.js patch | view | blame | history
securis/src/main/resources/static/js/login.js patch | view | blame | history
securis/src/main/resources/static/js/main.js patch | view | blame | history
securis/src/main/resources/static/licenses.html patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/Pack.java
....@@ -73,6 +73,16 @@
7373 @Column(name = "num_licenses")
7474 @JsonProperty("num_licenses")
7575 private int numLicenses;
76
+
77
+ @Column(name = "init_valid_date")
78
+ @JsonProperty("init_valid_date")
79
+ private Date initValidDate;
80
+
81
+ @Column(name = "end_valid_date")
82
+ @JsonProperty("end_valid_date")
83
+ private Date endValidDate;
84
+
85
+ private String status;
7686
7787 @Column(name = "license_preactivation")
7888 @JsonProperty("license_preactivation")
....@@ -239,7 +249,7 @@
239249
240250 @JsonProperty("created_by_name")
241251 public String getCreatedByname() {
242
- return createdBy == null ? null : String.format("%s %s (%s)", createdBy.getFirstName(), createdBy.getLastName(), createdBy.getUsername());
252
+ return createdBy == null ? null : String.format("%s %s (%s)", createdBy.getFirstName(), createdBy.getLastName() != null ? createdBy.getLastName() : "", createdBy.getUsername());
243253 }
244254
245255 @JsonProperty("licensetype_code")
....@@ -271,6 +281,30 @@
271281 this.metadata = metadata;
272282 }
273283
284
+ public String getStatus() {
285
+ return status;
286
+ }
287
+
288
+ public void setStatus(String status) {
289
+ this.status = status;
290
+ }
291
+
292
+ public Date getInitValidDate() {
293
+ return initValidDate;
294
+ }
295
+
296
+ public void setInitValidDate(Date initValidDate) {
297
+ this.initValidDate = initValidDate;
298
+ }
299
+
300
+ public Date getEndValidDate() {
301
+ return endValidDate;
302
+ }
303
+
304
+ public void setEndValidDate(Date endValidDate) {
305
+ this.endValidDate = endValidDate;
306
+ }
307
+
274308 @Override
275309 public boolean equals(Object obj) {
276310 if (!(obj instanceof Pack))
securis/src/main/resources/db/schema.sql
....@@ -75,6 +75,9 @@
7575 id INT NOT NULL auto_increment,
7676 code VARCHAR(50) NOT NULL ,
7777 num_licenses INT NOT NULL ,
78
+ init_valid_date DATE NOT NULL default today(),
79
+ end_valid_date DATE NOT NULL default today(),
80
+ status VARCHAR(2) NOT NULL default 'PE',
7881 comments VARCHAR(1024) NULL ,
7982 license_type_id INT NOT NULL,
8083 organization_id INT NOT NULL,
securis/src/main/resources/static/admin.html
....@@ -77,7 +77,7 @@
7777 </td>
7878 <td>
7979 <input type="text" id="md_value" name="md_value" placeholder=""
80
- class="form-control" ng-model="row_md['value']" ng-required="row_md['mandatory']" ng-maxlength="150" />
80
+ class="form-control" ng-model="row_md['value']" ng-required="false" ng-maxlength="150" />
8181 </td>
8282 <td>
8383 <input type="checkbox" id="md_mandatory" name="md_mandatory" ng-disabled="!field.allow_creation"
securis/src/main/resources/static/js/admin.js
....@@ -38,7 +38,9 @@
3838 '$store',
3939 '$L',
4040 function($scope, $http, toaster, Catalogs, $store, $L) {
41
- $scope.showForm = false;
41
+ $store.set('location', '/admin');
42
+
43
+ $scope.showForm = false;
4244 $scope.isNew = false;
4345 $scope.formu = {};
4446 $scope.catalogIndex = 0;
....@@ -145,8 +147,6 @@
145147 $('select').val(null);
146148 $scope.$parent.formu = {};
147149
148
- console.log("Refs for new form:");
149
- console.log($scope.refs);
150150 var fields = Catalogs.getMetadata().fields;
151151 fields.forEach(function(field) {
152152 if (!field.listingOnly) $scope.$parent.formu[field.name] = null;
securis/src/main/resources/static/js/licenses.js
....@@ -74,7 +74,8 @@
7474 '$store',
7575 '$L',
7676 function($scope, $http, toaster, $store, $L) {
77
-
77
+ $store.set('location', '/licenses');
78
+
7879 $scope.maxLengthErrorMsg = function(displayname, fieldMaxlength) {
7980 return $L.get("{0} length is too long (max: {1}).", $L.get(displayname), fieldMaxlength);
8081 }
....@@ -101,6 +102,13 @@
101102 var packResource = $resource('/pack/:packId', {
102103 packId : '@id'
103104 });
105
+ var PACK_STATUS = [
106
+ {id: 'PE', label: $L.get('Pending')},
107
+ {id: 'AC', label: $L.get('Active')},
108
+ {id: 'OH', label: $L.get('On Hold')},
109
+ {id: 'EX', label: $L.get('Expired')},
110
+ {id: 'CA', label: $L.get('Cancelled')}
111
+ ];
104112 $scope.mandatory = {
105113 code: true,
106114 num_licenses: true,
....@@ -116,6 +124,7 @@
116124 var refFields = [{resource: 'organization', name: 'organization_id'},{resource: 'licensetype', name: 'license_type_id'}];
117125 Catalogs.loadRefs(function(refs) {
118126 $scope.refs = refs;
127
+ $scope.refs['pack_status'] = PACK_STATUS;
119128 }, refFields);
120129 });
121130
....@@ -128,12 +137,28 @@
128137
129138 $scope.packs = packResource.query();
130139
131
- $scope.save = function() {
140
+ var _savePackData = function() {
132141 var _success = function() {
133142 if (!$scope.isNew) $scope.showForm = false;
134143 $scope.packs = packResource.query();
144
+ toaster.pop('success', Catalogs.getName(), $L.get("Pack '{0}' {1} successfully", $scope.pack.code, $scope.isNew ? $L.get("created") : $L.get("updated")));
135145 }
136
- packResource.save($scope.pack, _success)
146
+ var _error = function(error) {
147
+ console.log(error);
148
+ toaster.pop('error', Catalogs.getName(), $L.get("Error {0} pack '{1}'. Reason: {2}", $scope.isNew ? $L.get("creating") : $L.get("updating"), $scope.pack.code, $L.get(error.headers('X-SECURIS-ERROR'))));
149
+ }
150
+ packResource.save($scope.pack, _success, _error);
151
+ }
152
+ $scope.save = function() {
153
+ if ($scope.pack.num_activations > 0) {
154
+ BootstrapDialog.confirm($L.get("The pack '{0}' has active licenses, Do you want to modify it ?", $scope.pack.code), function(answer){
155
+ if (answer) {
156
+ _savePackData();
157
+ }
158
+ });
159
+ } else {
160
+ _savePackData();
161
+ }
137162 }
138163
139164 $scope.newPack = function() {
....@@ -141,9 +166,10 @@
141166 $scope.showForm = true;
142167 $scope.pack = {
143168 license_preactivation: true,
169
+ status: 'PE',
144170 num_licenses: 1,
145
- license_type_id: !$scope.refs.license_type_id || !$scope.refs.license_type_id.length ? null : $scope.refs.license_type_id[0].id,
146
- organization_id: !$scope.refs.organization_id || !$scope.refs.organization_id.length ? null : $scope.refs.organization_id[0].id
171
+ license_type_id: null,
172
+ organization_id: null //!$scope.refs.organization_id || !$scope.refs.organization_id.length ? null : $scope.refs.organization_id[0].id
147173 }
148174 setTimeout(function() {
149175 $('#code').focus();
....@@ -188,6 +214,33 @@
188214 $scope.$parent.$broadcast('pack_changed', pack);
189215 }
190216
217
+ $scope.createMetadataRow = function() {
218
+ if (!$scope.formu.metadata) {
219
+ $scope.formu.metadata = [];
220
+ }
221
+ $scope.formu.metadata.push({key: '', value: '', mandatory: true});
222
+ }
223
+ $scope.removeMetadataKey = function(row_md) {
224
+ $scope.formu.metadata.splice( $scope.formu.metadata.indexOf(row_md), 1 );
225
+ }
226
+ $scope.updateMetadata = function() {
227
+ // Called when Application ID change in current field
228
+ var newLTId = $scope.pack['license_type_id'];
229
+ if (newLTId) {
230
+ // Only if there is a "valid" value selected we should update the metadata
231
+ Catalogs.getResource('licensetype').get({licenseTypeId: newLTId}).$promise.then(function(lt) {
232
+ $scope.pack.metadata = [];
233
+ lt.metadata.forEach(function(md) {
234
+ $scope.pack.metadata.push({
235
+ key: md.key,
236
+ value: md.value,
237
+ readonly: !!md.value,
238
+ mandatory: md.mandatory
239
+ });
240
+ });
241
+ });
242
+ }
243
+ }
191244 } ]);
192245
193246 app.controller('LicensesCtrl', [
securis/src/main/resources/static/js/login.js
....@@ -23,14 +23,18 @@
2323 }).
2424 success(function(data, status, headers, config) {
2525 toaster.pop('success', $L.get('Login successful'), $L.get('User {0} has logged in application', $scope.username), 1500);
26
- $location.path('/licenses');
26
+ var location = $store.get('location') || '/licenses';
27
+
28
+ $location.path(location);
2729 $store.put('username', $scope.username);
2830 $store.put('token', data.token);
2931 $http.defaults.headers.common['X-SECURIS-TOKEN'] = data.token;
3032 }).
3133 error(function(data, status, headers, config) {
32
- if (status === 403 /* forbidden */) {
33
- toaster.pop('error', $L.get('Login error'), $L.get('Invalid credentials'), 3000);
34
+ if (status === 403 /* forbidden */ || status === 401 /* unauthorized */) {
35
+ toaster.pop('error', $L.get('Login error'), $L.get('Invalid credentials'), 2000);
36
+ } else if (status === 418 /* Teapot */) {
37
+ toaster.pop('error', $L.get('Login error'), $L.get(headers['X-SECURIS-ERROR-MSG']), 2000);
3438 } else {
3539 console.error(data + " status: "+ status);
3640 toaster.pop('error', $L.get('Unexpected Login error'), $L.get('Unexpected error HTTP ({0}) accessing to server. Contact with the administrator.', status), 5000);
securis/src/main/resources/static/js/main.js
....@@ -78,10 +78,14 @@
7878 // configure html5 to get links working on jsfiddle
7979 $locationProvider.html5Mode(true);
8080 $httpProvider.interceptors.push('securisHttpInterceptor');
81
- });
81
+ });
82
+
8283 m.controller('MainCtrl', ['$scope', '$http', '$location', '$L', '$store',
8384 function($scope, $http, $location, $L, $store) {
8485
86
+ $scope.currentRoute = null;
87
+ console.log('Current location: ' + $location);
88
+ console.log($location);
8589 $location.path('/login');
8690 if ($store.get('token') != null) {
8791
....@@ -91,8 +95,10 @@
9195 }
9296 }).success(function(data) {
9397 if (data.valid) {
94
- $http.defaults.headers.common['X-SECURIS-TOKEN'] = $store.get('token');
95
- $location.path('/licenses');
98
+ $http.defaults.headers.common['X-SECURIS-TOKEN'] = $store.get('token');
99
+ var location = $store.get('location') || '/licenses';
100
+
101
+ $location.path(location);
96102 $store.set('user', data.user);
97103 }
98104 });
securis/src/main/resources/static/licenses.html
....@@ -21,15 +21,16 @@
2121 </a></li>
2222 </ul>
2323 <div class="navbar-form navbar-right form-group">
24
- <span class="input-group input-group-sm">
25
- <div class="input-group-addon" style="width: 28px;" >
24
+ <span class="input-group input-group-sm">
25
+ <div class="input-group-addon" style="width: 28px;">
2626 <span class=" glyphicon glyphicon-search"></span>
27
+ </div> <input type="text" class="form-control" placeholder="Search"
28
+ ng-model="$searchPacksText">
29
+ <div class="input-group-addon" style="width: 20px;">
30
+ <span class=" glyphicon glyphicon-remove"
31
+ ng-click="$searchPacksText = '';"></span>
2732 </div>
28
- <input type="text" class="form-control" placeholder="Search" ng-model="$searchPacksText">
29
- <div class="input-group-addon" style="width: 20px;" >
30
- <span class=" glyphicon glyphicon-remove" ng-click="$searchPacksText = '';"></span>
31
- </div>
32
- </span>
33
+ </span>
3334 </div>
3435 </div>
3536 </div>
....@@ -63,6 +64,32 @@
6364 </div>
6465
6566 <div class="form-group">
67
+ <label class="col-md-3 control-label" for="code" i18n>Validity (from - to)</label>
68
+ <div class="col-md-4">
69
+ <input type="date" id="init_valid_date" name="init_valid_date" placeholder=""
70
+ class="form-control" ng-model="pack.init_valid_date"
71
+ ng-required="mandatory.init_valid_date" />
72
+ <div class="alert inline-alert alert-warning"
73
+ ng-show="packForm.initValidDate.$invalid">
74
+ <span class="glyphicon glyphicon-warning-sign"></span>
75
+ <span ng-show="packForm.init_valid_date.$error.required"
76
+ ng-bind="mandatoryFieldErrorMsg('Init valid date')"></span>
77
+ </div>
78
+ </div>
79
+ <div class="col-md-4">
80
+ <input type="date" id="end_valid_date" name="end_valid_date" placeholder=""
81
+ class="form-control" ng-model="pack.end_valid_date"
82
+ ng-required="mandatory.end_valid_date" />
83
+ <div class="alert inline-alert alert-warning"
84
+ ng-show="packForm.initValidDate.$invalid">
85
+ <span class="glyphicon glyphicon-warning-sign"></span>
86
+ <span ng-show="packForm.end_valid_date.$error.required"
87
+ ng-bind="mandatoryFieldErrorMsg('End valid date')"></span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+
92
+ <div class="form-group">
6693 <label class="col-md-3 control-label" for="num_licenses" i18n>Num.
6794 Licenses</label>
6895 <div class="col-md-8">
....@@ -80,15 +107,33 @@
80107 </div>
81108 </div>
82109
110
+ <div class="form-group" ng-if="!isNew">
111
+ <label class="col-md-3 control-label" for="status" i18n>Status</label>
112
+ <div class="col-md-8">
113
+ <select class="form-control" id="status"
114
+ ng-required="mandatory.status"
115
+ ng-model="pack.status"
116
+ ng-options="o.id as o.label for o in refs.pack_status">
117
+ </select>
118
+ <div class="alert inline-alert alert-warning"
119
+ ng-show="packForm.status.$invalid">
120
+ <span class="glyphicon glyphicon-warning-sign"></span> <span
121
+ ng-show="packForm.status.$error.required"
122
+ ng-bind="mandatoryFieldErrorMsg('Status')"></span>
123
+ </div>
124
+ </div>
125
+ </div>
126
+
83127 <div class="form-group">
84128 <label class="col-md-3 control-label" for="license_type_id" i18n>License
85129 type</label>
86130 <div class="col-md-8">
87
- <select class="form-control"
131
+ <select class="form-control" id="license_type_id"
132
+ ng-change="updateMetadata()"
88133 ng-required="mandatory.license_type_id"
89134 ng-model="pack.license_type_id"
90135 ng-options="o.id as o.label for o in refs.license_type_id">
91
-
136
+
92137 </select>
93138 <div class="alert inline-alert alert-warning"
94139 ng-show="packForm.license_type_id.$invalid">
....@@ -143,17 +188,42 @@
143188 </div>
144189
145190 <div class="form-group" ng-if="!isNew">
146
- <label class="col-md-3 control-label">Created by</label>
191
+ <label i18n class="col-md-3 control-label">Created by</label>
147192 <div class="col-md-8">
148193 <p class="form-control-static" ng-bind="pack.created_by_name"></p>
149194 </div>
150195 </div>
151196
152197 <div class="form-group" ng-if="!isNew">
153
- <label class="col-md-3 control-label">Creation date</label>
198
+ <label i18n class="col-md-3 control-label">Creation date</label>
154199 <div class="col-md-8">
155200 <p class="form-control-static"
156201 ng-bind="pack.creationTimestamp | date:'medium'"></p>
202
+ </div>
203
+ </div>
204
+
205
+ <div class="form-group">
206
+ <label class="col-md-3 control-label" i18n>Metadata</label>
207
+ <div class="col-md-8">
208
+ <table class="table table-hover table-condensed">
209
+ <thead>
210
+ <tr>
211
+ <th i18n>Key</th>
212
+ <th i18n>Value</th>
213
+ </tr>
214
+ </thead>
215
+ <tbody>
216
+ <tr ng-repeat="row_md in pack.metadata">
217
+ <td><input type="text" id="md_key" name="md_key"
218
+ placeholder="" ng-readonly="true"
219
+ class="form-control" ng-model="row_md['key']"
220
+ ng-required="true" /></td>
221
+ <td><input type="text" id="md_value" name="md_value" ng-readonly="row_md['readonly']"
222
+ placeholder="" class="form-control" ng-model="row_md['value']"
223
+ ng-required="row_md['mandatory']" ng-maxlength="150" /></td>
224
+ </tr>
225
+ </tbody>
226
+ </table>
157227 </div>
158228 </div>
159229
....@@ -213,33 +283,34 @@
213283 <nav class="navbar navbar-default navbar-static-top"
214284 ng-disabled="!currentPack">
215285 <div class="container-fluid">
216
- <!-- Brand and toggle get grouped for better mobile display -->
217
- <div class="navbar-header success">
218
- <a class="navbar-brand" i18n>Licenses</a>
219
- </div>
286
+ <!-- Brand and toggle get grouped for better mobile display -->
287
+ <div class="navbar-header success">
288
+ <a class="navbar-brand" i18n>Licenses</a>
289
+ </div>
220290
221
- <!-- Collect the nav links, forms, and other content for toggling -->
222
- <div class="collapse navbar-collapse"
223
- id="bs-example-navbar-collapse-1">
224
- <ul class="nav navbar-nav">
225
- <li><a i18n ng-click="newLicense()"><span
226
- class="glyphicon glyphicon-plus"></span> New</a></li>
227
- <li><a i18n ng-click="cancel()"> <span
228
- class="glyphicon glyphicon-ban-circle"></span> Cancel
229
- </a></li>
230
- </ul>
231
- <div class="navbar-form navbar-right form-group">
232
- <span class="input-group input-group-sm">
233
- <div class="input-group-addon" style="width: 28px;" >
291
+ <!-- Collect the nav links, forms, and other content for toggling -->
292
+ <div class="collapse navbar-collapse"
293
+ id="bs-example-navbar-collapse-1">
294
+ <ul class="nav navbar-nav">
295
+ <li><a i18n ng-click="newLicense()"><span
296
+ class="glyphicon glyphicon-plus"></span> New</a></li>
297
+ <li><a i18n ng-click="cancel()"> <span
298
+ class="glyphicon glyphicon-ban-circle"></span> Cancel
299
+ </a></li>
300
+ </ul>
301
+ <div class="navbar-form navbar-right form-group">
302
+ <span class="input-group input-group-sm">
303
+ <div class="input-group-addon" style="width: 28px;">
234304 <span class=" glyphicon glyphicon-search"></span>
305
+ </div> <input type="text" class="form-control" placeholder="Search"
306
+ ng-model="$searchLicensesText">
307
+ <div class="input-group-addon" style="width: 20px;">
308
+ <span class=" glyphicon glyphicon-remove"
309
+ ng-click="$searchLicensesText = '';"></span>
235310 </div>
236
- <input type="text" class="form-control" placeholder="Search" ng-model="$searchLicensesText">
237
- <div class="input-group-addon" style="width: 20px;" >
238
- <span class=" glyphicon glyphicon-remove" ng-click="$searchLicensesText = '';"></span>
239
- </div>
240
- </span>
311
+ </span>
241312 </div>
242
- </div>
313
+ </div>
243314 </div>
244315 </nav>
245316