View Javadoc
1   package de.japrost.jabudget.vaadin.spring;
2   
3   import com.vaadin.flow.component.ClickEvent;
4   import com.vaadin.flow.component.HasValue;
5   import com.vaadin.flow.component.button.Button;
6   import com.vaadin.flow.component.formlayout.FormLayout;
7   import com.vaadin.flow.component.grid.Grid;
8   import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
9   import com.vaadin.flow.component.orderedlayout.VerticalLayout;
10  import com.vaadin.flow.component.textfield.TextField;
11  import com.vaadin.flow.data.provider.ListDataProvider;
12  import com.vaadin.flow.data.selection.SelectionEvent;
13  import com.vaadin.flow.router.Route;
14  
15  import de.japrost.jabudget.domain.DomainException;
16  import de.japrost.jabudget.domain.account.Account;
17  import de.japrost.jabudget.service.AccountService;
18  import de.japrost.jabudget.service.SerializationService;
19  
20  /**
21   * Main UI for JaBudget.
22   */
23  // this is a hack just to test main functionality
24  @Route("")
25  public class JaBudGetUI extends HorizontalLayout {
26  
27  	private static final long serialVersionUID = 1L;
28  
29  	// Account
30  	private final transient AccountService accountService;
31  	private ListDataProvider<Account> accountData;
32  	private Account selectedAccount;
33  	private Button newAccount;
34  	private Button clear;
35  	private Button delete;
36  	private TextField newId;
37  	private TextField newName;
38  	// Serialization
39  	private final transient SerializationService serializationService;
40  	private Button export;
41  	private Button impoort;
42  
43  	/**
44  	 * Instantiate with all dependencies.
45  	 *
46  	 * @param accountService the {@link AccountService} to use.
47  	 * @param serializationService the {@link SerializationService} to use.
48  	 */
49  	public JaBudGetUI(final AccountService accountService, final SerializationService serializationService) {
50  		this.accountService = accountService;
51  		this.serializationService = serializationService;
52  		setSizeFull();
53  		add(initAccountOverview());
54  		add(initAccountForm());
55  		add(initSerialization());
56  	}
57  
58  	private VerticalLayout initAccountOverview() {
59  		final VerticalLayout layout = new VerticalLayout();
60  		final Grid<Account> accounts = new Grid<>(Account.class);
61  		// accounts.setCaption("Accounts"); // I18N?
62  		accounts.setColumns("id", "name");
63  		accountData = new ListDataProvider<>(accountService.retrieveAll());
64  		accounts.setDataProvider(accountData);
65  		accounts.addSelectionListener(this::itemClicked);
66  		layout.add(accounts);
67  		return layout;
68  	}
69  
70  	private void itemClicked(final SelectionEvent<Grid<Account>, Account> e) {
71  		selectedAccount = e.getFirstSelectedItem().get();
72  		newId.setValue(selectedAccount.getId());
73  		newName.setValue(selectedAccount.getName());
74  		newAccount.setText("Update");
75  		delete.setEnabled(true);
76  	}
77  
78  	private FormLayout initAccountForm() {
79  		final FormLayout newAccountLayout = new FormLayout();
80  		newId = new TextField();
81  		newId.setLabel("id");
82  		newId.setRequiredIndicatorVisible(true);
83  		newId.addValueChangeListener(this::newIdValueChanged);
84  		newAccountLayout.add(newId);
85  		newName = new TextField();
86  		newName.setLabel("name");
87  		newAccountLayout.add(newName);
88  		newAccount = new Button();
89  		newAccount.setText("New");
90  		newAccount.setEnabled(false);
91  		newAccount.addClickListener(this::createNewAccount);
92  		newAccountLayout.add(newAccount);
93  		clear = new Button();
94  		clear.setText("Clear");
95  		clear.setEnabled(false);
96  		clear.addClickListener(this::clearAccount);
97  		newAccountLayout.add(clear);
98  		delete = new Button();
99  		delete.setText("Delete");
100 		delete.setEnabled(false);
101 		delete.addClickListener(this::deleteAccount);
102 		newAccountLayout.add(delete);
103 		return newAccountLayout;
104 	}
105 
106 	private void clearAccount(final ClickEvent<Button> event) {
107 		newId.clear();
108 		newName.clear();
109 		newAccount.setText("New");
110 	}
111 
112 	private void deleteAccount(final ClickEvent<Button> event) {
113 		final Boolean erased = accountService.erase(newId.getValue());
114 		if (erased) {
115 			accountData.getItems().remove(selectedAccount);
116 			accountData.refreshAll();
117 			// clear after remove since the newIdValueChanged is faster and sets selectedAccount to null
118 			newId.clear();
119 			newName.clear();
120 			newAccount.setText("New");
121 		}
122 	}
123 
124 	private void createNewAccount(final ClickEvent<Button> event) {
125 		Account account;
126 		try {
127 			// this is a hack just to test main functionality
128 			if (newAccount.getText().equals("New")) {
129 				account = accountService.create(Account.Builder.builder(newId.getValue()).setName(newName.getValue()).build());
130 				accountData.getItems().add(account);
131 			} else {
132 				account = accountService.update(Account.Builder.builder(newId.getValue()).setName(newName.getValue()).build());
133 				accountData.getItems().remove(account);
134 				accountData.getItems().add(account);
135 			}
136 		} catch (final DomainException e) {
137 			// FIXME show error message
138 			return;
139 		}
140 		newId.clear();
141 		newName.clear();
142 		newAccount.setText("New");
143 		accountData.refreshAll();
144 	}
145 
146 	private void newIdValueChanged(final HasValue.ValueChangeEvent<String> event) {
147 		if (event.getValue().length() == 0) {
148 			newAccount.setEnabled(false);
149 			clear.setEnabled(false);
150 			delete.setEnabled(false);
151 			selectedAccount = null;
152 		} else {
153 			newAccount.setEnabled(true);
154 			clear.setEnabled(true);
155 		}
156 	}
157 
158 	private VerticalLayout initSerialization() {
159 		final VerticalLayout layout = new VerticalLayout();
160 		impoort = new Button();
161 		impoort.setText("Import");
162 
163 		impoort.addClickListener(e -> {
164 			serializationService.deserialize();
165 			reloadAccounts();
166 		});
167 		layout.add(impoort);
168 		export = new Button();
169 		export.setText("Export");
170 		export.addClickListener(e -> serializationService.serialize());
171 		layout.add(export);
172 		return layout;
173 	}
174 
175 	private void reloadAccounts() {
176 		accountData.getItems().clear();
177 		accountData.getItems().addAll(accountService.retrieveAll());
178 		accountData.refreshAll();
179 	}
180 }