io.devbench.uibuilder.components.editorwindow.UIBuilderEditorWindow Maven / Gradle / Ivy
/*
*
* Copyright © 2018 Webvalto Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.devbench.uibuilder.components.editorwindow;
import com.vaadin.flow.component.HasElement;
import com.vaadin.flow.component.Synchronize;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.internal.nodefeature.VirtualChildrenList;
import io.devbench.uibuilder.api.components.HasItemType;
import io.devbench.uibuilder.api.components.HasRawElementComponent;
import io.devbench.uibuilder.api.components.form.UIBuilderDetailCapable;
import io.devbench.uibuilder.api.listeners.BackendAttachListener;
import io.devbench.uibuilder.components.confirmdialog.ConfirmDialog;
import io.devbench.uibuilder.components.detailpanel.UIBuilderDetailPanel;
import io.devbench.uibuilder.components.form.PropertyValidityDescriptorFilterable;
import io.devbench.uibuilder.components.form.validator.PropertyValidityDescriptor;
import io.devbench.uibuilder.components.masterdetail.MasterDetailControllerEventListener;
import io.devbench.uibuilder.components.window.UIBuilderWindow;
import lombok.Getter;
import org.jsoup.nodes.Element;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.Predicate;
import static com.vaadin.flow.internal.nodefeature.NodeProperties.INJECT_BY_ID;
import static io.devbench.uibuilder.core.utils.ElementCollector.ID;
@Tag(UIBuilderEditorWindow.TAG_NAME)
@JsModule("./uibuilder-editor-window/src/uibuilder-editor-window.js")
public class UIBuilderEditorWindow extends HasRawElementComponent
implements HasElement, BackendAttachListener, MasterDetailControllerEventListener,
UIBuilderDetailCapable, PropertyValidityDescriptorFilterable, HasItemType {
static final String TAG_NAME = "uibuilder-editor-window";
static final String PROP_READONLY = "readonly";
private static final String VALUE_CHANGED = "value-changed";
private UIBuilderWindow window;
private ConfirmDialog confirm;
@Getter
private UIBuilderDetailPanel detailPanel;
private Class itemType;
@Override
public Predicate getPropertyValidityDescriptorPredicate() {
Objects.requireNonNull(detailPanel, "Could not get detail panel before attach");
return detailPanel.getPropertyValidityDescriptorPredicate();
}
@Override
public void setPropertyValidityDescriptorPredicate(Predicate propertyValidityDescriptorPredicate) {
Objects.requireNonNull(detailPanel, "Could not get detail panel before attach");
detailPanel.setPropertyValidityDescriptorPredicate(propertyValidityDescriptorPredicate);
}
@Override
public void onAttached() {
VirtualChildrenList virtualChildrenList = getVirtualChildrenList();
window = injectById(virtualChildrenList, new UIBuilderWindow(), "window");
confirm = injectById(virtualChildrenList, new ConfirmDialog(), "confirm");
detailPanel = injectById(virtualChildrenList, createDetailPanel(), "detailPanel");
detailPanel.getElement().callJsFunction("_initInternalForm");
confirm.onAttached();
detailPanel.onAttached();
getElement().addEventListener("close", e -> window.setOpened(false));
}
public void setChangedOnlyValidation(boolean changedOnlyValidation) {
detailPanel.setChangedOnlyValidation(changedOnlyValidation);
}
public boolean isChangedOnlyValidation() {
return detailPanel.isChangedOnlyValidation();
}
@Override
public Class getItemType() {
return itemType;
}
@Override
@SuppressWarnings("unchecked")
public void setItemType(Class> itemType) {
this.itemType = (Class) itemType;
}
@Override
public void edit(T item) {
detailPanel.setItem(item);
window.setOpened(true);
}
@Override
public void create(T item) {
detailPanel.setItem(item);
detailPanel.getElement().callJsFunction("markNewItem");
window.setOpened(true);
}
@Override
public void save(T item) {
resetValueChanged();
close();
}
@Override
public void reset() {
resetValueChanged();
}
@Override
public void cancel() {
resetValueChanged();
}
private void resetValueChanged() {
getElement().callJsFunction("_resetValueChanged");
}
public void close() {
window.setOpened(false);
}
@Override
public T getItem() {
return detailPanel.getItem();
}
@Override
public void setItem(T item) {
detailPanel.setItem(item);
}
public boolean isOpen() {
return "true".equals(window.getOpened());
}
private COMPONENT injectById(VirtualChildrenList virtualChildrenList, COMPONENT component, String id) {
virtualChildrenList.append(component.getElement().getNode(), INJECT_BY_ID, id);
return component;
}
private UIBuilderDetailPanel createDetailPanel() {
UIBuilderDetailPanel detailPanel = new UIBuilderDetailPanel<>();
detailPanel.setRawElement(createRawDetailPanel());
return detailPanel;
}
private Element createRawDetailPanel() {
org.jsoup.nodes.Element element = new org.jsoup.nodes.Element(UIBuilderDetailPanel.TAG_NAME);
element.attr(ID, "detailPanel");
element.append(getRawElement().html());
return element;
}
private VirtualChildrenList getVirtualChildrenList() {
return getElement().getNode().getFeature(VirtualChildrenList.class);
}
public void setInternalFormDirty() {
detailPanel.setInternalFormDirty();
}
@Synchronize({"readonly-changed", "detail-ready"})
public boolean isReadonly() {
return getElement().getProperty(PROP_READONLY, false);
}
public void setReadonly(Boolean readonly) {
getElement().setProperty(PROP_READONLY, readonly);
}
}