diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java index 22a37a4eaf8f4fa70cab20718acc8e997cd58b11..3fa93d5e8979ed3c3d5b96f2587460fd4c6632b6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java @@ -74,6 +74,14 @@ public abstract class Dict // Buttons // + public static final String TOOLTIP_REFRESH_ENABLED = "tooltip_refresh_enabled"; + + public static final String TOOLTIP_REFRESH_DISABLED = "tooltip_refresh_disabled"; + + public static final String TOOLTIP_EXPORT_ENABLED = "tooltip_export_enabled"; + + public static final String TOOLTIP_EXPORT_DISABLED = "tooltip_export_disabled"; + public static final String BUTTON_SAVE = "button_save"; public static final String BUTTON_CANCEL = "button_cancel"; @@ -84,6 +92,8 @@ public abstract class Dict public static final String BUTTON_REFRESH = "button_refresh"; + public static final String BUTTON_SHOW = "button_show"; + public static final String BUTTON_EXPORT_DATA = "button_exportData"; public static final String BUTTON_ADD_GROUP = "button_add_group"; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java index 5771d3ffb45e0d31f552eb0be0ecb5732eb23342..2cff9ea3de57db616c6fa6d423215f9ba21439c4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MatchingEntitiesPanel.java @@ -53,12 +53,27 @@ final class MatchingEntitiesPanel extends AbstractBrowserGrid<MatchingEntity, Ma MatchingEntitiesPanel(final IViewContext<ICommonClientServiceAsync> viewContext, final SearchableEntity searchableEntity, final String queryText) { - super(viewContext, GRID_ID); + super(viewContext, GRID_ID, false); this.searchableEntity = searchableEntity; this.queryText = queryText; setId(PREFIX + XDOM.getUniqueId()); + updateDefaultRefreshButtons(); } + @Override + protected boolean isRefreshEnabled() + { + return true; + } + + /** used to refresh the results of the previously executed query */ + @Override + protected final void refresh() + { + super.refresh(null, null, false); + } + + /** used to make a first data refresh, but can be also called many times */ public final void refresh(final IDataRefreshCallback newRefreshCallback) { super.refresh(newRefreshCallback, null, true); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java index b9079c4116236c1d9e150d2b444cb031b1a7836f..86ca341be4a08b663a6335a3a67c99c2a8c4a7c6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/ExternalDataGrid.java @@ -40,6 +40,12 @@ public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, External super(viewContext, gridId); } + @Override + protected boolean isRefreshEnabled() + { + return true; + } + @Override protected ColumnDefsAndConfigs<ExternalData> createColumnsDefinition() { @@ -76,4 +82,10 @@ public class ExternalDataGrid extends AbstractBrowserGrid<ExternalData, External // TODO Auto-generated method stub } + @Override + protected void refresh() + { + // TODO Auto-generated method stub + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowser.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowser.java index ee2571a253d7811aa6b1548c9f03809e43f0dd92..d847adfade52ba8c36b8611b52837377e0c9b9d3 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowser.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowser.java @@ -45,9 +45,8 @@ public final class ExperimentBrowser extends LayoutContainer implements Listener setId(ID); setLayout(new RowLayout()); - experimentBrowserGrid = new ExperimentBrowserGrid(viewContext); - final ExperimentBrowserToolbar toolbar = - new ExperimentBrowserToolbar(viewContext, experimentBrowserGrid); + final ExperimentBrowserToolbar toolbar = new ExperimentBrowserToolbar(viewContext); + experimentBrowserGrid = new ExperimentBrowserGrid(viewContext, toolbar); add(toolbar); add(experimentBrowserGrid, new RowData(1, 1)); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java index b3dc2cc09a4b542ef33026913d44f9cee5cc65b2..398c26920b3d681c206bdef7dfe9a2d2245c7c68 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserGrid.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experi import java.util.List; +import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.LayoutContainer; import ch.systemsx.cisd.openbis.generic.client.shared.ExperimentType; @@ -34,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetCo import ch.systemsx.cisd.openbis.generic.client.web.client.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria; -import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria; @@ -51,14 +51,26 @@ public final class ExperimentBrowserGrid extends AbstractBrowserGrid<Experiment, public static final String GRID_ID = BROWSER_ID + "_grid"; - private ListExperimentsCriteria criteria; + private final ExperimentBrowserToolbar topToolbar; - ExperimentBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext) + private ListExperimentsCriteria criteria; + + ExperimentBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext, + ExperimentBrowserToolbar topToolbar) { super(viewContext, GRID_ID); + this.topToolbar = topToolbar; + SelectionChangedListener<?> refreshButtonListener = addRefreshButton(topToolbar); + this.topToolbar.setCriteriaChangedListener(refreshButtonListener); setId(BROWSER_ID); } + @Override + protected boolean isRefreshEnabled() + { + return topToolbar.tryGetCriteria() != null; + } + @Override protected void listEntities(DefaultResultSetConfig<String, Experiment> resultSetConfig, AbstractAsyncCallback<ResultSet<Experiment>> callback) @@ -118,24 +130,20 @@ public final class ExperimentBrowserGrid extends AbstractBrowserGrid<Experiment, return builder.toString(); } - public final void refresh(final IDataRefreshCallback newRefreshCallback, - final ExperimentType newSelectedType, final Project selectedProject) + @Override + public final void refresh() { - boolean refreshColumnsDefinition = hasColumnsDefinitionChanged(newSelectedType); - this.criteria = createListCriteria(newSelectedType, selectedProject); + ListExperimentsCriteria newCriteria = topToolbar.tryGetCriteria(); + if (newCriteria == null) + { + return; + } + boolean refreshColumnsDefinition = + hasColumnsDefinitionChanged(newCriteria.getExperimentType()); + this.criteria = newCriteria; String newHeader = createHeader(criteria); - super.refresh(newRefreshCallback, newHeader, refreshColumnsDefinition); - } - - private static ListExperimentsCriteria createListCriteria(final ExperimentType selectedType, - final Project selectedProject) - { - ListExperimentsCriteria criteria = new ListExperimentsCriteria(); - criteria.setExperimentType(selectedType); - criteria.setProjectCode(selectedProject.getCode()); - criteria.setGroupCode(selectedProject.getGroup().getCode()); - return criteria; + super.refresh(newHeader, refreshColumnsDefinition); } private boolean hasColumnsDefinitionChanged(ExperimentType entityType) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java index d7decdfc9239ae5fea629719a34145af9f50277c..16078bd1d49dc52be5e247a5334403ea2e6b41ed 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ExperimentBrowserToolbar.java @@ -16,14 +16,8 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment; -import com.extjs.gxt.ui.client.event.ButtonEvent; -import com.extjs.gxt.ui.client.event.ComponentEvent; -import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; -import com.extjs.gxt.ui.client.event.SelectionListener; -import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; -import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; @@ -34,10 +28,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExperimentTypeModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ProjectModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid.IDataRefreshCallback; +import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project; /** @@ -50,103 +41,29 @@ class ExperimentBrowserToolbar extends ToolBar { public static final String ID = "experiment-browser-toolbar"; - private static final String PREFIX = ID + "_"; - - static final String REFRESH_BUTTON_ID = GenericConstants.ID_PREFIX + PREFIX + "refresh-button"; - - private final ExperimentBrowserGrid experimentBrowserGrid; - private final ExperimentTypeSelectionWidget selectExperimentTypeCombo; private final ProjectSelectionWidget selectProjectCombo; - private final Button submitButton; - - private final Button exportButton; - private final IViewContext<ICommonClientServiceAsync> viewContext; - public ExperimentBrowserToolbar(final IViewContext<ICommonClientServiceAsync> viewContext, - final ExperimentBrowserGrid experimentBrowserGrid) + public ExperimentBrowserToolbar(final IViewContext<ICommonClientServiceAsync> viewContext) { - this.experimentBrowserGrid = experimentBrowserGrid; this.viewContext = viewContext; selectExperimentTypeCombo = new ExperimentTypeSelectionWidget(viewContext, ID); selectProjectCombo = new ProjectSelectionWidget(viewContext, ID); - submitButton = createSubmitButton(); - submitButton.setEnabled(false); - exportButton = createExportButton(); - exportButton.setEnabled(false); - addSelectSampleTypeListeners(); - addSelectGroupListeners(); - } - - private final void refreshButtons(final Project projectOrNull, - final ExperimentType experimentTypeOrNull) - { - final boolean experimentTypeSelected = experimentTypeOrNull != null; - final boolean projectChosen = projectOrNull != null; - final boolean enabled = experimentTypeSelected && projectChosen; - submitButton.setEnabled(enabled); - exportButton.setEnabled(enabled); - if (enabled) - { - submitButton.setTitle("Load or update experiment table"); - exportButton.setTitle("Export experiment table to excel file"); - } else - { - final String msg = "HINT: To activate choose experiment type and project."; - submitButton.setTitle(msg); - exportButton.setTitle(msg); - } - } - - private void addSelectGroupListeners() - { - selectProjectCombo.addSelectionChangedListener(new SelectionChangedListener<ProjectModel>() - { - // - // SelectionChangedListener - // - - @Override - public final void selectionChanged(final SelectionChangedEvent<ProjectModel> se) - { - final ProjectModel selectedItem = se.getSelectedItem(); - refreshButtons(selectedItem != null ? (Project) selectedItem - .get(ModelDataPropertyNames.OBJECT) : null, selectExperimentTypeCombo - .tryGetSelectedExperimentType()); - } - }); - + display(); } - private void addSelectSampleTypeListeners() + public void setCriteriaChangedListener(SelectionChangedListener<?> criteriaChangedListener) { - selectExperimentTypeCombo - .addSelectionChangedListener(new SelectionChangedListener<ExperimentTypeModel>() - { - - // - // SelectionChangedListener - // - - @Override - public final void selectionChanged( - final SelectionChangedEvent<ExperimentTypeModel> se) - { - final ExperimentTypeModel selectedItem = se.getSelectedItem(); - refreshButtons(selectProjectCombo.tryGetSelectedProject(), - selectedItem != null ? (ExperimentType) selectedItem - .get(ModelDataPropertyNames.OBJECT) : null); - } - }); + selectProjectCombo.addSelectionChangedListener(criteriaChangedListener); + selectExperimentTypeCombo.addSelectionChangedListener(criteriaChangedListener); } private void display() { setBorders(true); - removeAll(); add(new LabelToolItem(viewContext.getMessage(Dict.EXPERIMENT_TYPE) + GenericConstants.LABEL_SEPARATOR)); add(new AdapterToolItem(selectExperimentTypeCombo)); @@ -154,75 +71,32 @@ class ExperimentBrowserToolbar extends ToolBar add(new LabelToolItem(viewContext.getMessage(Dict.PROJECT) + GenericConstants.LABEL_SEPARATOR)); add(new AdapterToolItem(selectProjectCombo)); - add(new FillToolItem()); - add(new AdapterToolItem(submitButton)); - add(new SeparatorToolItem()); - add(new AdapterToolItem(exportButton)); - layout(); - } - - private Button createSubmitButton() - { - final Button refreshButton = - new Button(viewContext.getMessage(Dict.BUTTON_REFRESH), - new SelectionListener<ButtonEvent>() - { - // - // SelectionListener - // - - @Override - public final void componentSelected(final ButtonEvent ce) - { - final ExperimentType selectedType = - selectExperimentTypeCombo - .tryGetSelectedExperimentType(); - assert selectedType != null : "No experiment type selected."; - final Project selectedProject = - selectProjectCombo.tryGetSelectedProject(); - assert selectedProject != null : "No project selected."; - experimentBrowserGrid.refresh(createRefreshCallback(), - selectedType, selectedProject); - } - }); - refreshButton.setId(REFRESH_BUTTON_ID); - return refreshButton; } - private IDataRefreshCallback createRefreshCallback() + public final ListExperimentsCriteria tryGetCriteria() { - return new IDataRefreshCallback() - { - public void postRefresh(boolean wasSuccessful) - { - if (wasSuccessful) - { - exportButton.setEnabled(true); - } - } - }; - } - - private final Button createExportButton() - { - final Button button = - new Button(viewContext.getMessage(Dict.BUTTON_EXPORT_DATA), - new SelectionListener<ComponentEvent>() - { - @Override - public final void componentSelected(final ComponentEvent ce) - { - experimentBrowserGrid.export(); - } - }); - return button; + final ExperimentType selectedType = + selectExperimentTypeCombo.tryGetSelectedExperimentType(); + if (selectedType == null) + { + return null; + } + final Project selectedProject = selectProjectCombo.tryGetSelectedProject(); + if (selectedProject == null) + { + return null; + } + ListExperimentsCriteria criteria = new ListExperimentsCriteria(); + criteria.setExperimentType(selectedType); + criteria.setProjectCode(selectedProject.getCode()); + criteria.setGroupCode(selectedProject.getGroup().getCode()); + return criteria; } @Override protected final void onRender(final Element parent, final int pos) { super.onRender(parent, pos); - display(); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java index c583c5b5fe7caf88a5f5ca9278ebf548b6bdaecd..ff06c184eeb998ddb5e45d308c3381400a219179 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java @@ -32,23 +32,28 @@ import com.extjs.gxt.ui.client.data.PagingLoader; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.GridEvent; import com.extjs.gxt.ui.client.event.Listener; +import com.extjs.gxt.ui.client.event.SelectionChangedEvent; +import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; -import com.extjs.gxt.ui.client.widget.PagingToolBar; +import com.extjs.gxt.ui.client.widget.button.Button; 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.Grid; import com.extjs.gxt.ui.client.widget.layout.FitLayout; +import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; +import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.user.client.rpc.AsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync; import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.VoidAsyncCallback; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.BrowserGridPagingToolBar.IBrowserGridActionInvoker; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.columns.ColumnDefsAndConfigs; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.PagingToolBarWithoutRefresh; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.URLMethodWithParameters; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WindowUtils; @@ -65,23 +70,42 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SortInfo.SortDir; public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> extends LayoutContainer { + /** Shows the detail view for the specified entity */ abstract protected void showEntityViewer(M modelData); abstract protected void listEntities(DefaultResultSetConfig<String, T> resultSetConfig, AbstractAsyncCallback<ResultSet<T>> callback); + /** Converts specified list of entities into a list of grid rows models */ abstract protected List<M> createModels(List<T> entities); + /** + * Called when user wants to export the data. It can happen only after a previous refresh of the + * data has taken place. The export criteria has only the cache key + */ abstract protected void prepareExportEntities(TableExportCriteria<T> exportCriteria, AbstractAsyncCallback<String> callback); + /** + * @return definition of all the columns in the grid: visible properties and the mechanism of + * creating each column's value from the row model + */ abstract protected ColumnDefsAndConfigs<T> createColumnsDefinition(); - private static final int PAGE_SIZE = 50; + /** + * Called when the user wants to refresh the data. Should be implemented by calling + * {@link #refresh(IDataRefreshCallback, String, boolean) at some point. } + */ + abstract protected void refresh(); + + /** @return should the refresh button be enabled? */ + abstract protected boolean isRefreshEnabled(); protected final IViewContext<ICommonClientServiceAsync> viewContext; - // NOTE: private fields should remain unaccessible to subclasses! + // ------ private section. NOTE: it should remain unaccessible to subclasses! --------------- + + private static final int PAGE_SIZE = 50; private final PagingLoader<PagingLoadConfig> pagingLoader; @@ -89,6 +113,9 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex private final Grid<M> grid; + // the toolbar has the refresh and export buttons besides the paging controls + private final BrowserGridPagingToolBar pagingToolbar; + // available columns configs and definitions private ColumnDefsAndConfigs<T> columns; @@ -112,18 +139,31 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex protected AbstractBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext, String gridId) + { + this(viewContext, gridId, true); + } + + protected AbstractBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext, + String gridId, boolean showHeader) { this.viewContext = viewContext; this.pagingLoader = createPagingLoader(); this.grid = createGrid(pagingLoader, createEntityViewerHandler(), gridId); - this.contentPanel = createContentPanel(); + this.pagingToolbar = + new BrowserGridPagingToolBar(asActionInvoker(), viewContext, PAGE_SIZE); + pagingToolbar.bind(pagingLoader); + + this.contentPanel = createEmptyContentPanel(); + contentPanel.add(grid); + contentPanel.setBottomComponent(pagingToolbar); + contentPanel.setHeaderVisible(showHeader); setLayout(new FitLayout()); add(contentPanel); } - private final PagingLoader<PagingLoadConfig> createPagingLoader() + private PagingLoader<PagingLoadConfig> createPagingLoader() { final RpcProxy<PagingLoadConfig, PagingLoadResult<M>> proxy = createDataLoaderProxy(); final BasePagingLoader<PagingLoadConfig, PagingLoadResult<M>> newPagingLoader = @@ -198,7 +238,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex } /** @return number of rows in the grid */ - public int getRowNumber() + public final int getRowNumber() { return grid.getStore().getCount(); } @@ -227,7 +267,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex @Override protected final void finishOnFailure(final Throwable caught) { - refreshCallback.postRefresh(false); + onComplete(false); delegate.onFailure(caught); } @@ -244,8 +284,13 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex new BasePagingLoadResult<M>(models, resultSetConfig.getOffset(), result .getTotalLength()); delegate.onSuccess(loadResult); - // notify that the refresh is done - refreshCallback.postRefresh(true); + onComplete(true); + } + + // notify that the refresh is done + private void onComplete(boolean wasSuccessful) + { + refreshCallback.postRefresh(wasSuccessful); } } @@ -262,15 +307,55 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex }; } - // creates a panel with grid and a toolbar for paging - private ContentPanel createContentPanel() + // wraps this browser into the interface appropriate for the toolbar. If this class would just + // implement the interface it could be very confusing for the code reader. + private final IBrowserGridActionInvoker asActionInvoker() + { + final AbstractBrowserGrid<T, M> delegate = this; + return new IBrowserGridActionInvoker() + { + public void export() + { + delegate.export(); + } + + public void refresh() + { + delegate.refresh(); + } + }; + } + + protected final SelectionChangedListener<?> addRefreshButton(ToolBar container) { - ContentPanel panel = createEmptyContentPanel(); - panel.add(grid); - final PagingToolBar toolBar = new PagingToolBarWithoutRefresh(PAGE_SIZE); - toolBar.bind(pagingLoader); - panel.setBottomComponent(toolBar); - return panel; + String title = viewContext.getMessage(Dict.BUTTON_SHOW); + Button showButton = BrowserGridPagingToolBar.createRefreshButton(title, asActionInvoker()); + container.add(new AdapterToolItem(showButton)); + return createRefreshButtonsListener(showButton); + } + + private <D extends ModelData> SelectionChangedListener<D> createRefreshButtonsListener( + final Button showButton) + { + return new SelectionChangedListener<D>() + { + @Override + public void selectionChanged(SelectionChangedEvent<D> se) + { + updateDefaultRefreshButtons(); + + boolean isEnabled = isRefreshEnabled(); + // Refreshes the state of the specified refresh button. + BrowserGridPagingToolBar + .updateRefreshButton(showButton, isEnabled, viewContext); + } + }; + } + + protected final void updateDefaultRefreshButtons() + { + boolean isEnabled = isRefreshEnabled(); + pagingToolbar.updateDefaultRefreshButton(isEnabled); } /** @@ -279,12 +364,21 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex * Note that, doing so, the result set associated on the server side will be removed. * </p> */ - protected void refresh(final IDataRefreshCallback newRefreshCallback, String newHeaderOrNull, - boolean refreshColumnsDefinition) + protected final void refresh(String headerOrNull, boolean refreshColumnsDefinition) + { + refresh(null, headerOrNull, refreshColumnsDefinition); + } + + /** + * @externalRefreshCallbackOrNull external class can define it's own refresh callback method. It + * will be merged with the internal one. + */ + protected final void refresh(final IDataRefreshCallback externalRefreshCallbackOrNull, + String headerOrNull, boolean refreshColumnsDefinition) { disposeCache(); - this.refreshCallback = newRefreshCallback; - setHeader(newHeaderOrNull); + this.refreshCallback = createRefreshCallback(externalRefreshCallbackOrNull); + setHeader(headerOrNull); if (refreshColumnsDefinition) { this.columns = createColumnsDefinition(); @@ -296,14 +390,52 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex pagingLoader.load(0, PAGE_SIZE); } - private void setHeader(String newHeaderOrNull) + private IDataRefreshCallback createRefreshCallback( + IDataRefreshCallback externalRefreshCallbackOrNull) { - if (newHeaderOrNull != null) + IDataRefreshCallback internalCallback = createInternalPostRefreshCallback(); + if (externalRefreshCallbackOrNull == null) { - this.contentPanel.setHeading(newHeaderOrNull); + return internalCallback; } else { - this.contentPanel.setHeaderVisible(false); + return mergeCallbacks(internalCallback, externalRefreshCallbackOrNull); + } + } + + private IDataRefreshCallback createInternalPostRefreshCallback() + { + return new IDataRefreshCallback() + { + public void postRefresh(boolean wasSuccessful) + { + if (wasSuccessful) + { + pagingToolbar.enableExportButton(); + } + } + }; + } + + private static IDataRefreshCallback mergeCallbacks(final IDataRefreshCallback c1, + final IDataRefreshCallback c2) + { + return new IDataRefreshCallback() + { + public void postRefresh(boolean wasSuccessful) + { + c1.postRefresh(wasSuccessful); + c2.postRefresh(wasSuccessful); + } + }; + } + + private void setHeader(String headerOrNull) + { + if (headerOrNull != null) + { + assert this.contentPanel.isHeaderVisible() : "header was switched off"; + this.contentPanel.setHeading(headerOrNull); } } @@ -331,7 +463,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends ModelData> ex } } - public void disposeCache() + public final void disposeCache() { if (resultSetKey != null) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/BrowserGridPagingToolBar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/BrowserGridPagingToolBar.java new file mode 100644 index 0000000000000000000000000000000000000000..62a7027e115c1ce7861ee5ef80fddd42cc7fbf86 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/BrowserGridPagingToolBar.java @@ -0,0 +1,160 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid; + +import com.extjs.gxt.ui.client.event.ButtonEvent; +import com.extjs.gxt.ui.client.event.SelectionListener; +import com.extjs.gxt.ui.client.widget.PagingToolBar; +import com.extjs.gxt.ui.client.widget.button.Button; +import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; + +import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.PagingToolBarAdapter; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider; + +/** + * {@link PagingToolBar} extension with overwritten behavior of the <i>Refresh</i> button and + * additional <i>Export</i> button. + * + * @author Tomasz Pylak + */ +public final class BrowserGridPagingToolBar extends PagingToolBarAdapter +{ + // @Private + public static final String REFRESH_BUTTON_ID = + GenericConstants.ID_PREFIX + "paged-grid-refresh-button"; + + private final IMessageProvider messageProvider; + + private final Button exportButton; + + private final Button refreshButton; + + /** internal interface to delegate export and refresh actions */ + interface IBrowserGridActionInvoker + { + void export(); + + void refresh(); + } + + public BrowserGridPagingToolBar(IBrowserGridActionInvoker invoker, + IMessageProvider messageProvider, int pageSize) + { + super(pageSize); + this.messageProvider = messageProvider; + + // NOTE: the original superclass refresh button is removed during rendering + this.refreshButton = createRefreshButton(invoker); + add(refreshButton); + updateDefaultRefreshButton(false); + this.refreshButton.setId(REFRESH_BUTTON_ID); + + this.exportButton = createExportButton(messageProvider, invoker); + disableExportButton(); + add(exportButton); + } + + private void add(Button button) + { + add(new AdapterToolItem(button)); + } + + protected final void updateDefaultRefreshButton(boolean isEnabled) + { + updateRefreshButton(refreshButton, isEnabled, messageProvider); + } + + /** + * Refreshes the refresh button state. + */ + public static final void updateRefreshButton(Button refreshButton, boolean isEnabled, + IMessageProvider messageProvider) + { + refreshButton.setEnabled(isEnabled); + if (isEnabled) + { + refreshButton.setTitle(messageProvider.getMessage(Dict.TOOLTIP_REFRESH_ENABLED)); + } else + { + refreshButton.setTitle(messageProvider.getMessage(Dict.TOOLTIP_REFRESH_DISABLED)); + } + } + + public final void enableExportButton() + { + exportButton.setEnabled(true); + String title = messageProvider.getMessage(Dict.TOOLTIP_EXPORT_ENABLED); + exportButton.setTitle(title); + } + + private final void disableExportButton() + { + exportButton.setEnabled(false); + String title = messageProvider.getMessage(Dict.TOOLTIP_EXPORT_DISABLED); + exportButton.setTitle(title); + } + + private Button createRefreshButton(final IBrowserGridActionInvoker invoker) + { + return createRefreshButton(messageProvider.getMessage(Dict.BUTTON_REFRESH), invoker); + } + + public static Button createRefreshButton(String title, final IBrowserGridActionInvoker invoker) + { + final Button button = new Button(title, new SelectionListener<ButtonEvent>() + { + @Override + public void componentSelected(ButtonEvent ce) + { + if (ce.button.isEnabled()) + { + invoker.refresh(); + } + } + }); + return button; + } + + public static Button createExportButton(IMessageProvider messageProvider, + final IBrowserGridActionInvoker invoker) + { + final Button button = + new Button(messageProvider.getMessage(Dict.BUTTON_EXPORT_DATA), + new SelectionListener<ButtonEvent>() + { + @Override + public void componentSelected(ButtonEvent ce) + { + invoker.export(); + } + }); + return button; + } + + // + // PagingToolBar + // + + @Override + protected final void afterRender() + { + removeOriginalRefreshButton(); + super.afterRender(); + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowser.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowser.java index 77921fd7a14f54c0752fb0aa3755dd155c34dbf9..113b38d466c03ebba78b91061c612ff6233aa3ea 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowser.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowser.java @@ -45,9 +45,8 @@ public final class SampleBrowser extends LayoutContainer implements Listener<Tab setId(ID); setLayout(new RowLayout()); - sampleBrowserGrid = new SampleBrowserGrid(viewContext); - final SampleBrowserToolbar toolbar = - new SampleBrowserToolbar(viewContext, sampleBrowserGrid); + final SampleBrowserToolbar toolbar = new SampleBrowserToolbar(viewContext); + sampleBrowserGrid = new SampleBrowserGrid(viewContext, toolbar); add(toolbar); add(sampleBrowserGrid, new RowData(1, 1)); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java index 767b92b363bb49f2ca472e1eb22f83a96d77caa7..a2affec84f8c29a6fb8870c2f022530614b7dd3b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserGrid.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample import java.util.List; +import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.widget.LayoutContainer; import ch.systemsx.cisd.openbis.generic.client.shared.SampleType; @@ -51,14 +52,27 @@ public final class SampleBrowserGrid extends AbstractBrowserGrid<Sample, SampleM public static final String GRID_ID = GenericConstants.ID_PREFIX + PREFIX + "grid"; + private final SampleBrowserToolbar topToolbar; + + // criteria used in the previous refresh operation or null if it has not occurred yet private ListSampleCriteria criteria; - SampleBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext) + SampleBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext, + SampleBrowserToolbar topToolbar) { super(viewContext, GRID_ID); + this.topToolbar = topToolbar; + SelectionChangedListener<?> refreshButtonListener = addRefreshButton(topToolbar); + this.topToolbar.setCriteriaChangedListener(refreshButtonListener); setId(BROWSER_ID); } + @Override + protected boolean isRefreshEnabled() + { + return topToolbar.tryGetCriteria() != null; + } + @Override protected void listEntities(DefaultResultSetConfig<String, Sample> resultSetConfig, AbstractAsyncCallback<ResultSet<Sample>> callback) @@ -123,14 +137,19 @@ public final class SampleBrowserGrid extends AbstractBrowserGrid<Sample, SampleM * <code>resultSetKey</code> will be removed. * </p> */ - public final void refresh(ListSampleCriteria newCriteria, - final IDataRefreshCallback newRefreshCallback) + @Override + public final void refresh() { + ListSampleCriteria newCriteria = topToolbar.tryGetCriteria(); + if (newCriteria == null) + { + return; + } boolean refreshColumnsDefinition = hasColumnsDefinitionChanged(newCriteria); this.criteria = newCriteria; String newHeader = createHeader(newCriteria); - super.refresh(newRefreshCallback, newHeader, refreshColumnsDefinition); + super.refresh(newHeader, refreshColumnsDefinition); } @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java index e318c41a256861cbefc7ac6a2d176963a05a981c..a102e4726cfc0a611ab4fcea58def93fd1d40cf1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SampleBrowserToolbar.java @@ -16,13 +16,8 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; -import com.extjs.gxt.ui.client.event.ButtonEvent; -import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; -import com.extjs.gxt.ui.client.event.SelectionListener; -import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; -import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; @@ -32,11 +27,7 @@ import ch.systemsx.cisd.openbis.generic.client.shared.SampleType; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.GroupModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SampleTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.GroupSelectionWidget; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid.IDataRefreshCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleCriteria; @@ -52,176 +43,61 @@ final class SampleBrowserToolbar extends ToolBar private static final String PREFIX = ID + "_"; - static final String REFRESH_BUTTON_ID = GenericConstants.ID_PREFIX + PREFIX + "refresh-button"; - public static final String INCLUDE_GROUP_CHECKBOX_ID = GenericConstants.ID_PREFIX + PREFIX + "include-group-checkbox"; - private final SampleBrowserGrid entitiesBrowser; - private final SampleTypeSelectionWidget selectSampleTypeCombo; private final GroupSelectionWidget selectGroupCombo; - private final ToolbarController controller; - - private final Button submitButton; - - private final Button exportButton; - private final IViewContext<?> viewContext; - public SampleBrowserToolbar(final IViewContext<?> viewContext, - final SampleBrowserGrid sampleBrowserGrid) + public SampleBrowserToolbar(final IViewContext<?> viewContext) { - this.entitiesBrowser = sampleBrowserGrid; this.viewContext = viewContext; selectSampleTypeCombo = new SampleTypeSelectionWidget(viewContext, ID, true); selectGroupCombo = new GroupSelectionWidget(viewContext, ID); - submitButton = createSubmitButton(); - submitButton.setEnabled(false); - exportButton = createExportButton(); - exportButton.setEnabled(false); - controller = new ToolbarController(submitButton, exportButton); - controller.disableExportButton(); - addSelectSampleTypeListeners(); - addSelectGroupListeners(); + display(); } - private void addSelectGroupListeners() + public ListSampleCriteria tryGetCriteria() { - selectGroupCombo.addSelectionChangedListener(new SelectionChangedListener<GroupModel>() - { - - // - // SelectionChangedListener - // - - @Override - public final void selectionChanged(final SelectionChangedEvent<GroupModel> se) - { - final GroupModel selectedItem = se.getSelectedItem(); - Group group = - selectedItem != null ? (Group) selectedItem - .get(ModelDataPropertyNames.OBJECT) : null; - controller.refreshSubmitButtons(selectSampleTypeCombo - .tryGetSelectedSampleType(), group); - } - }); + final SampleType selectedType = selectSampleTypeCombo.tryGetSelectedSampleType(); + if (selectedType == null) + { + return null; + } + final Group selectedGroup = selectGroupCombo.tryGetSelectedGroup(); + if (selectedGroup == null) + { + return null; + } + final boolean includeInstance = GroupSelectionWidget.isSharedGroup(selectedGroup); + final boolean includeGroup = (includeInstance == false); + + ListSampleCriteria criteria = new ListSampleCriteria(); + criteria.setSampleType(selectedType); + criteria.setGroupCode(selectedGroup.getCode()); + criteria.setIncludeGroup(includeGroup); + criteria.setIncludeInstance(includeInstance); + return criteria; } - private void addSelectSampleTypeListeners() + public void setCriteriaChangedListener(SelectionChangedListener<?> criteriaChangedListener) { - selectSampleTypeCombo - .addSelectionChangedListener(new SelectionChangedListener<SampleTypeModel>() - { - // - // SelectionChangedListener - // - - @Override - public final void selectionChanged( - final SelectionChangedEvent<SampleTypeModel> se) - { - final SampleTypeModel selectedItem = se.getSelectedItem(); - SampleType sampleType = - selectedItem != null ? (SampleType) selectedItem - .get(ModelDataPropertyNames.OBJECT) : null; - controller.refreshSubmitButtons(sampleType, selectGroupCombo - .tryGetSelectedGroup()); - } - }); + selectGroupCombo.addSelectionChangedListener(criteriaChangedListener); + selectSampleTypeCombo.addSelectionChangedListener(criteriaChangedListener); } private void display() { setBorders(true); - removeAll(); add(new LabelToolItem(viewContext.getMessage(Dict.SAMPLE_TYPE) + GenericConstants.LABEL_SEPARATOR)); add(new AdapterToolItem(selectSampleTypeCombo)); add(new SeparatorToolItem()); add(new LabelToolItem(viewContext.getMessage(Dict.GROUP) + GenericConstants.LABEL_SEPARATOR)); add(new AdapterToolItem(selectGroupCombo)); - add(new FillToolItem()); - add(new AdapterToolItem(submitButton)); - add(new SeparatorToolItem()); - add(new AdapterToolItem(exportButton)); - layout(); - } - - private Button createSubmitButton() - { - final Button refreshButton = - new Button(viewContext.getMessage(Dict.BUTTON_REFRESH), - new SelectionListener<ButtonEvent>() - { - // - // SelectionListener - // - - @Override - public final void componentSelected(final ButtonEvent ce) - { - final SampleType selectedType = - selectSampleTypeCombo.tryGetSelectedSampleType(); - assert selectedType != null : "No sample type is selected."; - final Group selectedGroup = - selectGroupCombo.tryGetSelectedGroup(); - assert selectedGroup != null : "No group is selected."; - final boolean includeInstance = - GroupSelectionWidget.isSharedGroup(selectedGroup); - final boolean includeGroup = (includeInstance == false); - ListSampleCriteria criteria = - createListCriteria(selectedType, selectedGroup, - includeGroup, includeInstance); - - entitiesBrowser.refresh(criteria, createPostRefreshCallback()); - } - - private ListSampleCriteria createListCriteria( - final SampleType selectedType, final Group selectedGroup, - final Boolean includeGroup, final Boolean includeInstance) - { - ListSampleCriteria criteria = new ListSampleCriteria(); - criteria.setSampleType(selectedType); - criteria.setGroupCode(selectedGroup.getCode()); - criteria.setIncludeGroup(includeGroup); - criteria.setIncludeInstance(includeInstance); - return criteria; - } - - private IDataRefreshCallback createPostRefreshCallback() - { - return new IDataRefreshCallback() - { - public void postRefresh(boolean wasSuccessful) - { - if (wasSuccessful) - { - controller.enableExportButton(); - } - } - }; - } - }); - refreshButton.setId(REFRESH_BUTTON_ID); - return refreshButton; - } - - private Button createExportButton() - { - final Button button = - new Button(viewContext.getMessage(Dict.BUTTON_EXPORT_DATA), - new SelectionListener<ButtonEvent>() - { - @Override - public void componentSelected(ButtonEvent ce) - { - entitiesBrowser.export(); - } - }); - return button; } // @@ -232,7 +108,6 @@ final class SampleBrowserToolbar extends ToolBar protected final void onRender(final Element parent, final int pos) { super.onRender(parent, pos); - display(); } } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ToolbarController.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ToolbarController.java deleted file mode 100644 index de758494b1bebc5cbadfc4ffb8d33603421fba31..0000000000000000000000000000000000000000 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ToolbarController.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2008 ETH Zuerich, CISD - * - * 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; - -import com.extjs.gxt.ui.client.widget.button.Button; - -import ch.systemsx.cisd.openbis.generic.client.shared.SampleType; -import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group; - -/** - * Encapsulates the logic of interaction between Sample Browser GUI elements. - * - * @author Izabela Adamczyk - */ -// TODO 2008-12-05, Tomasz Pylak: use dictionary instead of hard coded strings -final class ToolbarController -{ - private final Button submitButton; - - private final Button exportButton; - - ToolbarController(final Button submitButton, final Button exportButton) - { - this.submitButton = submitButton; - this.exportButton = exportButton; - } - - /** - * Refreshes the <i>refresh</i> resp. <i>export</i> button. - */ - final void refreshSubmitButtons(final SampleType sampleTypeOrNull, final Group groupOrNull) - { - final boolean sampleTypeSelected = sampleTypeOrNull != null; - final boolean groupChosen = groupOrNull != null; - final boolean enable = sampleTypeSelected && groupChosen; - submitButton.setEnabled(enable); - if (enable) - { - submitButton.setTitle("Load or update the sample table"); - } else - { - submitButton.setTitle("HINT: To activate select group or shared checkbox"); - } - } - - final void enableExportButton() - { - exportButton.setEnabled(true); - exportButton.setTitle("Export the table visible on the screen to an Excel file"); - } - - final void disableExportButton() - { - exportButton.setEnabled(false); - exportButton.setTitle("Refresh the data before exporting them."); - } -} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarWithoutRefresh.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarAdapter.java similarity index 60% rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarWithoutRefresh.java rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarAdapter.java index f2d4c2b91d0568a2467a79beeffaca912b1e4d0a..58fb12f616a7a445ebf57c0f1b87a32450ebf8b8 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarWithoutRefresh.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/PagingToolBarAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 ETH Zuerich, CISD + * Copyright 2009 ETH Zuerich, CISD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,40 +16,37 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget; +import java.util.List; + import com.extjs.gxt.ui.client.widget.PagingToolBar; +import com.extjs.gxt.ui.client.widget.toolbar.ToolItem; /** - * A small {@link PagingToolBar} extension which does not contain the <i>Refresh</i> button. + * Use this subclass instead of the {@link PagingToolBar}. It is compatible with our UI testing + * framework. It also allows to remove the default refresh button. * - * @author Christian Ribeaud + * @author Tomasz Pylak */ -public final class PagingToolBarWithoutRefresh extends PagingToolBar +public class PagingToolBarAdapter extends PagingToolBar { - public PagingToolBarWithoutRefresh(int pageSize) + public PagingToolBarAdapter(int pageSize) { super(pageSize); } - private final void removeRefreshButton() + protected final void removeOriginalRefreshButton() { final int refreshIndex = toolBar.indexOf(refresh); if (refreshIndex > -1) { toolBar.remove(refresh); - // Remove the SeparatorToolItem placed just before the refresh button. - toolBar.remove(toolBar.getItem(refreshIndex - 1)); } } - // - // PagingToolBar - // - - @Override - protected final void afterRender() + /** Exposes items of the toolbar. NOTE: use only for testing! */ + public List<ToolItem> getItems() { - removeRefreshButton(); - super.afterRender(); + return toolBar.getItems(); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js index 3eb172985a95a109f67931fbcfedf54dc0cfd6b9..6804dab6fb94c4fa9251f69d7eaaabab22befa95 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js +++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js @@ -39,9 +39,14 @@ var common = { button_reset: "Reset", button_submit: "Submit", button_refresh: "Refresh", + button_show: "Show", button_exportData: "Export Data", button_add_group: "Add Group", - + tooltip_refresh_disabled: "To activate select appropriate criteria first.", + tooltip_refresh_enabled: "Load or update the table.", + tooltip_export_enabled: "Export the table visible on the screen to an Excel file", + tooltip_export_disabled: "Refresh the data before exporting them.", + // // LoginWidget // @@ -135,7 +140,7 @@ var common = { vocabulary_terms: "Terms", vocabulary_terms_empty: "White space or comma separated list", mandatory: "Mandatory", - default_value: "Global Value", + default_value: "Default Value", entity_type_assignments: "{0} Type Assignment{1}", // @@ -180,7 +185,7 @@ var common = { // vocabulary_browser: "Vocabulary Browser", is_managed_internally: "Managed Internally?", - + // LAST LINE: KEEP IT AT THE END lastline: "" // we need a line without a comma }; diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ListExperiments.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ListExperiments.java index b0f9661a9f9c32852b097ec6c01884c25cd04bc2..f49d5bf48cd05a9931e0ca01f40972170f046c39 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ListExperiments.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/ListExperiments.java @@ -21,6 +21,7 @@ import com.extjs.gxt.ui.client.widget.form.ComboBox; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ExperimentTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.BrowserGridPagingToolBar; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractDefaultTestCommand; import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.GWTTestUtil; @@ -64,8 +65,8 @@ public class ListExperiments extends AbstractDefaultTestCommand GWTUtils.setSelectedItem(project, ModelDataPropertyNames.CODE, projectCodeOrNull); final Button refresh = - (Button) GWTTestUtil.getWidgetWithID(ExperimentBrowserToolbar.REFRESH_BUTTON_ID); + (Button) GWTTestUtil.getWidgetWithID(BrowserGridPagingToolBar.REFRESH_BUTTON_ID); assertTrue(refresh.isEnabled()); - GWTTestUtil.clickButtonWithID(ExperimentBrowserToolbar.REFRESH_BUTTON_ID); + GWTTestUtil.clickButtonWithID(BrowserGridPagingToolBar.REFRESH_BUTTON_ID); } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ListSamples.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ListSamples.java index 5c429c89580f88235c05c09a173066d01d57ef58..c410d398091b532dcf926e72b08345714eadb771 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ListSamples.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/ListSamples.java @@ -22,6 +22,7 @@ import com.extjs.gxt.ui.client.widget.form.ComboBox; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SampleTypeModel; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.GroupSelectionWidget; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.BrowserGridPagingToolBar; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractDefaultTestCommand; import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.GWTTestUtil; @@ -64,8 +65,8 @@ public class ListSamples extends AbstractDefaultTestCommand GWTUtils.setSelectedItem(groupSelector, ModelDataPropertyNames.CODE, groupNameOrNull); final Button refresh = - (Button) GWTTestUtil.getWidgetWithID(SampleBrowserToolbar.REFRESH_BUTTON_ID); + (Button) GWTTestUtil.getWidgetWithID(BrowserGridPagingToolBar.REFRESH_BUTTON_ID); assertTrue(refresh.isEnabled()); - GWTTestUtil.clickButtonWithID(SampleBrowserToolbar.REFRESH_BUTTON_ID); + GWTTestUtil.clickButtonWithID(BrowserGridPagingToolBar.REFRESH_BUTTON_ID); } } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/GWTTestUtil.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/GWTTestUtil.java index e1f4a67c24982c544a11e1118bbfcb3ec561fc46..8d7ae9cda7ecfe75b3c5bb4c4776cec02417b85f 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/GWTTestUtil.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/testframework/GWTTestUtil.java @@ -38,6 +38,7 @@ import com.extjs.gxt.ui.client.widget.form.MultiField; import com.extjs.gxt.ui.client.widget.form.TextArea; import com.extjs.gxt.ui.client.widget.form.TextField; import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem; +import com.extjs.gxt.ui.client.widget.toolbar.ToolItem; import com.extjs.gxt.ui.client.widget.tree.Tree; import com.extjs.gxt.ui.client.widget.tree.TreeItem; import com.google.gwt.user.client.Element; @@ -49,6 +50,7 @@ import com.google.gwt.user.client.ui.Widget; import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.LeftMenu; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.PagingToolBarAdapter; /** * Useful static methods for testing. @@ -319,15 +321,7 @@ public final class GWTTestUtil @SuppressWarnings("unchecked") public final boolean handle(final Widget widgetOrNull) { - Widget widget = widgetOrNull; - if (widgetOrNull instanceof AdapterToolItem) - { - widget = ((AdapterToolItem) widgetOrNull).getWidget(); - } - if (widgetOrNull instanceof AdapterField) - { - widget = ((AdapterField) widgetOrNull).getWidget(); - } + Widget widget = unwrapWidget(widgetOrNull); if (handler.handle(widget)) { return true; @@ -344,11 +338,59 @@ public final class GWTTestUtil } else if (widget instanceof MultiField) { return new MultiFieldHandler(this).handle((MultiField<Field<?>>) widget); + } else if (widget instanceof PagingToolBarAdapter) + { + return new PagingToolBarHandler(this).handle((PagingToolBarAdapter) widget); + } else { return false; } } + + private static Widget unwrapWidget(final Widget widgetOrNull) + { + if (widgetOrNull == null) + { + return null; + } + if (widgetOrNull instanceof AdapterToolItem) + { + return ((AdapterToolItem) widgetOrNull).getWidget(); + } + if (widgetOrNull instanceof AdapterField) + { + return ((AdapterField) widgetOrNull).getWidget(); + } + return widgetOrNull; + } + } + + private static final class PagingToolBarHandler implements IWidgetHandler<PagingToolBarAdapter> + { + private final IWidgetHandler<Widget> handler; + + PagingToolBarHandler(final IWidgetHandler<Widget> handler) + { + this.handler = handler; + } + + // + // IWidgetHandler + // + + public final boolean handle(final PagingToolBarAdapter pagingToolBar) + { + for (final ToolItem item : pagingToolBar.getItems()) + { + if (handler.handle(item)) + { + return true; + } + + } + return false; + } } private static final class TreeHandler implements IWidgetHandler<Tree>