<commit_before>/*
 * Copyright 2015-2016 Red Hat, Inc, and individual contributors.
 *
 * 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 org.jboss.hal.core.mbui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

import com.google.common.collect.Iterables;
import elemental2.dom.HTMLElement;
import org.jboss.gwt.elemento.core.Elements;
import org.jboss.gwt.elemento.core.IsElement;
import org.jboss.hal.ballroom.Attachable;
import org.jboss.hal.ballroom.LabelBuilder;
import org.jboss.hal.ballroom.Pages;
import org.jboss.hal.ballroom.Tabs;
import org.jboss.hal.ballroom.form.Form;
import org.jboss.hal.ballroom.form.FormItemProvider;
import org.jboss.hal.ballroom.form.FormValidation;
import org.jboss.hal.ballroom.table.Column;
import org.jboss.hal.ballroom.table.InlineAction;
import org.jboss.hal.ballroom.table.Table;
import org.jboss.hal.core.ComplexAttributeOperations;
import org.jboss.hal.core.CrudOperations;
import org.jboss.hal.core.mbui.form.ModelNodeForm;
import org.jboss.hal.core.mbui.table.ModelNodeTable;
import org.jboss.hal.dmr.ModelNode;
import org.jboss.hal.dmr.NamedNode;
import org.jboss.hal.dmr.Operation;
import org.jboss.hal.dmr.Property;
import org.jboss.hal.dmr.ResourceAddress;
import org.jboss.hal.meta.AddressTemplate;
import org.jboss.hal.meta.Metadata;
import org.jboss.hal.resources.Ids;
import org.jboss.hal.resources.Names;
import org.jboss.hal.spi.Callback;
import org.jetbrains.annotations.NonNls;

import static elemental2.dom.DomGlobal.alert;
import static java.util.Collections.singletonList;
import static org.jboss.gwt.elemento.core.Elements.h;
import static org.jboss.gwt.elemento.core.Elements.p;
import static org.jboss.gwt.elemento.core.Elements.section;
import static org.jboss.hal.dmr.ModelDescriptionConstants.*;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeBoolean;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeGet;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeList;
import static org.jboss.hal.dmr.ModelNodeHelper.storeIndex;

/**
 * Master detail element for a resource with support for n complex attributes of type {@code OBJECT} and one
 * complex attribute of type {@code LIST}.
 *
 * <p>This class provides the following features:</p>
 * <ul>
 * <li>Table for the main resource with add and remove buttons.</li>
 * <li>Form with all simple configuration attributes of the main resource.</li>
 * <li>A tab for each complex attribute of type {@code OBJECT}. The tab contains a form to add, save, reset and remove
 * the complex attribute (remove is only available if the complex attribute is not required).</li>
 * <li>If there's a complex attribute of type {@code LIST}, the table contains a link to a sub-page. The sub-page
 * contains a table and a form to CRUD the elements of the complex attribute. Only simple attributes in the complex
 * attribute of type {@code LIST} are supported.</li>
 * <li>All CRUD actions are delegated to {@link CrudOperations} and {@link ComplexAttributeOperations}</li>
 * </ul>
 *
 * <p>Multiple complex attributes of type {@code LIST} or nested complex attributes are not supported.</p>
 */
public class ResourceElement implements IsElement<HTMLElement>, Attachable {

    private final Builder builder;
    private final Table<NamedNode> table;
    private final Form<NamedNode> form;
    private final Map<String, Form<ModelNode>> coForms;
    private final Pages pages;
    private final Table<ModelNode> clTable;
    private final Form<ModelNode> clForm;
    private final HTMLElement root;

    private String selectedResource;
    private int clIndex;

