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.framework.overlay;
35
36 import info.magnolia.ui.DialogBuilder;
37 import info.magnolia.ui.framework.ViewProvider;
38 import info.magnolia.ui.framework.chooser.Chooser;
39 import info.magnolia.ui.framework.chooser.definition.ChooserDefinition;
40 import info.magnolia.ui.framework.ioc.SessionStore;
41 import info.magnolia.ui.framework.ioc.UiContextBoundComponentProvider;
42 import info.magnolia.ui.framework.ioc.UiContextReference;
43
44 import java.util.Optional;
45 import java.util.concurrent.CompletableFuture;
46 import java.util.concurrent.atomic.AtomicBoolean;
47
48 import javax.inject.Inject;
49 import javax.inject.Singleton;
50
51 import org.apache.commons.lang3.StringUtils;
52
53 import com.google.common.collect.Lists;
54 import com.vaadin.ui.Button;
55 import com.vaadin.ui.UI;
56
57 import lombok.AccessLevel;
58 import lombok.AllArgsConstructor;
59 import lombok.Getter;
60
61
62
63
64 @Singleton
65 public class ChooserController {
66
67 @Inject
68 public ChooserController() {
69 }
70
71 private <T> CompletableFuture<ChooseResult<T>> openChooser(Chooser<T> chooser) {
72 CompletableFuture<ChooseResult<T>> result = new CompletableFuture<>();
73 AtomicBoolean dialogCommited = new AtomicBoolean(false);
74
75 Button cancel = new Button("Cancel");
76 cancel.addStyleName("v-button-secondary");
77 Button choose = new Button("Select");
78 choose.addStyleName("v-button-commit");
79 choose.addClickListener(event -> {
80 dialogCommited.set(true);
81 UI.getCurrent().access(() ->
82 result.complete(ChooseResult.ofChoice(Optional.ofNullable(chooser.getChoice()))));
83 });
84
85 DialogBuilder.dialog()
86 .withTitle(StringUtils.defaultIfBlank(chooser.getTitle(), "Choose"))
87 .withContent(chooser.asVaadinComponent())
88 .withActions(Lists.newArrayList(cancel, choose))
89 .buildAndOpen()
90 .addCloseListener(e -> {
91 chooser.destroy();
92 if (!dialogCommited.get()) {
93 result.complete(ChooseResult.ofNoChoice());
94 }
95 });
96
97 return result;
98 }
99
100 public <T, C extends Chooser<T>> CompletableFuture<ChooseResult<T>> openChooser(ChooserDefinition<T, ? extends C> definition) {
101 return this.openChooser(definition, null);
102 }
103
104 public <T, C extends Chooser<T>> CompletableFuture<ChooseResult<T>> openChooser(ChooserDefinition<T, ? extends C> definition, T initialChoice) {
105 Chooser<T> chooser = getViewProvider(definition.getName()).create(definition);
106 chooser.setChoice(initialChoice);
107 return openChooser(chooser);
108 }
109
110 private ViewProvider getViewProvider(String name) {
111 UiContextReference contextReference = UiContextReference.ofView(name, UiContextReference.ofCurrentUi());
112 SessionStore.access().createBeanStore(contextReference);
113
114 return new UiContextBoundComponentProvider(contextReference).getComponent(ViewProvider.class);
115 }
116
117
118
119
120
121 @Getter
122 @AllArgsConstructor(access = AccessLevel.PRIVATE)
123 public static class ChooseResult<T> {
124 boolean chosen;
125 Optional<T> choice;
126
127 static <T> ChooseResult<T> ofNoChoice() {
128 return new ChooseResult<>(false, Optional.empty());
129 }
130
131 static <T> ChooseResult<T> ofChoice(Optional<T> choice) {
132 return new ChooseResult<>(true, choice);
133 }
134 }
135 }