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.layout;
35
36 import info.magnolia.objectfactory.Components;
37 import info.magnolia.ui.field.EditorPropertyDefinition;
38 import info.magnolia.ui.field.FormRowOutliner;
39 import info.magnolia.ui.field.NamedFieldDefinition;
40 import info.magnolia.ui.framework.layout.field.FieldComponentDecorator;
41 import info.magnolia.ui.vaadin.extension.FocusFieldCaption;
42
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Map.Entry;
46 import java.util.stream.Collectors;
47 import java.util.stream.StreamSupport;
48
49 import javax.inject.Inject;
50
51 import org.apache.commons.lang3.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.vaadin.ui.Component;
56 import com.vaadin.ui.FormLayout;
57 import com.vaadin.ui.TabSheet;
58 import com.vaadin.ui.themes.ValoTheme;
59
60
61
62
63
64
65 public class TabbedLayoutProducer implements FieldLayoutProducer<TabbedLayoutDefinition> {
66
67 private static final Logger log = LoggerFactory.getLogger(TabbedLayoutProducer.class);
68
69 private final FieldComponentDecorator fieldComponentDecorator;
70
71 @Inject
72 protected TabbedLayoutProducer(FieldComponentDecorator fieldComponentDecorator) {
73 this.fieldComponentDecorator = fieldComponentDecorator;
74 }
75
76
77
78
79 @Deprecated
80 public TabbedLayoutProducer() {
81 this(Components.getComponent(FieldComponentDecorator.class));
82 }
83
84 @Override
85 public Component createLayout(TabbedLayoutDefinition definition, Map<EditorPropertyDefinition, Component> mappings) {
86 TabSheet tabSheet = new TabSheet();
87
88 tabSheet.addStyleNames(ValoTheme.TABSHEET_FRAMED);
89
90 List<TabDefinition> tabs = definition.getTabs();
91 Map<String, Entry<EditorPropertyDefinition, Component>> fieldNameMappings = mappings.entrySet().stream()
92 .collect(Collectors.toMap(def -> def.getKey().getName(), entry -> entry));
93
94 if (tabs.size() == 1) {
95 tabSheet.addStyleName("single-tab");
96 }
97
98 for (TabDefinition tabDefinition : tabs) {
99 FormLayout formSection = new FormLayout();
100 formSection.setWidth("100%");
101 formSection.setMargin(true);
102
103 for (NamedFieldDefinition tabField : tabDefinition.getFields()) {
104 String fieldName = tabField.getName();
105 if (fieldNameMappings.containsKey(fieldName)) {
106 Entry<EditorPropertyDefinition, Component> tabFieldMapping = fieldNameMappings.get(fieldName);
107 Component decoratedField = createFieldComponentLayout(tabFieldMapping.getValue(), tabFieldMapping.getKey());
108 FormRowOutliner.considerOutlining(decoratedField, tabFieldMapping.getKey());
109 formSection.addComponent(decoratedField);
110 } else {
111 log.warn(String.format("Could not retrieve component field named %s from mappings", fieldName));
112 }
113 }
114
115 tabSheet.addTab(formSection, StringUtils.defaultIfBlank(tabDefinition.getLabel(), tabDefinition.getName()));
116 FocusFieldCaption.focusCaptionOf(formSection);
117 }
118
119 tabSheet.addAttachListener(event -> focusFirstField(tabSheet));
120 tabSheet.addSelectedTabChangeListener(event -> focusFirstField(tabSheet));
121
122 return tabSheet;
123 }
124
125 private Component createFieldComponentLayout(Component component, EditorPropertyDefinition editorPropertyDefinition) {
126 return fieldComponentDecorator.decorateField(component, editorPropertyDefinition);
127 }
128
129 private void focusFirstField(TabSheet tabSheet) {
130 if (tabSheet.getSelectedTab() instanceof FormLayout) {
131 StreamSupport.stream(((FormLayout) tabSheet.getSelectedTab()).spliterator(), false)
132 .filter(field -> field instanceof Component.Focusable)
133 .findFirst()
134 .ifPresent(field -> ((Component.Focusable) field).focus());
135 }
136 }
137 }