    @SuppressWarnings("unchecked")
    private ResourceElement(Builder builder) {
        this.builder = builder;
        this.selectedResource = null;
        this.clIndex = -1;

        HTMLElement section;
        LabelBuilder labelBuilder = new LabelBuilder();

        // main table and form
        if (builder.onAdd != null) {
            builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().add(builder.metadata.getTemplate(),
                    table -> builder.onAdd.execute()));
        } else {
            builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().add(builder.metadata.getTemplate(),
                    table -> builder.mbuiContext.crud().add(Ids.build(builder.baseId, Ids.ADD), builder.type,
                            builder.metadata.getTemplate(), (name, address) -> builder.crudCallback.execute())));
        }
        builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().remove(builder.metadata.getTemplate(),
                table -> builder.mbuiContext.crud().remove(builder.type, table.selectedRow().getName(),
                        builder.metadata.getTemplate(), builder.crudCallback)));
        if (builder.clAttribute != null) {
            builder.tableBuilder.column(
                    new InlineAction<>(labelBuilder.label(builder.clAttribute), this::showComplexList));
        }
        table = builder.tableBuilder.build();

        ModelNodeForm.Builder formBuilder = new ModelNodeForm.Builder<NamedNode>(Ids.build(builder.baseId, Ids.FORM),
                builder.metadata)
                .onSave((f, changedValues) -> builder.mbuiContext.crud().save(builder.type, f.getModel().getName(),
                        builder.metadata.getTemplate(), changedValues, builder.crudCallback));
        builder.customFormItems.forEach(formBuilder::customFormItem);

        form = formBuilder.build();

        // complex attributes of type OBJECT
        coForms = new HashMap<>();
        if (!builder.coAttributes.isEmpty()) {
            Tabs tabs = new Tabs(Ids.build(builder.baseId, Ids.TAB_CONTAINER));
            tabs.add(Ids.build(builder.baseId, ATTRIBUTES, Ids.TAB),
                    builder.mbuiContext.resources().constants().attributes(), form.element());

            for (String complexAttribute : builder.coAttributes.keySet()) {
                // is the complex attribute *itself* required?
                boolean requiredComplexAttribute = false;<commit_msg>HAL-1569 Missing reset link on forms of elytron resources https://issues.jboss.org/browse/HAL-1569<commit_after>/*
 * Copyright 2015-2016 Red Hat, Inc, and individual contributors.
 *
 * 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 org.jboss.hal.core.mbui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

import com.google.common.collect.Iterables;
import elemental2.dom.HTMLElement;
import org.jboss.gwt.elemento.core.Elements;
import org.jboss.gwt.elemento.core.IsElement;
import org.jboss.hal.ballroom.Attachable;
import org.jboss.hal.ballroom.LabelBuilder;
import org.jboss.hal.ballroom.Pages;
import org.jboss.hal.ballroom.Tabs;
import org.jboss.hal.ballroom.form.Form;
import org.jboss.hal.ballroom.form.FormItemProvider;
import org.jboss.hal.ballroom.form.FormValidation;
import org.jboss.hal.ballroom.table.Column;
import org.jboss.hal.ballroom.table.InlineAction;
import org.jboss.hal.ballroom.table.Table;
import org.jboss.hal.core.ComplexAttributeOperations;
import org.jboss.hal.core.CrudOperations;
import org.jboss.hal.core.mbui.form.ModelNodeForm;
import org.jboss.hal.core.mbui.table.ModelNodeTable;
import org.jboss.hal.dmr.ModelNode;
import org.jboss.hal.dmr.NamedNode;
import org.jboss.hal.dmr.Operation;
import org.jboss.hal.dmr.Property;
import org.jboss.hal.dmr.ResourceAddress;
import org.jboss.hal.meta.AddressTemplate;
import org.jboss.hal.meta.Metadata;
import org.jboss.hal.resources.Ids;
import org.jboss.hal.resources.Names;
import org.jboss.hal.spi.Callback;
import org.jetbrains.annotations.NonNls;

import static elemental2.dom.DomGlobal.alert;
import static java.util.Collections.singletonList;
import static org.jboss.gwt.elemento.core.Elements.h;
import static org.jboss.gwt.elemento.core.Elements.p;
import static org.jboss.gwt.elemento.core.Elements.section;
import static org.jboss.hal.dmr.ModelDescriptionConstants.*;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeBoolean;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeGet;
import static org.jboss.hal.dmr.ModelNodeHelper.failSafeList;
import static org.jboss.hal.dmr.ModelNodeHelper.storeIndex;

/**
 * Master detail element for a resource with support for n complex attributes of type {@code OBJECT} and one
 * complex attribute of type {@code LIST}.
 *
 * <p>This class provides the following features:</p>
 * <ul>
 * <li>Table for the main resource with add and remove buttons.</li>
 * <li>Form with all simple configuration attributes of the main resource.</li>
 * <li>A tab for each complex attribute of type {@code OBJECT}. The tab contains a form to add, save, reset and remove
 * the complex attribute (remove is only available if the complex attribute is not required).</li>
 * <li>If there's a complex attribute of type {@code LIST}, the table contains a link to a sub-page. The sub-page
 * contains a table and a form to CRUD the elements of the complex attribute. Only simple attributes in the complex
 * attribute of type {@code LIST} are supported.</li>
 * <li>All CRUD actions are delegated to {@link CrudOperations} and {@link ComplexAttributeOperations}</li>
 * </ul>
 *
 * <p>Multiple complex attributes of type {@code LIST} or nested complex attributes are not supported.</p>
 */
public class ResourceElement implements IsElement<HTMLElement>, Attachable {

    private final Builder builder;
    private final Table<NamedNode> table;
    private final Form<NamedNode> form;
    private final Map<String, Form<ModelNode>> coForms;
    private final Pages pages;
    private final Table<ModelNode> clTable;
    private final Form<ModelNode> clForm;
    private final HTMLElement root;

    private String selectedResource;
    private int clIndex;

    @SuppressWarnings("unchecked")
    private ResourceElement(Builder builder) {
        this.builder = builder;
        this.selectedResource = null;
        this.clIndex = -1;

        HTMLElement section;
        LabelBuilder labelBuilder = new LabelBuilder();

        // main table and form
        if (builder.onAdd != null) {
            builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().add(builder.metadata.getTemplate(),
                    table -> builder.onAdd.execute()));
        } else {
            builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().add(builder.metadata.getTemplate(),
                    table -> builder.mbuiContext.crud().add(Ids.build(builder.baseId, Ids.ADD), builder.type,
                            builder.metadata.getTemplate(), (name, address) -> builder.crudCallback.execute())));
        }
        builder.tableBuilder.button(builder.mbuiContext.tableButtonFactory().remove(builder.metadata.getTemplate(),
                table -> builder.mbuiContext.crud().remove(builder.type, table.selectedRow().getName(),
                        builder.metadata.getTemplate(), builder.crudCallback)));
        if (builder.clAttribute != null) {
            builder.tableBuilder.column(
                    new InlineAction<>(labelBuilder.label(builder.clAttribute), this::showComplexList));
        }
        table = builder.tableBuilder.build();

        ModelNodeForm.Builder formBuilder = new ModelNodeForm.Builder<NamedNode>(Ids.build(builder.baseId, Ids.FORM),
                builder.metadata)
                .prepareReset(f -> builder.mbuiContext.crud()
                        .reset(builder.type, f.getModel().getName(), builder.metadata.getTemplate(), f,
                                builder.metadata, builder.crudCallback))
                .onSave((f, changedValues) -> builder.mbuiContext.crud().save(builder.type, f.getModel().getName(),
                        builder.metadata.getTemplate(), changedValues, builder.crudCallback));
        builder.customFormItems.forEach(formBuilder::customFormItem);

        form = formBuilder.build();

        // complex attributes of type OBJECT
        coForms = new HashMap<>();
        if (!builder.coAttributes.isEmpty()) {
            Tabs tabs = new Tabs(Ids.build(builder.baseId, Ids.TAB_CONTAINER));
            tabs.add(Ids.build(builder.baseId, ATTRIBUTES, Ids.TAB),
                    builder.mbuiContext.resources().constants().attributes(), form.element());

            for (String complexAttribute : builder.coAttributes.keySet()) {
                // is the complex attribute *itself* required?
                boolean requiredComplexAttribute = false;
{'fraction_non_alphanumeric': 0.10769789397240377, 'fraction_numerical': 0.002759622367465505, 'mean_word_length': 3.6041457706452693, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 66, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3108324', 'n_tokens_mistral': 3956, 'n_tokens_neox': 3825, 'n_words': 1004}