usermanager
This commit is contained in:
parent
4f050f6034
commit
04a118528a
7 changed files with 120 additions and 27 deletions
|
@ -1,6 +1,7 @@
|
|||
package com.faendir.acra.ui.base;
|
||||
|
||||
import com.faendir.acra.dataprovider.QueryDslDataProvider;
|
||||
import com.faendir.acra.ui.component.HasSize;
|
||||
import com.querydsl.core.types.Expression;
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.ComponentEventListener;
|
||||
|
@ -26,7 +27,7 @@ import java.util.function.Function;
|
|||
* @author lukas
|
||||
* @since 13.07.18
|
||||
*/
|
||||
public class MyGrid<T> extends Composite<Grid<T>> implements LocaleChangeObserver {
|
||||
public class MyGrid<T> extends Composite<Grid<T>> implements LocaleChangeObserver, HasSize {
|
||||
private final QueryDslDataProvider<T> dataProvider;
|
||||
private final Map<Grid.Column<T>, Pair<String, Object[]>> columnCaptions;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.faendir.acra.ui.base.popup;
|
||||
|
||||
import com.vaadin.flow.component.Component;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.component.HasValidation;
|
||||
import com.vaadin.flow.component.HasValue;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
@ -33,28 +34,34 @@ import java.util.function.Supplier;
|
|||
* @author Lukas
|
||||
* @since 22.06.2017
|
||||
*/
|
||||
public class ValidatedField<V, T extends Component & HasValue<?,V> & HasValidation> {
|
||||
public class ValidatedField<V, T extends Component> {
|
||||
private final T field;
|
||||
private final Supplier<V> valueSupplier;
|
||||
private final Consumer<String> messageSetter;
|
||||
private final Map<Function<V, Boolean>, String> validators;
|
||||
private final List<Listener> listeners;
|
||||
private boolean valid;
|
||||
|
||||
private ValidatedField(T field, Supplier<V> valueSupplier, Consumer<Consumer<V>> listenerRegistration) {
|
||||
private ValidatedField(T field, Supplier<V> valueSupplier, Consumer<Consumer<V>> listenerRegistration, Consumer<String> messageSetter) {
|
||||
this.field = field;
|
||||
this.valueSupplier = valueSupplier;
|
||||
this.messageSetter = messageSetter;
|
||||
this.validators = new HashMap<>();
|
||||
this.listeners = new ArrayList<>();
|
||||
this.valid = false;
|
||||
listenerRegistration.accept(this::validate);
|
||||
}
|
||||
|
||||
public static <V, T extends Component & HasValue<?,V> & HasValidation> ValidatedField<V, T> of(T field) {
|
||||
return new ValidatedField<>(field, field::getValue, vConsumer -> field.addValueChangeListener(event -> vConsumer.accept(event.getValue())));
|
||||
public static <V, T extends Component & HasValue<?, V> & HasValidation> ValidatedField<V, T> of(T field) {
|
||||
return new ValidatedField<>(field, field::getValue, vConsumer -> field.addValueChangeListener(event -> vConsumer.accept(event.getValue())), field::setErrorMessage);
|
||||
}
|
||||
|
||||
public static <V, T extends Component & HasValue<?,V> & HasValidation> ValidatedField<V, T> of(T field, Supplier<V> valueSupplier, Consumer<Consumer<V>> listenerRegistration) {
|
||||
return new ValidatedField<>(field, valueSupplier, listenerRegistration);
|
||||
public static <V, C extends Composite<T>, T extends Component & HasValue<?, V> & HasValidation> ValidatedField<V, C> of(C field) {
|
||||
return new ValidatedField<>(field, () -> field.getContent().getValue(), vConsumer -> field.getContent().addValueChangeListener(event -> vConsumer.accept(event.getValue())), m -> field.getContent().setErrorMessage(m));
|
||||
}
|
||||
|
||||
public static <V, T extends Component & HasValue<?, V> & HasValidation> ValidatedField<V, T> of(T field, Supplier<V> valueSupplier, Consumer<Consumer<V>> listenerRegistration) {
|
||||
return new ValidatedField<>(field, valueSupplier, listenerRegistration, field::setErrorMessage);
|
||||
}
|
||||
|
||||
public ValidatedField<V, T> addValidator(Function<V, Boolean> validator, String errorMessage) {
|
||||
|
@ -73,10 +80,10 @@ public class ValidatedField<V, T extends Component & HasValue<?,V> & HasValidati
|
|||
private boolean validate(V value) {
|
||||
boolean valid = validators.entrySet().stream().allMatch(entry -> {
|
||||
if (entry.getKey().apply(value)) {
|
||||
field.setErrorMessage(null);
|
||||
messageSetter.accept(null);
|
||||
return true;
|
||||
} else {
|
||||
field.setErrorMessage(entry.getValue());
|
||||
messageSetter.accept(entry.getValue());
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -33,7 +33,8 @@ public class FlexLayout extends com.vaadin.flow.component.orderedlayout.FlexLayo
|
|||
}
|
||||
|
||||
public enum FlexDirection {
|
||||
COLUMN("column");
|
||||
COLUMN("column"),
|
||||
ROW("row");
|
||||
private final String value;
|
||||
|
||||
FlexDirection(@NonNull String value) {
|
||||
|
|
|
@ -10,7 +10,6 @@ import com.faendir.acra.ui.component.FlexLayout;
|
|||
import com.faendir.acra.ui.component.Translatable;
|
||||
import com.faendir.acra.ui.view.MainView;
|
||||
import com.faendir.acra.ui.view.Overview;
|
||||
import com.vaadin.flow.component.AttachEvent;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.component.UI;
|
||||
import com.vaadin.flow.component.notification.Notification;
|
||||
|
@ -69,11 +68,6 @@ public class ChangePasswordView extends Composite<FlexLayout> implements HasRout
|
|||
getContent().setAlignItems(FlexComponent.Alignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttach(AttachEvent attachEvent) {
|
||||
super.onAttach(attachEvent);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Path.Element<?> getPathElement() {
|
||||
|
|
|
@ -1,14 +1,104 @@
|
|||
package com.faendir.acra.ui.view.user;
|
||||
|
||||
import com.faendir.acra.i18n.Messages;
|
||||
import com.faendir.acra.model.App;
|
||||
import com.faendir.acra.model.Permission;
|
||||
import com.faendir.acra.model.QUser;
|
||||
import com.faendir.acra.model.User;
|
||||
import com.faendir.acra.security.SecurityUtils;
|
||||
import com.faendir.acra.service.DataService;
|
||||
import com.faendir.acra.service.UserService;
|
||||
import com.faendir.acra.ui.base.MyGrid;
|
||||
import com.faendir.acra.ui.base.popup.Popup;
|
||||
import com.faendir.acra.ui.base.popup.ValidatedField;
|
||||
import com.faendir.acra.ui.component.FlexLayout;
|
||||
import com.faendir.acra.ui.component.Translatable;
|
||||
import com.faendir.acra.ui.view.MainView;
|
||||
import com.vaadin.flow.component.AttachEvent;
|
||||
import com.vaadin.flow.component.Composite;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.checkbox.Checkbox;
|
||||
import com.vaadin.flow.component.combobox.ComboBox;
|
||||
import com.vaadin.flow.component.grid.Grid;
|
||||
import com.vaadin.flow.component.textfield.PasswordField;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||
import com.vaadin.flow.router.Route;
|
||||
import com.vaadin.flow.spring.annotation.SpringComponent;
|
||||
import com.vaadin.flow.spring.annotation.UIScope;
|
||||
import org.springframework.lang.NonNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author lukas
|
||||
* @since 15.11.18
|
||||
*/
|
||||
@UIScope
|
||||
@SpringComponent
|
||||
@Route(value = "user-manager", layout = MainView.class)
|
||||
public class UserManager extends Composite<FlexLayout> {
|
||||
private final UserService userService;
|
||||
private final DataService dataService;
|
||||
|
||||
public UserManager(@NonNull UserService userService, @NonNull DataService dataService) {
|
||||
this.userService = userService;
|
||||
this.dataService = dataService;
|
||||
getContent().setFlexDirection(FlexLayout.FlexDirection.COLUMN);
|
||||
getContent().setWidthFull();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttach(AttachEvent attachEvent) {
|
||||
super.onAttach(attachEvent);
|
||||
getContent().removeAll();
|
||||
getContent().add(Translatable.createLabel(Messages.USERS));
|
||||
MyGrid<User> userGrid = new MyGrid<>(userService.getUserProvider());
|
||||
userGrid.setWidthFull();
|
||||
userGrid.setSelectionMode(Grid.SelectionMode.NONE);
|
||||
userGrid.addColumn(User::getUsername, QUser.user.username, Messages.USERNAME);
|
||||
userGrid.addColumn(new ComponentRenderer<>(user -> {
|
||||
Checkbox checkbox = new Checkbox(user.getRoles().contains(User.Role.ADMIN));
|
||||
checkbox.addValueChangeListener(e -> {
|
||||
userService.setAdmin(user, e.getValue());
|
||||
userGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
checkbox.setEnabled(!user.getUsername().equals(SecurityUtils.getUsername()));
|
||||
return checkbox;
|
||||
}), Messages.ADMIN);
|
||||
userGrid.addColumn(new ComponentRenderer<>(user -> {
|
||||
Checkbox checkbox = new Checkbox(user.getRoles().contains(User.Role.API));
|
||||
checkbox.addValueChangeListener(e -> {
|
||||
userService.setApiAccess(user, e.getValue());
|
||||
userGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
return checkbox;
|
||||
}), Messages.API);
|
||||
for (App app : dataService.findAllApps()) {
|
||||
userGrid.addColumn(new ComponentRenderer<>(user -> {
|
||||
Permission.Level permission = SecurityUtils.getPermission(app, user);
|
||||
ComboBox<Permission.Level> levelComboBox = new ComboBox<>(null, Arrays.asList(Permission.Level.values()));
|
||||
levelComboBox.setValue(permission);
|
||||
levelComboBox.addValueChangeListener(e -> {
|
||||
userService.setPermission(user, app, e.getValue());
|
||||
userGrid.getDataProvider().refreshAll();
|
||||
});
|
||||
return levelComboBox;
|
||||
}), Messages.ACCESS_PERMISSION, app.getName());
|
||||
}
|
||||
Translatable<Button> newUser = Translatable.createButton(e -> {
|
||||
Translatable<TextField> name = Translatable.createTextField("", Messages.USERNAME);
|
||||
Translatable<PasswordField> password = Translatable.createPasswordField(Messages.PASSWORD);
|
||||
new Popup().setTitle(Messages.NEW_USER)
|
||||
.addValidatedField(ValidatedField.of(name).addValidator(s -> !s.isEmpty(), Messages.USERNAME_EMPTY))
|
||||
.addValidatedField(ValidatedField.of(password).addValidator(s -> !s.isEmpty(), Messages.PASSWORD_EMPTY))
|
||||
.addValidatedField(ValidatedField.of(Translatable.createPasswordField(Messages.REPEAT_PASSWORD)).addValidator(s -> s.equals(password.getContent().getValue()), Messages.PASSWORDS_NOT_MATCHING))
|
||||
.addCreateButton(popup -> {
|
||||
userService.createUser(name.getContent().getValue().toLowerCase(), password.getContent().getValue());
|
||||
userGrid.getDataProvider().refreshAll();
|
||||
}, true)
|
||||
.show();
|
||||
}, Messages.NEW_USER);
|
||||
getContent().add(userGrid, newUser);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ host=Host
|
|||
port=Port
|
||||
ssl=Nutze SSL
|
||||
databaseName=Datenbankname
|
||||
importSuccess=Import erfolgreich für {0} von {1} Berichten.
|
||||
importSuccess=Import erfolgreich für %s von %s Berichten.
|
||||
acrarium=Acrarium
|
||||
configurationLabel=Notiere die folgende ACRA Konfiguration. Sie kann später nicht mehr angezeigt werden:<br><code>\
|
||||
@AcraCore(reportFormat = StringFormat.JSON)<br>\
|
||||
@AcraHttpSender(uri = "{0}{1}",<br>\
|
||||
basicAuthLogin = "{2}",<br>\
|
||||
basicAuthPassword = "{3}",<br>\
|
||||
@AcraHttpSender(uri = "%s%s",<br>\
|
||||
basicAuthLogin = "%s",<br>\
|
||||
basicAuthPassword = "%s",<br>\
|
||||
httpMethod = HttpSender.Method.POST)<br></code>
|
||||
create=Erzeugen
|
||||
close=Schließen
|
||||
|
@ -115,7 +115,7 @@ changePassword=Passwort ändern
|
|||
success=Erfolgreich!
|
||||
users=Nutzer
|
||||
username=Nutzername
|
||||
accessPermission=Zugriffsrechte für {0}
|
||||
accessPermission=Zugriffsrechte für %s
|
||||
newUser=Neuer Benutzer
|
||||
password=Passwort
|
||||
usernameEmpty=Nutzername darf nicht leer sein
|
||||
|
|
|
@ -24,13 +24,13 @@ host=Host
|
|||
port=Port
|
||||
ssl=Use SSL
|
||||
databaseName=Database Name
|
||||
importSuccess=Import successful for {0} of {1} reports.
|
||||
importSuccess=Import successful for %s of %s reports.
|
||||
acrarium=Acrarium
|
||||
configurationLabel=Take note of the following ACRA configuration. It cannot be viewed later:<br><code>\
|
||||
@AcraCore(reportFormat = StringFormat.JSON)<br>\
|
||||
@AcraHttpSender(uri = "{0}{1}",<br>\
|
||||
basicAuthLogin = "{2}",<br>\
|
||||
basicAuthPassword = "{3}",<br>\
|
||||
@AcraHttpSender(uri = "%s%s",<br>\
|
||||
basicAuthLogin = "%s",<br>\
|
||||
basicAuthPassword = "%s",<br>\
|
||||
httpMethod = HttpSender.Method.POST)<br></code>
|
||||
create=Create
|
||||
close=Close
|
||||
|
@ -67,7 +67,7 @@ download=Download
|
|||
nothingSelected=Nothing selected
|
||||
export=Export
|
||||
version=Version
|
||||
deleteMappingConfirm=Are you sure you want to delete the mapping for version {0}?
|
||||
deleteMappingConfirm=Are you sure you want to delete the mapping for version %s?
|
||||
newFile=Add File
|
||||
versionCode=Version code
|
||||
mappingFile=Mapping file
|
||||
|
@ -115,7 +115,7 @@ changePassword=Change Password
|
|||
success=Successful!
|
||||
users=Users
|
||||
username=Username
|
||||
accessPermission=Access Permission for {0}
|
||||
accessPermission=Access Permission for %s
|
||||
newUser=New User
|
||||
password=Password
|
||||
usernameEmpty=Username cannot be empty
|
||||
|
|
Loading…
Reference in a new issue