Roberto Sánchez
2014-01-22 79121484b7e6f721f5435a102018152a164ed655
#395 feature - Implemented pack section
11 files modified
changed files
securis/src/main/java/net/curisit/securis/db/License.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/LicenseType.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/Pack.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/db/User.java patch | view | blame | history
securis/src/main/java/net/curisit/securis/services/PackResource.java patch | view | blame | history
securis/src/main/resources/db/schema.sql patch | view | blame | history
securis/src/main/resources/static/js/admin.js patch | view | blame | history
securis/src/main/resources/static/js/catalogs.js patch | view | blame | history
securis/src/main/resources/static/js/licenses.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/License.java
....@@ -55,7 +55,7 @@
5555
5656 private int status;
5757
58
- @JoinColumn(name = "full_name")
58
+ @Column(name = "full_name")
5959 private String fullName;
6060
6161 private String email;
securis/src/main/java/net/curisit/securis/db/LicenseType.java
....@@ -57,6 +57,10 @@
5757 return id;
5858 }
5959
60
+ public void setId(Integer id) {
61
+ this.id = id;
62
+ }
63
+
6064 public String getName() {
6165 return name;
6266 }
securis/src/main/java/net/curisit/securis/db/Pack.java
....@@ -8,6 +8,7 @@
88 import javax.persistence.Column;
99 import javax.persistence.Entity;
1010 import javax.persistence.FetchType;
11
+import javax.persistence.GeneratedValue;
1112 import javax.persistence.Id;
1213 import javax.persistence.JoinColumn;
1314 import javax.persistence.ManyToOne;
....@@ -31,15 +32,18 @@
3132 @Table(name = "pack")
3233 @NamedQueries(
3334 { @NamedQuery(name = "list-packs", query = "SELECT pa FROM Pack pa"),//
34
- @NamedQuery(name = "list-packs-by-org", query = "SELECT pa FROM Pack pa where pa.organization = :organization") })
35
+ @NamedQuery(name = "list-packs-by-orgs", query = "SELECT pa FROM Pack pa where pa.organization.id in :list_ids") })
3536 public class Pack implements Serializable {
3637
3738 private static final long serialVersionUID = 1L;
3839
3940 @Id
41
+ @GeneratedValue
4042 private int id;
4143
4244 private String code;
45
+
46
+ private String comments;
4347
4448 @Column(name = "creation_timestamp")
4549 private Date creationTimestamp;
....@@ -63,7 +67,8 @@
6367 @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "pack")
6468 private Set<License> licenses;
6569
66
- @JoinColumn(name = "num_licenses")
70
+ @Column(name = "num_licenses")
71
+ @JsonProperty("num_licenses")
6772 private int numLicenses;
6873
6974 public int getId() {
....@@ -190,6 +195,16 @@
190195 }
191196
192197 @JsonProperty("license_type_id")
198
+ public void setLicTypeId(Integer idLT) {
199
+ if (idLT == null) {
200
+ licenseType = null;
201
+ } else {
202
+ licenseType = new LicenseType();
203
+ licenseType.setId(idLT);
204
+ }
205
+ }
206
+
207
+ @JsonProperty("license_type_id")
193208 public Integer getLicTypeId() {
194209 return licenseType == null ? null : licenseType.getId();
195210 }
....@@ -205,9 +220,22 @@
205220 createdBy.setUsername(username);
206221 }
207222
223
+ @JsonProperty("created_by_name")
224
+ public String getCreatedByname() {
225
+ return createdBy == null ? null : String.format("%s %s", createdBy.getFirstName(), createdBy.getFirstName());
226
+ }
227
+
208228 @JsonProperty("licensetype_code")
209229 public String getLicenseTypcode() {
210230 return licenseType == null ? null : licenseType.getCode();
211231 }
212232
233
+ public String getComments() {
234
+ return comments;
235
+ }
236
+
237
+ public void setComments(String comments) {
238
+ this.comments = comments;
239
+ }
240
+
213241 }
securis/src/main/java/net/curisit/securis/db/User.java
....@@ -52,7 +52,6 @@
5252
5353 private int roles;
5454
55
- @JsonProperty(value = "last_login")
5655 @Column(name = "last_login")
5756 private Date lastLogin;
5857
securis/src/main/java/net/curisit/securis/services/PackResource.java
....@@ -1,8 +1,10 @@
11 package net.curisit.securis.services;
22
3
+import java.security.Principal;
34 import java.util.Date;
45 import java.util.List;
56
7
+import javax.annotation.security.RolesAllowed;
68 import javax.inject.Inject;
79 import javax.inject.Provider;
810 import javax.persistence.EntityManager;
....@@ -23,10 +25,10 @@
2325 import javax.ws.rs.core.Response.Status;
2426
2527 import net.curisit.integrity.commons.Utils;
26
-import net.curisit.integrity.exception.CurisException;
2728 import net.curisit.securis.DefaultExceptionHandler;
2829 import net.curisit.securis.db.Pack;
29
-import net.curisit.securis.db.User;
30
+import net.curisit.securis.security.BasicSecurityContext;
31
+import net.curisit.securis.security.Securable;
3032 import net.curisit.securis.utils.TokenHelper;
3133
3234 import org.slf4j.Logger;
....@@ -59,17 +61,35 @@
5961 */
6062 @GET
6163 @Path("/")
64
+ @Securable
6265 @Produces(
6366 { MediaType.APPLICATION_JSON })
64
- public Response index() {
67
+ public Response index(@Context BasicSecurityContext bsc) {
6568 log.info("Getting packs list ");
6669
6770 EntityManager em = emProvider.get();
68
- TypedQuery<Pack> q = em.createNamedQuery("list-packs-by-orgs", Pack.class);
71
+ // TypedQuery<Pack> q = em.createNamedQuery("list-packs-by-orgs", Pack.class);
72
+
73
+ TypedQuery<Pack> q;
74
+ if (bsc.isUserInRole(BasicSecurityContext.ROL_ADMIN)) {
75
+ log.info("Getting all packs for user: " + bsc.getUserPrincipal());
76
+ q = em.createNamedQuery("list-packs", Pack.class);
77
+ } else {
78
+ q = em.createNamedQuery("list-packs-by-orgs", Pack.class);
79
+ if (bsc.getOrganizationsIds() == null)
80
+ Response.ok().build();
81
+ // log.info("Getting only {} orgs for user: {}", securityContext.getOrganizationsIds(), securityContext.getUserPrincipal());
82
+ q.setParameter("list_ids", bsc.getOrganizationsIds());
83
+ }
6984
7085 List<Pack> list = q.getResultList();
7186
7287 return Response.ok(list).build();
88
+ }
89
+
90
+ private Response generateErrorUnathorizedAccess(Pack pack, Principal user) {
91
+ log.error("Pack with id {} not accesible by user {}", pack, user);
92
+ return Response.status(Status.UNAUTHORIZED).header(DefaultExceptionHandler.ERROR_MESSAGE_HEADER, "Unathorized access to pack").build();
7393 }
7494
7595 /**
....@@ -78,9 +98,10 @@
7898 */
7999 @GET
80100 @Path("/{packId}")
101
+ @Securable
81102 @Produces(
82103 { MediaType.APPLICATION_JSON })
83
- public Response get(@PathParam("packId") String packId, @HeaderParam(TokenHelper.TOKEN_HEADER_PÀRAM) String token) {
104
+ public Response get(@PathParam("packId") String packId, @Context BasicSecurityContext bsc) {
84105 log.info("Getting pack data for id: {}: ", packId);
85106 if (packId == null || packId.equals("")) {
86107 log.error("Pack ID is mandatory");
....@@ -88,16 +109,23 @@
88109 }
89110
90111 EntityManager em = emProvider.get();
91
- Pack lt = em.find(Pack.class, Integer.parseInt(packId));
92
- if (lt == null) {
112
+ Pack pack = em.find(Pack.class, Integer.parseInt(packId));
113
+ if (pack == null) {
93114 log.error("Pack with id {} not found in DB", packId);
94115 return Response.status(Status.NOT_FOUND).build();
95116 }
96
- return Response.ok(lt).build();
117
+ if (bsc.isUserInRole(BasicSecurityContext.ROL_ADVANCE)) {
118
+ if (bsc.getOrganizationsIds() == null || !bsc.getOrganizationsIds().contains(pack.getOrgId())) {
119
+ return generateErrorUnathorizedAccess(pack, bsc.getUserPrincipal());
120
+ }
121
+ }
122
+ return Response.ok(pack).build();
97123 }
98124
99125 @POST
100126 @Path("/")
127
+ @Securable
128
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
101129 @Consumes(MediaType.APPLICATION_JSON)
102130 @Produces(
103131 { MediaType.APPLICATION_JSON })
....@@ -112,21 +140,12 @@
112140 return Response.ok(pack).build();
113141 }
114142
115
- private User getUser(String username, EntityManager em) throws CurisException {
116
- User user = null;
117
- if (username != null) {
118
- user = em.find(User.class, username);
119
- if (user == null) {
120
- throw new CurisException("User not found");
121
- }
122
- }
123
- return user;
124
- }
125
-
126143 @PUT
127144 @POST
128145 @Path("/{packId}")
129146 @Transactional
147
+ @Securable
148
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
130149 @Consumes(MediaType.APPLICATION_JSON)
131150 @Produces(
132151 { MediaType.APPLICATION_JSON })
....@@ -141,6 +160,8 @@
141160
142161 @DELETE
143162 @Path("/{packId}")
163
+ @Securable
164
+ @RolesAllowed(BasicSecurityContext.ROL_ADMIN)
144165 @Transactional
145166 @Produces(
146167 { MediaType.APPLICATION_JSON })
securis/src/main/resources/db/schema.sql
....@@ -55,9 +55,10 @@
5555
5656 drop table IF EXISTS pack;
5757 CREATE TABLE IF NOT EXISTS pack (
58
- id INT NOT NULL,
58
+ id INT NOT NULL auto_increment,
5959 code VARCHAR(50) NOT NULL ,
6060 num_licenses INT NOT NULL ,
61
+ comments VARCHAR(1024) NULL ,
6162 license_type_id INT NOT NULL,
6263 organization_id INT NOT NULL,
6364 created_by varchar(45) NULL ,
....@@ -66,13 +67,14 @@
6667
6768 drop table IF EXISTS license;
6869 CREATE TABLE IF NOT EXISTS license (
69
- id INT NOT NULL,
70
+ id INT NOT NULL auto_increment,
7071 code VARCHAR(100) NOT NULL ,
7172 request_data VARCHAR(1024) NULL ,
7273 license_data VARCHAR(1024) NULL ,
7374 pack_id INT NOT NULL,
7475 full_name VARCHAR(150) NULL,
7576 email VARCHAR(100) NOT NULL,
77
+ comments VARCHAR(1024) NULL ,
7678 creation_timestamp DATETIME NOT NULL ,
7779 send_timestamp DATETIME NULL ,
7880 modification_timestamp DATETIME NULL ,
securis/src/main/resources/static/js/admin.js
....@@ -4,7 +4,8 @@
44 var app = angular.module('securis');
55
66 var HTTP_ERRORS = {
7
- 403: "Forbidden action",
7
+ 401: "Unathorized action",
8
+ 403: "Forbidden action",
89 500: "Server error",
910 404: "Element not found"
1011 }
....@@ -99,8 +100,8 @@
99100
100101 } ]);
101102
102
- app.controller('CatalogFormCtrl', [ '$scope', '$http', 'toaster', 'Catalogs',
103
- function($scope, $http, toaster, Catalogs) {
103
+ app.controller('CatalogFormCtrl', [ '$scope', '$http', 'toaster', 'Catalogs', '$L',
104
+ function($scope, $http, toaster, Catalogs, $L) {
104105 $scope.scope = $scope;
105106 console.log('Form: currentCatalog:' + $scope.cataLogIndex);
106107
securis/src/main/resources/static/js/catalogs.js
....@@ -2,8 +2,8 @@
22 'use strict';
33
44 /*
5
- * Catalogs module
6
- */
5
+ * Catalogs module
6
+ */
77
88 angular
99 .module('catalogs', [ 'ngResource' ])
....@@ -44,6 +44,12 @@
4444 })
4545 }
4646 this.init = function() {
47
+ if (_metadata) {
48
+ console.debug('Catalogs already initilizated');
49
+ var defer = $q.defer();
50
+ defer.resolve(_metadata);
51
+ return defer.promise;
52
+ }
4753 return _list();
4854 }
4955 this.getList = function() {
....@@ -59,7 +65,7 @@
5965 if (res === undefined)
6066 return _current ? resources[_current.resource]
6167 : null;
62
- return _current ? resources[res] : null;
68
+ return resources[res];
6369 }
6470 this.getPk = function(catalogMetadata) {
6571 if (!catalogMetadata)
....@@ -72,14 +78,14 @@
7278 return null;
7379 }
7480 /**
75
- * Returns catalog metadata
76
- *
77
- * @param index:
78
- * Return current catalog if
79
- * undefined, if string It find the
80
- * catalog by resoource name if
81
- * number it find it by position
82
- */
81
+ * Returns catalog metadata
82
+ *
83
+ * @param index:
84
+ * Return current catalog if
85
+ * undefined, if string It find the
86
+ * catalog by resoource name if
87
+ * number it find it by position
88
+ */
8389 this.getMetadata = function(index) {
8490 if (!_metadata)
8591 throw new Error(
....@@ -105,14 +111,14 @@
105111 _current = _metadata[index];
106112 }
107113 /***********************************************
108
- * Catalog fields methods *
109
- **********************************************/
114
+ * Catalog fields methods *
115
+ **********************************************/
110116
111117 /**
112
- * Returns the first field in form that should
113
- * get the focus. We find the first field that
114
- * is not read only
115
- */
118
+ * Returns the first field in form that should
119
+ * get the focus. We find the first field that
120
+ * is not read only
121
+ */
116122 this.getFFF = this.getFirstFocusableField = function() {
117123 if (!_current)
118124 throw new Error(
....@@ -126,16 +132,17 @@
126132 }
127133
128134 /**
129
- * Find the field by name or position
130
- */
131
- this.getField = function(key) {
132
- if (!_current)
135
+ * Find the field by name or position
136
+ */
137
+ this.getField = function(key, catalog) {
138
+ catalog = catalog || _current;
139
+ if (!catalog)
133140 throw new Error(
134141 'There is no current catalog selected');
135142 var index = -1;
136143 if (typeof key === 'string') {
137
- for (var i = _current.fields.length - 1; i >= 0
138
- && _current.fields[i].name !== key; i--)
144
+ for (var i = catalog.fields.length - 1; i >= 0
145
+ && catalog.fields[i].name !== key; i--)
139146 ;
140147 index = i;
141148 } else {
....@@ -144,12 +151,12 @@
144151 }
145152
146153 return index === -1 ? {}
147
- : _current.fields[index];
154
+ : catalog.fields[index];
148155 }
149156
150157 /***********************************************
151
- * Catalog resource operations on server *
152
- **********************************************/
158
+ * Catalog resource operations on server *
159
+ **********************************************/
153160
154161 function _success(response) {
155162 console.log('$resource')
....@@ -214,16 +221,18 @@
214221 refs[field.name] = comboData;
215222 })
216223 }
217
- this.loadRefs = function(refs) {
218
- if (!_current)
219
- throw new Error(
220
- 'There is no current catalog selected');
221
- var refsFields = [];
222
- _current.fields.forEach(function(f) {
223
- if (f.resource)
224
- refsFields.push(f)
225
-
226
- });
224
+ this.loadRefs = function(refs, refsFields) {
225
+ if (!refsFields || refsFields.length === 0) {
226
+ if (!_current)
227
+ throw new Error(
228
+ 'There is no current catalog selected');
229
+ refsFields = [];
230
+ _current.fields.forEach(function(f) {
231
+ if (f.resource)
232
+ refsFields.push(f)
233
+
234
+ });
235
+ }
227236
228237 var that = this;
229238 var promises = []
....@@ -238,56 +247,38 @@
238247 console.log('promises: ' + promises.length
239248 + ' ')
240249 console.log(promises)
241
- $q
242
- .all(promises)
243
- .then(
244
- function() {
245
-
246
- for ( var k in refs) {
247
- var field = that
248
- .getField(k);
249
- var pk = that
250
- .getPk(that
251
- .getMetadata(field.resource))
252
- console
253
- .log('PK field for '
254
- + k
255
- + ' is '
256
- + pk)
257
- var comboData = []
258
- refs[k]
259
- .forEach(function(
260
- row) {
261
- console
262
- .log('field.resource !== _current.resource: '
263
- + field.resource
264
- + ' '
265
- + _current.resource)
266
- comboData
267
- .push({
268
- id : row[pk],
269
- label : row.label
270
- || row.name
271
- || row.code
272
- || row.first_name
273
- + ' '
274
- + (row.last_name || '')
275
- });
276
- })
277
- refs[k] = comboData;
278
- console
279
- .log('Ready for combo for '
280
- + k)
281
- console
282
- .log(comboData);
283
- }
284
- _current.fields
285
- .forEach(function(
286
- f) {
287
- if (f.values)
288
- refs[f.name] = f.values;
289
- });
290
- })
250
+ $q.all(promises)
251
+ .then(function() {
252
+ for(var i in refsFields) {
253
+ //for ( var k in refs) {
254
+ var rf = refsFields[i];
255
+ var cat = that.getResource(rf.resource);
256
+ var pk = that.getPk(that.getMetadata(rf.resource))
257
+ console.log('PK field for '
258
+ + rf.name
259
+ + ' is '
260
+ + pk)
261
+ var comboData = []
262
+ refs[rf.name].forEach(function(row) {
263
+ comboData.push({
264
+ id : row[pk],
265
+ label : row.label
266
+ || row.name
267
+ || row.code
268
+ || row.first_name
269
+ + ' '
270
+ + (row.last_name || '')
271
+ });
272
+ })
273
+ refs[rf.name] = comboData;
274
+ console.log('Ready for combo for ' + rf.name)
275
+ console.log(comboData);
276
+ }
277
+ _current && _current.fields.forEach(function(f) {
278
+ if (f.values)
279
+ refs[f.name] = f.values;
280
+ });
281
+ })
291282
292283 console.log(refs);
293284 return refs;
securis/src/main/resources/static/js/licenses.js
....@@ -1,92 +1,160 @@
11 (function() {
22 'use strict';
33
4
+ var HTTP_ERRORS = {
5
+ 401: "Unathorized action",
6
+ 403: "Forbidden action",
7
+ 500: "Server error",
8
+ 404: "Element not found"
9
+ }
10
+
411 var app = angular.module('securis');
12
+
13
+ app.controller('PackAndLicensesCtrl', [
14
+ '$scope',
15
+ '$http',
16
+ 'toaster',
17
+ '$store',
18
+ '$L',
19
+ function($scope, $http, toaster, $store, $L) {
20
+ $scope.licenses = [
21
+ {id: 1,
22
+ "code": "BP-SA-001-AKSJMS234",
23
+ "user_fullname": "Johnny Belmonte",
24
+ "user_email": "jb@curisit.net",
25
+ "status": 3},
26
+ {id: 2,
27
+ "code": "BP-SA-001-KAJSDHAJS",
28
+ "user_fullname": "Walter Simons",
29
+ "user_email": "ws@curisit.net",
30
+ "status": 1},
31
+ {id: 3,
32
+ "code": "BP-SA-001-ASKDGHKA",
33
+ "user_fullname": "Frank Belmonte",
34
+ "user_email": "fb@curisit.net",
35
+ "status": 2},
36
+ {id: 4,
37
+ "code": "BP-SA-001-BBBGGGG",
38
+ "user_fullname": "John Dalton",
39
+ "user_email": "jd@curisit.net",
40
+ "status": 3},
41
+ {id: 5,
42
+ "code": "BP-SA-001-AKADNAJANA",
43
+ "user_fullname": "Walter Martins",
44
+ "user_email": "wm@curisit.net",
45
+ "status": 3},
46
+ {id: 6,
47
+ "code": "BP-SA-001-AKANDAKS",
48
+ "user_fullname": "Joe Bolton",
49
+ "user_email": "jbol@curisit.net",
50
+ "status": 2}
51
+ ];
52
+
53
+ $scope.maxLengthErrorMsg = function(displayname, fieldMaxlength) {
54
+ return $L.get("{0} length is too long (max: {1}).", $L.get(displayname), fieldMaxlength);
55
+ }
56
+ $scope.mandatoryFieldErrorMsg = function(displayname) {
57
+ return $L.get("'{0}' is required.", $L.get(displayname));
58
+ }
59
+ $scope.ellipsis = function(txt, len) {
60
+ if (!txt || txt.length <= len) return txt;
61
+ return txt.substring(0, len) + '...';
62
+ }
63
+ $scope.currentPackId = $store.get('currentPackId');
64
+
65
+ }]);
566
6
- app.controller('LicensesCtrl', [
67
+ app.controller('PacksCtrl', [
768 '$scope',
869 '$http',
70
+ '$resource',
971 'toaster',
1072 'Catalogs',
1173 '$store',
1274 '$L',
13
- function($scope, $http, toaster, Catalogs, $store, $L) {
14
- $scope.currentPack = $store.get('currentPack');
15
- $scope.packs = [
16
- {id: 1,
17
- "organization_name": "BP-Spain",
18
- "application_name": "CurisIntegrity",
19
- "licensetype_code": "CIBS",
20
- "code": "BP-SA-0001",
21
- "licenses": 50,
22
- "lic_available": 23},
23
- {id: 2,
24
- "organization_name": "Exxon",
25
- "application_name": "CurisData",
26
- "licensetype_code": "CDL1",
27
- "code": "EX-SA-0001",
28
- "licenses": 1,
29
- "lic_available": 0},
30
- {id: 3,
31
- "organization_name": "Repsol S.A. empresa con nombre muy largo",
32
- "application_name": "CurisData",
33
- "licensetype_code": "CDL2",
34
- "code": "RE-SA-0001",
35
- "licenses": 5,
36
- "lic_available": 2},
37
- {id: 4,
38
- "organization_name": "BP-Spain",
39
- "application_name": "CurisIntegrity v3.0",
40
- "code": "BP-SA-0002",
41
- "licensetype_code": "CISA",
42
- "licenses": 150,
43
- "lic_available": 13},
44
- ];
75
+ function($scope, $http, $resource, toaster, Catalogs, $store, $L) {
76
+ var packResource = $resource('/pack/:packId', {
77
+ packId : '@id'
78
+ });
79
+ $scope.mandatory = {
80
+ code: true,
81
+ num_licenses: true,
82
+ organization_id: true,
83
+ license_type_id: true
84
+ }
85
+ $scope.maxlength = {
86
+ code: 50,
87
+ comments: 1024
88
+ }
89
+ $scope.refs = {};
90
+ Catalogs.init().then(function() {
91
+ Catalogs.loadRefs($scope.refs, [{resource: 'organization', name: 'organization_id'},{resource: 'licensetype', name: 'license_type_id'}])
92
+ });
4593
46
- $scope.licenses = [
47
- {id: 1,
48
- "code": "BP-SA-001-AKSJMS234",
49
- "user_fullname": "Johnny Belmonte",
50
- "user_email": "jb@curisit.net",
51
- "status": 3},
52
- {id: 2,
53
- "code": "BP-SA-001-KAJSDHAJS",
54
- "user_fullname": "Walter Simons",
55
- "user_email": "ws@curisit.net",
56
- "status": 1},
57
- {id: 3,
58
- "code": "BP-SA-001-ASKDGHKA",
59
- "user_fullname": "Frank Belmonte",
60
- "user_email": "fb@curisit.net",
61
- "status": 2},
62
- {id: 4,
63
- "code": "BP-SA-001-BBBGGGG",
64
- "user_fullname": "John Dalton",
65
- "user_email": "jd@curisit.net",
66
- "status": 3},
67
- {id: 5,
68
- "code": "BP-SA-001-AKADNAJANA",
69
- "user_fullname": "Walter Martins",
70
- "user_email": "wm@curisit.net",
71
- "status": 3},
72
- {id: 6,
73
- "code": "BP-SA-001-AKANDAKS",
74
- "user_fullname": "Joe Bolton",
75
- "user_email": "jbol@curisit.net",
76
- "status": 2}
77
- ];
78
-
94
+ // Used to create the form with the appropriate data
95
+ $scope.isNew = undefined;
7996
97
+ // Selected pack from listing
98
+ // pack is the edited pack, in creation contains the data for the new pack
99
+ $scope.pack = null;
100
+
101
+ $scope.packs = packResource.query();
80102
81
- $scope.ellipsis = function(txt, len) {
82
- if (!txt || txt.length <= len) return txt;
83
- return txt.substring(0, len) + '...';
103
+ $scope.save = function() {
104
+ var _success = function() {
105
+ $scope.packs = packResource.query();
106
+ }
107
+ packResource.save($scope.pack, _success)
84108 }
85109
86
- $scope.selectPack = function(pack) {
87
- console.log('Pack selected: ' + JSON.stringify(pack));
88
- $scope.currentPack = pack;
89
- $store.put('currentPack', pack);
110
+ $scope.newPack = function() {
111
+ $scope.isNew = true;
112
+ $scope.showForm = true;
113
+ $scope.pack = {
114
+ num_licenses: 1,
115
+ license_type_id: !$scope.refs.license_type_id || !$scope.refs.license_type_id.length ? null : $scope.refs.license_type_id[0].id,
116
+ organization_id: !$scope.refs.organization_id || !$scope.refs.organization_id.length ? null : $scope.refs.organization_id[0].id
117
+ }
118
+ setTimeout(function() {
119
+ $('#code').focus();
120
+ }, 0);
121
+ }
122
+
123
+ $scope.editPack = function(selectedPack) {
124
+ $scope.isNew = false;
125
+ $scope.showForm = true;
126
+ $scope.pack = selectedPack;
127
+ setTimeout(function() {
128
+ $('#code').focus();
129
+ }, 0);
130
+ }
131
+
132
+ $scope.deletePack = function(selectedPack) {
133
+ $scope.showForm = false;
134
+ BootstrapDialog.confirm($L.get("The pack '{0}' will be deleted, are you sure?", selectedPack.code), function(result){
135
+ if(result) {
136
+ var promise = packResource.remove({}, {id: selectedPack.id}).$promise;
137
+ promise.then(function(data) {
138
+ $scope.selectPack(null);
139
+ $scope.packs = packResource.query();
140
+ toaster.pop('success', Catalogs.getName(), $L.get("Pack '{0}' deleted successfully", selectedPack.code));
141
+ },function(error) {
142
+ console.log(error);
143
+ toaster.pop('error', Catalogs.getName(), $L.get("Error deleting pack, reason: {0}. Details: {1}", $L.get(HTTP_ERRORS[error.status]), error.headers('X-SECURIS-ERROR')), 10000);
144
+ });
145
+ }
146
+ });
147
+ $scope.isNew = false;
148
+ }
149
+
150
+
151
+ $scope.cancel = function() {
152
+ $scope.showForm = false;
153
+ }
154
+
155
+ $scope.selectPack = function(packId) {
156
+ $scope.$parent.currentPackId = packId;
157
+ $store.put('currentPackId', packId);
90158 }
91159
92160 } ]);
securis/src/main/resources/static/js/main.js
....@@ -53,7 +53,7 @@
5353 });
5454 $routeProvider.when('/licenses', {
5555 templateUrl: 'licenses.html',
56
- controller: 'LicensesCtrl'
56
+ controller: 'PackAndLicensesCtrl'
5757 });
5858 $routeProvider.when('/admin', {
5959 templateUrl: 'admin.html',
securis/src/main/resources/static/licenses.html
....@@ -3,7 +3,7 @@
33
44 <div class="container">
55 <div class="col-md-12">&nbsp;</div>
6
- <div id="packs_section" class="col-md-6">
6
+ <div id="packs_section" class="col-md-6" ng-controller="PacksCtrl">
77 <nav class="navbar navbar-default navbar-static-top">
88 <!-- Brand and toggle get grouped for better mobile display -->
99 <div class="navbar-header">
....@@ -14,7 +14,7 @@
1414 <div class="collapse navbar-collapse"
1515 id="bs-example-navbar-collapse-1">
1616 <ul class="nav navbar-nav">
17
- <li><a i18n ng-click="editNew()"><span class="glyphicon glyphicon-plus"></span>
17
+ <li><a i18n ng-click="newPack()"><span class="glyphicon glyphicon-plus"></span>
1818 New</a></li>
1919 <li><a i18n ng-click="cancel()"> <span
2020 class="glyphicon glyphicon-ban-circle"></span> Cancel
....@@ -23,12 +23,112 @@
2323 <div class="navbar-form navbar-right">
2424 <div class="input-group input-group-sm">
2525 <span class="input-group-addon glyphicon glyphicon-search" style="top: 0px;"></span>
26
- <input type="text" class="form-control" placeholder="Search" ng-model="$parent.searchText" >
27
- <span class="btn input-group-addon glyphicon glyphicon-remove" ng-click="$parent.searchText = ''" style="top: 0px;"></span>
26
+ <input type="text" class="form-control" placeholder="Search" ng-model="searchText" >
27
+ <span class="btn input-group-addon glyphicon glyphicon-remove" ng-click="searchText = ''" style="top: 0px;"></span>
2828 </div>
2929 </div>
3030 </div>
3131 </nav>
32
+
33
+ <div class="panel panel-default animate-show ng-hide" ng-show="showForm">
34
+ <form role="form" class="form-horizontal " name="packForm" id="packForm" ng-submit="save()" >
35
+ <div class="form-group" ng-if="!isNew">
36
+ <label class="col-md-3 control-label" >ID</label>
37
+ <div class="col-md-8">
38
+ <p class="form-control-static" ng-bind="pack.id"></p>
39
+ </div>
40
+ </div>
41
+ <div class="form-group" >
42
+ <label class="col-md-3 control-label" for="code" i18n>Code</label>
43
+ <div class="col-md-8">
44
+ <input type="string" id="code" name="code" placeholder="" class="form-control" ng-model="pack.code" ng-required="mandatory.code" ng-maxlength="{{maxlength.code}}" />
45
+ <div class="alert inline-alert alert-warning" ng-show="packForm.code.$invalid">
46
+ <span class="glyphicon glyphicon-warning-sign"></span>
47
+ <span ng-show="packForm.code.$error.maxlength" ng-bind="maxlengthErrorMsg('Code', maxlength.code)"></span>
48
+ <span ng-show="packForm.code.$error.required" ng-bind="mandatoryFieldErrorMsg('Code')"></span>
49
+ </div>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="form-group" >
54
+ <label class="col-md-3 control-label" for="num_licenses" i18n>Num. Licenses</label>
55
+ <div class="col-md-8">
56
+ <input type="number" id="num_licenses" name="num_licenses" placeholder="" class="form-control" ng-model="pack.num_licenses" ng-required="mandatory.num_licenses" />
57
+ <div class="alert inline-alert alert-warning" ng-show="packForm.num_licenses.$invalid">
58
+ <span class="glyphicon glyphicon-warning-sign"></span>
59
+ <span ng-show="packForm.num_licenses.$error.maxlength" ng-bind="maxlengthErrorMsg('Num. Licenses', maxlength.num_licenses)"></span>
60
+ <span ng-show="packForm.num_licenses.$error.required" ng-bind="mandatoryFieldErrorMsg('Num. Licenses')"></span>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="form-group" >
66
+ <label class="col-md-3 control-label" for="license_type_id" i18n>License type</label>
67
+ <div class="col-md-8">
68
+ <select class="form-control" ng-required="mandatory.license_type_id" ng-model="pack.license_type_id"
69
+ ng-options="o.id as o.label for o in refs.license_type_id" >
70
+ <option selected="true" ng-if="!mandatory.license_type_id" value=""></option>
71
+ </select>
72
+ <div class="alert inline-alert alert-warning" ng-show="packForm.license_type_id.$invalid">
73
+ <span class="glyphicon glyphicon-warning-sign"></span>
74
+ <span ng-show="packForm.license_type_id.$error.required" ng-bind="mandatoryFieldErrorMsg('License type')"></span>
75
+ </div>
76
+ </div>
77
+ </div>
78
+
79
+ <div class="form-group" >
80
+ <label class="col-md-3 control-label" for="organization_id" i18n>Organization</label>
81
+ <div class="col-md-8">
82
+ <select class="form-control" ng-required="field.mandatory" ng-model="pack.organization_id"
83
+ ng-options="o.id as o.label for o in refs.organization_id" >
84
+ <option selected="true" ng-if="!mandatory.organization_id" value=""></option>
85
+ </select>
86
+ <div class="alert inline-alert alert-warning" ng-show="packForm.organization_id.$invalid">
87
+ <span class="glyphicon glyphicon-warning-sign"></span>
88
+ <span ng-show="packForm.organization_id.$error.required" ng-bind="mandatoryFieldErrorMsg('Organization')"></span>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+
94
+ <div class="form-group" >
95
+ <label class="col-md-3 control-label" for="comments" i18n>Comments</label>
96
+ <div class="col-md-8">
97
+ <textarea type="string" id="comments" name="comments" placeholder=""
98
+ class="form-control" ng-model="pack.comments" rows="2" ng-required="mandatory.comments" ng-maxlength="{{maxlength.comments}}"></textarea>
99
+ <div class="alert inline-alert alert-warning" ng-show="packForm.comments.$invalid">
100
+ <span class="glyphicon glyphicon-warning-sign"></span>
101
+ <span ng-show="packForm.comments.$error.maxlength" ng-bind="maxlengthErrorMsg('Comments', maxlength.comments)"></span>
102
+ <span ng-show="packForm.comments.$error.required" ng-bind="mandatoryFieldErrorMsg('comments')"></span>
103
+ </div>
104
+ </div>
105
+ </div>
106
+
107
+ <div class="form-group" ng-if="!isNew">
108
+ <label class="col-md-3 control-label" >Created by</label>
109
+ <div class="col-md-8">
110
+ <p class="form-control-static" ng-bind="pack.created_by_name"></p>
111
+ </div>
112
+ </div>
113
+
114
+ <div class="form-group" ng-if="!isNew">
115
+ <label class="col-md-3 control-label" >Creation date</label>
116
+ <div class="col-md-8">
117
+ <p class="form-control-static" ng-bind="pack.creationTimestamp | date:'medium'"></p>
118
+ </div>
119
+ </div>
120
+
121
+ <div class="form-group">
122
+ <div class="col-md-offset-3 col-md-10" id="saveContainer">
123
+ <button id="save" type="submit" class="btn btn-primary" >
124
+ <span i18n class="glyphicon glyphicon-floppy-disk"></span> Save
125
+ </button>
126
+ </div>
127
+ </div>
128
+ </form>
129
+ </div>
130
+
131
+
32132 <div class="panel panel-default" >
33133 <div class="panel-heading">
34134 Packs <span class="badge pull-right" ng-bind="packs.length || 0"></span>
....@@ -37,22 +137,22 @@
37137 <table class="table table-hover table-condensed">
38138 <thead>
39139 <tr>
140
+ <th i18n >Code</th>
40141 <th i18n >Organization</th>
41142 <th i18n >Application</th>
42
- <th i18n >Code</th>
43143 <th i18n >Licenses</th>
44144 <th></th>
45145 </tr>
46146 </thead>
47147 <tbody>
48
- <tr ng-repeat="pack in packs | filter:searchText" ng-dblclick="editPack(row)" ng-class="{success: currentPack.id === pack.id}" ng-click="selectPack(pack)">
49
- <td ng-bind="ellipsis(pack.organization_name, 20)" title="{{pack.organization_name}}" ></td>
50
- <td ng-bind="pack.application_name"></td>
51
- <td style="white-space: nowrap;" ng-bind="pack.code"></td>
52
- <td title="Total: {{pack.licenses}}, avaliable: {{pack.lic_available}}">{{pack.licenses}} ({{pack.lic_available}})</td>
53
- <td><span ng-click="editPack(row)"
148
+ <tr ng-repeat="p in packs | filter:searchText" ng-dblclick="editPack(p)" ng-class="{success: currentPackId === p.id}" ng-click="selectPack(p.id)">
149
+ <td style="white-space: nowrap;" ng-bind="p.code"></td>
150
+ <td ng-bind="ellipsis(p.organization_name, 20)" title="{{pack.organization_name}}" ></td>
151
+ <td ng-bind="p.application_name"></td>
152
+ <td title="Total: {{p.num_licenses}}, available: {{p.num_available}}">{{p.num_licenses}} ({{p.num_available}})</td>
153
+ <td><span ng-click="editPack(p)"
54154 class="glyphicon glyphicon-pencil"></span>
55
- <span ng-click="deletePack(row)"
155
+ <span ng-click="deletePack(p)"
56156 class="glyphicon glyphicon-remove"></span>
57157 </td>
58158 </tr>
....@@ -61,11 +161,11 @@
61161 </tfoot>
62162 </table>
63163 </div>
64
-
164
+
65165 </div>
66166
67167 <div id="licenses_section" class="col-md-6" >
68
- <nav class="navbar navbar-default navbar-static-top" ng-disabled="!!currentPack">
168
+ <nav class="navbar navbar-default navbar-static-top" ng-disabled="currentPackId === null">
69169 <!-- Brand and toggle get grouped for better mobile display -->
70170 <div class="navbar-header success">
71171 <a class="navbar-brand" i18n>Licenses</a>
....@@ -91,12 +191,12 @@
91191 </div>
92192 </nav>
93193
94
- <div ng-if="!currentPack" class="well well-lg">
194
+ <div ng-if="currentPackId === null" class="well well-lg">
95195 <h4 i18n>No pack selected</h4>
96196 <p i18n>Please, select a pack to manage its licenses</p>
97197 </div>
98198
99
- <div class="panel panel-default" ng-if="currentPack">
199
+ <div class="panel panel-default" ng-if="currentPackId !== null">
100200 <div class="panel-heading">
101201 <span i18n>Licenses for pack: </span>{{currentPack.code}}
102202 <span style="color: lightgreen;" class="badge pull-right" ng-bind="currentPack.lic_available || 0"></span>