package org.activityinfo.ui.client.page.config;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* 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/gpl-3.0.html>.
* #L%
*/
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.SimpleEventBus;
import org.activityinfo.i18n.shared.I18N;
import org.activityinfo.legacy.client.AsyncMonitor;
import org.activityinfo.legacy.client.monitor.NullAsyncMonitor;
import org.activityinfo.legacy.shared.model.*;
import org.activityinfo.ui.client.page.common.columns.EditCheckColumnConfig;
import org.activityinfo.ui.client.page.common.columns.EditableLocalDateColumn;
import org.activityinfo.ui.client.page.common.columns.ReadLockedPeriodTypeColumn;
import org.activityinfo.ui.client.page.common.columns.ReadTextColumn;
import org.activityinfo.ui.client.page.common.dialog.FormDialogCallback;
import org.activityinfo.ui.client.page.common.dialog.FormDialogImpl;
import org.activityinfo.ui.client.page.common.dialog.FormDialogTether;
import org.activityinfo.ui.client.page.common.toolbar.ActionListener;
import org.activityinfo.ui.client.page.common.toolbar.ActionToolBar;
import org.activityinfo.ui.client.page.common.toolbar.UIActions;
import org.activityinfo.ui.client.page.config.LockedPeriodsPresenter.LockedPeriodListEditor;
import org.activityinfo.ui.client.page.config.mvp.CanCreate;
import org.activityinfo.ui.client.page.config.mvp.CanDelete;
import org.activityinfo.ui.client.page.config.mvp.CanUpdate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LockedPeriodGrid extends ContentPanel implements LockedPeriodListEditor {
private EventBus eventBus = new SimpleEventBus();
private boolean mustConfirmDelete = true;
// UI stuff
private ListStore<LockedPeriodDTO> lockedPeriodStore;
private EditorGrid<LockedPeriodDTO> lockedPeriodGrid;
private AsyncMonitor deletingMonitor = new NullAsyncMonitor();
private AsyncMonitor loadingMonitor = new NullAsyncMonitor();
private AsyncMonitor updatingMonitor = new NullAsyncMonitor();
// Data
private LockedPeriodDTO lockedPeriod;
private ActivityFormDTO activityFilter = null;
// Nested views
private AddLockedPeriodDialog addLockedPeriod;
private ActionToolBar actionToolbar;
private FormDialogImpl<AddLockedPeriodDialog> form;
public LockedPeriodGrid() {
super();
initializeComponent();
createListStore();
createActionToolbar();
createAddLockedPeriodDialog();
createGrid();
}
private void createGrid() {
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig columnEnabled = new EditCheckColumnConfig("enabled", I18N.CONSTANTS.enabledColumn(), 55);
columnEnabled.setSortable(false);
ColumnConfig columnPeriodType = new ReadLockedPeriodTypeColumn();
columnPeriodType.setSortable(false);
configs.add(columnEnabled);
configs.add(columnPeriodType);
configs.add(new ReadTextColumn("parentName", I18N.CONSTANTS.parentName(), 150));
configs.add(new ReadTextColumn("name", I18N.CONSTANTS.name(), 100));
configs.add(new EditableLocalDateColumn("fromDate", I18N.CONSTANTS.fromDate(), 100));
configs.add(new EditableLocalDateColumn("toDate", I18N.CONSTANTS.toDate(), 100));
lockedPeriodGrid = new EditorGrid<LockedPeriodDTO>(lockedPeriodStore, new ColumnModel(configs));
lockedPeriodGrid.addListener(Events.OnClick, new Listener<ComponentEvent>() {
@Override
public void handleEvent(ComponentEvent be) {
lockedPeriod = lockedPeriodGrid.getSelectionModel().getSelectedItem();
setDeleteEnabled(lockedPeriodGrid.getSelectionModel().getSelectedItem() != null);
}
});
add(lockedPeriodGrid);
}
private void initializeComponent() {
setHeadingText(I18N.CONSTANTS.lockPanelTitle());
setLayout(new FitLayout());
}
private void createListStore() {
lockedPeriodStore = new ListStore<LockedPeriodDTO>();
lockedPeriodStore.addListener(Store.DataChanged, new Listener<StoreEvent>() {
@Override
public void handleEvent(StoreEvent be) {
actionToolbar.setUpdateEnabled(true);
}
});
}
private void createActionToolbar() {
actionToolbar = new ActionToolBar(new ActionListener() {
@Override
public void onUIAction(String actionId) {
if (actionId.equals(UIActions.ADD)) {
eventBus.fireEvent(new StartCreateEvent());
} else if (actionId.equals(UIActions.DELETE)) {
eventBus.fireEvent(new RequestDeleteEvent());
} else if (actionId.equals(UIActions.SAVE)) {
eventBus.fireEvent(new UpdateEvent());
} else if (actionId.equals(UIActions.DISCARD_CHANGES)) {
eventBus.fireEvent(new CancelUpdateEvent());
// } else if (actionId.equals(UIActions.refresh)) {
// eventBus.fireEvent(new RefreshEvent());
}
}
});
actionToolbar.addDeleteButton();
actionToolbar.addCreateButton();
actionToolbar.addSaveSplitButton();
// actionToolbar.addRefreshButton();
actionToolbar.setDeleteEnabled(false);
actionToolbar.setUpdateEnabled(false);
this.setTopComponent(actionToolbar);
}
private void createAddLockedPeriodDialog() {
addLockedPeriod = new AddLockedPeriodDialog();
addLockedPeriod.addCreateHandler(new CreateHandler() {
@Override
public void onCreate(CreateEvent createEvent) {
lockedPeriod = addLockedPeriod.getValue();
eventBus.fireEvent(new CreateEvent());
}
});
addLockedPeriod.addCancelCreateHandler(new CancelCreateHandler() {
@Override
public void onCancelCreate(CancelCreateEvent createEvent) {
eventBus.fireEvent(new CancelCreateEvent());
}
});
}
@Override
public void create(LockedPeriodDTO item) {
lockedPeriodStore.add(item);
addLockedPeriod.cancelCreate();
if (form != null) {
form.hide();
}
}
@Override
public void update(LockedPeriodDTO item) {
lockedPeriodStore.commitChanges();
}
@Override
public void delete(LockedPeriodDTO item) {
lockedPeriodStore.remove(item);
}
@Override
public void setCreateEnabled(boolean createEnabled) {
actionToolbar.setAddEnabled(createEnabled);
}
@Override
public void setUpdateEnabled(boolean updateEnabled) {
actionToolbar.setUpdateEnabled(updateEnabled);
}
@Override
public final void setDeleteEnabled(boolean deleteEnabled) {
actionToolbar.setDeleteEnabled(deleteEnabled);
}
@Override
public LockedPeriodDTO getValue() {
return lockedPeriod;
}
@Override
public HandlerRegistration addCreateHandler(CreateHandler handler) {
return eventBus.addHandler(CreateEvent.TYPE, handler);
}
@Override
public HandlerRegistration addUpdateHandler(UpdateHandler handler) {
return eventBus.addHandler(UpdateEvent.TYPE, handler);
}
@Override
public HandlerRegistration addConfirmDeleteHandler(ConfirmDeleteHandler handler) {
return eventBus.addHandler(ConfirmDeleteEvent.TYPE, handler);
}
@Override
public void cancelUpdate(LockedPeriodDTO item) {
lockedPeriodGrid.stopEditing(true);
}
@Override
public void askConfirmDelete(LockedPeriodDTO item) {
if (mustConfirmDelete) {
MessageBox.confirm(I18N.CONSTANTS.deleteLockedPeriodTitle(),
I18N.CONSTANTS.deleteLockedPeriodQuestion(),
new Listener<MessageBoxEvent>() {
@Override
public void handleEvent(MessageBoxEvent be) {
if (be.isCancelled()) {
eventBus.fireEvent(new CancelDeleteEvent());
} else {
eventBus.fireEvent(new ConfirmDeleteEvent());
}
}
});
} else {
eventBus.fireEvent(new ConfirmDeleteEvent());
}
}
@Override
public void setParent(UserDatabaseDTO parent) {
addLockedPeriod.setUserDatabase(parent);
}
@Override
public void setItems(List<LockedPeriodDTO> items) {
lockedPeriodStore.removeAll();
lockedPeriodStore.add(filterLockedPeriodsByActivity(items));
}
private List<LockedPeriodDTO> filterLockedPeriodsByActivity(List<LockedPeriodDTO> items) {
if (activityFilter != null) {
// Remove LockedPeriods which have a different Activity then the
// activiftyFilter
List<LockedPeriodDTO> lockedPeriodsFilteredByActivity = new ArrayList<LockedPeriodDTO>();
for (LockedPeriodDTO lockedPeriod : items) {
if (lockedPeriod.getParent() != null && lockedPeriod.getParent() instanceof IsActivityDTO) {
// Activity as parent, only add when activity equals filter
if (lockedPeriod.getParent().getId() == activityFilter.getId()) {
lockedPeriodsFilteredByActivity.add(lockedPeriod);
}
} else {
// Database or Project, can be added
lockedPeriodsFilteredByActivity.add(lockedPeriod);
}
}
return lockedPeriodsFilteredByActivity;
} else {
// No filter, just return the items
return items;
}
}
@Override
public HandlerRegistration addCancelUpdateHandler(CancelUpdateHandler handler) {
return eventBus.addHandler(CancelUpdateEvent.TYPE, handler);
}
@Override
public HandlerRegistration addRequestDeleteHandler(RequestDeleteHandler handler) {
return eventBus.addHandler(RequestDeleteEvent.TYPE, handler);
}
@Override
public HandlerRegistration addCancelCreateHandler(CanCreate.CancelCreateHandler handler) {
return eventBus.addHandler(CancelCreateEvent.TYPE, handler);
}
@Override
public HandlerRegistration addStartCreateHandler(CanCreate.StartCreateHandler handler) {
return eventBus.addHandler(StartCreateEvent.TYPE, handler);
}
@Override
public HandlerRegistration addCancelDeleteHandler(CanDelete.CancelDeleteHandler handler) {
return eventBus.addHandler(CancelDeleteEvent.TYPE, handler);
}
@Override
public HandlerRegistration addRequestUpdateHandler(CanUpdate.RequestUpdateHandler handler) {
return eventBus.addHandler(RequestUpdateEvent.TYPE, handler);
}
@Override
public List<LockedPeriodDTO> getUnsavedItems() {
List<LockedPeriodDTO> unsavedItems = new ArrayList<LockedPeriodDTO>();
List<Record> modifiedRecords = lockedPeriodStore.getModifiedRecords();
for (Record record : modifiedRecords) {
unsavedItems.add((LockedPeriodDTO) record.getModel());
}
return unsavedItems;
}
@Override
public boolean hasChangedItems() {
return getUnsavedItems().size() > 0;
}
@Override
public boolean hasSingleChangedItem() {
return getUnsavedItems().size() == 1;
}
@Override
public Map<String, Object> getChanges(LockedPeriodDTO item) {
for (Record record : lockedPeriodStore.getModifiedRecords()) {
LockedPeriodDTO lockedPeriod = (LockedPeriodDTO) record.getModel();
if (lockedPeriod.getId() == item.getId()) {
Map<String, Object> changes = new HashMap<String, Object>();
for (String property : record.getPropertyNames()) {
changes.put(property, lockedPeriod.get(property));
}
return changes;
}
}
return null;
}
@Override
public void cancelUpdateAll() {
lockedPeriodStore.rejectChanges();
}
@Override
public void startCreate() {
addLockedPeriod.startCreate();
form = new FormDialogImpl<AddLockedPeriodDialog>(addLockedPeriod);
form.setHeadingText(I18N.CONSTANTS.addTimeLock());
form.setWidth(400);
form.setHeight(350);
form.show(new FormDialogCallback() {
@Override
public void onValidated() {
super.onValidated();
}
@Override
public void onValidated(FormDialogTether dlg) {
if (addLockedPeriod.isValid()) {
LockedPeriodGrid.this.lockedPeriod = addLockedPeriod.getValue();
eventBus.fireEvent(new CreateEvent());
}
}
@Override
public void onCancelled() {
eventBus.fireEvent(new CancelCreateEvent());
}
});
}
@Override
public void cancelCreate() {
addLockedPeriod.cancelCreate();
if (form != null) {
form.hide();
}
}
@Override
public AsyncMonitor getLoadingMonitor() {
return loadingMonitor;
}
@Override
public AsyncMonitor getCreatingMonitor() {
return form;
}
@Override
public AsyncMonitor getUpdatingMonitor() {
return updatingMonitor;
}
@Override
public AsyncMonitor getDeletingMonitor() {
return deletingMonitor;
}
@Override
public void setMustConfirmDelete(boolean mustConfirmDelete) {
}
@Override
public void setRefreshEnabled(boolean canRefresh) {
}
@Override
public void startUpdate() {
}
@Override
public void cancelDelete() {
}
@Override
public HandlerRegistration addRefreshHandler(RefreshHandler handler) {
return eventBus.addHandler(RefreshEvent.TYPE, handler);
}
@Override
public HandlerRegistration addFilterHandler(FilterHandler filter) {
return null;
}
@Override
public void initialize() {
}
@Override
public void setValue(LockedPeriodDTO value) {
}
public void setActivityFilter(ActivityFormDTO activityFilter) {
this.activityFilter = activityFilter;
}
public ActivityFormDTO getActivityFilter() {
return activityFilter;
}
public void setReadOnly(boolean isReadOnly) {
if (isReadOnly) {
remove(actionToolbar);
}
}
@Override
public void setTitle(String title) {
setHeadingText(title);
}
}