/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * 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.drools.workbench.screens.guided.dtable.client.wizard.table.pages; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.MultiSelectionModel; import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SingleSelectionModel; import org.drools.workbench.models.guided.dtable.shared.model.ActionSetFieldCol52; import org.drools.workbench.models.guided.dtable.shared.model.GuidedDecisionTable52; import org.drools.workbench.models.guided.dtable.shared.model.LimitedEntryActionSetFieldCol52; import org.drools.workbench.models.guided.dtable.shared.model.Pattern52; import org.drools.workbench.screens.guided.dtable.client.resources.i18n.GuidedDecisionTableConstants; import org.drools.workbench.screens.guided.dtable.client.widget.DTCellValueWidgetFactory; import org.drools.workbench.screens.guided.dtable.client.widget.Validator; import org.drools.workbench.screens.guided.dtable.client.wizard.table.pages.cells.ActionSetFieldCell; import org.drools.workbench.screens.guided.dtable.client.wizard.table.pages.cells.ActionSetFieldPatternCell; import org.drools.workbench.screens.guided.dtable.client.wizard.table.pages.cells.AvailableFieldCell; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.CheckBox; import org.gwtbootstrap3.client.ui.FormGroup; import org.gwtbootstrap3.client.ui.HelpBlock; import org.gwtbootstrap3.client.ui.Label; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.constants.ValidationState; import org.uberfire.ext.widgets.core.client.resources.WizardCellListResources; /** * An implementation of the ActionSetFields page */ @Dependent public class ActionSetFieldsPageViewImpl extends Composite implements ActionSetFieldsPageView { private Presenter presenter; private Validator validator; private List<Pattern52> availablePatterns; private Pattern52 availablePatternsSelection; private MinimumWidthCellList<Pattern52> availablePatternsWidget; private Set<AvailableField> availableFieldsSelections; private MinimumWidthCellList<AvailableField> availableFieldsWidget; private List<ActionSetFieldCol52> chosenFields; private ActionSetFieldCol52 chosenFieldsSelection; private Set<ActionSetFieldCol52> chosenFieldsSelections; private MinimumWidthCellList<ActionSetFieldCol52> chosenFieldsWidget; private DTCellValueWidgetFactory factory; @UiField protected ScrollPanel availablePatternsContainer; @UiField protected ScrollPanel availableFieldsContainer; @UiField protected ScrollPanel chosenFieldsContainer; @UiField protected Button btnAdd; @UiField protected Button btnRemove; @UiField VerticalPanel fieldDefinition; @UiField TextBox txtColumnHeader; @UiField HelpBlock txtColumnHeaderHelp; @UiField FormGroup columnHeaderContainer; @UiField TextBox txtValueList; @UiField CheckBox chkUpdateEngine; @UiField VerticalPanel criteriaExtendedEntry; @UiField VerticalPanel criteriaLimitedEntry; @UiField FormGroup limitedEntryValueContainer; @UiField SimplePanel limitedEntryValueWidgetContainer; @UiField FormGroup defaultValueContainer; @UiField SimplePanel defaultValueWidgetContainer; @Inject private ActionSetFieldPatternCell actionSetFieldPatternCell; @Inject private ActionSetFieldCell actionSetFieldCell; interface ActionSetFieldPageWidgetBinder extends UiBinder<Widget, ActionSetFieldsPageViewImpl> { } private static ActionSetFieldPageWidgetBinder uiBinder = GWT.create( ActionSetFieldPageWidgetBinder.class ); public ActionSetFieldsPageViewImpl() { initWidget( uiBinder.createAndBindUi( this ) ); } @PostConstruct public void setup() { this.availablePatternsWidget = new MinimumWidthCellList<Pattern52>( actionSetFieldPatternCell, WizardCellListResources.INSTANCE ); this.availableFieldsWidget = new MinimumWidthCellList<AvailableField>( new AvailableFieldCell(), WizardCellListResources.INSTANCE ); this.chosenFieldsWidget = new MinimumWidthCellList<ActionSetFieldCol52>( actionSetFieldCell, WizardCellListResources.INSTANCE ); initialiseAvailablePatterns(); initialiseAvailableFields(); initialiseChosenFields(); initialiseColumnHeader(); initialiseValueList(); initialiseUpdateEngine(); } @Override public void setValidator( final Validator validator ) { this.validator = validator; this.actionSetFieldPatternCell.setValidator( validator ); this.actionSetFieldCell.setValidator( validator ); } private void initialiseAvailablePatterns() { availablePatternsContainer.add( availablePatternsWidget ); availablePatternsWidget.setKeyboardSelectionPolicy( KeyboardSelectionPolicy.ENABLED ); availablePatternsWidget.setMinimumWidth( 170 ); final Label lstEmpty = new Label( GuidedDecisionTableConstants.INSTANCE.DecisionTableWizardNoAvailablePatterns() ); lstEmpty.setStyleName( WizardCellListResources.INSTANCE.cellListStyle().cellListEmptyItem() ); availablePatternsWidget.setEmptyListWidget( lstEmpty ); final SingleSelectionModel<Pattern52> selectionModel = new SingleSelectionModel<Pattern52>(); availablePatternsWidget.setSelectionModel( selectionModel ); selectionModel.addSelectionChangeHandler( new SelectionChangeEvent.Handler() { @Override public void onSelectionChange( final SelectionChangeEvent event ) { availablePatternsSelection = selectionModel.getSelectedObject(); presenter.selectPattern( availablePatternsSelection ); } } ); } private void initialiseAvailableFields() { availableFieldsContainer.add( availableFieldsWidget ); availableFieldsWidget.setKeyboardSelectionPolicy( KeyboardSelectionPolicy.ENABLED ); availableFieldsWidget.setMinimumWidth( 170 ); final Label lstEmpty = new Label( GuidedDecisionTableConstants.INSTANCE.DecisionTableWizardNoAvailableFields() ); lstEmpty.setStyleName( WizardCellListResources.INSTANCE.cellListStyle().cellListEmptyItem() ); availableFieldsWidget.setEmptyListWidget( lstEmpty ); final MultiSelectionModel<AvailableField> selectionModel = new MultiSelectionModel<AvailableField>(); availableFieldsWidget.setSelectionModel( selectionModel ); selectionModel.addSelectionChangeHandler( new SelectionChangeEvent.Handler() { @Override public void onSelectionChange( final SelectionChangeEvent event ) { availableFieldsSelections = selectionModel.getSelectedSet(); btnAdd.setEnabled( availableFieldsSelections.size() > 0 ); } } ); } private void initialiseChosenFields() { chosenFieldsContainer.add( chosenFieldsWidget ); chosenFieldsWidget.setKeyboardSelectionPolicy( KeyboardSelectionPolicy.ENABLED ); chosenFieldsWidget.setMinimumWidth( 170 ); final Label lstEmpty = new Label( GuidedDecisionTableConstants.INSTANCE.DecisionTableWizardNoChosenFields() ); lstEmpty.setStyleName( WizardCellListResources.INSTANCE.cellListStyle().cellListEmptyItem() ); chosenFieldsWidget.setEmptyListWidget( lstEmpty ); final MultiSelectionModel<ActionSetFieldCol52> selectionModel = new MultiSelectionModel<ActionSetFieldCol52>(System::identityHashCode); chosenFieldsWidget.setSelectionModel( selectionModel ); selectionModel.addSelectionChangeHandler( new SelectionChangeEvent.Handler() { @Override public void onSelectionChange( final SelectionChangeEvent event ) { chosenFieldsSelections = selectionModel.getSelectedSet(); chosenConditionsSelected( chosenFieldsSelections ); } private void chosenConditionsSelected( final Set<ActionSetFieldCol52> cws ) { btnRemove.setEnabled( true ); if ( cws.size() == 1 ) { chosenFieldsSelection = cws.iterator().next(); fieldDefinition.setVisible( true ); validateFieldHeader(); populateFieldDefinition(); } else { chosenFieldsSelection = null; fieldDefinition.setVisible( false ); txtColumnHeader.setEnabled( false ); txtValueList.setEnabled( false ); defaultValueContainer.setVisible( false ); chkUpdateEngine.setEnabled( false ); } } private void populateFieldDefinition() { // Fields common to all table formats txtColumnHeader.setEnabled( true ); chkUpdateEngine.setEnabled( true ); txtColumnHeader.setText( chosenFieldsSelection.getHeader() ); chkUpdateEngine.setValue( chosenFieldsSelection.isUpdate() ); criteriaExtendedEntry.setVisible( presenter.getTableFormat() == GuidedDecisionTable52.TableFormat.EXTENDED_ENTRY ); criteriaLimitedEntry.setVisible( presenter.getTableFormat() == GuidedDecisionTable52.TableFormat.LIMITED_ENTRY ); // Fields specific to the table format switch ( presenter.getTableFormat() ) { case EXTENDED_ENTRY: txtValueList.setEnabled( !presenter.hasEnums( chosenFieldsSelection ) ); txtValueList.setText( chosenFieldsSelection.getValueList() ); makeDefaultValueWidget(); defaultValueContainer.setVisible( true ); break; case LIMITED_ENTRY: makeLimitedValueWidget(); limitedEntryValueContainer.setVisible( true ); break; } } private void makeLimitedValueWidget() { if ( !( chosenFieldsSelection instanceof LimitedEntryActionSetFieldCol52 ) ) { return; } final LimitedEntryActionSetFieldCol52 lea = (LimitedEntryActionSetFieldCol52) chosenFieldsSelection; if ( lea.getValue() == null ) { lea.setValue( factory.makeNewValue( availablePatternsSelection, chosenFieldsSelection ) ); } limitedEntryValueWidgetContainer.setWidget( factory.getWidget( availablePatternsSelection, chosenFieldsSelection, lea.getValue() ) ); } } ); } private void makeDefaultValueWidget() { if ( chosenFieldsSelection.getDefaultValue() == null ) { chosenFieldsSelection.setDefaultValue( factory.makeNewValue( availablePatternsSelection, chosenFieldsSelection ) ); } defaultValueWidgetContainer.setWidget( factory.getWidget( availablePatternsSelection, chosenFieldsSelection, chosenFieldsSelection.getDefaultValue() ) ); } private void validateFieldHeader() { if ( validator.isActionHeaderValid( chosenFieldsSelection ) ) { txtColumnHeaderHelp.setVisible( false ); columnHeaderContainer.removeStyleName( ValidationState.ERROR.getCssName() ); } else { txtColumnHeaderHelp.setVisible( true ); columnHeaderContainer.addStyleName( ValidationState.ERROR.getCssName() ); } } private void initialiseColumnHeader() { txtColumnHeader.addValueChangeHandler( new ValueChangeHandler<String>() { @Override public void onValueChange( ValueChangeEvent<String> event ) { final String header = txtColumnHeader.getText(); chosenFieldsSelection.setHeader( header ); presenter.stateChanged(); validateFieldHeader(); } } ); } private void initialiseValueList() { //Copy value back to model txtValueList.addValueChangeHandler( new ValueChangeHandler<String>() { @Override public void onValueChange( final ValueChangeEvent<String> event ) { final String valueList = txtValueList.getText(); chosenFieldsSelection.setValueList( valueList ); // ValueList is optional, no need to advise of state change } } ); //Update Default Value widget if necessary txtValueList.addBlurHandler( new BlurHandler() { @Override public void onBlur( final BlurEvent event ) { presenter.assertDefaultValue( availablePatternsSelection, chosenFieldsSelection ); makeDefaultValueWidget(); } } ); } private void initialiseUpdateEngine() { chkUpdateEngine.addClickHandler( new ClickHandler() { @Override public void onClick( final ClickEvent event ) { chosenFieldsSelection.setUpdate( chkUpdateEngine.getValue() ); } } ); } @Override public void init( final ActionSetFieldsPageView.Presenter presenter ) { this.presenter = presenter; } @Override public void setDTCellValueWidgetFactory( final DTCellValueWidgetFactory factory ) { this.factory = factory; } @Override public void setArePatternBindingsUnique( final boolean arePatternBindingsUnique ) { availablePatternsWidget.redraw(); } @Override public void setAreActionSetFieldsDefined( final boolean areActionSetFieldsDefined ) { chosenFieldsWidget.redraw(); } @Override public void setAvailablePatterns( final List<Pattern52> patterns ) { availablePatterns = patterns; availablePatternsWidget.setRowCount( availablePatterns.size(), true ); availablePatternsWidget.setRowData( availablePatterns ); if ( availablePatternsSelection != null ) { // If the currently selected pattern is no longer available clear selections if ( !availablePatterns.contains( availablePatternsSelection ) ) { availablePatternsWidget.getSelectionModel().setSelected( availablePatternsSelection, false ); availablePatternsSelection = null; setAvailableFields( new ArrayList<AvailableField>() ); availableFieldsSelections = null; setChosenFields( new ArrayList<ActionSetFieldCol52>() ); chosenFieldsSelection = null; fieldDefinition.setVisible( false ); } } else { // If no available pattern is selected clear fields setAvailableFields( new ArrayList<AvailableField>() ); setChosenFields( new ArrayList<ActionSetFieldCol52>() ); } } @Override public void setAvailableFields( final List<AvailableField> fields ) { availableFieldsWidget.setRowCount( fields.size(), true ); availableFieldsWidget.setRowData( fields ); } @Override public void setChosenFields( final List<ActionSetFieldCol52> fields ) { chosenFields = fields; chosenFieldsWidget.setRowCount( fields.size(), true ); chosenFieldsWidget.setRowData( fields ); fieldDefinition.setVisible( fields.contains( chosenFieldsSelection ) ); presenter.stateChanged(); } @UiHandler(value = "btnAdd") public void btnAddClick( final ClickEvent event ) { for ( AvailableField f : availableFieldsSelections ) { chosenFields.add( makeNewActionColumn( f ) ); } setChosenFields( chosenFields ); presenter.stateChanged(); } private ActionSetFieldCol52 makeNewActionColumn( final AvailableField f ) { final GuidedDecisionTable52.TableFormat format = presenter.getTableFormat(); if ( format == GuidedDecisionTable52.TableFormat.EXTENDED_ENTRY ) { final ActionSetFieldCol52 a = new ActionSetFieldCol52(); a.setBoundName( availablePatternsSelection.getBoundName() ); a.setFactField( f.getName() ); a.setType( f.getType() ); return a; } else { final LimitedEntryActionSetFieldCol52 a = new LimitedEntryActionSetFieldCol52(); a.setBoundName( availablePatternsSelection.getBoundName() ); a.setFactField( f.getName() ); a.setType( f.getType() ); return a; } } @UiHandler(value = "btnRemove") public void btnRemoveClick( final ClickEvent event ) { for ( ActionSetFieldCol52 a : chosenFieldsSelections ) { chosenFields.remove( a ); } chosenFieldsSelections.clear(); setChosenFields( chosenFields ); presenter.stateChanged(); txtColumnHeader.setText( "" ); txtValueList.setText( "" ); defaultValueContainer.setVisible( false ); fieldDefinition.setVisible( false ); btnRemove.setEnabled( false ); } }