/** * Copyright 2015 ArcBees Inc. * * 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 com.arcbees.gaestudio.client.application.visualizer.sidebar; import java.util.List; import javax.inject.Inject; import com.arcbees.analytics.shared.Analytics; import com.arcbees.chosen.client.ChosenOptions; import com.arcbees.chosen.client.event.ChosenChangeEvent; import com.arcbees.chosen.client.gwt.ChosenListBox; import com.arcbees.gaestudio.client.application.visualizer.ExportFormats; import com.arcbees.gaestudio.client.resources.AppResources; import com.arcbees.gaestudio.client.resources.ChosenResources; import com.arcbees.gaestudio.client.resources.FontsResources; import com.arcbees.gaestudio.client.resources.VisualizerResources; import com.arcbees.gaestudio.client.ui.PanelToggle; import com.arcbees.gaestudio.client.ui.PanelToggleFactory; import com.google.common.base.Strings; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.BrowserEvents; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Element; import com.google.gwt.query.client.Function; import com.google.gwt.safehtml.client.SafeHtmlTemplates; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Frame; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.gwtplatform.mvp.client.ViewWithUiHandlers; import static com.arcbees.gaestudio.client.application.analytics.EventCategories.UI_ELEMENTS; import static com.google.gwt.query.client.GQuery.$; public class SidebarView extends ViewWithUiHandlers<SidebarUiHandlers> implements SidebarPresenter.MyView, PanelToggle.ToggleHandler { interface KindTemplate extends SafeHtmlTemplates { @SafeHtmlTemplates.Template("<div class=\"{1}\"><span>{0}</span><i class=\"{2}\"></i></div>") SafeHtml create(String kindName, String cssClass, String deleteClass); } interface EmptyKindsTemplate extends SafeHtmlTemplates { @SafeHtmlTemplates.Template("<span class='{0}'>No entity type detected</span>") SafeHtml create(String cssClassEmpty); } interface Binder extends UiBinder<HTMLPanel, SidebarView> { } @UiField HTMLPanel kinds; @UiField HTML emptyKinds; @UiField SimplePanel namespaces; @UiField(provided = true) PanelToggle closeToggle; @UiField DivElement importKind; @UiField DivElement exportKind; @UiField Frame downloadFrame; @UiField(provided = true) ChosenListBox chosenFormat; private final KindTemplate kindTemplate; private final EmptyKindsTemplate emptyKindsTemplate; private final FontsResources fontsResources; private final AppResources appResources; private final VisualizerResources visualizerResources; private final String emptyListTypeStyleName; private final String hiddenOverlayStyleName; private final String revealOverlayStyleName; private final String revealUnderOverlayStyleName; private final String entityDetailPanelVisibilityStyleName; private final Analytics analytics; private Widget selectedKind; private String currentKind; private String currentFormat = ExportFormats.JSON; @Inject SidebarView( Binder binder, ChosenResources chosenResources, KindTemplate kindTemplate, EmptyKindsTemplate emptyKindsTemplate, FontsResources fontsResources, AppResources appResources, VisualizerResources visualizerResources, PanelToggleFactory panelToggleFactory, final Analytics analytics) { this.kindTemplate = kindTemplate; this.emptyKindsTemplate = emptyKindsTemplate; this.fontsResources = fontsResources; this.appResources = appResources; this.visualizerResources = visualizerResources; this.analytics = analytics; this.closeToggle = panelToggleFactory.create(this); ChosenOptions chosenOptions = new ChosenOptions(); chosenOptions.setResources(chosenResources); chosenOptions.setDisableSearchThreshold(1000); // must never display the search box chosenFormat = new ChosenListBox(chosenOptions); chosenFormat.addItem(ExportFormats.CSV); chosenFormat.addItem(ExportFormats.JSON); chosenFormat.update(); initWidget(binder.createAndBindUi(this)); emptyListTypeStyleName = appResources.styles().entityTypeSelectorEmpty(); hiddenOverlayStyleName = appResources.styles().hiddenOverlay(); revealOverlayStyleName = appResources.styles().revealOverlay(); revealUnderOverlayStyleName = appResources.styles().revealUnderOverlay(); entityDetailPanelVisibilityStyleName = appResources.styles().entityDetailPanelVisibility(); $(importKind).click(new Function() { @Override public void f() { if (chosenFormat.getValue().equals(ExportFormats.CSV)) { getUiHandlers().importCsv(); } else { getUiHandlers().importKind(); } analytics.sendEvent(UI_ELEMENTS, "click") .eventLabel("Visualizer -> Kinds Sidebar -> Import Button"); } }); $(exportKind).click(new Function() { @Override public void f() { if (chosenFormat.getValue().equals(ExportFormats.CSV)) { getUiHandlers().exportCsv(); } else { getUiHandlers().exportJson(); } analytics.sendEvent(UI_ELEMENTS, "click") .eventLabel("Visualizer -> Kinds Sidebar -> Export Button"); } }); chosenFormat.addChosenChangeHandler(new ChosenChangeEvent.ChosenChangeHandler() { @Override public void onChange(ChosenChangeEvent chosenChangeEvent) { currentFormat = chosenChangeEvent.getValue(); if (currentFormat.equals(ExportFormats.CSV)) { setImportEnabled(false); } else { setImportEnabled(true); } analytics.sendEvent(UI_ELEMENTS, "click") .eventLabel("Visualizer -> Kinds Sidebar -> Chosen format: " + currentFormat) .go(); } }); } @Override public void updateKinds(List<String> kinds) { this.kinds.clear(); if (kinds.isEmpty()) { addEmptyEntityListStyle(); setExportEnabled(false); return; } for (String kind : kinds) { addKind(kind); } } @Override public void addEmptyEntityListStyle() { SafeHtml html = emptyKindsTemplate.create(emptyListTypeStyleName); emptyKinds.setHTML(html); } @Override public void setInSlot(Object slot, IsWidget content) { if (SidebarPresenter.SLOT_NAMESPACES.equals(slot)) { namespaces.setWidget(content); } } @Override public void setDownloadUrl(String downloadUrl) { downloadFrame.setUrl(downloadUrl); } @Override public void setSelectedFormat() { chosenFormat.setSelectedValue(currentFormat); } @Override public void onToggle() { boolean closing = closeToggle.isOpen(); if (closing) { selectedKind = $("." + appResources.styles().kindListElementSelected()).widget(); analytics.sendEvent(UI_ELEMENTS, "close").eventLabel("Visualizer -> Kinds Sidebar"); } else { analytics.sendEvent(UI_ELEMENTS, "open").eventLabel("Visualizer -> Kinds Sidebar"); } $(selectedKind).toggleClass(appResources.styles().kindListElementSelected(), !closing); $(selectedKind).toggleClass(appResources.styles().kindListElementSelectedHidden(), closing); getUiHandlers().onCloseHandleActivated(); } private void showCloseHandle() { this.closeToggle.asWidget().setVisible(true); } private void setExportEnabled(boolean enabled) { if (enabled) { exportKind.removeClassName(visualizerResources.styles().btnDisabled()); } else { exportKind.addClassName(visualizerResources.styles().btnDisabled()); } } private void setImportEnabled(boolean enabled) { if (enabled) { importKind.removeClassName(visualizerResources.styles().btnDisabled()); } else { importKind.addClassName(visualizerResources.styles().btnDisabled()); } } private void addKind(String kind) { String cssClass = appResources.styles().kindListElement(); String deleteClass = fontsResources.icons().icon_delete(); SafeHtml html = kindTemplate.create(kind, cssClass, deleteClass); final HTML kindWidget = new HTML(html); kinds.add(kindWidget); $(kindWidget).click(new Function() { @Override public void f(Element e) { onKindSelected(e); analytics.sendEvent(UI_ELEMENTS, "click").eventLabel("Visualizer -> Sidebar -> Kind Name"); } }); if (kind.equals(currentKind)) { Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { onKindSelected(kindWidget.getElement().getFirstChildElement()); } }); } emptyKinds.setHTML(""); } private void onKindSelected(Element e) { String iconDelete = "." + fontsResources.icons().icon_delete(); $("." + appResources.styles().kindListElementSelected() + " " + iconDelete).unbind(BrowserEvents.CLICK); setActive(e); currentKind = $("span", e).html(); showCloseHandle(); setExportEnabled(!Strings.isNullOrEmpty(currentKind)); getUiHandlers().displayEntitiesOfSelectedKind(currentKind); } private void setActive(final Element e) { revealEntityDivNToolbar(); final String activeClass = appResources.styles().kindListElementSelected(); $(kinds).find("div").removeClass(activeClass); Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { doSelectKind(e, activeClass); } }); } private void doSelectKind(Element e, String activeClass) { $(e).addClass(activeClass); String iconDelete = "." + fontsResources.icons().icon_delete(); $("." + appResources.styles().kindListElementSelected() + " " + iconDelete).click(new Function() { @Override public void f() { getUiHandlers().deleteAllOfKind(); } }); } private void revealEntityDivNToolbar() { $("." + hiddenOverlayStyleName).addClass(revealOverlayStyleName); Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() { @Override public void execute() { $("." + hiddenOverlayStyleName).addClass(revealUnderOverlayStyleName); $("." + entityDetailPanelVisibilityStyleName).show(); } }); } }