package com.example.widgets;
import com.example.data.ChartDataService;
import com.example.data.DashboardFilter;
import com.vaadin.flow.shared.Registration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
/**
* The dashboard's current {@link DashboardFilter} plus the widgets listening to
* it — the small event bus between the filter bar (which sets) and the widgets
* (which subscribe and re-request their data from
* {@link ChartDataService}). Neither side knows the other.
*
* One context per dashboard instance, deliberately not a Spring bean: it is
* view state, so nothing leaks between users, tabs or visits. For the same
* reason the filter is not persisted — a reload starts from
* {@link DashboardFilter#defaults()}, unlike the grid layout, which
* {@code GridStackLayout} keeps in {@code localStorage}.
*/
public class DashboardContext {
private final List> listeners = new ArrayList<>();
private DashboardFilter filter = DashboardFilter.defaults();
public DashboardFilter getFilter() {
return filter;
}
/**
* Applies a filter and hands it to every listener. A filter equal to the
* current one changes nothing and notifies nobody, so re-picking the same
* value in the filter bar does not make the widgets re-fetch.
*/
public void setFilter(DashboardFilter filter) {
Objects.requireNonNull(filter, "filter");
if (this.filter.equals(filter)) {
return;
}
this.filter = filter;
// Over a copy: a listener may unsubscribe while being notified (a
// widget closing in reaction to the update).
List.copyOf(listeners).forEach(listener -> listener.accept(filter));
}
/**
* Subscribes to later filter changes. The listener is not called with the
* current filter — a widget is built from it already — so a subscriber
* feeds itself once and then only reacts.
*/
public Registration addFilterChangeListener(Consumer listener) {
listeners.add(listener);
return () -> listeners.remove(listener);
}
/** How many widgets are currently listening; for tests and diagnostics. */
public int getListenerCount() {
return listeners.size();
}
}