/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.syncope.client.console.panels;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.syncope.client.console.rest.BaseRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.ajax.form.IndicatorAjaxFormChoiceComponentUpdatingBehavior;
import org.apache.syncope.client.console.bulk.BulkActionModal;
import org.apache.syncope.client.console.bulk.BulkContent;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.DirectoryPanel.EventDataWrapper;
import org.apache.syncope.client.console.rest.RestClient;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CheckGroupColumn;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AjaxFallbackDataTable;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.CheckGroup;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;
public final class AjaxDataTablePanel<T extends Serializable, S> extends DataTablePanel<T, S> {
private static final long serialVersionUID = -7264400471578272966L;
public static class Builder<T extends Serializable, S> implements Serializable {
private static final long serialVersionUID = 8876232177473972722L;
private boolean checkBoxEnabled = true;
private final List<IColumn<T, S>> columns = new ArrayList<>();
private final ISortableDataProvider<T, S> dataProvider;
private int rowsPerPage = 10;
private final Collection<ActionLink.ActionType> bulkActions = new ArrayList<>();
private RestClient bulkActionExecutor;
private String itemKeyField;
private final PageReference pageRef;
private WebMarkupContainer container;
private MultilevelPanel multiLevelPanel;
private BaseModal<?> baseModal;
public Builder(final ISortableDataProvider<T, S> provider, final PageReference pageRef) {
this.dataProvider = provider;
this.pageRef = pageRef;
}
public AjaxDataTablePanel<T, S> build(final String id) {
return new AjaxDataTablePanel<>(id, this);
}
public Builder<T, S> setContainer(final WebMarkupContainer container) {
this.container = container;
return this;
}
public Builder<T, S> addBulkAction(final ActionLink.ActionType actionType) {
bulkActions.add(actionType);
return this;
}
public Builder<T, S> setBulkActionExecutor(final BaseRestClient bulkActionExecutor) {
this.bulkActionExecutor = bulkActionExecutor;
return this;
}
public Builder<T, S> setItemKeyField(final String itemKeyField) {
this.itemKeyField = itemKeyField;
return this;
}
public Builder<T, S> setBulkActions(
final Collection<ActionLink.ActionType> bulkActions,
final RestClient bulkActionExecutor,
final String itemKeyField) {
this.bulkActions.clear();
if (bulkActions != null) {
this.bulkActions.addAll(bulkActions);
}
this.bulkActionExecutor = bulkActionExecutor;
this.itemKeyField = itemKeyField;
return this;
}
public Builder<T, S> addColumn(final IColumn<T, S> column) {
columns.add(column);
return this;
}
public Builder<T, S> setColumns(final List<IColumn<T, S>> columns) {
this.columns.clear();
if (columns != null) {
this.columns.addAll(columns);
}
return this;
}
public Builder<T, S> setRowsPerPage(final int rowsPerPage) {
this.rowsPerPage = rowsPerPage;
return this;
}
public Builder<T, S> disableCheckBoxes() {
this.checkBoxEnabled = false;
return this;
}
private boolean isBulkEnabled() {
return checkBoxEnabled && bulkActionExecutor != null && !bulkActions.isEmpty();
}
public void setMultiLevelPanel(final BaseModal<?> baseModal, final MultilevelPanel multiLevelPanel) {
this.multiLevelPanel = multiLevelPanel;
this.baseModal = baseModal;
}
protected ActionsPanel<T> getActions(final IModel<T> model) {
return null;
}
protected ActionLinksTogglePanel<T> getTogglePanel() {
return null;
}
}
private AjaxDataTablePanel(final String id, final Builder<T, S> builder) {
super(id);
final BaseModal<T> bulkModal = new BaseModal<>("bulkModal");
add(bulkModal);
bulkModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
private static final long serialVersionUID = 8804221891699487149L;
@Override
public void onClose(final AjaxRequestTarget target) {
bulkModal.show(false);
EventDataWrapper data = new EventDataWrapper();
data.setTarget(target);
data.setRows(builder.rowsPerPage);
send(builder.pageRef.getPage(), Broadcast.BREADTH, data);
BasePage page = (BasePage) findPage();
if (page != null) {
page.getNotificationPanel().refresh(target);
}
}
});
Fragment fragment = new Fragment("tablePanel", "bulkAvailable", this);
add(fragment);
Form<T> bulkActionForm = new Form<>("groupForm");
fragment.add(bulkActionForm);
group = new CheckGroup<>("checkgroup", model);
group.add(new IndicatorAjaxFormChoiceComponentUpdatingBehavior() {
private static final long serialVersionUID = -151291731388673682L;
@Override
protected void onUpdate(final AjaxRequestTarget target) {
}
});
bulkActionForm.add(group);
if (builder.checkBoxEnabled) {
builder.columns.add(0, new CheckGroupColumn<T, S>(group));
}
dataTable = new AjaxFallbackDataTable<T, S>(
"dataTable", builder.columns, builder.dataProvider, builder.rowsPerPage, builder.container) {
private static final long serialVersionUID = -7370603907251344224L;
@Override
protected ActionsPanel<T> getActions(final IModel<T> model) {
return builder.getActions(model);
}
@Override
protected ActionLinksTogglePanel<T> getTogglePanel() {
return builder.getTogglePanel();
}
};
dataTable.add(new AttributeModifier("class", "table table-bordered table-hover dataTable"));
group.add(dataTable);
fragment.add(new IndicatingAjaxButton("bulkActionLink", bulkActionForm) {
private static final long serialVersionUID = 382302811235019988L;
@Override
protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
if (builder.multiLevelPanel == null) {
bulkModal.header(new ResourceModel("bulk.action", "Bulk action"));
bulkModal.changeCloseButtonLabel(getString("cancel", null, "Cancel"), target);
target.add(bulkModal.setContent(new BulkActionModal<>(
bulkModal,
builder.pageRef,
new ArrayList<>(group.getModelObject()),
// serialization problem with sublist only
new ArrayList<>(builder.columns.subList(1, builder.columns.size())),
builder.bulkActions,
builder.bulkActionExecutor,
builder.itemKeyField)));
bulkModal.show(true);
} else {
builder.multiLevelPanel.next(
getString("bulk.action"),
new BulkContent<>(
builder.baseModal,
new ArrayList<>(group.getModelObject()),
// serialization problem with sublist only
new ArrayList<>(builder.columns.subList(1, builder.columns.size() - 1)),
builder.bulkActions,
builder.bulkActionExecutor,
builder.itemKeyField),
target);
}
group.setModelObject(Collections.<T>emptyList());
target.add(group);
}
}.setEnabled(builder.isBulkEnabled()).setVisible(builder.isBulkEnabled()));
}
}