1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.contentapp.browser;
35
36 import info.magnolia.objectfactory.ComponentProvider;
37 import info.magnolia.ui.contentapp.configuration.GridViewDefinition;
38 import info.magnolia.ui.framework.ioc.Destructible;
39
40 import java.util.stream.Stream;
41
42 import org.apache.commons.lang3.StringUtils;
43
44 import com.vaadin.data.PropertySet;
45 import com.vaadin.data.provider.DataProvider;
46 import com.vaadin.icons.VaadinIcons;
47 import com.vaadin.server.FontIcon;
48 import com.vaadin.shared.data.sort.SortDirection;
49 import com.vaadin.ui.Grid;
50 import com.vaadin.ui.components.grid.HeaderCell;
51 import com.vaadin.ui.components.grid.HeaderRow;
52
53
54
55
56
57
58
59 public abstract class GridViewPresenter<T> implements Destructible {
60
61 protected final GridViewDefinition<T> definition;
62
63 protected final ComponentProvider componentProvider;
64
65 private final ActionExecutionService actionExecutionService;
66
67 private PropertySet<T> propertySet = null;
68
69 protected DataProvider<T,?> dataProvider = null;
70
71 protected Grid<T> grid = null;
72
73 protected GridViewPresenter(GridViewDefinition<T> viewDefinition, ComponentProvider componentProvider, ActionExecutionService actionExecutionService) {
74 this.definition = viewDefinition;
75 this.componentProvider = componentProvider;
76 this.actionExecutionService = actionExecutionService;
77 }
78
79 protected abstract DataProvider<T, ?> createDataProvider();
80
81 protected abstract PropertySet<T> createPropertySet();
82
83 public Grid<T> grid() {
84 if (this.grid == null) {
85 this.grid = createGrid();
86
87 GridColumnConfigurer<T> columnConfigurer = componentProvider.newInstance(GridColumnConfigurer.class, definition, propertySet());
88 grid.setDataProvider(dataProvider());
89 columnConfigurer.configureColumns(grid);
90
91 grid.addSortListener(event -> event.getSortOrder()
92 .forEach(sortOrder -> {
93 HeaderRow headerRow = grid.getDefaultHeaderRow();
94
95 grid.getColumns().stream()
96 .map(headerRow::getCell)
97 .forEach(headerCell -> headerCell.setHtml(headerCell.getText()));
98
99 HeaderCell headerCell = headerRow.getCell(sortOrder.getSorted());
100 FontIcon icon = sortOrder.getDirection() == SortDirection.ASCENDING ? VaadinIcons.ARROWS_LONG_UP : VaadinIcons.ARROW_LONG_DOWN;
101 headerCell.setHtml(headerCell.getText() + " " + icon.getHtml());
102 })
103 );
104 }
105
106 return grid;
107 }
108
109 protected boolean isPropertyEditable(Grid.Column property, T item) {
110 return definition.getColumns().stream()
111 .filter(columnDefinition -> StringUtils.equals(columnDefinition.getName(), property.getId()))
112 .findFirst()
113 .map(columnDefinition -> actionExecutionService.getAvailabilityFilter(Stream.of(item)).test(columnDefinition.getEditor().getAvailability()))
114 .orElse(false);
115 }
116
117 protected Grid<T> createGrid() {
118 return new MagnoliaGrid<>(
119 propertySet(),
120 this::isItemAvailable,
121 this::isPropertyEditable);
122 }
123
124 protected DataProvider<T, ?> dataProvider() {
125 if (this.dataProvider == null) {
126 this.dataProvider = createDataProvider();
127 }
128 return this.dataProvider;
129 }
130
131 protected PropertySet<T> propertySet() {
132 if (this.propertySet == null) {
133 this.propertySet = createPropertySet();
134 }
135 return this.propertySet;
136 }
137
138 public boolean isItemAvailable(T item) {
139 return true;
140 }
141 }