Closes #79: UI: Change background and logo image

This commit is contained in:
jendib 2016-05-08 18:57:32 +02:00
parent 4d79dd7076
commit 26685334a1
No known key found for this signature in database
GPG Key ID: 06EE7F699579166F
5 changed files with 83 additions and 23 deletions

View File

@ -120,26 +120,23 @@ public class ThemeResource extends BaseResource {
} }
@PUT @PUT
@Path("images") @Path("image/{type: logo|background}")
@Consumes("multipart/form-data") @Consumes("multipart/form-data")
public Response images( public Response images(@PathParam("type") String type,
@FormDataParam("logo") FormDataBodyPart logoBodyPart, @FormDataParam("image") FormDataBodyPart imageBodyPart) {
@FormDataParam("background") FormDataBodyPart backgrounBodyPart) {
if (!authenticate()) { if (!authenticate()) {
throw new ForbiddenClientException(); throw new ForbiddenClientException();
} }
checkBaseFunction(BaseFunction.ADMIN); checkBaseFunction(BaseFunction.ADMIN);
if (logoBodyPart == null && backgrounBodyPart == null) { if (imageBodyPart == null) {
throw new ClientException("NoImageProvided", "logo or background is required"); throw new ClientException("NoImageProvided", "An image is required");
} }
// Only a background or a logo is handled // Only a background or a logo is handled
FormDataBodyPart bodyPart = logoBodyPart == null ? backgrounBodyPart : logoBodyPart;
String type = logoBodyPart == null ? BACKGROUND_IMAGE : LOGO_IMAGE;
java.nio.file.Path filePath = DirectoryUtil.getThemeDirectory().resolve(type); java.nio.file.Path filePath = DirectoryUtil.getThemeDirectory().resolve(type);
// Copy the image to the theme directory // Copy the image to the theme directory
try (InputStream inputStream = bodyPart.getValueAs(InputStream.class)) { try (InputStream inputStream = imageBodyPart.getValueAs(InputStream.class)) {
Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING); Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) { } catch (Exception e) {
throw new ServerException("CopyError", "Error copying the image to the theme directory", e); throw new ServerException("CopyError", "Error copying the image to the theme directory", e);
@ -152,10 +149,6 @@ public class ThemeResource extends BaseResource {
@Produces("image/*") @Produces("image/*")
@Path("image/{type: logo|background}") @Path("image/{type: logo|background}")
public Response getImage(@PathParam("type") final String type) { public Response getImage(@PathParam("type") final String type) {
if (!LOGO_IMAGE.equals(type) && !BACKGROUND_IMAGE.equals(type)) {
throw new ClientException("InvalidType", "Type must be logo or background");
}
final java.nio.file.Path filePath = DirectoryUtil.getThemeDirectory().resolve(type); final java.nio.file.Path filePath = DirectoryUtil.getThemeDirectory().resolve(type);
// Copy the image to the response output // Copy the image to the response output

View File

@ -18,5 +18,36 @@ angular.module('docs').controller('SettingsTheme', function($scope, $rootScope,
stylesheet.href = stylesheet.href.replace(/\?.*|$/, '?' + new Date().getTime()); stylesheet.href = stylesheet.href.replace(/\?.*|$/, '?' + new Date().getTime());
$rootScope.appName = $scope.theme.name; $rootScope.appName = $scope.theme.name;
}); });
};
// Send an image
$scope.sendingImage = false;
$scope.sendImage = function(type, image) {
// Build the payload
var formData = new FormData();
formData.append('image', image);
// Send the file
var done = function() {
$scope.$apply(function() {
$scope.sendingImage = false;
$scope[type] = null;
});
};
$scope.sendingImage = true;
$.ajax({
type: 'PUT',
url: '../api/theme/image/' + type,
data: formData,
cache: false,
contentType: false,
processData: false,
success: function() {
done();
},
error: function() {
done();
} }
});
};
}); });

View File

@ -10,12 +10,11 @@ angular.module('docs').directive('file', function() {
replace: true, replace: true,
require: 'ngModel', require: 'ngModel',
link: function(scope, element, attr, ctrl) { link: function(scope, element, attr, ctrl) {
var listener = function() { element.bind('change', function() {
scope.$apply(function() { scope.$apply(function() {
attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]); attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
}); });
} });
element.bind('change', listener);
} }
} }
}); });

View File

@ -23,4 +23,41 @@
id="inputCss" ng-model="theme.css" ng-blur="update()"></textarea> id="inputCss" ng-model="theme.css" ng-blur="update()"></textarea>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputLogo">Logo</label>
<div class="col-sm-2">
<file accept="image/gif,image/png,image/jpg,image/jpeg"
class="form-control" id="inputLogo" ng-model="logo" ng-disabled="sendingImage" />
</div>
<div class="col-sm-2">
<button class="btn btn-default" ng-click="sendImage('logo', logo)" ng-disabled="sendingImage || !logo">
<span class="glyphicon glyphicon-save"></span>
Send
</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="inputBackground">Background image</label>
<div class="col-sm-2">
<file accept="image/gif,image/png,image/jpg,image/jpeg"
class="form-control" id="inputLogo" ng-model="background" ng-disabled="sendingImage" />
</div>
<div class="col-sm-2">
<button class="btn btn-default" ng-click="sendImage('background', background)" ng-disabled="sendingImage || !background">
<span class="glyphicon glyphicon-save"></span>
Send
</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<p class="form-control-static text-info" ng-if="sendingImage">
Uploading the image...
</p>
</div>
</div>
</form> </form>

View File

@ -72,11 +72,11 @@ public class TestThemeResource extends BaseJerseyTest {
// Change the logo // Change the logo
try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) { try (InputStream is = Resources.getResource("file/PIA00452.jpg").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("logo", is, "PIA00452.jpg"); StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("image", is, "PIA00452.jpg");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) { try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
target() target()
.register(MultiPartFeature.class) .register(MultiPartFeature.class)
.path("/theme/images").request() .path("/theme/image/logo").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart), .put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class); MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
@ -85,11 +85,11 @@ public class TestThemeResource extends BaseJerseyTest {
// Change the background // Change the background
try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) { try (InputStream is = Resources.getResource("file/Einstein-Roosevelt-letter.png").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("background", is, "Einstein-Roosevelt-letter.png"); StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("image", is, "Einstein-Roosevelt-letter.png");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) { try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
target() target()
.register(MultiPartFeature.class) .register(MultiPartFeature.class)
.path("/theme/images").request() .path("/theme/image/background").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken) .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
.put(Entity.entity(multiPart.bodyPart(streamDataBodyPart), .put(Entity.entity(multiPart.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class); MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);