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.field.factory;
35
36 import info.magnolia.objectfactory.ComponentProvider;
37 import info.magnolia.objectfactory.Components;
38 import info.magnolia.ui.datasource.ItemResolver;
39 import info.magnolia.ui.editor.ItemPreviewDefinition;
40 import info.magnolia.ui.field.LinkField;
41 import info.magnolia.ui.field.LinkFieldDefinition;
42 import info.magnolia.ui.field.SelectFieldSupport;
43 import info.magnolia.ui.framework.overlay.ChooserController;
44 import info.magnolia.ui.framework.overlay.ChooserController.ChooseResult;
45 import info.magnolia.ui.preview.ItemPreviewComponent;
46
47 import java.util.Optional;
48 import java.util.concurrent.CompletableFuture;
49
50 import javax.inject.Inject;
51
52 import com.vaadin.data.HasValue;
53 import com.vaadin.ui.ComboBox;
54
55
56
57
58
59
60 public class LinkFieldFactory<T, D extends LinkFieldDefinition<T>> extends ComboBoxFieldFactory<T, LinkFieldDefinition<T>> {
61
62 private final ChooserController chooserController;
63
64 @Inject
65 public LinkFieldFactory(D definition, ComponentProvider componentProvider, ChooserController chooserController, SelectFieldSupport<T> selectFieldSupport) {
66 super(definition, componentProvider, selectFieldSupport);
67
68 if (definition.getChooser() == null) {
69 throw new IllegalArgumentException("Could not find a chooser dialog definition at LinkField definition " + definition.getName());
70 }
71
72 this.chooserController = chooserController;
73 }
74
75
76
77
78 @Deprecated
79 public LinkFieldFactory(LinkFieldDefinition<T> definition, ComponentProvider componentProvider, ItemResolver<T> itemResolver, ChooserController chooserController) {
80 this((D) definition, componentProvider, chooserController, Components.getComponent(SelectFieldSupport.class));
81 }
82
83 @Override
84 public HasValue<T> createField() {
85 LinkField<T> linkField = new LinkField<>((ComboBox<T>) super.createField());
86 linkField.setCaption(getDefinition().getLabel());
87 linkField.setButtonCaptionNew(getDefinition().getButtonSelectNewLabel());
88 linkField.setButtonCaptionOther(getDefinition().getButtonSelectOtherLabel());
89 linkField.setEditable(getDefinition().isEditable());
90 linkField.setDisableOnClick(true);
91 linkField.addClickListener(event -> openChooser(linkField));
92
93 newItemPreviewComponent().ifPresent(itemPreviewComponent -> {
94 linkField.addValueChangeListener(event -> {
95 T item = event.getValue();
96 itemPreviewComponent.onValueChange(item);
97 itemPreviewComponent.setVisible(item != null);
98 });
99 linkField.setContentPreview(itemPreviewComponent);
100 });
101
102 return linkField;
103 }
104
105 CompletableFuture<ChooseResult<T>> openChooser(LinkField<T> linkField) {
106 return chooserController.openChooser(getDefinition().getChooser(), linkField.getValue())
107 .whenComplete((ChooseResult<T> result, Throwable err) -> {
108 linkField.setEnabled(true);
109 if (err != null) {
110 throw new RuntimeException(err);
111 }
112 result.getChoice().ifPresent(linkField::setValue);
113 });
114 }
115
116 protected Optional<? extends ItemPreviewComponent<T>> newItemPreviewComponent() {
117 return Optional.ofNullable(getDefinition().getPreview())
118 .map(ItemPreviewDefinition::getImplementationClass)
119 .map(clazz -> componentProvider.newInstance(clazz));
120 }
121
122 }