Skip to content

Commit

Permalink
Merge pull request #12 from penguineer/userfunctions
Browse files Browse the repository at this point in the history
Add user functions
  • Loading branch information
penguineer authored Jul 19, 2024
2 parents 497bb0b + a1d0c7c commit 70b8db0
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 9 deletions.
14 changes: 13 additions & 1 deletion frontend/themes/gartenplus/styles.css
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
/* GartenPlus theme */
/* GartenPlus theme */

vaadin-menu-bar-button[theme="icon"] {
background: unset;
color: var(--lumo-base-color) !important;
height: 100%;
}

vaadin-menu-bar-overlay[theme="icon"] {
z-index: 1000;
top: 64px !important;
}

Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package com.penguineering.gartenplus.ui.appframe;

import com.penguineering.gartenplus.auth.user.UserDTO;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.avatar.Avatar;
import com.vaadin.flow.component.avatar.AvatarVariant;
import com.vaadin.flow.component.contextmenu.MenuItem;
import com.vaadin.flow.component.contextmenu.SubMenu;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.IconFactory;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.menubar.MenuBar;
import com.vaadin.flow.component.menubar.MenuBarVariant;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import org.slf4j.Logger;
Expand All @@ -17,21 +25,16 @@ public class LoggedUserView extends Div {
Logger logger = LoggerFactory.getLogger(LoggedUserView.class);

final Avatar avatar;
final MenuBar userMenu;

public LoggedUserView(Supplier<UserDTO> currentUser) {
Optional<UserDTO> optUser = Optional.ofNullable(currentUser.get());

HorizontalLayout avatarLayout = new HorizontalLayout();
avatarLayout.setAlignItems(FlexComponent.Alignment.CENTER);

avatar = new Avatar();
avatar.setId("logged-user-avatar");
avatar.addThemeVariants(AvatarVariant.LUMO_LARGE);
avatar.setTooltipEnabled(true);

avatarLayout.add(avatar);
add(avatarLayout);

// Set the user's name
optUser.
map(UserDTO::displayName)
Expand All @@ -42,5 +45,44 @@ public LoggedUserView(Supplier<UserDTO> currentUser) {
.map(UserDTO::avatarUrl)
.map(URI::toASCIIString)
.ifPresent(avatar::setImage);


// Set up the menu
userMenu = new MenuBar();
userMenu.addThemeVariants(MenuBarVariant.LUMO_ICON);
userMenu.setHeightFull();

MenuItem menuItem = userMenu.addItem(avatar);
SubMenu subMenu = menuItem.getSubMenu();

subMenu.addItem(createMenuItemWithIcon("Profil", VaadinIcon.USER),
e -> navigateTo("/admin/profile"));
//subMenu.addSeparator();
//subMenu.addSeparator();
subMenu.addItem(createMenuItemWithIcon("Abmelden", VaadinIcon.SIGN_OUT),
e -> navigateTo("/admin/logout"));

add(userMenu);

}

private Component createMenuItemWithIcon(String text, IconFactory icon) {
HorizontalLayout menuItem = new HorizontalLayout();

menuItem.setWidthFull();
menuItem.setPadding(false);
menuItem.setMargin(false);
// menuItem.setSpacing(false);

var iconComponent = icon.create();
iconComponent.setSize("var(--lumo-icon-size-s)");
menuItem.add(iconComponent);
menuItem.add(text);

return menuItem;
}

private void navigateTo(String path) {
getUI().ifPresent(ui -> ui.navigate(path));
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.penguineering.gartenplus.ui.appframe;
package com.penguineering.gartenplus.ui.content;

import com.penguineering.gartenplus.ui.appframe.AppFrameLayout;
import com.penguineering.gartenplus.ui.appframe.GartenplusPage;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.H4;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;

@Route(value = "/datenschutz", layout = AppFrameLayout.class)
@AnonymousAllowed
@PageTitle("GartenPlus | Datenschutz")
public class LegalDatenschutzPage extends GartenplusPage {
public LegalDatenschutzPage() {
add(new H2("Datenschutz"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.penguineering.gartenplus.ui.appframe;
package com.penguineering.gartenplus.ui.content;


import com.penguineering.gartenplus.ui.appframe.AppFrameLayout;
import com.penguineering.gartenplus.ui.appframe.GartenplusPage;
import com.vaadin.flow.component.html.*;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;

@Route(value = "/impressum", layout = AppFrameLayout.class)
@AnonymousAllowed
@PageTitle("GartenPlus | Impressum")
public class LegalImpressumPage extends GartenplusPage {

public LegalImpressumPage() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.penguineering.gartenplus.ui.content.admin;


import com.penguineering.gartenplus.ui.appframe.AppFrameLayout;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.router.ParentLayout;
import com.vaadin.flow.router.RoutePrefix;
import com.vaadin.flow.router.RouterLayout;
import jakarta.annotation.security.PermitAll;

@ParentLayout(AppFrameLayout.class)
@RoutePrefix(value = "admin")
public class AdminLayout extends Div implements RouterLayout {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.penguineering.gartenplus.ui.content.admin;

import com.penguineering.gartenplus.ui.appframe.GartenplusPage;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.VaadinSession;
import jakarta.annotation.security.PermitAll;

import java.util.Arrays;

@Route(value = "logout", layout = AdminLayout.class)
@PermitAll
@PageTitle("GartenPlus | Abmelden")
public class LogoutPage extends GartenplusPage {
private static final String[] descriptionText = {
"Auf dieser Seite kann man sich abmelden.",
"Hinweis: Durch SSO kommt es sofort zur erneuten Anmeldung.",
"Die Abmeldung setzt die Session zurück und lädt Daten vom OIDC-Provider neu."
};

public LogoutPage() {
VerticalLayout description = new VerticalLayout();
description.setMargin(false);
description.setPadding(false);
description.setSpacing(false);
description.getStyle()
.set("margin", "0px auto");

Arrays.stream(descriptionText).map(Paragraph::new).forEach(description::add);
add(description);

var button = new Button("Abmelden", VaadinIcon.SIGN_OUT.create(),
e -> logout());

add(button);
}

private void logout() {
VaadinSession.getCurrent().close();

getUI()
.map(UI::getPage)
.ifPresent(page -> page.setLocation("/login"));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.penguineering.gartenplus.ui.content.admin;

import com.penguineering.gartenplus.auth.user.UserDTO;
import com.penguineering.gartenplus.ui.appframe.GartenplusPage;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import org.springframework.beans.factory.annotation.Qualifier;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

@Route(value = "profile", layout = AdminLayout.class)
@PermitAll
@PageTitle("GartenPlus | Benutzerprofil")
public class ProfilePage extends GartenplusPage {
public ProfilePage(@Qualifier("user") Supplier<UserDTO> currentUser) {
Optional<UserDTO> userOpt = Optional.of(currentUser).map(Supplier::get);

add(new H2("Benutzerprofil"));
add(new Paragraph("Folgende Daten wurden vom OIDC-Provider übernommen:"));

Grid<Map.Entry<String, String>> grid = new Grid<>();
grid.setAllRowsVisible(true);

grid.addColumn(Map.Entry::getKey).setHeader("Bezeichnung").setAutoWidth(true).setFlexGrow(0);
grid.addColumn(Map.Entry::getValue).setHeader("Wert").setAutoWidth(true).setFlexGrow(1);

List<Map.Entry<String, String>> items = new ArrayList<>();
userOpt.ifPresent(userDTO -> {
items.add(Map.entry("Name", userDTO.displayName()));
items.add(Map.entry("E-Mail-Adresse", userDTO.email()));
items.add(Map.entry("Avatar-URL", userDTO.avatarUrl().toASCIIString()));
});

grid.setItems(items);

add(grid);

add(new Paragraph("Der Avatar wird oben rechts angezeigt."));

add(new Paragraph("Die Daten können beim OIDC-Provider geändert werden."));
}
}

0 comments on commit 70b8db0

Please sign in to comment.