/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.uberfire.ext.security.management.client.widgets.management.list;
import java.util.Collection;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Alternative;
import javax.inject.Inject;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import org.gwtbootstrap3.client.ui.constants.HeadingSize;
import org.uberfire.client.mvp.UberView;
import org.uberfire.ext.security.management.api.AbstractEntityManager;
import org.uberfire.ext.security.management.client.widgets.popup.LoadingBox;
/**
* <p>Presenter class for listing entities.</p>
*/
@Dependent
@Alternative
public class EntitiesList<T> implements IsWidget {
protected static final int DEFAULT_PAGE_SIZE = 5;
public View view;
LoadingBox loadingBox;
int pageSize = DEFAULT_PAGE_SIZE;
HeadingSize headingSize = HeadingSize.H3;
Callback callback;
PaginationConstraints paginationConstraints;
int totalPages = -1;
String emptyEntitiesText = null;
@Inject
public EntitiesList(LoadingBox loadingBox,
View view) {
this.loadingBox = loadingBox;
this.view = view;
}
@PostConstruct
protected void init() {
view.init(this);
}
public void show(final AbstractEntityManager.SearchResponse<T> response,
final Callback<T> callback) {
if (callback != null && response != null) {
show(response.getResults(),
createPaginationCallback(response),
callback);
}
}
public void select(final String identifier) {
doSelectEntity(identifier,
true);
}
public void unselect(final String identifier) {
doSelectEntity(identifier,
false);
}
/* ******************************************************************************************************
PUBLIC PRESENTER API
****************************************************************************************************** */
public void clear() {
callback = null;
paginationConstraints = null;
totalPages = -1;
emptyEntitiesText = null;
view.clear();
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setEmptyEntitiesText(String emptyEntitiesText) {
this.emptyEntitiesText = emptyEntitiesText;
}
public void setEntityTitleSize(HeadingSize headingSize) {
this.headingSize = headingSize;
}
@Override
public Widget asWidget() {
return view.asWidget();
}
String getEntityType() {
return callback.getEntityType();
}
void onReadEntity(final String identifier) {
callback.onReadEntity(identifier);
}
void onRemoveEntity(final String identifier) {
callback.onRemoveEntity(identifier);
}
/* ******************************************************************************************************
PACKAGE PROTECTED METHODS FOR USING AS CALLBACKS FOR THE VIEW
****************************************************************************************************** */
void onGoToFirstPage() {
final int currentPage = paginationConstraints.getCurrentPage();
callback.onChangePage(currentPage,
1);
}
void onGoToPrevPage() {
final int currentPage = paginationConstraints.getCurrentPage();
callback.onChangePage(currentPage,
currentPage - 1);
}
void onGoToNextPage() {
final int currentPage = paginationConstraints.getCurrentPage();
callback.onChangePage(currentPage,
currentPage + 1);
}
void onGoToLastPage() {
final int currentPage = paginationConstraints.getCurrentPage();
if (totalPages > 0) {
callback.onChangePage(currentPage,
totalPages + 1);
}
}
void onSelectEntity(String identifier,
int index,
boolean isSelected) {
doSelectEntity(identifier,
isSelected);
}
private void doSelectEntity(String identifier,
boolean isSelected) {
callback.onSelectEntity(identifier,
isSelected);
}
protected void show(final Collection<T> entities,
final PaginationConstraints paginationConstraints,
final Callback<T> callback) {
this.callback = callback;
this.paginationConstraints = paginationConstraints;
if (callback != null && entities != null) {
showLoadingView();
// Configure view and the paginator.
view.configure(emptyEntitiesText,
paginationConstraints);
// Add the entities.
if (!entities.isEmpty()) {
int index = 0;
for (final T entity : entities) {
final String id = callback.getIdentifier(entity);
final String title = callback.getTitle(entity);
final boolean isSelected = callback.isSelected(id);
view.add(index,
id,
title,
headingSize,
callback.canRead(),
callback.canRemove(),
callback.canSelect(),
isSelected);
index++;
}
}
hideLoadingView();
}
}
protected PaginationConstraints createPaginationCallback(final AbstractEntityManager.SearchResponse searchResponse) {
if (searchResponse != null) {
final int page = searchResponse.getPage();
final int total = searchResponse.getTotal();
// If the SPI is able to get max row count, calculate total pages.
final int totalPagesRounded = (int) Math.ceil(total / (double) searchResponse.getPageSize());
EntitiesList.this.totalPages = total > -1 ? total / searchResponse.getPageSize() : -1;
final boolean hasNextPage = totalPages > -1 ? page < totalPagesRounded : searchResponse.hasNextPage();
final boolean notInFistPage = page > 1;
final boolean isLastPageButtonEnabled = EntitiesList.this.totalPages > -1 && hasNextPage;
return (new PaginationConstraints() {
@Override
public boolean isFirstPageEnabled() {
return notInFistPage;
}
@Override
public boolean isFirstPageVisible() {
return notInFistPage;
}
@Override
public boolean isPrevPageEnabled() {
return notInFistPage;
}
@Override
public boolean isPrevPageVisible() {
return notInFistPage;
}
@Override
public int getCurrentPage() {
return page;
}
@Override
public boolean isNextPageEnabled() {
return hasNextPage;
}
@Override
public boolean isNextPageVisible() {
return hasNextPage;
}
@Override
public boolean isLastPageEnabled() {
return isLastPageButtonEnabled;
}
@Override
public boolean isLastPageVisible() {
return isLastPageButtonEnabled;
}
@Override
public Integer getTotal() {
return total > -1 ? total : null;
}
});
}
return null;
}
/* ******************************************************************************************************
PROTECTED METHODS FOR INTERNAL PRESENTER LOGIC
****************************************************************************************************** */
protected void showLoadingView() {
loadingBox.show();
}
protected void hideLoadingView() {
loadingBox.hide();
}
public interface View extends UberView<EntitiesList> {
View configure(final String emptyEntitiesText,
final PaginationConstraints paginationConstraints);
View add(final int index,
final String identifier,
final String title,
final HeadingSize titleSize,
final boolean canRead,
final boolean canRemove,
final boolean canSelect,
final boolean isSelected);
View clear();
}
/**
* <p>The pagination constraints for view's pager component.</p>
*/
public interface PaginationConstraints {
/**
* <p>First page button status.</p>
* @return The first page button will be enabled if <code>true</code>, otherwise disabled.
*/
boolean isFirstPageEnabled();
/**
* <p>First page button visibility.</p>
* @return The first page button will be visible if <code>true</code>, otherwise hidden.
*/
boolean isFirstPageVisible();
/**
* <p>Previous page button status.</p>
* @return The previous page button will be enabled if <code>true</code>, otherwise disabled.
*/
boolean isPrevPageEnabled();
/**
* <p>Previous page button visibility.</p>
* @return The previous page button will be visible if <code>true</code>, otherwise hidden.
*/
boolean isPrevPageVisible();
/**
* <p>Current page.</p>
* @return The current page.
*/
int getCurrentPage();
/**
* <p>Next page button status.</p>
* @return The next page button will be enabled if <code>true</code>, otherwise disabled.
*/
boolean isNextPageEnabled();
/**
* <p>Next page button visibility.</p>
* @return The next page button will be visible if <code>true</code>, otherwise hidden.
*/
boolean isNextPageVisible();
/**
* <p>Last page button status.</p>
* @return The last page button will be enabled if <code>true</code>, otherwise disabled.
*/
boolean isLastPageEnabled();
/**
* <p>Last page button visibility.</p>
* @return The last page button will be visible if <code>true</code>, otherwise hidden.
*/
boolean isLastPageVisible();
/**
* <p>Show the total number of entities, if available.</p>
* @return The total number of entities or <code>null</code> if not available.
*/
Integer getTotal();
}
/**
* <p>Callback methods for view's user actions.</p>
*/
public interface Callback<T> {
/**
* <p>The title for the entity type to manage, such as "user" or "group".</p>
* @return The entity type title.
*/
String getEntityType();
/**
* <p>Allows enabling or disabling the entities read feature.</p>
* @return <p>Two possible values:</p>
* <ul>
* <li><code>true</code> - The entities list widget enables the read feature.</li>
* <li><code>false</code> - The entities list widget disables the read feature.</li>
* </ul>
*/
boolean canRead();
/**
* <p>Allows enabling or disabling the entities delete feature.</p>
* @return <p>Two possible values:</p>
* <ul>
* <li><code>true</code> - The entities list widget enables the delete feature.</li>
* <li><code>false</code> - The entities list widget disables the delete feature.</li>
* </ul>
*/
boolean canRemove();
/**
* <p>Allows enabling or disabling the entities selection feature.</p>
* @return <p>Two possible values:</p>
* <ul>
* <li><code>true</code> - The entities list widget enables the selection feature.</li>
* <li><code>false</code> - The entities list widget disables the selection feature.</li>
* </ul>
*/
boolean canSelect();
/**
* <p>Specify if the entity must be marked as selected..</p>
*/
boolean isSelected(final String identifier);
/**
* <p>The entity identifier.</p>
* @param entity The entity.
* @return The entity identifier.
*/
String getIdentifier(final T entity);
/**
* <p>The entity title.</p>
* @param entity The title.
* @return The entity identifier.
*/
String getTitle(final T entity);
/**
* <p>Read an entity</p>
* @param identifier The entity's identifier to read.
*/
void onReadEntity(final String identifier);
/**
* <p>Remove an entity</p>
* @param identifier The entity's identifier to remove.
*/
void onRemoveEntity(final String identifier);
/**
* <p>Select or unselect an entity from the list.</p>
* @param identifier The entity's identifier to remove.
* @param isSelected If <code>true</code>, the entity has been selected, otherwise has been unselected.
*/
void onSelectEntity(final String identifier,
final boolean isSelected);
/**
* <p>Change current page.</p>
* @param currentPage Current page.
* @param goToPage The target page number to navigate.
*/
void onChangePage(final int currentPage,
final int goToPage);
}
}