Erweiterungen
This commit is contained in:
@@ -6,7 +6,6 @@ import org.springframework.data.annotation.Id;
|
|||||||
import org.springframework.data.mongodb.core.mapping.Document;
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
import org.springframework.data.mongodb.core.index.Indexed;
|
import org.springframework.data.mongodb.core.index.Indexed;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -18,28 +17,29 @@ public class User {
|
|||||||
private ObjectId id;
|
private ObjectId id;
|
||||||
|
|
||||||
private int usrId;
|
private int usrId;
|
||||||
private int hqId;
|
|
||||||
private short type;
|
|
||||||
private String title;
|
private String title;
|
||||||
private String name;
|
private String name; // Nachname
|
||||||
private String firstname;
|
private String firstname; // Vorname
|
||||||
private LocalDate birthdate;
|
|
||||||
|
// Firmen-/Adressdaten
|
||||||
|
private String company; // Firma
|
||||||
|
private String street; // Straße
|
||||||
|
private String houseNumber; // Hausnr
|
||||||
|
private String addressAddition; // Adresszusatz (optional)
|
||||||
|
private String zip; // Postleitzahl
|
||||||
|
private String city; // Stadt
|
||||||
|
|
||||||
@Indexed(unique = true)
|
@Indexed(unique = true)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
private String invitationEmail;
|
|
||||||
private String phone;
|
private String phone;
|
||||||
private String phone2;
|
private String phone2;
|
||||||
private String fax;
|
private String fax;
|
||||||
private String password;
|
private String password;
|
||||||
private byte isActivated;
|
private byte isActivated;
|
||||||
private String activationCode;
|
|
||||||
private byte isEmailConfirmed;
|
private byte isEmailConfirmed;
|
||||||
private byte isPasswordLost;
|
|
||||||
private String passwordCode;
|
private String passwordCode;
|
||||||
private LocalDateTime passwordTimestamp;
|
private LocalDateTime passwordTimestamp;
|
||||||
private LocalDateTime activationDate;
|
|
||||||
private LocalDateTime createdAt;
|
private LocalDateTime createdAt;
|
||||||
private LocalDateTime updatedAt;
|
private LocalDateTime updatedAt;
|
||||||
private Set<String> roles;
|
private Set<String> roles;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class AddJobService {
|
|||||||
job.setCreatedAt(now);
|
job.setCreatedAt(now);
|
||||||
job.setUpdatedAt(now);
|
job.setUpdatedAt(now);
|
||||||
job.setStatus(JobStatus.CREATED);
|
job.setStatus(JobStatus.CREATED);
|
||||||
job.setCreatedBy(securityService.getCurrentUsername());
|
job.setCreatedBy(securityService.getCurrentUserId().toHexString());
|
||||||
|
|
||||||
// Auftragsnummer generieren, falls nicht vorhanden
|
// Auftragsnummer generieren, falls nicht vorhanden
|
||||||
if (job.getJobNumber() == null || job.getJobNumber().isEmpty()) {
|
if (job.getJobNumber() == null || job.getJobNumber().isEmpty()) {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import com.vaadin.flow.component.html.H2;
|
|||||||
import com.vaadin.flow.component.notification.Notification;
|
import com.vaadin.flow.component.notification.Notification;
|
||||||
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.formlayout.FormLayout;
|
||||||
import com.vaadin.flow.component.textfield.PasswordField;
|
import com.vaadin.flow.component.textfield.PasswordField;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
@@ -31,6 +33,17 @@ public class RegisterView extends VerticalLayout {
|
|||||||
private TextField emailField;
|
private TextField emailField;
|
||||||
private PasswordField passwordField;
|
private PasswordField passwordField;
|
||||||
private PasswordField confirmPasswordField;
|
private PasswordField confirmPasswordField;
|
||||||
|
|
||||||
|
// Zusätzliche Pflichtfelder aus EditProfileView
|
||||||
|
private TextField firstNameField;
|
||||||
|
private TextField lastNameField;
|
||||||
|
private TextField phoneField;
|
||||||
|
private TextField companyField;
|
||||||
|
private TextField streetField;
|
||||||
|
private TextField houseNumberField;
|
||||||
|
private TextField zipField;
|
||||||
|
private TextField cityField;
|
||||||
|
|
||||||
private TextField codeField;
|
private TextField codeField;
|
||||||
private Button submitButton;
|
private Button submitButton;
|
||||||
private Button verifyButton;
|
private Button verifyButton;
|
||||||
@@ -58,7 +71,7 @@ public class RegisterView extends VerticalLayout {
|
|||||||
|
|
||||||
private VerticalLayout createFormContainer() {
|
private VerticalLayout createFormContainer() {
|
||||||
VerticalLayout container = new VerticalLayout();
|
VerticalLayout container = new VerticalLayout();
|
||||||
container.setWidth("400px");
|
container.setWidth("980px");
|
||||||
container.setPadding(true);
|
container.setPadding(true);
|
||||||
container.setSpacing(true);
|
container.setSpacing(true);
|
||||||
container.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
|
container.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.STRETCH);
|
||||||
@@ -98,6 +111,32 @@ public class RegisterView extends VerticalLayout {
|
|||||||
confirmPasswordField.setRequired(true);
|
confirmPasswordField.setRequired(true);
|
||||||
confirmPasswordField.setPlaceholder("Passwort wiederholen");
|
confirmPasswordField.setPlaceholder("Passwort wiederholen");
|
||||||
|
|
||||||
|
// Pflichtfelder aus EditProfileView
|
||||||
|
firstNameField = new TextField("Vorname");
|
||||||
|
firstNameField.setWidthFull();
|
||||||
|
firstNameField.setRequired(true);
|
||||||
|
lastNameField = new TextField("Nachname");
|
||||||
|
lastNameField.setWidthFull();
|
||||||
|
lastNameField.setRequired(true);
|
||||||
|
phoneField = new TextField("Telefonnummer");
|
||||||
|
phoneField.setWidthFull();
|
||||||
|
phoneField.setRequired(true);
|
||||||
|
companyField = new TextField("Firma");
|
||||||
|
companyField.setWidthFull();
|
||||||
|
companyField.setRequired(true);
|
||||||
|
streetField = new TextField("Straße");
|
||||||
|
streetField.setWidthFull();
|
||||||
|
streetField.setRequired(true);
|
||||||
|
houseNumberField = new TextField("Hausnr");
|
||||||
|
houseNumberField.setWidthFull();
|
||||||
|
houseNumberField.setRequired(true);
|
||||||
|
zipField = new TextField("Postleitzahl");
|
||||||
|
zipField.setWidthFull();
|
||||||
|
zipField.setRequired(true);
|
||||||
|
cityField = new TextField("Stadt");
|
||||||
|
cityField.setWidthFull();
|
||||||
|
cityField.setRequired(true);
|
||||||
|
|
||||||
codeField = new TextField("Bestätigungscode (6 Ziffern)");
|
codeField = new TextField("Bestätigungscode (6 Ziffern)");
|
||||||
codeField.setWidthFull();
|
codeField.setWidthFull();
|
||||||
codeField.setMaxLength(6);
|
codeField.setMaxLength(6);
|
||||||
@@ -132,8 +171,43 @@ public class RegisterView extends VerticalLayout {
|
|||||||
backButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
backButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
|
||||||
backButton.setWidthFull();
|
backButton.setWidthFull();
|
||||||
|
|
||||||
container.add(title, subtitle, emailField, passwordField, confirmPasswordField,
|
// Zweispaltiges Formular
|
||||||
submitButton, codeField, verifyButton, resendButton, backButton);
|
FormLayout form = new FormLayout();
|
||||||
|
form.setWidthFull();
|
||||||
|
form.setResponsiveSteps(
|
||||||
|
new FormLayout.ResponsiveStep("0", 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Erste Reihe: Zugangsdaten
|
||||||
|
form.add(emailField, passwordField, confirmPasswordField);
|
||||||
|
form.setColspan(emailField, 2);
|
||||||
|
|
||||||
|
// Personen-/Firmendaten
|
||||||
|
form.add(firstNameField, lastNameField);
|
||||||
|
form.add(phoneField, companyField);
|
||||||
|
form.add(streetField, houseNumberField);
|
||||||
|
form.add(zipField, cityField);
|
||||||
|
|
||||||
|
// Code und Verifikations-Buttons (ausgeblendet bis Versand)
|
||||||
|
form.add(codeField);
|
||||||
|
form.setColspan(codeField, 2);
|
||||||
|
|
||||||
|
// Button-Zeile: Verifizieren/Resenden nebeneinander
|
||||||
|
HorizontalLayout verifyRow = new HorizontalLayout(verifyButton, resendButton);
|
||||||
|
verifyRow.setWidthFull();
|
||||||
|
verifyRow.setSpacing(true);
|
||||||
|
verifyRow.setAlignItems(FlexComponent.Alignment.STRETCH);
|
||||||
|
verifyRow.setFlexGrow(1, verifyButton, resendButton);
|
||||||
|
form.add(verifyRow);
|
||||||
|
form.setColspan(verifyRow, 2);
|
||||||
|
|
||||||
|
// Haupt-Submit-Button und Zurück-Link über volle Breite
|
||||||
|
form.add(submitButton);
|
||||||
|
form.setColspan(submitButton, 2);
|
||||||
|
form.add(backButton);
|
||||||
|
form.setColspan(backButton, 2);
|
||||||
|
|
||||||
|
container.add(title, subtitle, form);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +247,56 @@ public class RegisterView extends VerticalLayout {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Weitere Pflichtfelder prüfen (aus Edit-Profile)
|
||||||
|
var firstName = firstNameField.getValue() != null ? firstNameField.getValue().trim() : "";
|
||||||
|
if (firstName.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie Ihren Vornamen ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
firstNameField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lastName = lastNameField.getValue() != null ? lastNameField.getValue().trim() : "";
|
||||||
|
if (lastName.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie Ihren Nachnamen ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
lastNameField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var phone = phoneField.getValue() != null ? phoneField.getValue().trim() : "";
|
||||||
|
if (phone.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie Ihre Telefonnummer ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
phoneField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var company = companyField.getValue() != null ? companyField.getValue().trim() : "";
|
||||||
|
if (company.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie den Firmennamen ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
companyField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var street = streetField.getValue() != null ? streetField.getValue().trim() : "";
|
||||||
|
if (street.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie die Straße ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
streetField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var houseNo = houseNumberField.getValue() != null ? houseNumberField.getValue().trim() : "";
|
||||||
|
if (houseNo.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie die Hausnummer ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
houseNumberField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var zip = zipField.getValue() != null ? zipField.getValue().trim() : "";
|
||||||
|
if (zip.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie die Postleitzahl ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
zipField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var city = cityField.getValue() != null ? cityField.getValue().trim() : "";
|
||||||
|
if (city.isEmpty()) {
|
||||||
|
Notification.show("Bitte geben Sie die Stadt ein.", 3000, Notification.Position.MIDDLE);
|
||||||
|
cityField.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Alles ok: Code erzeugen und senden
|
// Alles ok: Code erzeugen und senden
|
||||||
sendVerificationCode(email);
|
sendVerificationCode(email);
|
||||||
}
|
}
|
||||||
@@ -205,6 +329,17 @@ public class RegisterView extends VerticalLayout {
|
|||||||
emailField.setReadOnly(true);
|
emailField.setReadOnly(true);
|
||||||
passwordField.setReadOnly(true);
|
passwordField.setReadOnly(true);
|
||||||
confirmPasswordField.setReadOnly(true);
|
confirmPasswordField.setReadOnly(true);
|
||||||
|
|
||||||
|
// Zusätzliche Felder sperren
|
||||||
|
firstNameField.setReadOnly(true);
|
||||||
|
lastNameField.setReadOnly(true);
|
||||||
|
phoneField.setReadOnly(true);
|
||||||
|
companyField.setReadOnly(true);
|
||||||
|
streetField.setReadOnly(true);
|
||||||
|
houseNumberField.setReadOnly(true);
|
||||||
|
zipField.setReadOnly(true);
|
||||||
|
cityField.setReadOnly(true);
|
||||||
|
|
||||||
submitButton.setEnabled(false);
|
submitButton.setEnabled(false);
|
||||||
|
|
||||||
Notification.show("Ein Bestätigungscode wurde an " + email + " gesendet.", 4000, Notification.Position.MIDDLE);
|
Notification.show("Ein Bestätigungscode wurde an " + email + " gesendet.", 4000, Notification.Position.MIDDLE);
|
||||||
@@ -236,8 +371,24 @@ public class RegisterView extends VerticalLayout {
|
|||||||
// Code korrekt -> Benutzer erstellen
|
// Code korrekt -> Benutzer erstellen
|
||||||
var email = emailField.getValue().trim();
|
var email = emailField.getValue().trim();
|
||||||
var password = passwordField.getValue();
|
var password = passwordField.getValue();
|
||||||
|
var firstName = firstNameField.getValue() != null ? firstNameField.getValue().trim() : "";
|
||||||
|
var lastName = lastNameField.getValue() != null ? lastNameField.getValue().trim() : "";
|
||||||
|
var phone = phoneField.getValue() != null ? phoneField.getValue().trim() : "";
|
||||||
try {
|
try {
|
||||||
userService.createUser(email, password, "Benutzer", "Name");
|
var user = userService.createUser(email, password, firstName, lastName);
|
||||||
|
// Persistiere zusätzliche Profil-/Adressdaten
|
||||||
|
if (!phone.isBlank()) user.setPhone(phone);
|
||||||
|
var company = companyField.getValue() != null ? companyField.getValue().trim() : null;
|
||||||
|
var street = streetField.getValue() != null ? streetField.getValue().trim() : null;
|
||||||
|
var houseNo = houseNumberField.getValue() != null ? houseNumberField.getValue().trim() : null;
|
||||||
|
var zip = zipField.getValue() != null ? zipField.getValue().trim() : null;
|
||||||
|
var city = cityField.getValue() != null ? cityField.getValue().trim() : null;
|
||||||
|
user.setCompany(company);
|
||||||
|
user.setStreet(street);
|
||||||
|
user.setHouseNumber(houseNo);
|
||||||
|
user.setZip(zip);
|
||||||
|
user.setCity(city);
|
||||||
|
userService.save(user);
|
||||||
VaadinSession.getCurrent().setAttribute("flashMessage", "Registrierung erfolgreich. Bitte melden Sie sich an.");
|
VaadinSession.getCurrent().setAttribute("flashMessage", "Registrierung erfolgreich. Bitte melden Sie sich an.");
|
||||||
getUI().ifPresent(ui -> ui.navigate("login"));
|
getUI().ifPresent(ui -> ui.navigate("login"));
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import com.vaadin.flow.router.PageTitle;
|
|||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import de.assecutor.votianlt.model.Customer;
|
import de.assecutor.votianlt.model.Customer;
|
||||||
import de.assecutor.votianlt.pages.service.CustomerService;
|
import de.assecutor.votianlt.pages.service.CustomerService;
|
||||||
|
import de.assecutor.votianlt.security.SecurityService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
@@ -20,11 +21,13 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
public class ShowCustomersView extends VerticalLayout {
|
public class ShowCustomersView extends VerticalLayout {
|
||||||
|
|
||||||
private final CustomerService customerService;
|
private final CustomerService customerService;
|
||||||
|
private final SecurityService securityService;
|
||||||
private final Grid<Customer> grid = new Grid<>(Customer.class, false);
|
private final Grid<Customer> grid = new Grid<>(Customer.class, false);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ShowCustomersView(CustomerService customerService) {
|
public ShowCustomersView(CustomerService customerService, SecurityService securityService) {
|
||||||
this.customerService = customerService;
|
this.customerService = customerService;
|
||||||
|
this.securityService = securityService;
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
setPadding(true);
|
setPadding(true);
|
||||||
setSpacing(true);
|
setSpacing(true);
|
||||||
@@ -86,6 +89,10 @@ public class ShowCustomersView extends VerticalLayout {
|
|||||||
|
|
||||||
private void loadData() {
|
private void loadData() {
|
||||||
var customers = customerService.findAll();
|
var customers = customerService.findAll();
|
||||||
grid.setItems(customers);
|
var currentUserId = securityService.getCurrentUserId();
|
||||||
|
var ownCustomers = customers.stream()
|
||||||
|
.filter(c -> c.getCreatedBy() != null && c.getCreatedBy().equals(currentUserId))
|
||||||
|
.toList();
|
||||||
|
grid.setItems(ownCustomers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import com.vaadin.flow.router.Route;
|
|||||||
import de.assecutor.votianlt.model.Job;
|
import de.assecutor.votianlt.model.Job;
|
||||||
import de.assecutor.votianlt.model.JobStatus;
|
import de.assecutor.votianlt.model.JobStatus;
|
||||||
import de.assecutor.votianlt.repository.JobRepository;
|
import de.assecutor.votianlt.repository.JobRepository;
|
||||||
|
import de.assecutor.votianlt.security.SecurityService;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
@@ -24,11 +25,13 @@ public class ShowJobsView extends VerticalLayout {
|
|||||||
private final DatePicker startDate = new DatePicker("Startdatum");
|
private final DatePicker startDate = new DatePicker("Startdatum");
|
||||||
private final DatePicker endDate = new DatePicker("Enddatum");
|
private final DatePicker endDate = new DatePicker("Enddatum");
|
||||||
private final JobRepository jobRepository;
|
private final JobRepository jobRepository;
|
||||||
|
private final SecurityService securityService;
|
||||||
private final Grid<Job> grid = new Grid<>(Job.class, false);
|
private final Grid<Job> grid = new Grid<>(Job.class, false);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ShowJobsView(JobRepository jobRepository) {
|
public ShowJobsView(JobRepository jobRepository, SecurityService securityService) {
|
||||||
this.jobRepository = jobRepository;
|
this.jobRepository = jobRepository;
|
||||||
|
this.securityService = securityService;
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
setPadding(true);
|
setPadding(true);
|
||||||
setSpacing(true);
|
setSpacing(true);
|
||||||
@@ -88,16 +91,20 @@ public class ShowJobsView extends VerticalLayout {
|
|||||||
java.time.LocalDateTime startDt = start != null ? start.atStartOfDay() : java.time.LocalDate.now().minusDays(30).atStartOfDay();
|
java.time.LocalDateTime startDt = start != null ? start.atStartOfDay() : java.time.LocalDate.now().minusDays(30).atStartOfDay();
|
||||||
java.time.LocalDateTime endDt = end != null ? end.atTime(23,59,59) : java.time.LocalDate.now().atTime(23,59,59);
|
java.time.LocalDateTime endDt = end != null ? end.atTime(23,59,59) : java.time.LocalDate.now().atTime(23,59,59);
|
||||||
|
|
||||||
// Hole Aufträge im Zeitraum und filtere auf offene Status
|
// Aktuellen Benutzer (ObjectId Hex) ermitteln
|
||||||
|
String currentUserIdHex = securityService.getCurrentUserId().toHexString();
|
||||||
|
|
||||||
|
// Hole Aufträge im Zeitraum, filtere auf offenen Status und auf den angemeldeten Benutzer
|
||||||
var inRange = jobRepository.findByCreatedAtBetween(startDt, endDt);
|
var inRange = jobRepository.findByCreatedAtBetween(startDt, endDt);
|
||||||
var open = inRange.stream()
|
var openAndOwn = inRange.stream()
|
||||||
.filter(j -> j.getStatus() == JobStatus.CREATED
|
.filter(j -> j.getStatus() == JobStatus.CREATED
|
||||||
|| j.getStatus() == JobStatus.IN_PROGRESS
|
|| j.getStatus() == JobStatus.IN_PROGRESS
|
||||||
|| j.getStatus() == JobStatus.PICKUP_SCHEDULED
|
|| j.getStatus() == JobStatus.PICKUP_SCHEDULED
|
||||||
|| j.getStatus() == JobStatus.PICKED_UP
|
|| j.getStatus() == JobStatus.PICKED_UP
|
||||||
|| j.getStatus() == JobStatus.IN_TRANSIT)
|
|| j.getStatus() == JobStatus.IN_TRANSIT)
|
||||||
|
.filter(j -> j.getCreatedBy() != null && j.getCreatedBy().equals(currentUserIdHex))
|
||||||
.toList();
|
.toList();
|
||||||
grid.setItems(open);
|
grid.setItems(openAndOwn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportToCsv() {
|
private void exportToCsv() {
|
||||||
|
|||||||
Reference in New Issue
Block a user