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.pages.app.detail.action;
35
36 import info.magnolia.config.registry.DefinitionProvider;
37 import info.magnolia.context.Context;
38 import info.magnolia.i18nsystem.I18nizer;
39 import info.magnolia.jcr.util.NodeNameHelper;
40 import info.magnolia.jcr.util.NodeTypes;
41 import info.magnolia.pages.app.data.NewRenderableNodeWrapper;
42 import info.magnolia.pages.app.data.RenderableNodeMetadata;
43 import info.magnolia.pages.app.detail.PageEditorStatus;
44 import info.magnolia.rendering.template.TemplateDefinition;
45 import info.magnolia.rendering.template.registry.TemplateDefinitionRegistry;
46 import info.magnolia.ui.CloseHandler;
47 import info.magnolia.ui.UIComponent;
48 import info.magnolia.ui.ValueContext;
49 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
50 import info.magnolia.ui.datasource.optionlist.Option;
51 import info.magnolia.ui.dialog.DialogDefinition;
52 import info.magnolia.ui.dialog.DialogDefinitionRegistry;
53 import info.magnolia.ui.editor.FormView;
54 import info.magnolia.ui.editor.LocaleContext;
55 import info.magnolia.ui.observation.DatasourceObservation;
56 import info.magnolia.ui.vaadin.gwt.client.shared.AbstractElement;
57 import info.magnolia.ui.vaadin.gwt.client.shared.ComponentElement;
58
59 import java.util.Optional;
60
61 import javax.inject.Inject;
62 import javax.jcr.Node;
63 import javax.jcr.Session;
64
65 import com.machinezoo.noexception.Exceptions;
66 import com.vaadin.data.BinderValidationStatus;
67 import com.vaadin.ui.Window;
68
69
70
71
72
73 public class CreateComponentAction extends EditElementAction {
74
75 static final String NEW_COMPONENT_POSITION = "mgnl:position";
76
77
78
79 static final String COMPONENT_POSITION_TOP = "top";
80
81 private AbstractElement parentElement;
82
83 private final NodeNameHelper nodeNameHelper;
84 private final FormView<Node> formView;
85 private final TemplateDefinitionRegistry templateDefinitionRegistry;
86 private final DatasourceObservation.Manual datasourceObservation;
87 private final CloseHandler closeHandler;
88
89 @Inject
90 public CreateComponentAction(CreateComponentActionDefinition definition, UIComponent parentView, LocaleContext localeContext, I18NAuthoringSupport i18NAuthoringSupport, DialogDefinitionRegistry dialogDefinitionRegistry, I18nizer i18nizer, Context context, ValueContext<Node> valueContext, PageEditorStatus pageEditorStatus, NodeNameHelper nodeNameHelper, FormView<Node> formView, TemplateDefinitionRegistry templateDefinitionRegistry, DatasourceObservation.Manual datasourceObservation, CloseHandler closeHandler) {
91 super(definition, parentView, localeContext, i18NAuthoringSupport, dialogDefinitionRegistry, i18nizer, context, valueContext, pageEditorStatus);
92 this.nodeNameHelper = nodeNameHelper;
93 this.formView = formView;
94 this.templateDefinitionRegistry = templateDefinitionRegistry;
95 this.datasourceObservation = datasourceObservation;
96 this.closeHandler = closeHandler;
97 }
98
99 @Override
100 public void execute() {
101 if (formView.validate().stream().allMatch(BinderValidationStatus::isOk)) {
102 Exceptions.wrap().run(() -> {
103 super.execute();
104 final Node parent = getValueContext().getSingleOrThrow();
105 final Session session = parent.getSession();
106 final String componentName = nodeNameHelper.getUniqueName(parent, "0");
107 final Node component = parent.addNode(componentName, NodeTypes.Component.NAME);
108
109
110 final String templateId = formView.<String>getPropertyValue(NodeTypes.Renderable.TEMPLATE)
111 .orElseThrow(IllegalArgumentException::new);
112
113 final Boolean onTop = formView.<Option>getPropertyValue(NEW_COMPONENT_POSITION)
114 .map(Option::getValue)
115 .map(COMPONENT_POSITION_TOP::equals)
116 .orElse(false);
117
118
119 final String dialog = Optional.of(templateId)
120 .map(templateDefinitionRegistry::getProvider)
121 .map(DefinitionProvider::get)
122 .map(TemplateDefinition::getDialog)
123 .orElse(null);
124
125 this.parentElement = getPageEditorStatus().getSelectedElement();
126 getPageEditorStatus().setSelectedElement(new ComponentElement(session.getWorkspace().getName(), component.getPath(), dialog));
127
128 RenderableNodeMetadata renderableNodeMetadata = RenderableNodeMetadata.builder()
129 .templateId(templateId)
130 .orderToTop(onTop)
131 .build();
132
133 getValueContext().set(new NewRenderableNodeWrapper(component, renderableNodeMetadata));
134
135
136
137 closeHandler.close();
138
139 if (dialog == null) {
140 session.save();
141 datasourceObservation.trigger();
142 } else {
143 super.execute();
144 }
145 });
146 }
147 }
148
149 @Override
150 protected DialogDefinition getDialogDefinition(DialogDefinitionRegistry dialogDefinitionRegistry, I18nizer i18nizer) {
151 if (getPageEditorStatus().getSelectedElement() instanceof ComponentElement) {
152 return super.getDialogDefinition(dialogDefinitionRegistry, i18nizer);
153 }
154 return null;
155 }
156
157 @Override
158 protected CloseHandler getCloseHandler(Window dialog) {
159 return () -> {
160
161 getValueContext().getSingle()
162 .filter(Node::isNew)
163 .ifPresent(any -> getPageEditorStatus().setSelectedElement(parentElement));
164
165 dialog.close();
166 };
167 }
168 }