Generated project

This commit is contained in:
start.vaadin.com
2024-05-27 21:00:34 +00:00
commit 7e577093a5
26 changed files with 2109 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
package dev.mars3142.fhq;
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* The entry point of the Spring Boot application.
*
* Use the @PWA annotation make the application installable on phones, tablets
* and some desktop browsers.
*
*/
@SpringBootApplication
@Theme(value = "website")
public class Application implements AppShellConfigurator {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@@ -0,0 +1,114 @@
package dev.mars3142.fhq.views;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.Header;
import com.vaadin.flow.component.html.ListItem;
import com.vaadin.flow.component.html.Nav;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.html.UnorderedList;
import com.vaadin.flow.router.RouterLink;
import com.vaadin.flow.theme.lumo.LumoUtility.AlignItems;
import com.vaadin.flow.theme.lumo.LumoUtility.BoxSizing;
import com.vaadin.flow.theme.lumo.LumoUtility.Display;
import com.vaadin.flow.theme.lumo.LumoUtility.FlexDirection;
import com.vaadin.flow.theme.lumo.LumoUtility.FontSize;
import com.vaadin.flow.theme.lumo.LumoUtility.FontWeight;
import com.vaadin.flow.theme.lumo.LumoUtility.Gap;
import com.vaadin.flow.theme.lumo.LumoUtility.Height;
import com.vaadin.flow.theme.lumo.LumoUtility.ListStyleType;
import com.vaadin.flow.theme.lumo.LumoUtility.Margin;
import com.vaadin.flow.theme.lumo.LumoUtility.Overflow;
import com.vaadin.flow.theme.lumo.LumoUtility.Padding;
import com.vaadin.flow.theme.lumo.LumoUtility.TextColor;
import com.vaadin.flow.theme.lumo.LumoUtility.Whitespace;
import com.vaadin.flow.theme.lumo.LumoUtility.Width;
import dev.mars3142.fhq.views.checkoutform.CheckoutFormView;
import dev.mars3142.fhq.views.dashboard.DashboardView;
import dev.mars3142.fhq.views.myview.MyViewView;
import org.vaadin.lineawesome.LineAwesomeIcon;
/**
* The main view is a top-level placeholder for other views.
*/
public class MainLayout extends AppLayout {
/**
* A simple navigation item component, based on ListItem element.
*/
public static class MenuItemInfo extends ListItem {
private final Class<? extends Component> view;
public MenuItemInfo(String menuTitle, Component icon, Class<? extends Component> view) {
this.view = view;
RouterLink link = new RouterLink();
// Use Lumo classnames for various styling
link.addClassNames(Display.FLEX, Gap.XSMALL, Height.MEDIUM, AlignItems.CENTER, Padding.Horizontal.SMALL,
TextColor.BODY);
link.setRoute(view);
Span text = new Span(menuTitle);
// Use Lumo classnames for various styling
text.addClassNames(FontWeight.MEDIUM, FontSize.MEDIUM, Whitespace.NOWRAP);
if (icon != null) {
link.add(icon);
}
link.add(text);
add(link);
}
public Class<?> getView() {
return view;
}
}
public MainLayout() {
addToNavbar(createHeaderContent());
}
private Component createHeaderContent() {
Header header = new Header();
header.addClassNames(BoxSizing.BORDER, Display.FLEX, FlexDirection.COLUMN, Width.FULL);
Div layout = new Div();
layout.addClassNames(Display.FLEX, AlignItems.CENTER, Padding.Horizontal.LARGE);
H1 appName = new H1("Firmware HQ");
appName.addClassNames(Margin.Vertical.MEDIUM, Margin.End.AUTO, FontSize.LARGE);
layout.add(appName);
Nav nav = new Nav();
nav.addClassNames(Display.FLEX, Overflow.AUTO, Padding.Horizontal.MEDIUM, Padding.Vertical.XSMALL);
// Wrap the links in a list; improves accessibility
UnorderedList list = new UnorderedList();
list.addClassNames(Display.FLEX, Gap.SMALL, ListStyleType.NONE, Margin.NONE, Padding.NONE);
nav.add(list);
for (MenuItemInfo menuItem : createMenuItems()) {
list.add(menuItem);
}
header.add(layout, nav);
return header;
}
private MenuItemInfo[] createMenuItems() {
return new MenuItemInfo[]{ //
new MenuItemInfo("Dashboard", LineAwesomeIcon.CHART_AREA_SOLID.create(), DashboardView.class), //
new MenuItemInfo("Checkout Form", LineAwesomeIcon.CREDIT_CARD.create(), CheckoutFormView.class), //
new MenuItemInfo("My View", LineAwesomeIcon.PENCIL_RULER_SOLID.create(), MyViewView.class), //
};
}
}

View File

@@ -0,0 +1,312 @@
package dev.mars3142.fhq.views.checkoutform;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.html.*;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.select.Select;
import com.vaadin.flow.component.textfield.EmailField;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility.AlignItems;
import com.vaadin.flow.theme.lumo.LumoUtility.Background;
import com.vaadin.flow.theme.lumo.LumoUtility.BorderRadius;
import com.vaadin.flow.theme.lumo.LumoUtility.BoxSizing;
import com.vaadin.flow.theme.lumo.LumoUtility.Display;
import com.vaadin.flow.theme.lumo.LumoUtility.Flex;
import com.vaadin.flow.theme.lumo.LumoUtility.FlexDirection;
import com.vaadin.flow.theme.lumo.LumoUtility.FlexWrap;
import com.vaadin.flow.theme.lumo.LumoUtility.FontSize;
import com.vaadin.flow.theme.lumo.LumoUtility.Gap;
import com.vaadin.flow.theme.lumo.LumoUtility.Height;
import com.vaadin.flow.theme.lumo.LumoUtility.JustifyContent;
import com.vaadin.flow.theme.lumo.LumoUtility.ListStyleType;
import com.vaadin.flow.theme.lumo.LumoUtility.Margin;
import com.vaadin.flow.theme.lumo.LumoUtility.MaxWidth;
import com.vaadin.flow.theme.lumo.LumoUtility.Padding;
import com.vaadin.flow.theme.lumo.LumoUtility.Position;
import com.vaadin.flow.theme.lumo.LumoUtility.TextColor;
import dev.mars3142.fhq.views.MainLayout;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
@PageTitle("Checkout Form")
@Route(value = "checkout-form", layout = MainLayout.class)
public class CheckoutFormView extends Div {
private static final Set<String> states = new LinkedHashSet<>();
private static final Set<String> countries = new LinkedHashSet<>();
static {
states.addAll(Arrays.asList("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut",
"Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas",
"Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York",
"North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington",
"West Virginia", "Wisconsin", "Wyoming"));
countries.addAll(Arrays.asList("Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola",
"Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia",
"Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize",
"Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island",
"Brazil", "British Indian Ocean Territory", "British Virgin Islands", "Brunei Darussalam", "Bulgaria",
"Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands",
"Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands",
"Colombia", "Comoros", "Congo", "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus",
"Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "East Timor", "Ecuador",
"Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands",
"Faroe Islands", "Federated States of Micronesia", "Fiji", "Finland", "France", "French Guiana",
"French Polynesia", "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana",
"Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea",
"Guinea-Bissau", "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong",
"Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Ivory Coast",
"Jamaica", "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
"Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau",
"Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
"Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Moldova", "Monaco", "Mongolia",
"Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands",
"Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue",
"Norfolk Island", "North Korea", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau",
"Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland", "Portugal",
"Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation", "Rwanda", "Saint Kitts and Nevis",
"Saint Lucia", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe",
"Saudi Arabia", "Senegal", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia",
"Solomon Islands", "Somalia", "South Africa", "South Georgia and the South Sandwich Islands",
"South Korea", "Spain", "Sri Lanka", "St. Helena", "St. Pierre and Miquelon", "Sudan", "Suriname",
"Svalbard and Jan Mayen Islands", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic",
"Taiwan", "Tajikistan", "Tanzania", "Thailand", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago",
"Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine",
"United Arab Emirates", "United Kingdom", "United States", "United States Minor Outlying Islands",
"United States Virgin Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Vatican City State", "Venezuela",
"Vietnam", "Wallis and Futuna Islands", "Western Sahara", "Yemen", "Yugoslavia", "Zaire", "Zambia",
"Zimbabwe"));
}
public CheckoutFormView() {
addClassNames("checkout-form-view");
addClassNames(Display.FLEX, FlexDirection.COLUMN, Height.FULL);
Main content = new Main();
content.addClassNames(Display.GRID, Gap.XLARGE, AlignItems.START, JustifyContent.CENTER, MaxWidth.SCREEN_MEDIUM,
Margin.Horizontal.AUTO, Padding.Bottom.LARGE, Padding.Horizontal.LARGE);
content.add(createCheckoutForm());
content.add(createAside());
add(content);
}
private Component createCheckoutForm() {
Section checkoutForm = new Section();
checkoutForm.addClassNames(Display.FLEX, FlexDirection.COLUMN, Flex.GROW);
H2 header = new H2("Checkout");
header.addClassNames(Margin.Bottom.NONE, Margin.Top.XLARGE, FontSize.XXXLARGE);
Paragraph note = new Paragraph("All fields are required unless otherwise noted");
note.addClassNames(Margin.Bottom.XLARGE, Margin.Top.NONE, TextColor.SECONDARY);
checkoutForm.add(header, note);
checkoutForm.add(createPersonalDetailsSection());
checkoutForm.add(createShippingAddressSection());
checkoutForm.add(createPaymentInformationSection());
checkoutForm.add(new Hr());
checkoutForm.add(createFooter());
return checkoutForm;
}
private Section createPersonalDetailsSection() {
Section personalDetails = new Section();
personalDetails.addClassNames(Display.FLEX, FlexDirection.COLUMN, Margin.Bottom.XLARGE, Margin.Top.MEDIUM);
Paragraph stepOne = new Paragraph("Checkout 1/3");
stepOne.addClassNames(Margin.NONE, FontSize.SMALL, TextColor.SECONDARY);
H3 header = new H3("Personal details");
header.addClassNames(Margin.Bottom.MEDIUM, Margin.Top.SMALL, FontSize.XXLARGE);
TextField name = new TextField("Name");
name.setRequiredIndicatorVisible(true);
name.setPattern("[\\p{L} \\-]+");
name.addClassNames(Margin.Bottom.SMALL);
EmailField email = new EmailField("Email address");
email.setRequiredIndicatorVisible(true);
email.addClassNames(Margin.Bottom.SMALL);
TextField phone = new TextField("Phone number");
phone.setRequiredIndicatorVisible(true);
phone.setPattern("[\\d \\-\\+]+");
phone.addClassNames(Margin.Bottom.SMALL);
Checkbox rememberDetails = new Checkbox("Remember personal details for next time");
rememberDetails.addClassNames(Margin.Top.SMALL);
personalDetails.add(stepOne, header, name, email, phone, rememberDetails);
return personalDetails;
}
private Section createShippingAddressSection() {
Section shippingDetails = new Section();
shippingDetails.addClassNames(Display.FLEX, FlexDirection.COLUMN, Margin.Bottom.XLARGE, Margin.Top.MEDIUM);
Paragraph stepTwo = new Paragraph("Checkout 2/3");
stepTwo.addClassNames(Margin.NONE, FontSize.SMALL, TextColor.SECONDARY);
H3 header = new H3("Shipping address");
header.addClassNames(Margin.Bottom.MEDIUM, Margin.Top.SMALL, FontSize.XXLARGE);
ComboBox<String> countrySelect = new ComboBox<>("Country");
countrySelect.setRequiredIndicatorVisible(true);
countrySelect.addClassNames(Margin.Bottom.SMALL);
TextArea address = new TextArea("Street address");
address.setMaxLength(200);
address.setRequiredIndicatorVisible(true);
address.addClassNames(Margin.Bottom.SMALL);
Div subSection = new Div();
subSection.addClassNames(Display.FLEX, FlexWrap.WRAP, Gap.MEDIUM);
TextField postalCode = new TextField("Postal Code");
postalCode.setRequiredIndicatorVisible(true);
postalCode.setPattern("[\\d \\p{L}]*");
postalCode.addClassNames(Margin.Bottom.SMALL);
TextField city = new TextField("City");
city.setRequiredIndicatorVisible(true);
city.addClassNames(Flex.GROW, Margin.Bottom.SMALL);
subSection.add(postalCode, city);
ComboBox<String> stateSelect = new ComboBox<>("State");
stateSelect.setRequiredIndicatorVisible(true);
stateSelect.setItems(states);
stateSelect.setVisible(false);
countrySelect.setItems(countries);
countrySelect
.addValueChangeListener(e -> stateSelect.setVisible(countrySelect.getValue().equals("United States")));
Checkbox sameAddress = new Checkbox("Billing address is the same as shipping address");
sameAddress.addClassNames(Margin.Top.SMALL);
Checkbox rememberAddress = new Checkbox("Remember address for next time");
shippingDetails.add(stepTwo, header, countrySelect, address, subSection, stateSelect, sameAddress,
rememberAddress);
return shippingDetails;
}
private Component createPaymentInformationSection() {
Section paymentInfo = new Section();
paymentInfo.addClassNames(Display.FLEX, FlexDirection.COLUMN, Margin.Bottom.XLARGE, Margin.Top.MEDIUM);
Paragraph stepThree = new Paragraph("Checkout 3/3");
stepThree.addClassNames(Margin.NONE, FontSize.SMALL, TextColor.SECONDARY);
H3 header = new H3("Personal details");
header.addClassNames(Margin.Bottom.MEDIUM, Margin.Top.SMALL, FontSize.XXLARGE);
TextField cardHolder = new TextField("Cardholder name");
cardHolder.setRequiredIndicatorVisible(true);
cardHolder.setPattern("[\\p{L} \\-]+");
cardHolder.addClassNames(Margin.Bottom.SMALL);
Div subSectionOne = new Div();
subSectionOne.addClassNames(Display.FLEX, FlexWrap.WRAP, Gap.MEDIUM);
TextField cardNumber = new TextField("Card Number");
cardNumber.setRequiredIndicatorVisible(true);
cardNumber.setPattern("[\\d ]{12,23}");
cardNumber.addClassNames(Margin.Bottom.SMALL);
TextField securityCode = new TextField("Security Code");
securityCode.setRequiredIndicatorVisible(true);
securityCode.setPattern("[0-9]{3,4}");
securityCode.addClassNames(Flex.GROW, Margin.Bottom.SMALL);
securityCode.setHelperText("What is this?");
subSectionOne.add(cardNumber, securityCode);
Div subSectionTwo = new Div();
subSectionTwo.addClassNames(Display.FLEX, FlexWrap.WRAP, Gap.MEDIUM);
Select<String> expirationMonth = new Select<>();
expirationMonth.setLabel("Expiration month");
expirationMonth.setRequiredIndicatorVisible(true);
expirationMonth.setItems("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12");
Select<String> expirationYear = new Select<>();
expirationYear.setLabel("Expiration year");
expirationYear.setRequiredIndicatorVisible(true);
expirationYear.setItems("22", "23", "24", "25", "26");
subSectionTwo.add(expirationMonth, expirationYear);
paymentInfo.add(stepThree, header, cardHolder, subSectionTwo);
return paymentInfo;
}
private Footer createFooter() {
Footer footer = new Footer();
footer.addClassNames(Display.FLEX, AlignItems.CENTER, JustifyContent.BETWEEN, Margin.Vertical.MEDIUM);
Button cancel = new Button("Cancel order");
cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
Button pay = new Button("Pay securely", new Icon(VaadinIcon.LOCK));
pay.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_SUCCESS);
footer.add(cancel, pay);
return footer;
}
private Aside createAside() {
Aside aside = new Aside();
aside.addClassNames(Background.CONTRAST_5, BoxSizing.BORDER, Padding.LARGE, BorderRadius.LARGE,
Position.STICKY);
Header headerSection = new Header();
headerSection.addClassNames(Display.FLEX, AlignItems.CENTER, JustifyContent.BETWEEN, Margin.Bottom.MEDIUM);
H3 header = new H3("Order");
header.addClassNames(Margin.NONE);
Button edit = new Button("Edit");
edit.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE);
headerSection.add(header, edit);
UnorderedList ul = new UnorderedList();
ul.addClassNames(ListStyleType.NONE, Margin.NONE, Padding.NONE, Display.FLEX, FlexDirection.COLUMN, Gap.MEDIUM);
ul.add(createListItem("Vanilla cracker", "With wholemeal flour", "$7.00"));
ul.add(createListItem("Vanilla blueberry cake", "With blueberry jam", "$8.00"));
ul.add(createListItem("Vanilla pastry", "With wholemeal flour", "$5.00"));
aside.add(headerSection, ul);
return aside;
}
private ListItem createListItem(String primary, String secondary, String price) {
ListItem item = new ListItem();
item.addClassNames(Display.FLEX, JustifyContent.BETWEEN);
Div subSection = new Div();
subSection.addClassNames(Display.FLEX, FlexDirection.COLUMN);
subSection.add(new Span(primary));
Span secondarySpan = new Span(secondary);
secondarySpan.addClassNames(FontSize.SMALL, TextColor.SECONDARY);
subSection.add(secondarySpan);
Span priceSpan = new Span(price);
item.add(subSection, priceSpan);
return item;
}
}

