From e5a3a1d737e88c89a4ba3fbc8d277745093139b1 Mon Sep 17 00:00:00 2001 From: Udo Walter Date: Wed, 13 May 2020 14:04:52 +0200 Subject: Add some debug logs. Rename the 'virtual' locations to groups. --- .../de/bwlehrpool/bwlp_guac/AvailableClient.java | 11 ++-- .../bwlp_guac/BwlpAuthenticationProvider.java | 26 ++++---- .../de/bwlehrpool/bwlp_guac/BwlpUserContext.java | 8 +-- .../de/bwlehrpool/bwlp_guac/ConnectionManager.java | 76 ++++++++++++---------- .../java/de/bwlehrpool/bwlp_guac/GroupField.java | 26 ++++++++ .../java/de/bwlehrpool/bwlp_guac/JsonGroup.java | 45 +++++++++++++ .../java/de/bwlehrpool/bwlp_guac/JsonLocation.java | 45 ------------- .../java/de/bwlehrpool/bwlp_guac/JsonRoot.java | 2 +- .../de/bwlehrpool/bwlp_guac/LocationField.java | 26 -------- src/main/resources/bwlpModule.js | 4 +- src/main/resources/config/groupConfig.js | 11 ++++ src/main/resources/config/locationConfig.js | 11 ---- .../resources/controllers/groupFieldController.js | 32 +++++++++ .../controllers/locationFieldController.js | 32 --------- src/main/resources/guac-manifest.json | 2 +- src/main/resources/styles/groupField.css | 52 +++++++++++++++ src/main/resources/styles/locationField.css | 52 --------------- src/main/resources/templates/groupField.html | 19 ++++++ src/main/resources/templates/locationField.html | 19 ------ src/main/resources/translations/en.json | 2 +- 20 files changed, 252 insertions(+), 249 deletions(-) create mode 100644 src/main/java/de/bwlehrpool/bwlp_guac/GroupField.java create mode 100644 src/main/java/de/bwlehrpool/bwlp_guac/JsonGroup.java delete mode 100644 src/main/java/de/bwlehrpool/bwlp_guac/JsonLocation.java delete mode 100644 src/main/java/de/bwlehrpool/bwlp_guac/LocationField.java create mode 100644 src/main/resources/config/groupConfig.js delete mode 100644 src/main/resources/config/locationConfig.js create mode 100644 src/main/resources/controllers/groupFieldController.js delete mode 100644 src/main/resources/controllers/locationFieldController.js create mode 100644 src/main/resources/styles/groupField.css delete mode 100644 src/main/resources/styles/locationField.css create mode 100644 src/main/resources/templates/groupField.html delete mode 100644 src/main/resources/templates/locationField.html diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/AvailableClient.java b/src/main/java/de/bwlehrpool/bwlp_guac/AvailableClient.java index 6126e77..0a9e8ec 100644 --- a/src/main/java/de/bwlehrpool/bwlp_guac/AvailableClient.java +++ b/src/main/java/de/bwlehrpool/bwlp_guac/AvailableClient.java @@ -16,7 +16,7 @@ public class AvailableClient implements Cloneable { private static final AtomicLong CON_ID = new AtomicLong(); - public ArrayList locationList = new ArrayList(); + public ArrayList groupList = new ArrayList(); private final String clientip; @@ -28,8 +28,6 @@ public class AvailableClient implements Cloneable { private String inUseBy; - private WrappedConnection connection; - private long deadline; private long lastConnectionCheck; @@ -59,7 +57,6 @@ public class AvailableClient implements Cloneable { if (this.inUseBy != null) { LOGGER.info("Client " + this + " is available again"); this.inUseBy = null; - this.connection = null; } } this.lastConnectionCheck = 0; @@ -76,7 +73,6 @@ public class AvailableClient implements Cloneable { if (this.inUseBy != null || this.password == null || this.state != State.IDLE || user == null) return false; this.inUseBy = user; - this.connection = new WrappedConnection(this.clientip + "/" + CON_ID.incrementAndGet(), this); this.state = State.OCCUPIED; return true; } @@ -87,7 +83,7 @@ public class AvailableClient implements Cloneable { public synchronized WrappedConnection getConnection(String expectedOwner) { if (isInUseBy(expectedOwner)) - return this.connection; + return new WrappedConnection(this.clientip + "/" + CON_ID.incrementAndGet(), this); return null; } @@ -95,7 +91,8 @@ public class AvailableClient implements Cloneable { if (isInUseBy(expectedOwner)) { LOGGER.info("Prematurely releasing client " + this); this.inUseBy = null; - this.connection = null; + } else { + LOGGER.info("Could not release client " + this + ". Already in use by " + this.inUseBy); } } diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/BwlpAuthenticationProvider.java b/src/main/java/de/bwlehrpool/bwlp_guac/BwlpAuthenticationProvider.java index 0fc7bc8..c59c477 100644 --- a/src/main/java/de/bwlehrpool/bwlp_guac/BwlpAuthenticationProvider.java +++ b/src/main/java/de/bwlehrpool/bwlp_guac/BwlpAuthenticationProvider.java @@ -66,26 +66,26 @@ public class BwlpAuthenticationProvider implements AuthenticationProvider { if (user != null && user.hasValidConnection()) return user; - int locationid = requestLocation(credentials); + int groupid = requestGroup(credentials); LOGGER.warn("Doing the REdecoration"); - user = new BwlpUserContext(authenticatedUser, context, locationid); + user = new BwlpUserContext(authenticatedUser, context, groupid); oldMappings.put(username, user); return user; } - private int requestLocation(Credentials credentials) throws GuacamoleException { - // Request the user to select a location + private int requestGroup(Credentials credentials) throws GuacamoleException { + // Request the user to select a group ConnectionManager.updateList(); HttpServletRequest request = credentials.getRequest(); - String locationJson = request.getParameter("location"); + String groupJson = request.getParameter("group"); - if (locationJson == null) { + if (groupJson == null) { throw new GuacamoleInsufficientCredentialsException( "Select Location", new CredentialsInfo( - Collections.singletonList(new LocationField()) + Collections.singletonList(new GroupField()) )); } @@ -98,14 +98,14 @@ public class BwlpAuthenticationProvider implements AuthenticationProvider { String password = ""; String correctPassword = null; try { - JsonNode location = mapper.readTree(locationJson); - selectedId = Integer.parseInt(location.get("id").asText()); + JsonNode group = mapper.readTree(groupJson); + selectedId = Integer.parseInt(group.get("id").asText()); if (selectedId != 0) { - password = location.get("password").asText(); - correctPassword = ConnectionManager.getLocationPool().get(selectedId).password; + password = group.get("password").asText(); + correctPassword = ConnectionManager.getGroupPool().get(selectedId).password; } } catch (Exception e) { - LOGGER.info("Error reading location", e); + LOGGER.info("Error reading group", e); tryAgain = true; } @@ -117,7 +117,7 @@ public class BwlpAuthenticationProvider implements AuthenticationProvider { if (tryAgain) { throw new GuacamoleCredentialsException( message, new CredentialsInfo( - Collections.singletonList(new LocationField()) + Collections.singletonList(new GroupField()) )); } diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/BwlpUserContext.java b/src/main/java/de/bwlehrpool/bwlp_guac/BwlpUserContext.java index ca020f6..91d5849 100644 --- a/src/main/java/de/bwlehrpool/bwlp_guac/BwlpUserContext.java +++ b/src/main/java/de/bwlehrpool/bwlp_guac/BwlpUserContext.java @@ -30,7 +30,7 @@ public class BwlpUserContext extends AbstractUserContext { private final AuthenticatedUser authUser; private final UserContext originalContext; - private final Integer locationid; + private final Integer groupid; /** * The Directory with access to all connections within the root group associated @@ -38,17 +38,17 @@ public class BwlpUserContext extends AbstractUserContext { */ private Directory connectionDirectory; - public BwlpUserContext(AuthenticatedUser authenticatedUser, UserContext context, int locationid) + public BwlpUserContext(AuthenticatedUser authenticatedUser, UserContext context, int groupid) throws GuacamoleCredentialsException { authUser = authenticatedUser; originalContext = context; - this.locationid = locationid; + this.groupid = groupid; // OK addConn(); } private void addConn() throws GuacamoleCredentialsException { - WrappedConnection connection = ConnectionManager.getForUser(authUser.getCredentials().getUsername(), locationid); + WrappedConnection connection = ConnectionManager.getForUser(authUser.getCredentials().getUsername(), groupid); if (connection != null) { connectionDirectory = new SimpleDirectory(connection); } else { diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java b/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java index eacb347..00ec284 100644 --- a/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java +++ b/src/main/java/de/bwlehrpool/bwlp_guac/ConnectionManager.java @@ -42,15 +42,15 @@ public class ConnectionManager { private static final LinkedHashMap clientPool = new LinkedHashMap(); - private static final LinkedHashMap locationPool = new LinkedHashMap(); + private static final LinkedHashMap groupPool = new LinkedHashMap(); - public static LinkedHashMap getLocationPool() { return locationPool; } + public static LinkedHashMap getGroupPool() { return groupPool; } /** * Pass plain user name, get existing connection (if any), or a fresh one * @param user (LDAP) user name */ - public static WrappedConnection getForUser(String user, int locationid) + public static WrappedConnection getForUser(String user, int groupid) throws GuacamoleCredentialsException { if (SOURCE_URL == null) { LOGGER.warn("Don't have a source URL for client machines!"); @@ -64,25 +64,26 @@ public class ConnectionManager { freeClient = null; synchronized (clientPool) { Collection clients; - if (locationid == 0) { + if (groupid == 0) { clients = new HashSet(); - for (JsonLocation loc : locationPool.values()) { - if (!loc.hasPassword()) clients.addAll(loc.clientList); + for (JsonGroup group : groupPool.values()) { + if (!group.hasPassword()) clients.addAll(group.clientList); } } else { - JsonLocation location = locationPool.get(locationid); - if (location == null) { - // Request the user to select a location + JsonGroup group = groupPool.get(groupid); + if (group == null) { + // Request the user to select a group throw new GuacamoleInsufficientCredentialsException( "Select Location", new CredentialsInfo( - Collections.singletonList(new LocationField()) + Collections.singletonList(new GroupField()) )); } - clients = location.clientList; + clients = group.clientList; } for (AvailableClient ac : clients) { if (ac.isInUseBy(user)) { + LOGGER.info("Client " + ac + " is in use by " + user); freeClient = ac; break; } @@ -90,6 +91,7 @@ public class ConnectionManager { if (freeClient == null) { for (AvailableClient ac : clients) { if (ac.claim(user)) { + LOGGER.info("Claiming client " + ac + " for " + user); freeClient = ac; break; } @@ -97,16 +99,18 @@ public class ConnectionManager { } } if (freeClient == null) { - // Request the user to select another location + // Request the user to select another Group throw new GuacamoleCredentialsException( - "No free client. Select another location.", new CredentialsInfo( - Collections.singletonList(new LocationField()) + "No free client. Select another Location.", new CredentialsInfo( + Collections.singletonList(new GroupField()) )); } // Found free or existing client, check if connection is (still) possible if (freeClient.checkConnection(0)) { LOGGER.info("Establishing mapping for user " + user + " to " + freeClient); return freeClient.getConnection(user); + } else { + LOGGER.info("Failed to establish mapping for user " + user + " to " + freeClient + ". Trying to find a new one."); } // Connection check failed - release and loop again freeClient.releaseConnection(user); @@ -174,23 +178,25 @@ public class ConnectionManager { return; } + // Temporary + JsonGroup[] groups = root.locations; - if (root.locations == null) { - LOGGER.info("Location list null"); + if (groups == null) { + LOGGER.info("Group list null"); } - synchronized (locationPool) { - for (JsonLocation lnew : root.locations) { - JsonLocation existing = locationPool.get(lnew.id); + synchronized (groupPool) { + for (JsonGroup gnew : groups) { + JsonGroup existing = groupPool.get(gnew.id); boolean redoClientMapping = false; if (existing == null) { - locationPool.put(lnew.id, lnew); - existing = lnew; + groupPool.put(gnew.id, gnew); + existing = gnew; redoClientMapping = true; } else { - if (existing.locationids != lnew.locationids) redoClientMapping = true; - existing.locationids = lnew.locationids; - existing.name = lnew.name; - existing.password = lnew.password; + if (existing.locationids != gnew.locationids) redoClientMapping = true; + existing.locationids = gnew.locationids; + existing.name = gnew.name; + existing.password = gnew.password; } if (redoClientMapping) { existing.clientList = new ArrayList(); @@ -205,11 +211,11 @@ public class ConnectionManager { } } existing.checked = true; - LOGGER.info("Location " + lnew.name + " with pw " + lnew.password); + LOGGER.info("Group " + gnew.name + " with pw " + gnew.password); } - for (JsonLocation loc : locationPool.values()) { - if (loc.checked) loc.checked = false; - else locationPool.remove(loc.id); + for (JsonGroup group : groupPool.values()) { + if (group.checked) group.checked = false; + else groupPool.remove(group.id); } } @@ -226,11 +232,11 @@ public class ConnectionManager { AvailableClient newClient = new AvailableClient(cnew); clientPool.put(cnew.clientip, newClient); - for (JsonLocation loc : locationPool.values()) { - for (int id : loc.locationids) { + for (JsonGroup group : groupPool.values()) { + for (int id : group.locationids) { if (id == cnew.locationid) { - loc.clientList.add(newClient); - newClient.locationList.add(loc); + group.clientList.add(newClient); + newClient.groupList.add(group); break; } } @@ -245,8 +251,8 @@ public class ConnectionManager { AvailableClient c = it.next(); if (c.isTimeout(NOW)) { LOGGER.info("Removing client " + c + " from list"); - for (JsonLocation loc : c.locationList) { - loc.clientList.remove(c); + for (JsonGroup group : c.groupList) { + group.clientList.remove(c); } it.remove(); } diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/GroupField.java b/src/main/java/de/bwlehrpool/bwlp_guac/GroupField.java new file mode 100644 index 0000000..c0f89d7 --- /dev/null +++ b/src/main/java/de/bwlehrpool/bwlp_guac/GroupField.java @@ -0,0 +1,26 @@ +package de.bwlehrpool.bwlp_guac; + +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.form.Field; +import org.codehaus.jackson.annotate.JsonProperty; +import org.codehaus.jackson.map.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collection; + +/** + * Field which lets the user select a group. + */ +public class GroupField extends Field { + + public GroupField() { + super("group", "GROUP"); + } + + @JsonProperty("groups") + public Collection getGroups() throws GuacamoleException { + return ConnectionManager.getGroupPool().values(); + } +} \ No newline at end of file diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/JsonGroup.java b/src/main/java/de/bwlehrpool/bwlp_guac/JsonGroup.java new file mode 100644 index 0000000..27e769c --- /dev/null +++ b/src/main/java/de/bwlehrpool/bwlp_guac/JsonGroup.java @@ -0,0 +1,45 @@ +package de.bwlehrpool.bwlp_guac; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.codehaus.jackson.annotate.JsonProperty; + +import java.util.ArrayList; + +public class JsonGroup { + + public int id; + + public int[] locationids; + + public String name; + + public String password; + + @JsonProperty("password") + public Boolean hasPassword() { return password != null; } + + @JsonProperty("freeCount") + public int getFreeCount() { + int count = 0; + for (AvailableClient client : clientList) { + if (client.getState() == JsonClient.State.IDLE) count++; + } + return count; + } + + @JsonProperty("offlineCount") + public int getOfflineCount() { + int count = 0; + for (AvailableClient client : clientList) { + if (client.getState() == JsonClient.State.OFFLINE || client.getState() == JsonClient.State.STANDBY) count++; + } + return count; + } + + @JsonIgnore + public ArrayList clientList = new ArrayList(); + + @JsonIgnore + public boolean checked = false; + +} diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/JsonLocation.java b/src/main/java/de/bwlehrpool/bwlp_guac/JsonLocation.java deleted file mode 100644 index e6fc1b6..0000000 --- a/src/main/java/de/bwlehrpool/bwlp_guac/JsonLocation.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.bwlehrpool.bwlp_guac; - -import org.codehaus.jackson.annotate.JsonIgnore; -import org.codehaus.jackson.annotate.JsonProperty; - -import java.util.ArrayList; - -public class JsonLocation { - - public int id; - - public int[] locationids; - - public String name; - - public String password; - - @JsonProperty("password") - public Boolean hasPassword() { return password != null; } - - @JsonProperty("freeCount") - public int getFreeCount() { - int count = 0; - for (AvailableClient client : clientList) { - if (client.getState() == JsonClient.State.IDLE) count++; - } - return count; - } - - @JsonProperty("offlineCount") - public int getOfflineCount() { - int count = 0; - for (AvailableClient client : clientList) { - if (client.getState() == JsonClient.State.OFFLINE || client.getState() == JsonClient.State.STANDBY) count++; - } - return count; - } - - @JsonIgnore - public ArrayList clientList = new ArrayList(); - - @JsonIgnore - public boolean checked = false; - -} diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/JsonRoot.java b/src/main/java/de/bwlehrpool/bwlp_guac/JsonRoot.java index e89eb64..3aae280 100644 --- a/src/main/java/de/bwlehrpool/bwlp_guac/JsonRoot.java +++ b/src/main/java/de/bwlehrpool/bwlp_guac/JsonRoot.java @@ -4,6 +4,6 @@ public class JsonRoot { public JsonClient[] clients; - public JsonLocation[] locations; + public JsonGroup[] locations; } diff --git a/src/main/java/de/bwlehrpool/bwlp_guac/LocationField.java b/src/main/java/de/bwlehrpool/bwlp_guac/LocationField.java deleted file mode 100644 index 5e0266d..0000000 --- a/src/main/java/de/bwlehrpool/bwlp_guac/LocationField.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.bwlehrpool.bwlp_guac; - -import org.apache.guacamole.GuacamoleException; -import org.apache.guacamole.form.Field; -import org.codehaus.jackson.annotate.JsonProperty; -import org.codehaus.jackson.map.ObjectMapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Collection; - -/** - * Field which lets the user select a location. - */ -public class LocationField extends Field { - - public LocationField() { - super("location", "LOCATION"); - } - - @JsonProperty("locations") - public Collection getLocations() throws GuacamoleException { - return ConnectionManager.getLocationPool().values(); - } -} \ No newline at end of file diff --git a/src/main/resources/bwlpModule.js b/src/main/resources/bwlpModule.js index 67fb487..0a0f116 100644 --- a/src/main/resources/bwlpModule.js +++ b/src/main/resources/bwlpModule.js @@ -1,5 +1,5 @@ -angular.module('location', [ +angular.module('group', [ 'form' ]); -angular.module('index').requires.push('location'); +angular.module('index').requires.push('group'); diff --git a/src/main/resources/config/groupConfig.js b/src/main/resources/config/groupConfig.js new file mode 100644 index 0000000..09adb0d --- /dev/null +++ b/src/main/resources/config/groupConfig.js @@ -0,0 +1,11 @@ +angular.module('group').config(['formServiceProvider', + function groupConfig(formServiceProvider) { + + // Define field for the TOTP code provided by the user + formServiceProvider.registerFieldType('GROUP', { + module : 'group', + controller : 'groupFieldController', + templateUrl : 'app/ext/bwlp/templates/groupField.html' + }); + + }]); \ No newline at end of file diff --git a/src/main/resources/config/locationConfig.js b/src/main/resources/config/locationConfig.js deleted file mode 100644 index 6074752..0000000 --- a/src/main/resources/config/locationConfig.js +++ /dev/null @@ -1,11 +0,0 @@ -angular.module('location').config(['formServiceProvider', - function locationConfig(formServiceProvider) { - - // Define field for the TOTP code provided by the user - formServiceProvider.registerFieldType('LOCATION', { - module : 'location', - controller : 'locationFieldController', - templateUrl : 'app/ext/bwlp/templates/locationField.html' - }); - - }]); \ No newline at end of file diff --git a/src/main/resources/controllers/groupFieldController.js b/src/main/resources/controllers/groupFieldController.js new file mode 100644 index 0000000..3b6f9ea --- /dev/null +++ b/src/main/resources/controllers/groupFieldController.js @@ -0,0 +1,32 @@ +angular.module('group').controller('groupFieldController', ['$scope', function groupFieldController($scope) { + + $scope.data = { id: 0, password: '' }; + + $scope.$watch('data', function(newValue) { + if (window.location.hash !== '#/') { + window.location.hash = '#/'; + window.location.reload(); + } + $scope.model = JSON.stringify(newValue); + }, true); + + $scope.selectGroup = function selectGroup($event, id) { + if (angular.element($event.target).hasClass('bwlp-password-input')) return; + $scope.data.password = ''; + if ($scope.data.id === id) { + $scope.data.id = 0; + angular.element('.selected-group').removeClass('selected-group'); + return; + } + $scope.data.id = id; + angular.element('.selected-group').removeClass('selected-group'); + angular.element($event.currentTarget).addClass('selected-group'); + }; + + $scope.logout = function logout() { + window.localStorage.removeItem('GUAC_AUTH'); + window.location.hash = '#/'; + window.location.reload(); + } + +}]); \ No newline at end of file diff --git a/src/main/resources/controllers/locationFieldController.js b/src/main/resources/controllers/locationFieldController.js deleted file mode 100644 index af2b6fe..0000000 --- a/src/main/resources/controllers/locationFieldController.js +++ /dev/null @@ -1,32 +0,0 @@ -angular.module('location').controller('locationFieldController', ['$scope', function locationFieldController($scope) { - - $scope.data = { id: 0, password: '' }; - - $scope.$watch('data', function(newValue) { - if (window.location.hash !== '#/') { - window.location.hash = '#/'; - window.location.reload(); - } - $scope.model = JSON.stringify(newValue); - }, true); - - $scope.selectLocation = function selectLocation($event, id) { - if (angular.element($event.target).hasClass('bwlp-password-input')) return; - $scope.data.password = ''; - if ($scope.data.id === id) { - $scope.data.id = 0; - angular.element('.selected-location').removeClass('selected-location'); - return; - } - $scope.data.id = id; - angular.element('.selected-location').removeClass('selected-location'); - angular.element($event.currentTarget).addClass('selected-location'); - }; - - $scope.logout = function logout() { - window.localStorage.removeItem('GUAC_AUTH'); - window.location.hash = '#/'; - window.location.reload(); - } - -}]); \ No newline at end of file diff --git a/src/main/resources/guac-manifest.json b/src/main/resources/guac-manifest.json index def8a3f..a71d8a9 100644 --- a/src/main/resources/guac-manifest.json +++ b/src/main/resources/guac-manifest.json @@ -17,6 +17,6 @@ ], "resources" : { "images/Logo_bwLehrpool.svg" : "image/svg+xml", - "templates/locationField.html" : "text/html" + "templates/groupField.html" : "text/html" } } diff --git a/src/main/resources/styles/groupField.css b/src/main/resources/styles/groupField.css new file mode 100644 index 0000000..337bac5 --- /dev/null +++ b/src/main/resources/styles/groupField.css @@ -0,0 +1,52 @@ +.bwlp-group-container { + border: 2px solid #3d3d3d; + width: 100%; + border-spacing: 0; +} + +.bwlp-group { + background-color: white; + cursor: pointer; +} + +.bwlp-group > td { + padding: 14px; +} + +.bwlp-group .bwlp-password { + padding: 4px 8px !important; + margin: -10px 0 !important; +} + +.bwlp-group:hover { + filter: brightness(0.9); +} + +.bwlp-group.selected-group { + background-color: #c8ffc8; +} + +.bwlp-group-status { + font-size: 16px; + text-align: center; +} + +.bwlp-password { + text-align: right; +} + +.bwlp-password > span { + font-size: 16px; + opacity: 0.5; +} + +.bwlp-password-input { + margin: 0 !important; + padding: 5px 8px !important; + background-color: white !important; +} + +.logout-button { + float: left; + margin: 20px 0 0 0; +} \ No newline at end of file diff --git a/src/main/resources/styles/locationField.css b/src/main/resources/styles/locationField.css deleted file mode 100644 index 1764af9..0000000 --- a/src/main/resources/styles/locationField.css +++ /dev/null @@ -1,52 +0,0 @@ -.bwlp-location-container { - border: 2px solid #3d3d3d; - width: 100%; - border-spacing: 0; -} - -.bwlp-location { - background-color: white; - cursor: pointer; -} - -.bwlp-location > td { - padding: 14px; -} - -.bwlp-location .bwlp-password { - padding: 4px 8px !important; - margin: -10px 0 !important; -} - -.bwlp-location:hover { - filter: brightness(0.9); -} - -.bwlp-location.selected-location { - background-color: #c8ffc8; -} - -.bwlp-location-status { - font-size: 16px; - text-align: center; -} - -.bwlp-password { - text-align: right; -} - -.bwlp-password > span { - font-size: 16px; - opacity: 0.5; -} - -.bwlp-password-input { - margin: 0 !important; - padding: 5px 8px !important; - background-color: white !important; -} - -.logout-button { - float: left; - margin: 20px 0 0 0; -} \ No newline at end of file diff --git a/src/main/resources/templates/groupField.html b/src/main/resources/templates/groupField.html new file mode 100644 index 0000000..c2ea026 --- /dev/null +++ b/src/main/resources/templates/groupField.html @@ -0,0 +1,19 @@ + + + + + + +
+ {{ group.name }} + + {{ group.freeCount }} available ({{ group.offlineCount }} offline) + +
+ Password protected + +
+
+ diff --git a/src/main/resources/templates/locationField.html b/src/main/resources/templates/locationField.html deleted file mode 100644 index 9feb83c..0000000 --- a/src/main/resources/templates/locationField.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -
- {{ location.name }} - - {{ location.freeCount }} available ({{ location.offlineCount }} offline) - -
- Password protected - -
-
- diff --git a/src/main/resources/translations/en.json b/src/main/resources/translations/en.json index 85a8b6e..8e4fdbc 100644 --- a/src/main/resources/translations/en.json +++ b/src/main/resources/translations/en.json @@ -3,6 +3,6 @@ "NAME" : "bwLehrpool" }, "LOGIN" : { - "FIELD_HEADER_LOCATION" : "" + "FIELD_HEADER_GROUP" : "" } } \ No newline at end of file -- cgit v1.2.3-55-g7522