package kornell.gui.client.presentation.admin.audit.generic; import static com.google.gwt.dom.client.BrowserEvents.CLICK; import static kornell.core.util.StringUtils.mkurl; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.CellTable; import com.github.gwtbootstrap.client.ui.ListBox; import com.github.gwtbootstrap.client.ui.Tab; import com.github.gwtbootstrap.client.ui.constants.IconType; import com.github.gwtbootstrap.client.ui.resources.ButtonSize; import com.google.gwt.cell.client.ActionCell; import com.google.gwt.cell.client.ActionCell.Delegate; import com.google.gwt.cell.client.Cell; import com.google.gwt.cell.client.CompositeCell; import com.google.gwt.cell.client.FieldUpdater; import com.google.gwt.cell.client.HasCell; import com.google.gwt.cell.client.ValueUpdater; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.ScriptInjector; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.place.shared.PlaceChangeEvent; import com.google.gwt.place.shared.PlaceController; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeHtmlUtils; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; import com.google.gwt.user.cellview.client.TextColumn; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.SelectionChangeEvent; import com.google.gwt.view.client.SingleSelectionModel; import com.google.web.bindery.event.shared.EventBus; import kornell.api.client.KornellSession; import kornell.core.entity.AuditedEntityType; import kornell.core.event.EntityChanged; import kornell.core.to.EntityChangedEventsTO; import kornell.core.util.StringUtils; import kornell.gui.client.ViewFactory; import kornell.gui.client.presentation.admin.audit.AdminAuditPresenter; import kornell.gui.client.presentation.admin.audit.AdminAuditView; import kornell.gui.client.presentation.admin.course.course.AdminCoursePlace; import kornell.gui.client.presentation.admin.courseclass.courseclass.AdminCourseClassPlace; import kornell.gui.client.presentation.admin.courseversion.courseversion.AdminCourseVersionPlace; import kornell.gui.client.presentation.admin.courseversion.courseversion.AdminCourseVersionView; import kornell.gui.client.presentation.admin.institution.AdminInstitutionPlace; import kornell.gui.client.presentation.profile.ProfilePlace; import kornell.gui.client.util.ClientConstants; import kornell.gui.client.util.forms.FormHelper; import kornell.gui.client.util.view.KornellPagination; public class GenericAdminAuditView extends Composite implements AdminAuditView { Logger logger = Logger.getLogger(GenericAdminAuditView.class.getName()); interface MyUiBinder extends UiBinder<Widget, GenericAdminAuditView> { } private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class); private PlaceController placeCtrl; final CellTable<EntityChanged> table; private KornellPagination pagination; private AdminAuditView.Presenter presenter; private FormHelper formHelper = GWT.create(FormHelper.class); private ListBox entityTypesList; private Timer updateTimer; private boolean jsondiffpatchLoaded; @UiField FlowPanel adminHomePanel; @UiField FlowPanel entitiesChangedPanel; @UiField FlowPanel entitiesChangedWrapper; @UiField FlowPanel diffWrapper; Tab adminsTab; FlowPanel adminsPanel; private AdminCourseVersionView view; private AdminAuditPresenter adminAuditPresenter; private FlowPanel tableTools; private EntityChangedEventsTO entityChangedEventsTO; public GenericAdminAuditView(final KornellSession session, final EventBus bus, final PlaceController placeCtrl, final ViewFactory viewFactory) { this.placeCtrl = placeCtrl; initWidget(uiBinder.createAndBindUi(this)); table = new CellTable<EntityChanged>(); bus.addHandler(PlaceChangeEvent.TYPE, new PlaceChangeEvent.Handler() { @Override public void onPlaceChange(PlaceChangeEvent event) { entitiesChangedPanel.setVisible(true); entitiesChangedWrapper.setVisible(true); view = null; } }); displayDiff(null); } @Override public EntityChangedEventsTO getEntityChangedEventsTO(){ return entityChangedEventsTO; } private void filter() { presenter.setPageNumber("1"); presenter.setSearchTerm(entityTypesList.getValue()); presenter.updateData(); } private void initSearch() { if (entityTypesList == null) { entityTypesList = new ListBox(); List<AuditedEntityType> auditedEntityTypes = Arrays.asList(AuditedEntityType.values()); entityTypesList.addItem("[Selecione]", ""); for (AuditedEntityType auditedEntityType : auditedEntityTypes) { entityTypesList.addItem(auditedEntityType.toString()); } entityTypesList.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { displayDiff(null); filter(); } }); } } private void initTable() { table.addStyleName("adminCellTable"); table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED); for (int i = 0; table.getColumnCount() > 0;) { table.removeColumn(i); } table.addColumn(new TextColumn<EntityChanged>() { @Override public String getValue(EntityChanged entityChanged) { return entityChanged.getEntityType().toString(); } }, "Tipo"); table.addColumn(new TextColumn<EntityChanged>() { @Override public String getValue(EntityChanged entityChanged) { return entityChanged.getEntityName(); } }, "Nome"); table.addColumn(new TextColumn<EntityChanged>() { @Override public String getValue(EntityChanged entityChanged) { return entityChanged.getFromUsername() + "(" + entityChanged.getFromPersonName() + ")"; } }, "Usuário"); table.addColumn(new TextColumn<EntityChanged>() { @Override public String getValue(EntityChanged entityChanged) { return DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss").format(entityChanged.getEventFiredAt()); } }, "Data"); List<HasCell<EntityChanged, ?>> cells = new LinkedList<HasCell<EntityChanged, ?>>(); cells.add(new AuditActionsHasCell("Comparar", getAuditDelegate())); cells.add(new AuditActionsHasCell("Gerenciar", getGoToPlaceDelegate())); CompositeCell<EntityChanged> cell = new CompositeCell<EntityChanged>(cells); table.addColumn(new Column<EntityChanged, EntityChanged>(cell) { @Override public EntityChanged getValue(EntityChanged entityChanged) { return entityChanged; } }, "Ações"); // Add a selection model to handle user selection. final SingleSelectionModel<EntityChanged> selectionModel = new SingleSelectionModel<EntityChanged>(); table.setSelectionModel(selectionModel); selectionModel .addSelectionChangeHandler(new SelectionChangeEvent.Handler() { public void onSelectionChange(SelectionChangeEvent event) { EntityChanged selected = selectionModel.getSelectedObject(); if (selected != null) { displayDiff(selected); } } }); } private void displayDiff(final EntityChanged entityChanged) { diffWrapper.setVisible(entityChanged != null); if(jsondiffpatchLoaded){ if(entityChanged != null) display(entityChanged.getFromValue(), entityChanged.getToValue()); } else { ScriptInjector .fromUrl(mkurl(ClientConstants.JS_PATH, "jsondiffpatch.js")) .setCallback( new com.google.gwt.core.client.Callback<Void, Exception>() { public void onFailure(Exception reason) { logger.severe("Screeenful script load failed."); } public void onSuccess(Void result) { Timer screenfulJsTimer = new Timer() { public void run() { if(entityChanged != null) display(entityChanged.getFromValue(), entityChanged.getToValue()); jsondiffpatchLoaded = true; } }; // wait 2 secs after loading the javascript file screenfulJsTimer.schedule((int) (3 * 1000)); } }).setWindow(ScriptInjector.TOP_WINDOW) .inject(); } } private static native String display(String from, String to) /*-{ console.log('from ', from); console.log('to ', to); $wnd.init(from, to); }-*/; public void goToEntityPlace(EntityChanged entityChanged){ switch (entityChanged.getEntityType()) { case person: case password: placeCtrl.goTo(new ProfilePlace(entityChanged.getEntityUUID(), false)); break; case institution: case institutionAdmin: case institutionHostName: case institutionEmailWhitelist: placeCtrl.goTo(new AdminInstitutionPlace()); break; case course: placeCtrl.goTo(new AdminCoursePlace(entityChanged.getEntityUUID())); break; case courseVersion: placeCtrl.goTo(new AdminCourseVersionPlace(entityChanged.getEntityUUID())); break; case courseClass: case courseClassAdmin: case courseClassObserver: case courseClassTutor: placeCtrl.goTo(new AdminCourseClassPlace(entityChanged.getEntityUUID())); break; default: break; } } @Override public void setPresenter(Presenter presenter) { this.presenter = presenter; pagination = new KornellPagination(table, presenter); } private Delegate<EntityChanged> getAuditDelegate() { return new Delegate<EntityChanged>() { @Override public void execute(EntityChanged entityChanged) { displayDiff(entityChanged); } }; } private Delegate<EntityChanged> getGoToPlaceDelegate() { return new Delegate<EntityChanged>() { @Override public void execute(EntityChanged entityChanged) { goToEntityPlace(entityChanged); } }; } private class AuditActionsActionCell<CourseVersion> extends ActionCell<EntityChanged> { public AuditActionsActionCell(String message, Delegate<EntityChanged> delegate) { super(message, delegate); } @Override public void onBrowserEvent(Context context, Element parent, EntityChanged value, NativeEvent event, ValueUpdater<EntityChanged> valueUpdater) { event.stopPropagation(); event.preventDefault(); super.onBrowserEvent(context, parent, value, event, valueUpdater); if (CLICK.equals(event.getType())) { EventTarget eventTarget = event.getEventTarget(); if (!Element.is(eventTarget)) { return; } if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) { // Ignore clicks that occur outside of the main element. onEnterKeyDown(context, parent, value, event, valueUpdater); } } } } private class AuditActionsHasCell implements HasCell<EntityChanged, EntityChanged> { private AuditActionsActionCell<EntityChanged> cell; public AuditActionsHasCell(String text, Delegate<EntityChanged> delegate) { final String actionName = text; cell = new AuditActionsActionCell<EntityChanged>(text, delegate) { @Override public void render(com.google.gwt.cell.client.Cell.Context context, EntityChanged object, SafeHtmlBuilder sb) { SafeHtml html = SafeHtmlUtils.fromTrustedString(buildButtonHTML(actionName)); sb.append(html); } private String buildButtonHTML(String actionName){ Button btn = new Button(); btn.setSize(ButtonSize.SMALL); btn.setTitle(actionName); if("Comparar".equals(actionName)){ btn.setIcon(IconType.EYE_OPEN); btn.addStyleName("btnAction"); } else if("Gerenciar".equals(actionName)){ btn.setIcon(IconType.COG); btn.addStyleName("btnAction"); } btn.addStyleName("btnIconSolo"); return btn.toString(); } }; } @Override public Cell<EntityChanged> getCell() { return cell; } @Override public FieldUpdater<EntityChanged, EntityChanged> getFieldUpdater() { return null; } @Override public EntityChanged getValue(EntityChanged object) { return object; } } @Override public void setEntitiesChangedEvents(EntityChangedEventsTO entityChangedEventsTO) { this.entityChangedEventsTO = entityChangedEventsTO; table.setVisible(false); pagination.setVisible(true); VerticalPanel panel = new VerticalPanel(); panel.setWidth("400"); panel.add(table); initTableTools(); entitiesChangedWrapper.clear(); entitiesChangedWrapper.add(tableTools); entitiesChangedWrapper.add(panel); entitiesChangedWrapper.add(pagination); if(entityChangedEventsTO != null){ pagination.setRowData(entityChangedEventsTO.getEntitiesChanged(), StringUtils.isSome(presenter.getSearchTerm()) ? entityChangedEventsTO.getSearchCount() : entityChangedEventsTO.getCount()); initTable(); table.setVisible(true); pagination.setVisible(true); } adminHomePanel.setVisible(true); } private void initTableTools() { if(tableTools == null){ tableTools = new FlowPanel(); final ListBox pageSizeListBox = new ListBox(); // pageSizeListBox.addItem("1"); // pageSizeListBox.addItem("10"); pageSizeListBox.addStyleName("pageSizeListBox"); pageSizeListBox.addItem("20"); pageSizeListBox.addItem("50"); pageSizeListBox.addItem("100"); pageSizeListBox.setSelectedValue(presenter.getPageSize()); pageSizeListBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { if (pageSizeListBox.getValue().matches("[0-9]*")){ presenter.setPageNumber("1"); presenter.setPageSize(pageSizeListBox.getValue()); presenter.updateData(); } } }); initSearch(); tableTools.addStyleName("marginTop25"); tableTools.add(entityTypesList); tableTools.add(pageSizeListBox); Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { } }); } } }