View File

@@ -0,0 +1,227 @@
package dev.mars3142.fhq.views.dashboard;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.board.Board;
import com.vaadin.flow.component.charts.Chart;
import com.vaadin.flow.component.charts.model.*;
import com.vaadin.flow.component.grid.ColumnTextAlign;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.select.Select;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;
import com.vaadin.flow.theme.lumo.LumoUtility.BoxSizing;
import com.vaadin.flow.theme.lumo.LumoUtility.FontSize;
import com.vaadin.flow.theme.lumo.LumoUtility.FontWeight;
import com.vaadin.flow.theme.lumo.LumoUtility.Margin;
import com.vaadin.flow.theme.lumo.LumoUtility.Padding;
import com.vaadin.flow.theme.lumo.LumoUtility.TextColor;
import dev.mars3142.fhq.views.MainLayout;
import dev.mars3142.fhq.views.dashboard.ServiceHealth.Status;
@PageTitle("Dashboard")
@Route(value = "", layout = MainLayout.class)
@RouteAlias(value = "", layout = MainLayout.class)
public class DashboardView extends Main {
public DashboardView() {
addClassName("dashboard-view");
Board board = new Board();
board.addRow(createHighlight("Current users", "745", 33.7), createHighlight("View events", "54.6k", -112.45),
createHighlight("Conversion rate", "18%", 3.9), createHighlight("Custom metric", "-123.45", 0.0));
board.addRow(createViewEvents());
board.addRow(createServiceHealth(), createResponseTimes());
add(board);
}
private Component createHighlight(String title, String value, Double percentage) {
VaadinIcon icon = VaadinIcon.ARROW_UP;
String prefix = "";
String theme = "badge";
if (percentage == 0) {
prefix = "±";
} else if (percentage > 0) {
prefix = "+";
theme += " success";
} else if (percentage < 0) {
icon = VaadinIcon.ARROW_DOWN;
theme += " error";
}
H2 h2 = new H2(title);
h2.addClassNames(FontWeight.NORMAL, Margin.NONE, TextColor.SECONDARY, FontSize.XSMALL);
Span span = new Span(value);
span.addClassNames(FontWeight.SEMIBOLD, FontSize.XXXLARGE);
Icon i = icon.create();
i.addClassNames(BoxSizing.BORDER, Padding.XSMALL);
Span badge = new Span(i, new Span(prefix + percentage.toString()));
badge.getElement().getThemeList().add(theme);
VerticalLayout layout = new VerticalLayout(h2, span, badge);
layout.addClassName(Padding.LARGE);
layout.setPadding(false);
layout.setSpacing(false);
return layout;
}
private Component createViewEvents() {
// Header
Select year = new Select();
year.setItems("2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021");
year.setValue("2021");
year.setWidth("100px");
HorizontalLayout header = createHeader("View events", "City/month");
header.add(year);
// Chart
Chart chart = new Chart(ChartType.AREASPLINE);
Configuration conf = chart.getConfiguration();
conf.getChart().setStyledMode(true);
XAxis xAxis = new XAxis();
xAxis.setCategories("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
conf.addxAxis(xAxis);
conf.getyAxis().setTitle("Values");
PlotOptionsAreaspline plotOptions = new PlotOptionsAreaspline();
plotOptions.setPointPlacement(PointPlacement.ON);
plotOptions.setMarker(new Marker(false));
conf.addPlotOptions(plotOptions);
conf.addSeries(new ListSeries("Berlin", 189, 191, 291, 396, 501, 403, 609, 712, 729, 942, 1044, 1247));
conf.addSeries(new ListSeries("London", 138, 246, 248, 348, 352, 353, 463, 573, 778, 779, 885, 887));
conf.addSeries(new ListSeries("New York", 65, 65, 166, 171, 293, 302, 308, 317, 427, 429, 535, 636));
conf.addSeries(new ListSeries("Tokyo", 0, 11, 17, 123, 130, 142, 248, 349, 452, 454, 458, 462));
// Add it all together
VerticalLayout viewEvents = new VerticalLayout(header, chart);
viewEvents.addClassName(Padding.LARGE);
viewEvents.setPadding(false);
viewEvents.setSpacing(false);
viewEvents.getElement().getThemeList().add("spacing-l");
return viewEvents;
}
private Component createServiceHealth() {
// Header
HorizontalLayout header = createHeader("Service health", "Input / output");
// Grid
Grid<ServiceHealth> grid = new Grid();
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
grid.setAllRowsVisible(true);
grid.addColumn(new ComponentRenderer<>(serviceHealth -> {
Span status = new Span();
String statusText = getStatusDisplayName(serviceHealth);
status.getElement().setAttribute("aria-label", "Status: " + statusText);
status.getElement().setAttribute("title", "Status: " + statusText);
status.getElement().getThemeList().add(getStatusTheme(serviceHealth));
return status;
})).setHeader("").setFlexGrow(0).setAutoWidth(true);
grid.addColumn(ServiceHealth::getCity).setHeader("City").setFlexGrow(1);
grid.addColumn(ServiceHealth::getInput).setHeader("Input").setAutoWidth(true).setTextAlign(ColumnTextAlign.END);
grid.addColumn(ServiceHealth::getOutput).setHeader("Output").setAutoWidth(true)
.setTextAlign(ColumnTextAlign.END);
grid.setItems(new ServiceHealth(Status.EXCELLENT, "Münster", 324, 1540),
new ServiceHealth(Status.OK, "Cluj-Napoca", 311, 1320),
new ServiceHealth(Status.FAILING, "Ciudad Victoria", 300, 1219));
// Add it all together
VerticalLayout serviceHealth = new VerticalLayout(header, grid);
serviceHealth.addClassName(Padding.LARGE);
serviceHealth.setPadding(false);
serviceHealth.setSpacing(false);
serviceHealth.getElement().getThemeList().add("spacing-l");
return serviceHealth;
}
private Component createResponseTimes() {
HorizontalLayout header = createHeader("Response times", "Average across all systems");
// Chart
Chart chart = new Chart(ChartType.PIE);
Configuration conf = chart.getConfiguration();
conf.getChart().setStyledMode(true);
chart.setThemeName("gradient");
DataSeries series = new DataSeries();
series.add(new DataSeriesItem("System 1", 12.5));
series.add(new DataSeriesItem("System 2", 12.5));
series.add(new DataSeriesItem("System 3", 12.5));
series.add(new DataSeriesItem("System 4", 12.5));
series.add(new DataSeriesItem("System 5", 12.5));
series.add(new DataSeriesItem("System 6", 12.5));
conf.addSeries(series);
// Add it all together
VerticalLayout serviceHealth = new VerticalLayout(header, chart);
serviceHealth.addClassName(Padding.LARGE);
serviceHealth.setPadding(false);
serviceHealth.setSpacing(false);
serviceHealth.getElement().getThemeList().add("spacing-l");
return serviceHealth;
}
private HorizontalLayout createHeader(String title, String subtitle) {
H2 h2 = new H2(title);
h2.addClassNames(FontSize.XLARGE, Margin.NONE);
Span span = new Span(subtitle);
span.addClassNames(TextColor.SECONDARY, FontSize.XSMALL);
VerticalLayout column = new VerticalLayout(h2, span);
column.setPadding(false);
column.setSpacing(false);
HorizontalLayout header = new HorizontalLayout(column);
header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
header.setSpacing(false);
header.setWidthFull();
return header;
}
private String getStatusDisplayName(ServiceHealth serviceHealth) {
Status status = serviceHealth.getStatus();
if (status == Status.OK) {
return "Ok";
} else if (status == Status.FAILING) {
return "Failing";
} else if (status == Status.EXCELLENT) {
return "Excellent";
} else {
return status.toString();
}
}
private String getStatusTheme(ServiceHealth serviceHealth) {
Status status = serviceHealth.getStatus();
String theme = "badge primary small";
if (status == Status.EXCELLENT) {
theme += " success";
} else if (status == Status.FAILING) {
theme += " error";
}
return theme;
}
}

View File

@@ -0,0 +1,65 @@
package dev.mars3142.fhq.views.dashboard;
/**
* Simple DTO class for the inbox list to demonstrate complex object data
*/
public class ServiceHealth {
private Status status;
private String city;
private int input;
private int output;
private String theme;
enum Status {
EXCELLENT, OK, FAILING;
}
public ServiceHealth() {
}
public ServiceHealth(Status status, String city, int input, int output) {
this.status = status;
this.city = city;
this.input = input;
this.output = output;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public int getInput() {
return input;
}
public void setInput(int input) {
this.input = input;
}
public int getOutput() {
return output;
}
public void setOutput(int output) {
this.output = output;
}
}

View File

@@ -0,0 +1,44 @@
package dev.mars3142.fhq.views.myview;
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility.Gap;
import dev.mars3142.fhq.views.MainLayout;
@PageTitle("My View")
@Route(value = "my-view", layout = MainLayout.class)
public class MyViewView extends Composite<VerticalLayout> {
public MyViewView() {
HorizontalLayout layoutRow2 = new HorizontalLayout();
HorizontalLayout layoutRow = new HorizontalLayout();
VerticalLayout layoutColumn2 = new VerticalLayout();
VerticalLayout layoutColumn3 = new VerticalLayout();
VerticalLayout layoutColumn4 = new VerticalLayout();
HorizontalLayout layoutRow3 = new HorizontalLayout();
getContent().setWidth("100%");
getContent().getStyle().set("flex-grow", "1");
layoutRow2.addClassName(Gap.MEDIUM);
layoutRow2.setWidth("100%");
layoutRow2.setHeight("min-content");
layoutRow.addClassName(Gap.MEDIUM);
layoutRow.setWidth("100%");
layoutRow.getStyle().set("flex-grow", "1");
layoutColumn2.getStyle().set("flex-grow", "1");
layoutColumn3.setWidth("100%");
layoutColumn3.getStyle().set("flex-grow", "1");
layoutColumn4.getStyle().set("flex-grow", "1");
layoutRow3.addClassName(Gap.MEDIUM);
layoutRow3.setWidth("100%");
layoutRow3.setHeight("min-content");
getContent().add(layoutRow2);
getContent().add(layoutRow);
layoutRow.add(layoutColumn2);
layoutRow.add(layoutColumn3);
layoutRow.add(layoutColumn4);
getContent().add(layoutRow3);
}
}