/*
* Copyright (C) 2015 Jan Pokorsky
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package cz.cas.lib.proarc.webapp.client.widget.workflow;
import com.smartgwt.client.data.AdvancedCriteria;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.data.ResultSet;
import com.smartgwt.client.types.CriteriaPolicy;
import com.smartgwt.client.types.FetchMode;
import com.smartgwt.client.types.MultipleAppearance;
import com.smartgwt.client.types.OperatorId;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedEvent;
import com.smartgwt.client.widgets.grid.events.SelectionUpdatedHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import cz.cas.lib.proarc.common.workflow.profile.WorkflowProfileConsts;
import cz.cas.lib.proarc.webapp.client.ClientMessages;
import cz.cas.lib.proarc.webapp.client.ClientUtils;
import cz.cas.lib.proarc.webapp.client.Editor;
import cz.cas.lib.proarc.webapp.client.action.Actions;
import cz.cas.lib.proarc.webapp.client.action.Actions.ActionSource;
import cz.cas.lib.proarc.webapp.client.action.RefreshAction;
import cz.cas.lib.proarc.webapp.client.action.RefreshAction.Refreshable;
import cz.cas.lib.proarc.webapp.client.ds.UserDataSource;
import cz.cas.lib.proarc.webapp.client.ds.ValueMapDataSource;
import cz.cas.lib.proarc.webapp.client.ds.WorkflowTaskDataSource;
import cz.cas.lib.proarc.webapp.client.presenter.WorkflowTasksEditor;
import cz.cas.lib.proarc.webapp.client.widget.ListGridPersistance;
/**
*
* @author Jan Pokorsky
*/
public class WorkflowTasksView implements Refreshable {
private final ClientMessages i18n;
private final Canvas widget;
private ListGrid taskGrid;
private WorkflowTaskFormView taskFormView;
private final WorkflowTasksEditor handler;
private ListGridPersistance taskListPersistance;
private final ActionSource actionSource = new ActionSource(this);
private boolean isUpdateOperation;
private boolean isDataInitialized;
private ListGridRecord lastSelection;
public WorkflowTasksView(ClientMessages i18n, WorkflowTasksEditor handler) {
this.i18n = i18n;
this.handler = handler;
this.widget = createMainLayout();
}
public Canvas getWidget() {
return widget;
}
private void init() {
if (!isDataInitialized) {
isDataInitialized = true;
taskGrid.fetchData(taskListPersistance.getFilterCriteria());
}
}
@Override
public void refresh() {
if (isDataInitialized) {
taskGrid.invalidateCache();
} else {
init();
}
}
public void edit(String taskId) {
if (taskId == null) {
init();
return ;
}
int taskRec = taskGrid.findIndex(
new AdvancedCriteria(WorkflowTaskDataSource.FIELD_ID, OperatorId.EQUALS, taskId));
if (taskRec >= 0) {
taskGrid.selectSingleRecord(taskRec);
taskGrid.scrollToRow(taskRec);
} else {
lastSelection = null;
taskGrid.deselectAllRecords();
Record r = new Record();
r.setAttribute(WorkflowTaskDataSource.FIELD_ID, taskId);
taskFormView.setTask(r);
}
}
public void editSelection() {
taskFormView.setTask(taskGrid.getSelectedRecord());
refreshState();
}
public void refreshState() {
actionSource.fireEvent();
taskFormView.refreshState();
}
public void refreshParameters(String taskId) {
taskFormView.setParameters(taskId);
}
/**
* Set to {@code true} before saving a job. It is a hack not to select
* the job again inside {@code onDataArrived}.
*/
public void setExpectUpdateOperation(boolean isUpdateOperation) {
this.isUpdateOperation = isUpdateOperation;
}
private Canvas createMainLayout() {
VLayout main = new VLayout();
main.addMember(createPanelLabel());
// filter
// main.addMember(createFilter());
main.addMember(createTaskLayout());
return main;
}
private Canvas createTaskLayout() {
VLayout left = new VLayout();
left.addMember(createToolbar());
left.addMember(createTaskList());
HLayout l = new HLayout();
l.addMember(left);
l.addMember(createTaskFormLayout());
return l;
}
private Label createPanelLabel() {
Label lblHeader = new Label();
String title = ClientUtils.format("<b>%s</b>", i18n.WorkflowTask_View_Title());
lblHeader.setContents(title);
lblHeader.setAutoHeight();
lblHeader.setPadding(4);
lblHeader.setStyleName(Editor.CSS_PANEL_DESCRIPTION_TITLE);
return lblHeader;
}
private DynamicForm createFilter() {
DynamicForm form = new DynamicForm();
form.setBrowserSpellCheck(false);
form.setValidateOnExit(true);
form.setSaveOnEnter(true);
form.setAutoHeight();
form.setWidth100();
form.setNumCols(3);
// ????
return form;
}
private ToolStrip createToolbar() {
ToolStrip toolbar = Actions.createToolStrip();
RefreshAction refreshAction = new RefreshAction(i18n);
toolbar.addMember(Actions.asIconButton(refreshAction, this));
return toolbar;
}
private ListGrid createTaskList() {
final ListGrid grid = new ListGrid();
taskListPersistance = new ListGridPersistance("WorkflowTasksView.taskList", grid);
grid.setShowFilterEditor(true);
grid.setAllowFilterOperators(false);
grid.setFilterOnKeypress(true);
grid.setCanSort(true);
grid.setCanGroupBy(false);
grid.setDataFetchMode(FetchMode.PAGED);
ResultSet rs = new ResultSet();
rs.setCriteriaPolicy(CriteriaPolicy.DROPONCHANGE);
rs.setUseClientFiltering(false);
rs.setUseClientSorting(false);
grid.setDataProperties(rs);
grid.setDataSource(WorkflowTaskDataSource.getInstance(),
new ListGridField(WorkflowTaskDataSource.FIELD_LABEL),
new ListGridField(WorkflowTaskDataSource.FIELD_TYPE),
new ListGridField(WorkflowTaskDataSource.FIELD_STATE, 50),
new ListGridField(WorkflowTaskDataSource.FIELD_PRIORITY, 60),
new ListGridField(WorkflowTaskDataSource.FIELD_OWNER, 50),
new ListGridField(WorkflowTaskDataSource.FIELD_CREATED, 100),
new ListGridField(WorkflowTaskDataSource.FIELD_MODIFIED, 100),
new ListGridField(WorkflowTaskDataSource.FIELD_ID, 30),
new ListGridField(WorkflowTaskDataSource.FIELD_NOTE),
new ListGridField(WorkflowTaskDataSource.FIELD_JOB_ID, 30),
new ListGridField(WorkflowTaskDataSource.FIELD_JOB_LABEL)
);
grid.getField(WorkflowTaskDataSource.FIELD_LABEL).setWidth("80%");
grid.getField(WorkflowTaskDataSource.FIELD_LABEL).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_LABEL).setCanSort(false);
grid.getField(WorkflowTaskDataSource.FIELD_LABEL).setFilterEditorProperties(createTaskFilterEditor());
grid.getField(WorkflowTaskDataSource.FIELD_OWNER).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_OWNER).setCanSort(false);
SelectItem owner = createMultiSelectColumnFilter();
owner.setOptionDataSource(UserDataSource.getInstance());
owner.setValueField(UserDataSource.FIELD_ID);
owner.setDisplayField(UserDataSource.FIELD_USERNAME);
grid.getField(WorkflowTaskDataSource.FIELD_OWNER).setFilterEditorProperties(owner);
grid.getField(WorkflowTaskDataSource.FIELD_PRIORITY).setFilterEditorProperties(createMultiSelectColumnFilter());
grid.getField(WorkflowTaskDataSource.FIELD_STATE).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_STATE).setCanSort(false);
grid.getField(WorkflowTaskDataSource.FIELD_STATE).setFilterEditorProperties(createMultiSelectColumnFilter());
grid.getField(WorkflowTaskDataSource.FIELD_CREATED).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_CREATED).setCanSort(true);
grid.getField(WorkflowTaskDataSource.FIELD_MODIFIED).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_MODIFIED).setCanSort(true);
grid.getField(WorkflowTaskDataSource.FIELD_NOTE).setCanFilter(false);
grid.getField(WorkflowTaskDataSource.FIELD_NOTE).setCanSort(false);
grid.getField(WorkflowTaskDataSource.FIELD_JOB_LABEL).setCanFilter(true);
grid.getField(WorkflowTaskDataSource.FIELD_JOB_LABEL).setFilterOnKeypress(false);
grid.getField(WorkflowTaskDataSource.FIELD_JOB_LABEL).setCanSort(true);
grid.getField(WorkflowTaskDataSource.FIELD_TYPE).setCanFilter(false);
grid.getField(WorkflowTaskDataSource.FIELD_TYPE).setCanSort(false);
grid.addDataArrivedHandler(new DataArrivedHandler() {
@Override
public void onDataArrived(DataArrivedEvent event) {
if (isUpdateOperation) {
isUpdateOperation = false;
return ;
}
int startRow = event.getStartRow();
int endRow = event.getEndRow();
if (startRow == 0 && endRow >= 0) {
updateSelection();
grid.focus();
} else if (endRow < 0) {
grid.deselectAllRecords();
}
}
});
grid.setSelectionType(SelectionStyle.SINGLE);
grid.addSelectionUpdatedHandler(new SelectionUpdatedHandler() {
@Override
public void onSelectionUpdated(SelectionUpdatedEvent event) {
lastSelection = taskGrid.getSelectedRecord();
editSelection();
}
});
grid.setViewState(taskListPersistance.getViewState());
taskGrid = grid;
return grid;
}
private SelectItem createMultiSelectColumnFilter() {
SelectItem options = new SelectItem();
options.setMultiple(true);
options.setMultipleAppearance(MultipleAppearance.PICKLIST);
return options;
}
private FormItem createTaskFilterEditor() {
SelectItem taskOptions = createMultiSelectColumnFilter();
taskOptions.setMultiple(true);
taskOptions.setMultipleAppearance(MultipleAppearance.PICKLIST);
taskOptions.setOptionDataSource(ValueMapDataSource.getInstance()
.getOptionDataSource(WorkflowProfileConsts.WORKFLOWITEMVIEW_TASKS_VALUEMAP));
taskOptions.setValueField(WorkflowProfileConsts.NAME);
taskOptions.setDisplayField(WorkflowProfileConsts.TITLE_EL);
taskOptions.setPickListFields(new ListGridField(WorkflowProfileConsts.TITLE_EL));
taskOptions.getPickListFields()[0].setCellFormatter(new CellFormatter() {
@Override
public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
Boolean disabled = record.getAttributeAsBoolean(WorkflowProfileConsts.DISABLED);
if (value == null) {
return null;
} else if (disabled != null && disabled) {
return "<s>" + value + "</s>";
} else {
return value.toString();
}
}
});
ListGrid profilePickListProperties = new ListGrid();
profilePickListProperties.setCanHover(true);
profilePickListProperties.setShowHover(true);
profilePickListProperties.setHoverWidth(300);
profilePickListProperties.setHoverCustomizer(new HoverCustomizer() {
@Override
public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
String hint = record.getAttribute(WorkflowProfileConsts.HINT_EL);
String name = record.getAttribute(WorkflowProfileConsts.NAME);
String title = record.getAttribute(WorkflowProfileConsts.TITLE_EL);
StringBuilder sb = new StringBuilder();
sb.append("<b>").append(title).append("</b>");
sb.append("<br><i>").append(name).append("</i></br>");
if (hint != null) {
sb.append("<p>").append(hint).append("</p>");
}
return sb.toString();
}
});
taskOptions.setPickListProperties(profilePickListProperties);
return taskOptions;
}
private void updateSelection() {
RecordList rl = taskGrid.getRecordList();
if (rl.isEmpty()) {
return ;
}
if (lastSelection == null) {
taskGrid.selectSingleRecord(0);
return ;
}
Record newRec = rl.find(WorkflowTaskDataSource.FIELD_ID,
lastSelection.getAttribute(WorkflowTaskDataSource.FIELD_ID));
if (newRec != null) {
taskGrid.selectSingleRecord(newRec);
int rowNum = taskGrid.getRecordIndex(newRec);
if (rowNum >= 0) {
taskGrid.scrollToRow(rowNum);
}
}
}
private Canvas createTaskFormLayout() {
taskFormView = new WorkflowTaskFormView(i18n, handler);
return taskFormView.getWidget();
}
}