From 0ccefa579b7ff207ba0435e3f72c1121c04d05f7 Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Fri, 31 Aug 2012 16:01:01 +1000 Subject: [PATCH 1/4] Work in progress: editing glossary term in editor --- .../service/impl/GlossaryFileServiceImpl.java | 16 ++-- .../presenter/GlossaryDetailsPresenter.java | 50 ++++++++++-- .../webtrans/client/resources/UiMessages.java | 9 +++ .../client/view/GlossaryDetailsView.java | 17 +++- .../client/view/GlossaryDetailsView.ui.xml | 12 +-- .../server/rpc/GetGlossaryDetailsHandler.java | 2 +- .../server/rpc/UpdateGlossaryTermHandler.java | 80 +++++++++++++++++++ .../shared/model/GlossaryDetails.java | 23 +++++- .../shared/rpc/GetGlossaryDetailsResult.java | 2 - .../shared/rpc/UpdateGlossaryTermAction.java | 52 ++++++++++++ .../shared/rpc/UpdateGlossaryTermResult.java | 27 +++++++ .../zanata/webtrans/public/Application.css | 23 ++++++ .../rpc/DummyGetGlossaryDetailsCommand.java | 2 +- 13 files changed, 289 insertions(+), 26 deletions(-) create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermAction.java create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermResult.java diff --git a/zanata-war/src/main/java/org/zanata/service/impl/GlossaryFileServiceImpl.java b/zanata-war/src/main/java/org/zanata/service/impl/GlossaryFileServiceImpl.java index 511d0c3150..7d521f5c46 100644 --- a/zanata-war/src/main/java/org/zanata/service/impl/GlossaryFileServiceImpl.java +++ b/zanata-war/src/main/java/org/zanata/service/impl/GlossaryFileServiceImpl.java @@ -144,7 +144,7 @@ private void transferGlossaryEntry(GlossaryEntry from) HLocale termHLocale = localeServiceImpl.validateSourceLocale(glossaryTerm.getLocale()); // check if there's existing term with same content, overrides comments - HGlossaryTerm hGlossaryTerm = getOrCreateGlossaryTerm(to, termHLocale, glossaryTerm.getContent()); + HGlossaryTerm hGlossaryTerm = getOrCreateGlossaryTerm(to, termHLocale, glossaryTerm); hGlossaryTerm.getComments().clear(); @@ -152,11 +152,13 @@ private void transferGlossaryEntry(GlossaryEntry from) { hGlossaryTerm.getComments().add(new HTermComment(comment)); } + + to.getGlossaryTerms().put(termHLocale, hGlossaryTerm); } glossaryDAO.makePersistent(to); } - private HGlossaryEntry getOrCreateGlossaryEntry(LocaleId srcLocale, String srcContent) + public HGlossaryEntry getOrCreateGlossaryEntry(LocaleId srcLocale, String srcContent) { HGlossaryEntry hGlossaryEntry = glossaryDAO.getEntryBySrcLocaleAndContent(srcLocale, srcContent); @@ -169,17 +171,21 @@ private HGlossaryEntry getOrCreateGlossaryEntry(LocaleId srcLocale, String srcCo return hGlossaryEntry; } - private HGlossaryTerm getOrCreateGlossaryTerm(HGlossaryEntry hGlossaryEntry, HLocale termHLocale, String content) + private HGlossaryTerm getOrCreateGlossaryTerm(HGlossaryEntry hGlossaryEntry, HLocale termHLocale, GlossaryTerm newTerm) { HGlossaryTerm hGlossaryTerm = hGlossaryEntry.getGlossaryTerms().get(termHLocale); if (hGlossaryTerm == null) { - hGlossaryTerm = new HGlossaryTerm(content); + hGlossaryTerm = new HGlossaryTerm(newTerm.getContent()); hGlossaryTerm.setLocale(termHLocale); hGlossaryTerm.setGlossaryEntry(hGlossaryEntry); - hGlossaryEntry.getGlossaryTerms().put(termHLocale, hGlossaryTerm); } + else if(!hGlossaryTerm.getContent().equals(newTerm.getContent())) + { + hGlossaryTerm.setContent(newTerm.getContent()); + } + return hGlossaryTerm; } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java index 12acd26681..f899ab022f 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java @@ -10,6 +10,8 @@ import org.zanata.webtrans.shared.model.GlossaryResultItem; import org.zanata.webtrans.shared.rpc.GetGlossaryDetailsAction; import org.zanata.webtrans.shared.rpc.GetGlossaryDetailsResult; +import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermAction; +import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermResult; import com.allen_sauer.gwt.log.client.Log; import com.google.gwt.event.dom.client.ChangeEvent; @@ -24,8 +26,6 @@ public class GlossaryDetailsPresenter extends WidgetPresenter { - private final CachingDispatchAsync dispatcher; - public interface Display extends WidgetDisplay { void hide(); @@ -52,6 +52,8 @@ public interface Display extends WidgetDisplay HasClickHandlers getDismissButton(); + HasClickHandlers getSaveButton(); + void clearEntries(); void addEntry(String text); @@ -59,10 +61,14 @@ public interface Display extends WidgetDisplay private GetGlossaryDetailsResult glossaryDetails; + private GlossaryDetails selectedDetailEntry; + private final UiMessages messages; + private final CachingDispatchAsync dispatcher; + @Inject - public GlossaryDetailsPresenter(final Display display, EventBus eventBus, UiMessages messages, CachingDispatchAsync dispatcher) + public GlossaryDetailsPresenter(final Display display, EventBus eventBus, UiMessages messages, final CachingDispatchAsync dispatcher) { super(display, eventBus); this.dispatcher = dispatcher; @@ -74,8 +80,38 @@ public GlossaryDetailsPresenter(final Display display, EventBus eventBus, UiMess public void onClick(ClickEvent event) { display.hide(); + selectedDetailEntry = null; + } + })); + + registerHandler(display.getSaveButton().addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + if (selectedDetailEntry != null) + { + // check if there's any changes and save + if(!display.getTargetText().getText().equals(selectedDetailEntry.getTarget())) + { + dispatcher.execute(new UpdateGlossaryTermAction(selectedDetailEntry.getSrcLocale(), selectedDetailEntry.getTargetLocale(), selectedDetailEntry.getSource(), display.getTargetText().getText(), selectedDetailEntry.getTargetVersionNum()), new AsyncCallback() + { + @Override + public void onFailure(Throwable caught) + { + Log.error(caught.getMessage(), caught); + } + @Override + public void onSuccess(UpdateGlossaryTermResult result) + { + //Update with lastest term details in list + } + }); + } + } } })); + registerHandler(display.getEntryListBox().addChangeHandler(new ChangeHandler() { @Override @@ -126,15 +162,15 @@ protected void selectEntry(int selected) String srcRef = ""; if (selected >= 0) { - GlossaryDetails item = glossaryDetails.getGlossaryDetails().get(selected); - srcRef = item.getSourceRef(); - for (String srcComment : item.getSourceComment()) + selectedDetailEntry = glossaryDetails.getGlossaryDetails().get(selected); + srcRef = selectedDetailEntry.getSourceRef(); + for (String srcComment : selectedDetailEntry.getSourceComment()) { srcComments.append(srcComment); srcComments.append("\n"); } - for (String targetComment : item.getTargetComment()) + for (String targetComment : selectedDetailEntry.getTargetComment()) { targetComments.append(targetComment); targetComments.append("\n"); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java index 7739369688..a9cdecd8b4 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java @@ -130,4 +130,13 @@ public interface UiMessages extends Messages @DefaultMessage("Action") String action(); + + @DefaultMessage("Glossary Details") + String glossaryDetails(); + + @DefaultMessage("Dismiss") + String dismiss(); + + @DefaultMessage("Save") + String save(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java index 5cdf4d3e5e..65d8a9e3c3 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java @@ -1,6 +1,7 @@ package org.zanata.webtrans.client.view; import org.zanata.webtrans.client.presenter.GlossaryDetailsPresenter; +import org.zanata.webtrans.client.resources.UiMessages; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.HasChangeHandlers; @@ -14,6 +15,7 @@ import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.Widget; +import com.google.inject.Inject; public class GlossaryDetailsView implements GlossaryDetailsPresenter.Display { @@ -48,14 +50,18 @@ interface TMIUiBinder extends UiBinder TextArea targetComment; @UiField - Button dismissButton; + Button dismissButton, saveButton; @UiField ListBox entryListBox; - public GlossaryDetailsView() + @Inject + public GlossaryDetailsView(UiMessages messages) { dialogBox = uiBinder.createAndBindUi(this); + dialogBox.setText(messages.glossaryDetails()); + dismissButton.setText(messages.dismiss()); + saveButton.setText(messages.save()); } public void hide() @@ -109,6 +115,13 @@ public HasClickHandlers getDismissButton() { return dismissButton; } + + @Override + public HasClickHandlers getSaveButton() + { + return saveButton; + } + @Override public int getSelectedDocumentIndex() diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml index 8f8d5ac2fa..4706d8794f 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml @@ -9,15 +9,14 @@ - - Glossary Details - + + Entries: - + @@ -36,13 +35,14 @@ - + Comments: - Dismiss + + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java index abc8b358bc..650f070e84 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java @@ -76,7 +76,7 @@ public GetGlossaryDetailsResult execute(GetGlossaryDetailsAction action, Executi { targetComments.add(termComment.getComment()); } - items.add(new GlossaryDetails(srcComments, targetComments, entry.getSourceRef(), entry.getSrcLocale().getLocaleId(), hLocale.getLocaleId())); + items.add(new GlossaryDetails(srcTerm.getContent(), entry.getGlossaryTerms().get(hLocale).getContent(), srcComments, targetComments, entry.getSourceRef(), entry.getSrcLocale().getLocaleId(), hLocale.getLocaleId(), entry.getGlossaryTerms().get(hLocale).getVersionNum())); } return new GetGlossaryDetailsResult(items); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java new file mode 100644 index 0000000000..68482e7384 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java @@ -0,0 +1,80 @@ +package org.zanata.webtrans.server.rpc; + +import java.util.ArrayList; + +import net.customware.gwt.dispatch.server.ExecutionContext; +import net.customware.gwt.dispatch.shared.ActionException; + +import org.jboss.seam.ScopeType; +import org.jboss.seam.annotations.In; +import org.jboss.seam.annotations.Logger; +import org.jboss.seam.annotations.Name; +import org.jboss.seam.annotations.Scope; +import org.jboss.seam.log.Log; +import org.zanata.dao.GlossaryDAO; +import org.zanata.model.HGlossaryEntry; +import org.zanata.model.HGlossaryTerm; +import org.zanata.model.HTermComment; +import org.zanata.webtrans.server.ActionHandlerFor; +import org.zanata.webtrans.shared.model.GlossaryDetails; +import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermAction; +import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermResult; + +@Name("webtrans.gwt.GetGlossaryDetailsHandler") +@Scope(ScopeType.STATELESS) +@ActionHandlerFor(UpdateGlossaryTermAction.class) +public class UpdateGlossaryTermHandler extends AbstractActionHandler +{ + + @Logger + private Log log; + + @In + private GlossaryDAO glossaryDAO; + + + + @Override + public UpdateGlossaryTermResult execute(UpdateGlossaryTermAction action, ExecutionContext context) throws ActionException + { + HGlossaryEntry entry = glossaryDAO.getEntryBySrcLocaleAndContent(action.getSrcLocale(), action.getSrcContent()); + + HGlossaryTerm targetTerm = entry.getGlossaryTerms().get(action.getTargetLocale()); + if(targetTerm == null) + { + throw new ActionException("Update failed for glossary term with source content: " + action.getSrcContent() + " and target locale: " + action.getTargetLocale()); + } + else if(action.getCurrentVerNum() != targetTerm.getVersionNum()) + { + throw new ActionException("Update failed for glossary term " + action.getTargetContent() + " base versionNum " + action.getCurrentVerNum() + " does not match current versionNum " + targetTerm.getVersionNum()); + } + else + { + targetTerm.setContent(action.getTargetContent()); + HGlossaryEntry entryResult = glossaryDAO.makePersistent(entry); + + ArrayList srcComments = new ArrayList(); + ArrayList targetComments = new ArrayList(); + + for(HTermComment termComment: entryResult.getGlossaryTerms().get(entryResult.getSrcLocale()).getComments()) + { + srcComments.add(termComment.getComment()); + } + + for(HTermComment termComment: targetTerm.getComments()) + { + targetComments.add(termComment.getComment()); + } + + GlossaryDetails details = new GlossaryDetails(action.getSrcContent(), action.getTargetContent(), srcComments, targetComments, entryResult.getSourceRef(), action.getSrcLocale(), action.getTargetLocale(), targetTerm.getVersionNum()); + + return new UpdateGlossaryTermResult(details); + } + } + + @Override + public void rollback(UpdateGlossaryTermAction action, UpdateGlossaryTermResult result, ExecutionContext context) throws ActionException + { + } + +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java index 378ba1d4a5..f35e1f19df 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java @@ -13,20 +13,24 @@ public class GlossaryDetails implements IsSerializable private String sourceRef; private LocaleId srcLocale; private LocaleId targetLocale; + private Integer targetVersionNum; + private String source; + private String target; @SuppressWarnings("unused") private GlossaryDetails() { - this(null, null, null, null, null); + this(null, null, null, null, null, null, null, null); } - public GlossaryDetails(List sourceComment, List targetComment, String sourceRef, LocaleId srcLocale, LocaleId targetLocale) + public GlossaryDetails(String source, String target, List sourceComment, List targetComment, String sourceRef, LocaleId srcLocale, LocaleId targetLocale, Integer targetVersionNum) { this.sourceComment = sourceComment; this.targetComment = targetComment; this.sourceRef = sourceRef; this.srcLocale = srcLocale; this.targetLocale = targetLocale; + this.targetVersionNum = targetVersionNum; } public List getSourceComment() @@ -53,4 +57,19 @@ public LocaleId getTargetLocale() { return targetLocale; } + + public Integer getTargetVersionNum() + { + return targetVersionNum; + } + + public String getSource() + { + return source; + } + + public String getTarget() + { + return target; + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetGlossaryDetailsResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetGlossaryDetailsResult.java index 363b89d49f..9fd1e2c5af 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetGlossaryDetailsResult.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/GetGlossaryDetailsResult.java @@ -26,6 +26,4 @@ public ArrayList getGlossaryDetails() { return glossaryDetails; } - - } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermAction.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermAction.java new file mode 100644 index 0000000000..2893988c00 --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermAction.java @@ -0,0 +1,52 @@ +package org.zanata.webtrans.shared.rpc; + +import org.zanata.common.LocaleId; + +public class UpdateGlossaryTermAction extends AbstractWorkspaceAction +{ + private static final long serialVersionUID = 1L; + + private LocaleId srcLocale, targetLocale; + private String srcContent, targetContent; + private Integer currentVerNum; + + @SuppressWarnings("unused") + private UpdateGlossaryTermAction() + { + this(null, null, null, null, null); + } + + public UpdateGlossaryTermAction(LocaleId srcLocale, LocaleId targetLocale, String srcContent, String targetContent, Integer currentVerNum) + { + this.srcLocale = srcLocale; + this.srcContent = srcContent; + this.targetLocale = targetLocale; + this.targetContent = targetContent; + this.currentVerNum = currentVerNum; + } + + public LocaleId getSrcLocale() + { + return srcLocale; + } + + public String getSrcContent() + { + return srcContent; + } + + public LocaleId getTargetLocale() + { + return targetLocale; + } + + public String getTargetContent() + { + return targetContent; + } + + public Integer getCurrentVerNum() + { + return currentVerNum; + } +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermResult.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermResult.java new file mode 100644 index 0000000000..ff6091e4ce --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/rpc/UpdateGlossaryTermResult.java @@ -0,0 +1,27 @@ +package org.zanata.webtrans.shared.rpc; + +import org.zanata.webtrans.shared.model.GlossaryDetails; + +public class UpdateGlossaryTermResult implements DispatchResult +{ + + private static final long serialVersionUID = 1L; + + private GlossaryDetails detail; + + @SuppressWarnings("unused") + private UpdateGlossaryTermResult() + { + this(null); + } + + public UpdateGlossaryTermResult(GlossaryDetails detail) + { + this.detail = detail; + } + + public GlossaryDetails getDetail() + { + return detail; + } +} diff --git a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css index e3c8cdb539..586744ba5c 100644 --- a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css +++ b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css @@ -921,3 +921,26 @@ td.ApprovedStateDecoration div div div box-shadow:0 0 6px gray inset; } +/* -------------- GWT Dialog Box ----------------*/ +.GWTDialogBox +{ + width:500px; + height:300px; + background:#F2F2F2; + border:1px solid #C0C0C0; + border-radius:3px; + padding:5px; + box-shadow:1px 1px 3px #5C5C5C; +} + +.GWTDialogBox .Caption +{ + padding:4px; + font-weight:bold; + font-size:1.1em; + border-radius:3px; + background:#575757; + color:#FFFFFF; + cursor:pointer; +} + diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java index 1a82bd79af..c5b7b2f683 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java @@ -41,7 +41,7 @@ public void execute() targetComments.add("Target Comment " + (2 + i)); targetComments.add("Target Comment " + (3 + i)); - items.add(new GlossaryDetails(srcComments, targetComments, "Dummy source ref " + (1 + i), new LocaleId("en-us"), action.getWorkspaceId().getLocaleId())); + items.add(new GlossaryDetails(srcComments, targetComments, "Dummy source ref " + (1 + i), new LocaleId("en-us"), action.getWorkspaceId().getLocaleId(), null)); } callback.onSuccess(new GetGlossaryDetailsResult(items)); From d28c15495ca06c9057ac9e744dbfb0dee644fd56 Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Tue, 4 Sep 2012 10:21:47 +1000 Subject: [PATCH 2/4] Work in progress: implement glossary editing --- .../zanata/webtrans/client/Application.java | 5 + .../client/presenter/AppPresenter.java | 43 +++- .../presenter/GlossaryDetailsPresenter.java | 6 +- .../client/presenter/GlossaryPresenter.java | 60 ++---- .../client/presenter/HasGlossaryEvent.java | 10 + .../webtrans/client/resources/UiMessages.java | 10 + .../client/resources/WebTransMessages.java | 6 + .../zanata/webtrans/client/view/AppView.java | 36 +++- .../webtrans/client/view/AppView.ui.xml | 29 ++- .../client/view/GlossaryDetailsView.java | 11 +- .../client/view/GlossaryDetailsView.ui.xml | 2 + .../webtrans/client/view/GlossaryView.java | 192 ++++++++++-------- .../webtrans/client/view/GlossaryView.ui.xml | 13 +- .../webtrans/client/view/TransMemoryView.java | 10 +- .../client/view/TransMemoryView.ui.xml | 3 +- .../server/rpc/GetGlossaryDetailsHandler.java | 6 +- .../rpc/GetTransMemoryDetailsHandler.java | 15 +- .../server/rpc/UpdateGlossaryTermHandler.java | 22 +- .../shared/model/GlossaryDetails.java | 13 +- .../webtrans/shared/model/WorkspaceId.java | 1 - .../zanata/webtrans/public/Application.css | 67 +++++- .../client/presenter/AppPresenterTest.java | 97 +++------ .../presenter/GlossaryPresenterTest.java | 24 +-- .../rpc/DummyGetGlossaryDetailsCommand.java | 3 +- 24 files changed, 414 insertions(+), 270 deletions(-) create mode 100644 zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/Application.java b/zanata-war/src/main/java/org/zanata/webtrans/client/Application.java index b0509126da..60f87a1f0b 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/Application.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/Application.java @@ -202,6 +202,11 @@ public static void redirectToZanataProjectHome(WorkspaceId workspaceId) redirectToUrl(getModuleParentBaseUrl() + "project/view/" + workspaceId.getProjectIterationId().getProjectSlug()); } + public static void redirectToIterationFiles(WorkspaceId workspaceId) + { + redirectToUrl(getModuleParentBaseUrl() + "iteration/files/" + workspaceId.getProjectIterationId().getProjectSlug() + "/" + workspaceId.getProjectIterationId().getIterationSlug() + "/" + workspaceId.getLocaleId().getId()); + } + public static native void redirectToUrl(String url)/*-{ $wnd.location = url; }-*/; diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/AppPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/AppPresenter.java index b646aa3df5..99155148e2 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/AppPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/AppPresenter.java @@ -26,6 +26,7 @@ import net.customware.gwt.presenter.client.widget.WidgetPresenter; import org.zanata.common.TranslationStats; +import org.zanata.webtrans.client.Application; import org.zanata.webtrans.client.events.DocumentSelectionEvent; import org.zanata.webtrans.client.events.DocumentStatsUpdatedEvent; import org.zanata.webtrans.client.events.DocumentStatsUpdatedEventHandler; @@ -51,6 +52,7 @@ import org.zanata.webtrans.shared.model.UserWorkspaceContext; import com.allen_sauer.gwt.log.client.Log; +import com.google.common.base.Strings; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasClickHandlers; @@ -66,9 +68,13 @@ public interface Display extends net.customware.gwt.presenter.client.widget.Widg { void showInMainView(MainView editor); + HasClickHandlers getProjectLink(); + + HasClickHandlers getIterationFilesLink(); + HasClickHandlers getDocumentsLink(); - void setWorkspaceNameLabel(String workspaceNameLabel, String workspaceTitle); + void setProjectLinkLabel(String workspaceNameLabel); void setDocumentLabel(String docPath, String docName); @@ -97,6 +103,8 @@ public interface Display extends net.customware.gwt.presenter.client.widget.Widg void setResizeVisible(boolean visible); void showSideMenu(boolean isShowing); + + void setIterationFilesLabel(String iterationSlug); } private final KeyShortcutPresenter keyShortcutPresenter; @@ -221,7 +229,25 @@ public void onProjectStatsRetrieved(ProjectStatsUpdatedEvent event) @Override public void onClick(ClickEvent event) { - gotoDocumentListView(); + Application.redirectToIterationFiles(userWorkspaceContext.getWorkspaceContext().getWorkspaceId()); + } + })); + + registerHandler(display.getProjectLink().addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + Application.redirectToZanataProjectHome(userWorkspaceContext.getWorkspaceContext().getWorkspaceId()); + } + })); + + registerHandler(display.getIterationFilesLink().addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + Application.redirectToIterationFiles(userWorkspaceContext.getWorkspaceContext().getWorkspaceId()); } })); @@ -341,9 +367,18 @@ public void onKeyShortcut(KeyShortcutEvent event) } })); + display.setProjectLinkLabel(userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().getProjectSlug()); + display.setIterationFilesLabel(userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getProjectIterationId().getIterationSlug() + "(" + userWorkspaceContext.getWorkspaceContext().getWorkspaceId().getLocaleId().getId() + ")"); + String workspaceTitle = windowLocation.getParameter(WORKSPACE_TITLE_QUERY_PARAMETER_KEY); - display.setWorkspaceNameLabel(userWorkspaceContext.getWorkspaceContext().getWorkspaceName(), workspaceTitle); - window.setTitle(messages.windowTitle(userWorkspaceContext.getWorkspaceContext().getWorkspaceName(), userWorkspaceContext.getWorkspaceContext().getLocaleName())); + if (!Strings.isNullOrEmpty(workspaceTitle)) + { + window.setTitle(messages.windowTitle2(userWorkspaceContext.getWorkspaceContext().getWorkspaceName(), userWorkspaceContext.getWorkspaceContext().getLocaleName(), workspaceTitle)); + } + else + { + window.setTitle(messages.windowTitle(userWorkspaceContext.getWorkspaceContext().getWorkspaceName(), userWorkspaceContext.getWorkspaceContext().getLocaleName())); + } display.setReadOnlyVisible(userWorkspaceContext.hasReadOnlyAccess()); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java index f899ab022f..1c7070a79b 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java @@ -57,6 +57,8 @@ public interface Display extends WidgetDisplay void clearEntries(); void addEntry(String text); + + HasText getLastModified(); } private GetGlossaryDetailsResult glossaryDetails; @@ -104,7 +106,7 @@ public void onFailure(Throwable caught) @Override public void onSuccess(UpdateGlossaryTermResult result) { - //Update with lastest term details in list + Log.info("Glossary term updated:" + result.getDetail().getTarget()); } }); } @@ -180,6 +182,8 @@ protected void selectEntry(int selected) display.getSrcRef().setText(srcRef); display.getSourceComment().setText(srcComments.toString()); display.getTargetComment().setText(targetComments.toString()); + display.getLastModified().setText(messages.lastModifiedOn(selectedDetailEntry.getLastModified())); + } @Override diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java index 284f69b5ad..1947e4931b 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java @@ -20,6 +20,8 @@ */ package org.zanata.webtrans.client.presenter; +import java.util.ArrayList; + import net.customware.gwt.presenter.client.EventBus; import net.customware.gwt.presenter.client.widget.WidgetDisplay; import net.customware.gwt.presenter.client.widget.WidgetPresenter; @@ -43,7 +45,6 @@ import org.zanata.webtrans.shared.rpc.HasSearchType.SearchType; import com.allen_sauer.gwt.log.client.Log; -import com.google.gwt.cell.client.FieldUpdater; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; @@ -53,12 +54,9 @@ import com.google.gwt.event.dom.client.HasAllFocusHandlers; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.resources.client.ImageResource; -import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.HasValue; -import com.google.gwt.view.client.ListDataProvider; import com.google.inject.Inject; /** @@ -66,7 +64,7 @@ * @author Alex Eng aeng@redhat.com * **/ -public class GlossaryPresenter extends WidgetPresenter +public class GlossaryPresenter extends WidgetPresenter implements HasGlossaryEvent { private final UserWorkspaceContext userWorkspaceContext; private final CachingDispatchAsync dispatcher; @@ -78,8 +76,6 @@ public class GlossaryPresenter extends WidgetPresenter dataProvider; - public interface Display extends WidgetDisplay { HasClickHandlers getSearchButton(); @@ -92,13 +88,9 @@ public interface Display extends WidgetDisplay void startProcessing(); - Column getCopyColumn(); - - Column getDetailsColumn(); - - void setDataProvider(ListDataProvider dataProvider); + void renderTable(ArrayList glossaries); - void setPageSize(int size); + void setListener(HasGlossaryEvent listener); } @Inject @@ -110,8 +102,6 @@ public GlossaryPresenter(Display display, EventBus eventBus, CachingDispatchAsyn this.glossaryDetailsPresenter = glossaryDetailsPresenter; this.keyShortcutPresenter = keyShortcutPresenter; this.messages = messages; - dataProvider = new ListDataProvider(); - display.setDataProvider(dataProvider); } @Override @@ -144,24 +134,6 @@ public void onTransUnitSelected(TransUnitSelectionEvent event) } })); - display.getCopyColumn().setFieldUpdater(new FieldUpdater() - { - @Override - public void update(int index, GlossaryResultItem object, String value) - { - eventBus.fireEvent(new InsertStringInEditorEvent(object.getSource(), object.getTarget())); - } - }); - - display.getDetailsColumn().setFieldUpdater(new FieldUpdater() - { - @Override - public void update(int index, GlossaryResultItem object, ImageResource value) - { - glossaryDetailsPresenter.show(object); - } - }); - display.getFocusGlossaryTextBox().addFocusHandler(new FocusHandler() { @Override @@ -184,6 +156,8 @@ public void onBlur(BlurEvent event) isFocused = false; } }); + + display.setListener(this); } private void fireSearchEvent() @@ -272,13 +246,7 @@ private void displayGlossaryResult(GetGlossaryResult result) display.getGlossaryTextBox().setText(query); display.getSearchType().setValue(submittedRequest.getSearchType()); - dataProvider.getList().clear(); - for (final GlossaryResultItem glossary : result.getGlossaries()) - { - dataProvider.getList().add(glossary); - } - display.setPageSize(dataProvider.getList().size()); - dataProvider.refresh(); + display.renderTable(result.getGlossaries()); } @Override @@ -295,4 +263,16 @@ public boolean isFocused() { return isFocused; } + + @Override + public void fireCopyEvent(GlossaryResultItem item) + { + eventBus.fireEvent(new InsertStringInEditorEvent(item.getSource(), item.getTarget())); + } + + @Override + public void showGlossaryDetail(GlossaryResultItem item) + { + glossaryDetailsPresenter.show(item); + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java new file mode 100644 index 0000000000..55f31b556a --- /dev/null +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java @@ -0,0 +1,10 @@ +package org.zanata.webtrans.client.presenter; + +import org.zanata.webtrans.shared.model.GlossaryResultItem; + +public interface HasGlossaryEvent +{ + void fireCopyEvent(GlossaryResultItem item); + + void showGlossaryDetail(GlossaryResultItem item); +} diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java index a9cdecd8b4..bbef43a033 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java @@ -139,4 +139,14 @@ public interface UiMessages extends Messages @DefaultMessage("Save") String save(); + + @DefaultMessage("Last modified on {0}") + String lastModifiedOn(String date); + + @DefaultMessage("Loading...") + String loading(); + + @DefaultMessage("Found no glossary results") + String foundNoGlossaryResults(); + } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java index 105c6751a6..3b447dcbc7 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/WebTransMessages.java @@ -26,6 +26,9 @@ public interface WebTransMessages extends Messages @DefaultMessage("{0} to {1} - Zanata Web Translation") String windowTitle(String workspaceName, String localeName); + @DefaultMessage("{0} to {1} - {2}") + String windowTitle2(String workspaceName, String localeName, String title); + @DefaultMessage("First Page") String firstPage(); @@ -400,4 +403,7 @@ public interface WebTransMessages extends Messages @DefaultMessage("Navigation key/button") String navOption(); + + @DefaultMessage("Read only") + String readOnly(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.java index 1cc2b9070a..1d57f41fac 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.java @@ -66,13 +66,10 @@ interface Styles extends CssResource TransUnitCountBar translationStatsBar; @UiField - InlineLabel readOnlyLabel, documentsLink, resize, notification, keyShortcuts; + InlineLabel projectLink, iterationFilesLink, resize, notification, keyShortcuts; @UiField - InlineLabel notificationLabel; - - @UiField - InlineLabel searchAndReplace, documentList; + InlineLabel notificationLabel, readOnlyLabel, searchAndReplace, documentList; @UiField SpanElement selectedDocumentSpan, selectedDocumentPathSpan; @@ -111,6 +108,8 @@ public AppView(Resources resources, WebTransMessages messages, DocumentListPrese // display initWidget(uiBinder.createAndBindUi(this)); + readOnlyLabel.setText("[" + messages.readOnly() + "]"); + keyShortcuts.setTitle(messages.availableKeyShortcutsTitle()); searchAndReplace.setTitle(messages.projectWideSearchAndReplace()); documentList.setTitle(messages.documentListTitle()); @@ -177,16 +176,19 @@ private void setWidgetVisible(Widget widget, boolean visible) @Override public HasClickHandlers getDocumentsLink() { - return documentsLink; + return projectLink; } @Override - public void setWorkspaceNameLabel(String workspaceNameLabel, String workspaceTitle) + public void setProjectLinkLabel(String workspaceNameLabel) { - if (workspaceTitle == null || workspaceTitle.length() == 0) - documentsLink.setText(workspaceNameLabel); - else - documentsLink.setText(workspaceNameLabel + " - " + workspaceTitle); + projectLink.setText(workspaceNameLabel); + } + + @Override + public void setIterationFilesLabel(String name) + { + iterationFilesLink.setText(name); } @Override @@ -308,4 +310,16 @@ public void showSideMenu(boolean isShowing) } rootContainer.animate(ANIMATE_DURATION); } + + @Override + public HasClickHandlers getProjectLink() + { + return projectLink; + } + + @Override + public HasClickHandlers getIterationFilesLink() + { + return iterationFilesLink; + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.ui.xml index 87edfe71d5..40e2b970ae 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/AppView.ui.xml @@ -41,23 +41,18 @@ color: #595959; } - .readOnly { - font-weight: bold; - color: #ff6622; - } - .divider { color: #000000; + font-size:12px; } - .documents-link { + .breadcrumbs-link { cursor: pointer; - display: inline; font-weight:bold; color:#0085CC; } - .documents-link:hover + .breadcrumbs-link:hover { text-decoration:underline; } @@ -100,6 +95,15 @@ { margin-left:5px; } + + .breadcrumbs_display + { + font-size:14px; + font-weight:bold; + color:#B62918; + font-style:normal; + } + @@ -109,11 +113,14 @@ - Read-only mode - Documents + + + + - No document selected + + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java index 65d8a9e3c3..554fe80976 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java @@ -41,10 +41,7 @@ interface TMIUiBinder extends UiBinder TextArea sourceComment; @UiField - Label sourceLabel; - - @UiField - Label targetLabel; + Label sourceLabel, targetLabel, lastModified; @UiField TextArea targetComment; @@ -159,4 +156,10 @@ public HasText getSrcRef() return srcRef; } + @Override + public HasText getLastModified() + { + return lastModified; + } + } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml index 4706d8794f..7e40409a5d 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml @@ -40,6 +40,8 @@ + + Last modified diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.java index 799e6f901b..a984e9017d 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.java @@ -1,58 +1,50 @@ package org.zanata.webtrans.client.view; +import java.util.ArrayList; + import org.zanata.webtrans.client.presenter.GlossaryPresenter; +import org.zanata.webtrans.client.presenter.HasGlossaryEvent; import org.zanata.webtrans.client.resources.Resources; import org.zanata.webtrans.client.resources.UiMessages; import org.zanata.webtrans.client.ui.EnumListBox; +import org.zanata.webtrans.client.ui.HighlightingLabel; import org.zanata.webtrans.client.ui.SearchTypeRenderer; -import org.zanata.webtrans.client.ui.table.column.CopyButtonColumn; -import org.zanata.webtrans.client.ui.table.column.DetailsColumn; -import org.zanata.webtrans.client.ui.table.column.HighlightingLabelGlossaryColumn; -import org.zanata.webtrans.client.view.TransMemoryView.Styles; import org.zanata.webtrans.shared.model.GlossaryResultItem; import org.zanata.webtrans.shared.rpc.HasSearchType.SearchType; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasAllFocusHandlers; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.resources.client.CssResource; -import com.google.gwt.resources.client.ImageResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.cellview.client.Column; -import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter; import com.google.gwt.user.client.ui.HasValue; +import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.view.client.DefaultSelectionEventManager; -import com.google.gwt.view.client.ListDataProvider; -import com.google.gwt.view.client.NoSelectionModel; import com.google.inject.Inject; public class GlossaryView extends Composite implements GlossaryPresenter.Display { private static GlossaryViewUiBinder uiBinder = GWT.create(GlossaryViewUiBinder.class); - CellTable glossaryTable; - - private ListDataProvider dataProvider; - interface GlossaryViewUiBinder extends UiBinder { } interface Styles extends CssResource { - String narrowColumn(); } @UiField @@ -76,29 +68,51 @@ interface Styles extends CssResource @UiField ScrollPanel scrollPanel; - private final UiMessages messages; - - private final HighlightingLabelGlossaryColumn sourceColumn; - private final HighlightingLabelGlossaryColumn targetColumn; - private final CopyButtonColumn copyColumn; - private final DetailsColumn detailsColumn; + private final FlexTable table; + + private final Label loadingLabel, noResultFoundLabel; + + private HasGlossaryEvent listener; + + private final static int SOURCE_COL = 0; + private final static int TARGET_COL = 1; + private final static int ACTION_COL = 2; + private final static int DETAILS_COL = 3; @Inject public GlossaryView(final UiMessages messages, SearchTypeRenderer searchTypeRenderer, Resources resources) { - this.messages = messages; - - sourceColumn = new HighlightingLabelGlossaryColumn(true, false); - targetColumn = new HighlightingLabelGlossaryColumn(false, true); - copyColumn = new CopyButtonColumn(); - detailsColumn = new DetailsColumn(resources); - + table = new FlexTable(); + table.setStyleName("glossaryTable"); + table.setCellSpacing(0); + + FlexCellFormatter formatter = table.getFlexCellFormatter(); + formatter.setStyleName(0, SOURCE_COL, "th"); + formatter.setStyleName(0, TARGET_COL, "th"); + formatter.setStyleName(0, ACTION_COL, "th"); + formatter.addStyleName(0, ACTION_COL, "centered"); + formatter.addStyleName(0, ACTION_COL, "actionCol"); + formatter.setStyleName(0, DETAILS_COL, "th"); + formatter.addStyleName(0, DETAILS_COL, "centered"); + formatter.addStyleName(0, DETAILS_COL, "detailCol"); + + table.setWidget(0, 0, new Label(messages.srcTermLabel())); + table.setWidget(0, 1, new Label(messages.targetTermLabel())); + table.setWidget(0, 2, null); + table.setWidget(0, 3, new Label(messages.detailsLabel())); + + loadingLabel = new Label(messages.loading()); + loadingLabel.setStyleName("tableMsg"); + noResultFoundLabel = new Label(messages.foundNoGlossaryResults()); + noResultFoundLabel.setStyleName("tableMsg"); + searchType = new EnumListBox(SearchType.class, searchTypeRenderer); - dataProvider = new ListDataProvider(); initWidget(uiBinder.createAndBindUi(this)); - copyColumn.setCellStyleNames(style.narrowColumn()); - detailsColumn.setCellStyleNames(style.narrowColumn()); + scrollPanel.add(loadingLabel); + + // copyColumn.setCellStyleNames(style.narrowCenteredColumn()); + // detailsColumn.setCellStyleNames(style.narrowCenteredColumn()); headerLabel.setText(messages.glossaryHeading()); clearButton.setText(messages.clearButtonLabel()); searchButton.setText(messages.searchButtonLabel()); @@ -112,12 +126,12 @@ void onGlossaryTextBoxKeyUp(KeyUpEvent event) searchButton.click(); } } - + @UiHandler("clearButton") - void onClearButtonClicked(ClickEvent event) + public void onClearButtonClicked(ClickEvent event) { glossaryTextBox.setText(""); - dataProvider.getList().clear(); + clearTableContent(); } @Override @@ -140,70 +154,88 @@ public Widget asWidget() @Override public void startProcessing() { - dataProvider.getList().clear(); - } + scrollPanel.clear(); + scrollPanel.add(loadingLabel); - @Override - public HasValue getSearchType() - { - return searchType; + clearTableContent(); } - - public void renderTable() + private void clearTableContent() { - glossaryTable = new CellTable(); - glossaryTable.addStyleName("glossaryTable"); - glossaryTable.addStyleName("southTable"); - glossaryTable.addColumn(sourceColumn, messages.srcTermLabel()); - glossaryTable.addColumn(targetColumn, messages.targetTermLabel()); - glossaryTable.addColumn(detailsColumn, messages.detailsLabel()); - glossaryTable.addColumn(copyColumn); - - Label noResult = new Label("Found no glossary results"); - noResult.setStyleName("boldFont"); - glossaryTable.setEmptyTableWidget(noResult); - - final NoSelectionModel selectionModel = new NoSelectionModel(); - final DefaultSelectionEventManager manager = DefaultSelectionEventManager.createBlacklistManager(0, 1, 2); - glossaryTable.setSelectionModel(selectionModel, manager); - - glossaryTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); - - dataProvider.addDataDisplay(glossaryTable); - - scrollPanel.clear(); - scrollPanel.add(glossaryTable); + for (int i = 1; i < table.getRowCount(); i++) + { + table.removeRow(i); + } } @Override - public Column getCopyColumn() - { - return copyColumn; - } - - @Override - public Column getDetailsColumn() + public HasValue getSearchType() { - return detailsColumn; + return searchType; } @Override - public void setDataProvider(ListDataProvider dataProvider) + public HasAllFocusHandlers getFocusGlossaryTextBox() { - this.dataProvider = dataProvider; - renderTable(); + return glossaryTextBox; } @Override - public void setPageSize(int size) + public void renderTable(ArrayList glossaries) { - glossaryTable.setPageSize(size); + startProcessing(); + + if (!glossaries.isEmpty()) + { + for (int i = 0; i < glossaries.size(); i++) + { + final GlossaryResultItem item = glossaries.get(i); + + table.setWidget(i + 1, SOURCE_COL, new HighlightingLabel(item.getSource())); + table.setWidget(i + 1, TARGET_COL, new HighlightingLabel(item.getTarget())); + + Button copyButton = new Button("Copy"); + copyButton.addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + listener.fireCopyEvent(item); + } + }); + + table.setWidget(i + 1, ACTION_COL, copyButton); + table.getFlexCellFormatter().setStyleName(i + 1, ACTION_COL, "centered"); + table.getFlexCellFormatter().addStyleName(i + 1, ACTION_COL, "actionCol"); + + InlineLabel infoCell = new InlineLabel(); + infoCell.setStyleName("icon-info-circle-2 details"); + infoCell.addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + listener.showGlossaryDetail(item); + } + }); + + table.setWidget(i + 1, DETAILS_COL, infoCell); + table.getFlexCellFormatter().setStyleName(i + 1, DETAILS_COL, "centered"); + table.getFlexCellFormatter().addStyleName(i + 1, DETAILS_COL, "detailCol"); + } + scrollPanel.clear(); + scrollPanel.add(table); + } + else + { + scrollPanel.add(noResultFoundLabel); + } } @Override - public HasAllFocusHandlers getFocusGlossaryTextBox() + public void setListener(HasGlossaryEvent listener) { - return glossaryTextBox; + this.listener = listener; + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml index 485a5013e3..054cbd7251 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml @@ -7,19 +7,24 @@ padding-top:5px; font-weight:bold; } - .narrowColumn { - width: 1em; - } + .container { border-left:2px solid #E0E8EE; } + + .searchBox + { + border:1px solid #A7A7A7; + border-radius:3px; + } + - + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.java index dc3cfab250..58f9b44819 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.java @@ -55,7 +55,7 @@ interface TransMemoryViewUiBinder extends UiBinder interface Styles extends CssResource { String headerLabel(); - String narrowColumn(); + String narrowCenteredColumn(); } @UiField @@ -236,15 +236,15 @@ public String getTooltipValue(TransMemoryResultItem item) } }; - countColumn.setCellStyleNames(style.narrowColumn()); + countColumn.setCellStyleNames(style.narrowCenteredColumn()); tmTable.addColumn(countColumn, Tooltips.textWithTooltip(messages.matchCountLabel(), messages.matchCountHeaderTooltip())); - copyColumn.setCellStyleNames(style.narrowColumn()); + copyColumn.setCellStyleNames(style.narrowCenteredColumn()); tmTable.addColumn(copyColumn); SimilarityColumn similarityColumn = new SimilarityColumn(); - similarityColumn.setCellStyleNames(style.narrowColumn()); + similarityColumn.setCellStyleNames(style.narrowCenteredColumn()); tmTable.addColumn(similarityColumn, messages.similarityLabel()); - detailsColumn.setCellStyleNames(style.narrowColumn()); + detailsColumn.setCellStyleNames(style.narrowCenteredColumn()); tmTable.addColumn(detailsColumn, messages.detailsLabel()); noResultWidget.setStyleName("boldFont"); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.ui.xml index 934c1557ad..5bd6669ba1 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/TransMemoryView.ui.xml @@ -9,8 +9,9 @@ padding-top:5px; font-weight:bold; } - .narrowColumn { + .narrowCenteredColumn { width: 1em; + text-align:center; } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java index 650f070e84..a0cdfdd5a1 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetGlossaryDetailsHandler.java @@ -1,5 +1,6 @@ package org.zanata.webtrans.server.rpc; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; @@ -76,7 +77,10 @@ public GetGlossaryDetailsResult execute(GetGlossaryDetailsAction action, Executi { targetComments.add(termComment.getComment()); } - items.add(new GlossaryDetails(srcTerm.getContent(), entry.getGlossaryTerms().get(hLocale).getContent(), srcComments, targetComments, entry.getSourceRef(), entry.getSrcLocale().getLocaleId(), hLocale.getLocaleId(), entry.getGlossaryTerms().get(hLocale).getVersionNum())); + + SimpleDateFormat dateFormat = new SimpleDateFormat(); + + items.add(new GlossaryDetails(srcTerm.getContent(), entry.getGlossaryTerms().get(hLocale).getContent(), srcComments, targetComments, entry.getSourceRef(), entry.getSrcLocale().getLocaleId(), hLocale.getLocaleId(), entry.getGlossaryTerms().get(hLocale).getVersionNum(), dateFormat.format(entry.getGlossaryTerms().get(hLocale).getLastChanged()))); } return new GetGlossaryDetailsResult(items); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransMemoryDetailsHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransMemoryDetailsHandler.java index 5218398df9..b2d7571541 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransMemoryDetailsHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/GetTransMemoryDetailsHandler.java @@ -1,11 +1,13 @@ package org.zanata.webtrans.server.rpc; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Date; import java.util.List; +import lombok.extern.slf4j.Slf4j; +import net.customware.gwt.dispatch.server.ExecutionContext; +import net.customware.gwt.dispatch.shared.ActionException; + import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Name; @@ -24,10 +26,6 @@ import org.zanata.webtrans.shared.rpc.GetTransMemoryDetailsAction; import org.zanata.webtrans.shared.rpc.TransMemoryDetailsList; -import lombok.extern.slf4j.Slf4j; -import net.customware.gwt.dispatch.server.ExecutionContext; -import net.customware.gwt.dispatch.shared.ActionException; - @Name("webtrans.gwt.GetTransMemoryDetailsHandler") @Scope(ScopeType.STATELESS) @ActionHandlerFor(GetTransMemoryDetailsAction.class) @@ -95,9 +93,4 @@ protected TransMemoryDetails getTransMemoryDetail(HLocale hLocale, HTextFlow tf) public void rollback(GetTransMemoryDetailsAction action, TransMemoryDetailsList result, ExecutionContext context) throws ActionException { } - - public static void main(String args[]) - { - SimpleDateFormat dateFormat = new SimpleDateFormat(); - } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java index 68482e7384..2e7f769233 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java @@ -1,5 +1,6 @@ package org.zanata.webtrans.server.rpc; +import java.text.SimpleDateFormat; import java.util.ArrayList; import net.customware.gwt.dispatch.server.ExecutionContext; @@ -14,13 +15,15 @@ import org.zanata.dao.GlossaryDAO; import org.zanata.model.HGlossaryEntry; import org.zanata.model.HGlossaryTerm; +import org.zanata.model.HLocale; import org.zanata.model.HTermComment; +import org.zanata.service.LocaleService; import org.zanata.webtrans.server.ActionHandlerFor; import org.zanata.webtrans.shared.model.GlossaryDetails; import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermAction; import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermResult; -@Name("webtrans.gwt.GetGlossaryDetailsHandler") +@Name("webtrans.gwt.UpdateGlossaryTermHandler") @Scope(ScopeType.STATELESS) @ActionHandlerFor(UpdateGlossaryTermAction.class) public class UpdateGlossaryTermHandler extends AbstractActionHandler @@ -32,19 +35,23 @@ public class UpdateGlossaryTermHandler extends AbstractActionHandler srcComments = new ArrayList(); ArrayList targetComments = new ArrayList(); @@ -66,7 +74,9 @@ else if(action.getCurrentVerNum() != targetTerm.getVersionNum()) targetComments.add(termComment.getComment()); } - GlossaryDetails details = new GlossaryDetails(action.getSrcContent(), action.getTargetContent(), srcComments, targetComments, entryResult.getSourceRef(), action.getSrcLocale(), action.getTargetLocale(), targetTerm.getVersionNum()); + SimpleDateFormat dateFormat = new SimpleDateFormat(); + + GlossaryDetails details = new GlossaryDetails(entryResult.getGlossaryTerms().get(entryResult.getSrcLocale()).getContent(), entryResult.getGlossaryTerms().get(targetLocale).getContent(), srcComments, targetComments, entryResult.getSourceRef(), action.getSrcLocale(), action.getTargetLocale(), targetTerm.getVersionNum(), dateFormat.format(targetTerm.getLastChanged())); return new UpdateGlossaryTermResult(details); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java index f35e1f19df..2e6c4bd92f 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/GlossaryDetails.java @@ -16,21 +16,25 @@ public class GlossaryDetails implements IsSerializable private Integer targetVersionNum; private String source; private String target; + private String lastModifiedOn; @SuppressWarnings("unused") private GlossaryDetails() { - this(null, null, null, null, null, null, null, null); + this(null, null, null, null, null, null, null, null, null); } - public GlossaryDetails(String source, String target, List sourceComment, List targetComment, String sourceRef, LocaleId srcLocale, LocaleId targetLocale, Integer targetVersionNum) + public GlossaryDetails(String source, String target, List sourceComment, List targetComment, String sourceRef, LocaleId srcLocale, LocaleId targetLocale, Integer targetVersionNum, String lastModifiedOn) { + this.source = source; + this.target = target; this.sourceComment = sourceComment; this.targetComment = targetComment; this.sourceRef = sourceRef; this.srcLocale = srcLocale; this.targetLocale = targetLocale; this.targetVersionNum = targetVersionNum; + this.lastModifiedOn = lastModifiedOn; } public List getSourceComment() @@ -72,4 +76,9 @@ public String getTarget() { return target; } + + public String getLastModified() + { + return lastModifiedOn; + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceId.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceId.java index 9c84445a93..9da69b93e0 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceId.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/WorkspaceId.java @@ -62,5 +62,4 @@ public String toString() { return localeId.toString() + ":" + projectIterationId; } - } diff --git a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css index 586744ba5c..a555a8745b 100644 --- a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css +++ b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css @@ -841,9 +841,66 @@ td.ApprovedStateDecoration div div div .southTable th { border-bottom: 0px; - color: blue; + color: #C35817; font-style: normal; - font-weight: bold + font-weight: bold; + font-size:13px; + text-shadow:none; + text-decoration:underline; +} + +.glossaryTable +{ + width:100%; + height:100%; +} + +.glossaryTable tr:hover +{ + background:#E7E7E7; +} + +.glossaryTable td.detailCol +{ + width:54px; +} + +.glossaryTable td.actionCol +{ + width:46px; +} + +.glossaryTable .th +{ + color: #C35817; + font-weight: bold; + font-size:13px; + text-decoration:underline; +} + +.glossaryTable .centered +{ + text-align:center; +} + +.glossaryTable .details +{ + font-size:16px; + color:#00264C; + cursor:pointer; +} + +.glossaryTable .details:hover +{ + color:red; +} + +.tableMsg +{ + font-size:16px; + font-weight:bold; + text-align:center; + padding:25px; } .loadingPanel { @@ -944,3 +1001,9 @@ td.ApprovedStateDecoration div div div cursor:pointer; } +.GWTDialogBox table +{ + width:100%; + height:100%; +} + diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/AppPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/AppPresenterTest.java index 0f1f34fb4d..1e038a7fcc 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/AppPresenterTest.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/AppPresenterTest.java @@ -1,7 +1,6 @@ package org.zanata.webtrans.client.presenter; import static org.easymock.EasyMock.and; -import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.eq; @@ -45,8 +44,10 @@ import org.zanata.webtrans.shared.model.DocumentId; import org.zanata.webtrans.shared.model.DocumentInfo; import org.zanata.webtrans.shared.model.Person; +import org.zanata.webtrans.shared.model.ProjectIterationId; import org.zanata.webtrans.shared.model.UserWorkspaceContext; import org.zanata.webtrans.shared.model.WorkspaceContext; +import org.zanata.webtrans.shared.model.WorkspaceId; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; @@ -62,6 +63,9 @@ public class AppPresenterTest extends PresenterTest private static final String TEST_WORKSPACE_NAME = "Test Workspace Name"; private static final String TEST_LOCALE_NAME = "Test Locale Name"; private static final String TEST_WINDOW_TITLE = "Test Window Title"; + private static final String TEST_PPROJET_SLUG = "sample-project"; + private static final String TEST_LOCALE_ID = "en-us"; + private static final String TEST_ITERATION_SLUG = "iteration-slug"; private static final String WORKSPACE_TITLE_QUERY_PARAMETER_KEY = "title"; private static final String NO_DOCUMENTS_STRING = "No document selected"; @@ -76,6 +80,8 @@ public class AppPresenterTest extends PresenterTest private AppPresenter appPresenter; HasClickHandlers mockDocumentsLink; + HasClickHandlers mockProjectLink; + HasClickHandlers mockIterationFilesLink; HasClickHandlers mockErrorNotificationBtn; HasClickHandlers mockSearchButton; HasClickHandlers mockDocumentListButton; @@ -101,8 +107,10 @@ public class AppPresenterTest extends PresenterTest Location mockWindowLocation; UserWorkspaceContext mockUserWorkspaceContext; WorkspaceContext mockWorkspaceContext; - + private Capture capturedDocumentLinkClickHandler; + private Capture capturedProjectLinkClickHandler; + private Capture capturedIterationFilesLinkClickHandler; private Capture capturedSearchLinkClickHandler; private Capture capturedDocumentListClickHandler; private Capture capturedResizeClickHandler; @@ -137,6 +145,8 @@ private void createAllMocks() mockDisplay = createAndAddMock(AppPresenter.Display.class); mockDocumentListPresenter = createAndAddMock(DocumentListPresenter.class); mockDocumentsLink = createAndAddMock(HasClickHandlers.class); + mockProjectLink = createAndAddMock(HasClickHandlers.class); + mockIterationFilesLink = createAndAddMock(HasClickHandlers.class); mockErrorNotificationBtn = createAndAddMock(HasClickHandlers.class); mockSearchButton = createAndAddMock(HasClickHandlers.class); mockDocumentListButton = createAndAddMock(HasClickHandlers.class); @@ -156,7 +166,6 @@ private void createAllMocks() mockNotificationPresenter = createAndAddMock(NotificationPresenter.class); mockLayoutPresenter = createAndAddMock(LayoutSelectorPresenter.class); mockSideMenuPresenter = createAndAddMock(SideMenuPresenter.class); - } private void createAllCaptures() @@ -166,6 +175,8 @@ private void createAllCaptures() capturedResizeClickHandler = new Capture(); capturedKeyShortcutButtonClickHandler = new Capture(); capturedDocumentLinkClickHandler = new Capture(); + capturedProjectLinkClickHandler = new Capture(); + capturedIterationFilesLinkClickHandler = new Capture(); capturedErrorNotificationBtnHandler = new Capture(); capturedDocumentSelectionEvent = new Capture(); capturedDocumentStatsUpdatedEventHandler = new Capture(); @@ -414,66 +425,6 @@ public void testUpdateDocumentStatsFromDoclistView() verifyAllMocks(); } - public void testDocumentsLinkGeneratesHistoryToken() - { - ClickEvent docLinkClickEvent = createMock(ClickEvent.class); - - // 1 - click doc link from default state - expect(mockHistory.getToken()).andReturn("").once(); - - // 2 - load a document in the editor - expectLoadDocAndViewEditor(); - - // 3 - click doc link to return to doclist - HistoryToken expectedDocInEditorToken = buildDocInEditorToken(); - expect(mockHistory.getToken()).andReturn(expectedDocInEditorToken.toTokenString()).once(); - expectViewTransitionFromEditorToDoclist(emptyProjectStats); - - // 4 - click doc link to return to editor - HistoryToken expectedDocListWithLoadedDocToken = new HistoryToken(); - expectedDocListWithLoadedDocToken.setDocumentPath(TEST_DOCUMENT_PATH + TEST_DOCUMENT_NAME); - expect(mockHistory.getToken()).andReturn(expectedDocListWithLoadedDocToken.toTokenString()).once(); - - // NOTE not expecting return to editor view as this test does not simulate - // the event for the new history item - - replayAllMocks(); - - appPresenter.bind(); - // discard captured tokens from bind to allow easy check for new token - capturedHistoryTokenString.reset(); - - // 1 - no doc loaded, don't generate MainView.Editor token - capturedDocumentLinkClickHandler.getValue().onClick(docLinkClickEvent); - assertThat(capturedHistoryTokenString.hasCaptured(), is(false)); - - // 2 - load doc in editor - HistoryToken token = simulateLoadDocAndViewEditor(); - - // 3 - doc loaded in editor, return to doclist - capturedDocumentLinkClickHandler.getValue().onClick(docLinkClickEvent); - HistoryToken returnToDoclistToken = HistoryToken.fromTokenString(capturedHistoryTokenString.getValue()); - assertThat("clicking documents link should always show doclist when editor is visible", returnToDoclistToken.getView(), is(MainView.Documents)); - assertThat("document path should be maintained when clicking documents link", returnToDoclistToken.getDocumentPath(), is(token.getDocumentPath())); - - // simulate history token event for new token - capturedHistoryValueChangeHandler.getValue().onValueChange(new ValueChangeEvent(returnToDoclistToken.toTokenString()) - { - }); - - // 4 - doc loaded, return to editor - capturedDocumentLinkClickHandler.getValue().onClick(docLinkClickEvent); - HistoryToken returnToEditorToken = HistoryToken.fromTokenString(capturedHistoryTokenString.getValue()); - assertThat("clicking documents link should show editor when doclist is visible and a valid document is selected", returnToEditorToken.getView(), is(MainView.Editor)); - assertThat("document path should be maintained when clicking documents link", returnToEditorToken.getDocumentPath(), is(token.getDocumentPath())); - - // NOTE not simulating history change event for newest history token - - // TODO could check that filter parameters haven't changed as well - - verifyAllMocks(); - } - public void testSearchLinkGeneratesHistoryToken() { ClickEvent searchLinkClickEvent = createMock(ClickEvent.class); @@ -771,6 +722,8 @@ private void expectHandlerRegistrations() expect(mockHistory.addValueChangeHandler(and(capture(capturedHistoryValueChangeHandler), isA(ValueChangeHandler.class)))).andReturn(mockHandlerRegistration()).once(); expectClickHandlerRegistration(mockDocumentsLink, capturedDocumentLinkClickHandler); + expectClickHandlerRegistration(mockProjectLink, capturedProjectLinkClickHandler); + expectClickHandlerRegistration(mockIterationFilesLink, capturedIterationFilesLinkClickHandler); expectClickHandlerRegistration(mockErrorNotificationBtn, capturedErrorNotificationBtnHandler); expectClickHandlerRegistration(mockSearchButton, capturedSearchLinkClickHandler); expectClickHandlerRegistration(mockKeyShortcutButton, capturedKeyShortcutButtonClickHandler); @@ -788,8 +741,9 @@ private void expectPresenterSetupActions() { mockWindow.setTitle(TEST_WINDOW_TITLE); expectLastCall().once(); - mockDisplay.setWorkspaceNameLabel(TEST_WORKSPACE_NAME, TEST_WORKSPACE_TITLE); - expectLastCall().anyTimes(); + // mockDisplay.setProjectLinkLabel(TEST_WORKSPACE_NAME, + // TEST_WORKSPACE_TITLE); + // expectLastCall().anyTimes(); mockDisplay.setReadOnlyVisible(false); expectLastCall().once(); // initially empty project stats @@ -820,9 +774,17 @@ private void expectPresenterSetupActions() private void setupMockGetterReturnValues() { + expect(mockDisplay.getProjectLink()).andReturn(mockProjectLink).anyTimes(); expect(mockDisplay.getDocumentsLink()).andReturn(mockDocumentsLink).anyTimes(); + expect(mockDisplay.getIterationFilesLink()).andReturn(mockIterationFilesLink).anyTimes(); expect(mockDisplay.getNotificationBtn()).andReturn(mockErrorNotificationBtn).anyTimes(); + mockDisplay.setProjectLinkLabel(TEST_PPROJET_SLUG); + expectLastCall().once(); + + mockDisplay.setIterationFilesLabel(TEST_ITERATION_SLUG + "(" + TEST_LOCALE_ID + ")"); + expectLastCall().once(); + expect(mockDisplay.getSearchAndReplaceButton()).andReturn(mockSearchButton).anyTimes(); expect(mockDisplay.getDocumentListButton()).andReturn(mockDocumentListButton).anyTimes(); expect(mockDisplay.getResizeButton()).andReturn(mockResizeButton).anyTimes(); @@ -833,6 +795,9 @@ private void setupMockGetterReturnValues() expect(mockWindowLocation.getParameter(WORKSPACE_TITLE_QUERY_PARAMETER_KEY)).andReturn(TEST_WORKSPACE_TITLE).anyTimes(); expect(mockMessages.windowTitle(TEST_WORKSPACE_NAME, TEST_LOCALE_NAME)).andReturn(TEST_WINDOW_TITLE).anyTimes(); + + expect(mockMessages.windowTitle2(TEST_WORKSPACE_NAME, TEST_LOCALE_NAME, TEST_WORKSPACE_TITLE)).andReturn(TEST_WINDOW_TITLE).anyTimes(); + expect(mockMessages.noDocumentSelected()).andReturn(NO_DOCUMENTS_STRING).anyTimes(); expect(mockMessages.projectWideSearchAndReplace()).andReturn(SEARCH_PAGE_LABEL).anyTimes(); expect(mockMessages.showDocumentListKeyShortcut()).andReturn(DOCUMENT_LIST_KEY_SHORTCUT_DESCRIPTION).anyTimes(); @@ -842,6 +807,8 @@ private void setupMockGetterReturnValues() expect(mockUserWorkspaceContext.getWorkspaceContext()).andReturn(mockWorkspaceContext).anyTimes(); expect(mockUserWorkspaceContext.hasReadOnlyAccess()).andReturn(false).anyTimes(); + expect(mockWorkspaceContext.getWorkspaceId()).andReturn(new WorkspaceId(new ProjectIterationId(TEST_PPROJET_SLUG, TEST_ITERATION_SLUG), new LocaleId(TEST_LOCALE_ID))).anyTimes(); + expect(mockWorkspaceContext.getWorkspaceName()).andReturn(TEST_WORKSPACE_NAME).anyTimes(); expect(mockWorkspaceContext.getLocaleName()).andReturn(TEST_LOCALE_NAME).anyTimes(); diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java index cf3719e863..926639a71a 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java @@ -39,19 +39,14 @@ import org.zanata.webtrans.client.presenter.GlossaryPresenter.Display; import org.zanata.webtrans.client.resources.WebTransMessages; import org.zanata.webtrans.client.rpc.CachingDispatchAsync; -import org.zanata.webtrans.shared.model.GlossaryResultItem; import org.zanata.webtrans.shared.model.UserWorkspaceContext; -import com.google.gwt.cell.client.FieldUpdater; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.HasAllFocusHandlers; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.shared.HandlerRegistration; -import com.google.gwt.resources.client.ImageResource; -import com.google.gwt.user.cellview.client.Column; -import com.google.gwt.view.client.ListDataProvider; /** * @@ -75,8 +70,6 @@ public class GlossaryPresenterTest extends PresenterTest HasAllFocusHandlers mockFocusTextBox; HasClickHandlers mockSearchButton; - Column mockDetailsColumn; - Column mockCopyColumn; private Capture capturedSearchButtonClickHandler; private Capture capturedKeyShortcuts; @@ -91,14 +84,13 @@ public void createMocks() mockEventBus = createAndAddMock(EventBus.class); mockDispatcher = createAndAddMock(CachingDispatchAsync.class); mockMessages = createAndAddMock(WebTransMessages.class); + mockGlossaryDetailsPresenter = createAndAddMock(GlossaryDetailsPresenter.class); mockUserWorkspaceContext = createAndAddMock(UserWorkspaceContext.class); mockKeyShortcutPresenter = createAndAddMock(KeyShortcutPresenter.class); mockFocusTextBox = createAndAddMock(HasAllFocusHandlers.class); mockSearchButton = createAndAddMock(HasClickHandlers.class); - mockDetailsColumn = createAndAddMock(Column.class); - mockCopyColumn = createAndAddMock(Column.class); capturedSearchButtonClickHandler = addCapture(new Capture()); capturedKeyShortcuts = addCapture(new Capture()); @@ -120,15 +112,13 @@ public void canBind() replayAllMocks(); glossaryPresenter = new GlossaryPresenter(mockDisplay, mockEventBus, mockDispatcher, mockMessages, mockGlossaryDetailsPresenter, mockUserWorkspaceContext, mockKeyShortcutPresenter); glossaryPresenter.bind(); + verifyAllMocks(); } @Override protected void setDefaultBindExpectations() { - mockDisplay.setDataProvider(isA(ListDataProvider.class)); - expectLastCall().once(); - expect(mockDisplay.getSearchButton()).andReturn(mockSearchButton).anyTimes(); expect(mockSearchButton.addClickHandler(capture(capturedSearchButtonClickHandler))).andReturn(createMock(HandlerRegistration.class)).once(); @@ -137,18 +127,12 @@ protected void setDefaultBindExpectations() expect(mockEventBus.addHandler(eq(TransUnitSelectionEvent.getType()), and(capture(capturedTransUnitSelectionEventHandler), isA(TransUnitSelectionHandler.class)))).andReturn(createMock(HandlerRegistration.class)).once(); - expect(mockDisplay.getCopyColumn()).andReturn(mockCopyColumn).once(); - mockCopyColumn.setFieldUpdater(isA(FieldUpdater.class)); - expectLastCall().once(); - - expect(mockDisplay.getDetailsColumn()).andReturn(mockDetailsColumn).once(); - mockDetailsColumn.setFieldUpdater(isA(FieldUpdater.class)); - expectLastCall().once(); - expect(mockDisplay.getFocusGlossaryTextBox()).andReturn(mockFocusTextBox).times(2); expect(mockFocusTextBox.addFocusHandler(capture(capturedFocusHandler))).andReturn(createMock(HandlerRegistration.class)).once(); expect(mockFocusTextBox.addBlurHandler(capture(capturedBlurHandler))).andReturn(createMock(HandlerRegistration.class)).once(); + mockDisplay.setListener(isA(HasGlossaryEvent.class)); + expectLastCall().once(); } } diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java index c5b7b2f683..9bcc802842 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java @@ -41,7 +41,8 @@ public void execute() targetComments.add("Target Comment " + (2 + i)); targetComments.add("Target Comment " + (3 + i)); - items.add(new GlossaryDetails(srcComments, targetComments, "Dummy source ref " + (1 + i), new LocaleId("en-us"), action.getWorkspaceId().getLocaleId(), null)); + GlossaryDetails details = new GlossaryDetails("source content:" + (i + 1), "target content:" + (i + 1), srcComments, targetComments, "Dummy source ref " + (i + 1), new LocaleId("en-us"), action.getWorkspaceId().getLocaleId(), i, "8/08/8888 12:00"); + items.add(details); } callback.onSuccess(new GetGlossaryDetailsResult(items)); From ad550981bad393e60d950f9728e8dc04d7264a1f Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Wed, 5 Sep 2012 13:03:25 +1000 Subject: [PATCH 3/4] Work in progress: implement glossary editing in workspace --- .../presenter/GlossaryDetailsPresenter.java | 92 ++++++--- .../client/presenter/GlossaryPresenter.java | 4 +- .../client/presenter/HasGlossaryEvent.java | 2 + .../webtrans/client/resources/UiMessages.java | 2 + .../client/view/GlossaryDetailsView.java | 169 ++++++++++++++-- .../client/view/GlossaryDetailsView.ui.xml | 188 ++++++++++++++---- .../webtrans/client/view/GlossaryView.ui.xml | 3 +- .../server/rpc/UpdateGlossaryTermHandler.java | 23 ++- .../shared/rpc/UpdateGlossaryTermAction.java | 46 ++--- .../zanata/webtrans/public/Application.css | 9 +- .../presenter/GlossaryPresenterTest.java | 4 + .../rpc/DummyGetGlossaryDetailsCommand.java | 3 + 12 files changed, 422 insertions(+), 123 deletions(-) diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java index 1c7070a79b..6851fb8bfe 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java @@ -1,9 +1,13 @@ package org.zanata.webtrans.client.presenter; +import java.util.List; + import net.customware.gwt.presenter.client.EventBus; import net.customware.gwt.presenter.client.widget.WidgetDisplay; import net.customware.gwt.presenter.client.widget.WidgetPresenter; +import org.zanata.webtrans.client.events.NotificationEvent; +import org.zanata.webtrans.client.events.NotificationEvent.Severity; import org.zanata.webtrans.client.resources.UiMessages; import org.zanata.webtrans.client.rpc.CachingDispatchAsync; import org.zanata.webtrans.shared.model.GlossaryDetails; @@ -14,6 +18,7 @@ import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermResult; import com.allen_sauer.gwt.log.client.Log; +import com.google.common.base.Strings; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; @@ -36,9 +41,9 @@ public interface Display extends WidgetDisplay HasText getTargetText(); - HasText getSourceComment(); + void setSourceComment(List comments); - HasText getTargetComment(); + void setTargetComment(List comments); HasText getSourceLabel(); @@ -59,6 +64,18 @@ public interface Display extends WidgetDisplay void addEntry(String text); HasText getLastModified(); + + HasClickHandlers getAddNewCommentButton(); + + void addRowIntoTargetComment(int row, String comment); + + HasText getNewCommentText(); + + int getTargetCommentRowCount(); + + List getCurrentTargetComments(); + + void showLoading(boolean visible); } private GetGlossaryDetailsResult glossaryDetails; @@ -69,8 +86,10 @@ public interface Display extends WidgetDisplay private final CachingDispatchAsync dispatcher; + private HasGlossaryEvent glossaryListener; + @Inject - public GlossaryDetailsPresenter(final Display display, EventBus eventBus, UiMessages messages, final CachingDispatchAsync dispatcher) + public GlossaryDetailsPresenter(final Display display, final EventBus eventBus, final UiMessages messages, final CachingDispatchAsync dispatcher) { super(display, eventBus); this.dispatcher = dispatcher; @@ -93,20 +112,31 @@ public void onClick(ClickEvent event) { if (selectedDetailEntry != null) { - // check if there's any changes and save - if(!display.getTargetText().getText().equals(selectedDetailEntry.getTarget())) + // check if there's any changes on the target term or the target + // comments and save + if (!display.getTargetText().getText().equals(selectedDetailEntry.getTarget())) { - dispatcher.execute(new UpdateGlossaryTermAction(selectedDetailEntry.getSrcLocale(), selectedDetailEntry.getTargetLocale(), selectedDetailEntry.getSource(), display.getTargetText().getText(), selectedDetailEntry.getTargetVersionNum()), new AsyncCallback() + display.showLoading(true); + UpdateGlossaryTermAction action = new UpdateGlossaryTermAction(selectedDetailEntry, display.getTargetText().getText(), display.getCurrentTargetComments()); + + dispatcher.execute(action, new AsyncCallback() { @Override public void onFailure(Throwable caught) { Log.error(caught.getMessage(), caught); + eventBus.fireEvent(new NotificationEvent(Severity.Error, messages.saveGlossaryFailed())); + display.showLoading(false); } + @Override public void onSuccess(UpdateGlossaryTermResult result) { Log.info("Glossary term updated:" + result.getDetail().getTarget()); + glossaryListener.fireSearchEvent(); + selectedDetailEntry = result.getDetail(); + populateDisplayData(); + display.showLoading(false); } }); } @@ -114,6 +144,19 @@ public void onSuccess(UpdateGlossaryTermResult result) } })); + registerHandler(display.getAddNewCommentButton().addClickHandler(new ClickHandler() + { + @Override + public void onClick(ClickEvent event) + { + if (!Strings.isNullOrEmpty(display.getNewCommentText().getText())) + { + display.addRowIntoTargetComment(display.getTargetCommentRowCount(), display.getNewCommentText().getText()); + display.getNewCommentText().setText(""); + } + } + })); + registerHandler(display.getEntryListBox().addChangeHandler(new ChangeHandler() { @Override @@ -157,33 +200,21 @@ public void onSuccess(GetGlossaryDetailsResult result) }); } - protected void selectEntry(int selected) + private void populateDisplayData() + { + display.getSrcRef().setText(selectedDetailEntry.getSourceRef()); + display.setSourceComment(selectedDetailEntry.getSourceComment()); + display.setTargetComment(selectedDetailEntry.getTargetComment()); + display.getLastModified().setText(messages.lastModifiedOn(selectedDetailEntry.getLastModified())); + } + + private void selectEntry(int selected) { - StringBuilder srcComments = new StringBuilder(); - StringBuilder targetComments = new StringBuilder(); - String srcRef = ""; if (selected >= 0) { selectedDetailEntry = glossaryDetails.getGlossaryDetails().get(selected); - srcRef = selectedDetailEntry.getSourceRef(); - for (String srcComment : selectedDetailEntry.getSourceComment()) - { - srcComments.append(srcComment); - srcComments.append("\n"); - } - - for (String targetComment : selectedDetailEntry.getTargetComment()) - { - targetComments.append(targetComment); - targetComments.append("\n"); - } } - - display.getSrcRef().setText(srcRef); - display.getSourceComment().setText(srcComments.toString()); - display.getTargetComment().setText(targetComments.toString()); - display.getLastModified().setText(messages.lastModifiedOn(selectedDetailEntry.getLastModified())); - + populateDisplayData(); } @Override @@ -200,4 +231,9 @@ protected void onUnbind() public void onRevealDisplay() { } + + public void setGlossaryListener(HasGlossaryEvent glossaryListener) + { + this.glossaryListener = glossaryListener; + } } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java index 1947e4931b..f3fa3a03fd 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryPresenter.java @@ -158,9 +158,11 @@ public void onBlur(BlurEvent event) }); display.setListener(this); + glossaryDetailsPresenter.setGlossaryListener(this); } - private void fireSearchEvent() + @Override + public void fireSearchEvent() { String query = display.getGlossaryTextBox().getText(); createGlossaryRequest(query, display.getSearchType().getValue()); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java index 55f31b556a..d4387b1454 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/HasGlossaryEvent.java @@ -7,4 +7,6 @@ public interface HasGlossaryEvent void fireCopyEvent(GlossaryResultItem item); void showGlossaryDetail(GlossaryResultItem item); + + void fireSearchEvent(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java index bbef43a033..16a7e97705 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/resources/UiMessages.java @@ -149,4 +149,6 @@ public interface UiMessages extends Messages @DefaultMessage("Found no glossary results") String foundNoGlossaryResults(); + @DefaultMessage("Glossary save fail") + String saveGlossaryFailed(); } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java index 554fe80976..531d5b8003 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java @@ -1,18 +1,30 @@ package org.zanata.webtrans.client.view; +import java.util.ArrayList; +import java.util.List; + import org.zanata.webtrans.client.presenter.GlossaryDetailsPresenter; +import org.zanata.webtrans.client.resources.Resources; import org.zanata.webtrans.client.resources.UiMessages; +import com.google.common.base.Strings; import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.HasChangeHandlers; import com.google.gwt.event.dom.client.HasClickHandlers; +import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DialogBox; +import com.google.gwt.user.client.ui.FlexTable; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasText; +import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; +import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; @@ -20,45 +32,89 @@ public class GlossaryDetailsView implements GlossaryDetailsPresenter.Display { - interface TMIUiBinder extends UiBinder + interface GlossaryIUiBinder extends UiBinder + { + } + + interface Styles extends CssResource { + String targetCommentListButton(); + + String targetCommentTextArea(); } - private static TMIUiBinder uiBinder = GWT.create(TMIUiBinder.class); + private static GlossaryIUiBinder uiBinder = GWT.create(GlossaryIUiBinder.class); DialogBox dialogBox; @UiField - TextArea srcRef; + TextArea srcRef, sourceText, targetText, newTargetComment; @UiField - TextArea sourceText; + Label sourceLabel, targetLabel, lastModified; @UiField - TextArea targetText; + ListBox sourceComment, entryListBox; @UiField - TextArea sourceComment; + Button dismissButton, saveButton, addNewCommentButton; @UiField - Label sourceLabel, targetLabel, lastModified; + FlexTable targetCommentsTable; @UiField - TextArea targetComment; + ScrollPanel targetCommentScrollTable; @UiField - Button dismissButton, saveButton; + Image loadingIcon; @UiField - ListBox entryListBox; + Styles style; + + private final int VISIBLE_COMMENTS = 4; + + private class DeleteRowHandler implements ClickHandler + { + private final Widget panel; + + public DeleteRowHandler(Widget panel) + { + this.panel = panel; + } + + @Override + public void onClick(ClickEvent event) + { + targetCommentsTable.remove(panel); + + // Clean up empty tag in the table + for (int i = 0; i < targetCommentsTable.getRowCount(); i++) + { + Widget widget = targetCommentsTable.getWidget(i, 0); + if (widget == null) + { + targetCommentsTable.removeRow(i); + } + } + } + } @Inject - public GlossaryDetailsView(UiMessages messages) + public GlossaryDetailsView(UiMessages messages, Resources resources) { dialogBox = uiBinder.createAndBindUi(this); dialogBox.setText(messages.glossaryDetails()); dismissButton.setText(messages.dismiss()); saveButton.setText(messages.save()); + sourceComment.setVisibleItemCount(VISIBLE_COMMENTS); + targetCommentsTable.setCellPadding(0); + targetCommentsTable.setCellSpacing(1); + + addNewCommentButton.addStyleName("icon-plus-1"); + targetCommentScrollTable.setAlwaysShowScrollBars(true); + + loadingIcon.setResource(resources.spinner()); + loadingIcon.setVisible(false); } public void hide() @@ -69,6 +125,7 @@ public void hide() public void show() { dialogBox.center(); + targetCommentScrollTable.scrollToBottom(); } @Override @@ -78,9 +135,13 @@ public Widget asWidget() } @Override - public HasText getSourceComment() + public void setSourceComment(List comments) { - return sourceComment; + sourceComment.clear(); + for (String comment : comments) + { + sourceComment.addItem(comment); + } } @Override @@ -89,10 +150,54 @@ public HasText getSourceText() return sourceText; } + private FlowPanel getTargetCommentRow(String comment) + { + FlowPanel panel = new FlowPanel(); + + Button deleteButton = new Button(); + deleteButton.setStyleName("icon-minus-1"); + deleteButton.addStyleName(style.targetCommentListButton()); + + deleteButton.addClickHandler(new DeleteRowHandler(panel)); + + TextArea commentArea = new TextArea(); + commentArea.setStyleName(style.targetCommentTextArea()); + commentArea.setVisibleLines(2); + + commentArea.setValue(comment); + + panel.add(commentArea); + panel.add(deleteButton); + + return panel; + } + @Override - public HasText getTargetComment() + public void setTargetComment(List comments) { - return targetComment; + targetCommentsTable.clear(); + for (int i = 0; i < comments.size(); i++) + { + String comment = comments.get(i); + targetCommentsTable.setWidget(i, 0, getTargetCommentRow(comment)); + } + } + + @Override + public List getCurrentTargetComments() + { + ArrayList currentComments = new ArrayList(); + + for (int i = 0; i < targetCommentsTable.getRowCount(); i++) + { + FlowPanel panel = (FlowPanel) targetCommentsTable.getWidget(i, 0); + TextArea textArea = (TextArea) panel.getWidget(0); + if (!Strings.isNullOrEmpty(textArea.getText())) + { + currentComments.add(textArea.getText()); + } + } + return currentComments; } @Override @@ -112,13 +217,18 @@ public HasClickHandlers getDismissButton() { return dismissButton; } - + @Override public HasClickHandlers getSaveButton() { return saveButton; } - + + @Override + public HasClickHandlers getAddNewCommentButton() + { + return addNewCommentButton; + } @Override public int getSelectedDocumentIndex() @@ -162,4 +272,29 @@ public HasText getLastModified() return lastModified; } + @Override + public HasText getNewCommentText() + { + return newTargetComment; + } + + @Override + public void addRowIntoTargetComment(int row, String comment) + { + targetCommentsTable.setWidget(row, 0, getTargetCommentRow(comment)); + targetCommentScrollTable.scrollToBottom(); + } + + @Override + public int getTargetCommentRowCount() + { + return targetCommentsTable.getRowCount(); + } + + @Override + public void showLoading(boolean visible) + { + loadingIcon.setVisible(visible); + } + } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml index 7e40409a5d..dae6b42721 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml @@ -9,42 +9,158 @@ + + .headerLabel + { + padding-right:5px; + color:#C35817; + font-weight:bold; + } + + .alignTop + { + vertical-align:top; + } + + .textArea + { + width:280px; + height:40px; + } + + .textArea[readonly] + { + background:#DDDDDD; + } + + .listBox + { + width:285px; + margin:0; + } + + .button + { + width:70px; + padding:3px; + margin:1px; + } + + .lastModifiedLabel + { + color:#C35817; + font-weight:bold; + } + + .targetCommentList + { + background:#FFFFFF; + border:1px solid #000000; + } + + .targetCommentListButton + { + font-size:10px; + background:none; + border:none; + border-radius:4px; + cursor:pointer; + padding:2px 1px 2px 3px; + margin:2px; + vertical-align:top; + } + + .targetCommentListButton:hover + { + background:gray; + color:white; + } + + .targetCommentTextArea + { + width:240px; + } + + .newTargetCommentTextArea + { + width:260px; + height:40px; + } + + .buttonDiv + { + text-align:right; + } + + + - - - - - - Entries: - - - - - - Source Reference: - - - - - - - - - Comments: - - - - - - Comments: - - - - - Last modified - - - - + + + + Entries: + + + + + + + Source Reference: + + + + + + + + + + + + + + Comments: + + + + + + + + + + + + + + Comments: + + + + + + + + + New target comment: + + + + + + + + + + + + + + + + + + + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml index 054cbd7251..416db0defc 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryView.ui.xml @@ -16,6 +16,7 @@ { border:1px solid #A7A7A7; border-radius:3px; + padding:2px; } @@ -24,7 +25,7 @@ - + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java index 2e7f769233..73af0eb324 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/UpdateGlossaryTermHandler.java @@ -42,22 +42,31 @@ public class UpdateGlossaryTermHandler extends AbstractActionHandler { private static final long serialVersionUID = 1L; - private LocaleId srcLocale, targetLocale; - private String srcContent, targetContent; - private Integer currentVerNum; - + private GlossaryDetails selectedDetailEntry; + private String newTargetTerm; + private List newTargetComment; + @SuppressWarnings("unused") private UpdateGlossaryTermAction() { - this(null, null, null, null, null); + this(null, null, null); } - public UpdateGlossaryTermAction(LocaleId srcLocale, LocaleId targetLocale, String srcContent, String targetContent, Integer currentVerNum) - { - this.srcLocale = srcLocale; - this.srcContent = srcContent; - this.targetLocale = targetLocale; - this.targetContent = targetContent; - this.currentVerNum = currentVerNum; - } - - public LocaleId getSrcLocale() - { - return srcLocale; - } - - public String getSrcContent() + public UpdateGlossaryTermAction(GlossaryDetails selectedDetailEntry, String newTargetTerm, List newTargetComment) { - return srcContent; + this.selectedDetailEntry = selectedDetailEntry; + this.newTargetComment = newTargetComment; + this.newTargetTerm = newTargetTerm; } - public LocaleId getTargetLocale() + public GlossaryDetails getSelectedDetailEntry() { - return targetLocale; + return selectedDetailEntry; } - public String getTargetContent() + public String getNewTargetTerm() { - return targetContent; + return newTargetTerm; } - public Integer getCurrentVerNum() + public List getNewTargetComment() { - return currentVerNum; + return newTargetComment; } } diff --git a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css index a555a8745b..204f25f9d1 100644 --- a/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css +++ b/zanata-war/src/main/resources/org/zanata/webtrans/public/Application.css @@ -897,7 +897,7 @@ td.ApprovedStateDecoration div div div .tableMsg { - font-size:16px; + font-size:14px; font-weight:bold; text-align:center; padding:25px; @@ -981,8 +981,8 @@ td.ApprovedStateDecoration div div div /* -------------- GWT Dialog Box ----------------*/ .GWTDialogBox { - width:500px; - height:300px; + width:600px; + height:400px; background:#F2F2F2; border:1px solid #C0C0C0; border-radius:3px; @@ -998,12 +998,11 @@ td.ApprovedStateDecoration div div div border-radius:3px; background:#575757; color:#FFFFFF; - cursor:pointer; + cursor:move; } .GWTDialogBox table { width:100%; - height:100%; } diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java index 926639a71a..34857fb974 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryPresenterTest.java @@ -133,6 +133,10 @@ protected void setDefaultBindExpectations() mockDisplay.setListener(isA(HasGlossaryEvent.class)); expectLastCall().once(); + + mockGlossaryDetailsPresenter.setGlossaryListener(isA(HasGlossaryEvent.class)); + expectLastCall().once(); + } } diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java index 9bcc802842..2a7e2eb1fd 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyGetGlossaryDetailsCommand.java @@ -40,6 +40,9 @@ public void execute() targetComments.add("Target Comment " + (1 + i)); targetComments.add("Target Comment " + (2 + i)); targetComments.add("Target Comment " + (3 + i)); + targetComments.add("Target Comment " + (4 + i)); + targetComments.add("Target Comment " + (5 + i)); + targetComments.add("Target Comment " + (6 + i)); GlossaryDetails details = new GlossaryDetails("source content:" + (i + 1), "target content:" + (i + 1), srcComments, targetComments, "Dummy source ref " + (i + 1), new LocaleId("en-us"), action.getWorkspaceId().getLocaleId(), i, "8/08/8888 12:00"); items.add(details); From 198e181331985b9dcd365f8e3308d3526716fc57 Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Wed, 5 Sep 2012 16:01:28 +1000 Subject: [PATCH 4/4] Implement glossary term editing in workspace --- .../presenter/GlossaryDetailsPresenter.java | 14 +- .../client/view/GlossaryDetailsView.java | 41 +++- .../client/view/GlossaryDetailsView.ui.xml | 17 +- .../server/rpc/ActivateWorkspaceHandler.java | 10 +- .../shared/model/UserWorkspaceContext.java | 9 +- .../GlossaryDetailsPresenterTest.java | 224 ++++++++++++++++++ .../rpc/DummyActivateWorkspaceCommand.java | 2 +- 7 files changed, 290 insertions(+), 27 deletions(-) create mode 100644 zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java index 6851fb8bfe..05e115f5d1 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenter.java @@ -12,6 +12,7 @@ import org.zanata.webtrans.client.rpc.CachingDispatchAsync; import org.zanata.webtrans.shared.model.GlossaryDetails; import org.zanata.webtrans.shared.model.GlossaryResultItem; +import org.zanata.webtrans.shared.model.UserWorkspaceContext; import org.zanata.webtrans.shared.rpc.GetGlossaryDetailsAction; import org.zanata.webtrans.shared.rpc.GetGlossaryDetailsResult; import org.zanata.webtrans.shared.rpc.UpdateGlossaryTermAction; @@ -76,6 +77,8 @@ public interface Display extends WidgetDisplay List getCurrentTargetComments(); void showLoading(boolean visible); + + void setHasUpdateAccess(boolean hasGlossaryUpdateAccess); } private GetGlossaryDetailsResult glossaryDetails; @@ -86,14 +89,17 @@ public interface Display extends WidgetDisplay private final CachingDispatchAsync dispatcher; + private final UserWorkspaceContext userWorkspaceContext; + private HasGlossaryEvent glossaryListener; @Inject - public GlossaryDetailsPresenter(final Display display, final EventBus eventBus, final UiMessages messages, final CachingDispatchAsync dispatcher) + public GlossaryDetailsPresenter(final Display display, final EventBus eventBus, final UiMessages messages, final CachingDispatchAsync dispatcher, final UserWorkspaceContext userWorkspaceContext) { super(display, eventBus); this.dispatcher = dispatcher; this.messages = messages; + this.userWorkspaceContext = userWorkspaceContext; registerHandler(display.getDismissButton().addClickHandler(new ClickHandler() { @@ -110,7 +116,7 @@ public void onClick(ClickEvent event) @Override public void onClick(ClickEvent event) { - if (selectedDetailEntry != null) + if (selectedDetailEntry != null && userWorkspaceContext.hasGlossaryUpdateAccess()) { // check if there's any changes on the target term or the target // comments and save @@ -149,7 +155,7 @@ public void onSuccess(UpdateGlossaryTermResult result) @Override public void onClick(ClickEvent event) { - if (!Strings.isNullOrEmpty(display.getNewCommentText().getText())) + if (!Strings.isNullOrEmpty(display.getNewCommentText().getText()) && userWorkspaceContext.hasGlossaryUpdateAccess()) { display.addRowIntoTargetComment(display.getTargetCommentRowCount(), display.getNewCommentText().getText()); display.getNewCommentText().setText(""); @@ -165,6 +171,8 @@ public void onChange(ChangeEvent event) selectEntry(display.getSelectedDocumentIndex()); } })); + + display.setHasUpdateAccess(userWorkspaceContext.hasGlossaryUpdateAccess()); } public void show(final GlossaryResultItem item) diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java index 531d5b8003..8f74ebd88b 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.java @@ -73,6 +73,8 @@ interface Styles extends CssResource private final int VISIBLE_COMMENTS = 4; + private boolean hasGlossaryUpdateAccess; + private class DeleteRowHandler implements ClickHandler { private final Widget panel; @@ -107,12 +109,17 @@ public GlossaryDetailsView(UiMessages messages, Resources resources) dismissButton.setText(messages.dismiss()); saveButton.setText(messages.save()); sourceComment.setVisibleItemCount(VISIBLE_COMMENTS); + + sourceComment.setEnabled(false); + sourceText.setEnabled(false); + srcRef.setEnabled(false); + targetCommentsTable.setCellPadding(0); targetCommentsTable.setCellSpacing(1); addNewCommentButton.addStyleName("icon-plus-1"); targetCommentScrollTable.setAlwaysShowScrollBars(true); - + loadingIcon.setResource(resources.spinner()); loadingIcon.setVisible(false); } @@ -154,21 +161,25 @@ private FlowPanel getTargetCommentRow(String comment) { FlowPanel panel = new FlowPanel(); - Button deleteButton = new Button(); - deleteButton.setStyleName("icon-minus-1"); - deleteButton.addStyleName(style.targetCommentListButton()); - - deleteButton.addClickHandler(new DeleteRowHandler(panel)); - TextArea commentArea = new TextArea(); commentArea.setStyleName(style.targetCommentTextArea()); commentArea.setVisibleLines(2); - commentArea.setValue(comment); + if (!hasGlossaryUpdateAccess) + { + commentArea.setEnabled(false); + } panel.add(commentArea); - panel.add(deleteButton); + if (hasGlossaryUpdateAccess) + { + Button deleteButton = new Button(); + deleteButton.setStyleName("icon-minus-1"); + deleteButton.addStyleName(style.targetCommentListButton()); + deleteButton.addClickHandler(new DeleteRowHandler(panel)); + panel.add(deleteButton); + } return panel; } @@ -187,7 +198,7 @@ public void setTargetComment(List comments) public List getCurrentTargetComments() { ArrayList currentComments = new ArrayList(); - + for (int i = 0; i < targetCommentsTable.getRowCount(); i++) { FlowPanel panel = (FlowPanel) targetCommentsTable.getWidget(i, 0); @@ -297,4 +308,14 @@ public void showLoading(boolean visible) loadingIcon.setVisible(visible); } + @Override + public void setHasUpdateAccess(boolean hasGlossaryUpdateAccess) + { + saveButton.setEnabled(hasGlossaryUpdateAccess); + newTargetComment.setEnabled(hasGlossaryUpdateAccess); + targetText.setEnabled(hasGlossaryUpdateAccess); + addNewCommentButton.setVisible(hasGlossaryUpdateAccess); + this.hasGlossaryUpdateAccess = hasGlossaryUpdateAccess; + } + } diff --git a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml index dae6b42721..bccba46858 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml +++ b/zanata-war/src/main/java/org/zanata/webtrans/client/view/GlossaryDetailsView.ui.xml @@ -26,11 +26,7 @@ { width:280px; height:40px; - } - - .textArea[readonly] - { - background:#DDDDDD; + resize:none; } .listBox @@ -42,8 +38,8 @@ .button { width:70px; - padding:3px; margin:1px; + padding:2px; } .lastModifiedLabel @@ -85,6 +81,7 @@ { width:260px; height:40px; + resize:none; } .buttonDiv @@ -106,21 +103,21 @@ Source Reference: - + - + Comments: - + @@ -152,7 +149,7 @@ - + diff --git a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java index 616d1659d6..6ab0caf14a 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/server/rpc/ActivateWorkspaceHandler.java @@ -105,9 +105,10 @@ public ActivateWorkspaceResult execute(ActivateWorkspaceAction action, Execution boolean isProjectActive = isProjectIterationActive(project.getStatus(), projectIteration.getStatus()); boolean hasWriteAccess = hasPermission(project, locale); - + boolean hasGlossaryUpdateAccess = hasGlossaryUpdatePermission(); + Identity identity = new Identity(editorClientId, person); - UserWorkspaceContext userWorkspaceContext = new UserWorkspaceContext(workspace.getWorkspaceContext(), isProjectActive, hasWriteAccess); + UserWorkspaceContext userWorkspaceContext = new UserWorkspaceContext(workspace.getWorkspaceContext(), isProjectActive, hasWriteAccess, hasGlossaryUpdateAccess); return new ActivateWorkspaceResult(userWorkspaceContext, identity); } @@ -116,6 +117,11 @@ private boolean hasPermission(HProject project, HLocale locale) return ZanataIdentity.instance().hasPermission("modify-translation", project, locale); } + private boolean hasGlossaryUpdatePermission() + { + return ZanataIdentity.instance().hasPermission("glossary-update", ""); + } + private boolean isProjectIterationActive(EntityStatus projectStatus, EntityStatus iterStatus) { return (projectStatus.equals(EntityStatus.ACTIVE) && iterStatus.equals(EntityStatus.ACTIVE)); diff --git a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java index c2836eaa09..11aacc0cb0 100644 --- a/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java +++ b/zanata-war/src/main/java/org/zanata/webtrans/shared/model/UserWorkspaceContext.java @@ -6,6 +6,7 @@ public class UserWorkspaceContext implements IsSerializable { private boolean isProjectActive; private boolean hasWriteAccess; + private boolean hasGlossaryUpdateAccess; private DocumentInfo selectedDoc; private WorkspaceContext workspaceContext; @@ -16,11 +17,17 @@ private UserWorkspaceContext() { } - public UserWorkspaceContext(WorkspaceContext workspaceContext, boolean isProjectActive, boolean hasWriteAccess) + public UserWorkspaceContext(WorkspaceContext workspaceContext, boolean isProjectActive, boolean hasWriteAccess, boolean hasGlossaryUpdateAccess) { this.workspaceContext = workspaceContext; this.isProjectActive = isProjectActive; this.hasWriteAccess = hasWriteAccess; + this.hasGlossaryUpdateAccess = hasGlossaryUpdateAccess; + } + + public boolean hasGlossaryUpdateAccess() + { + return hasGlossaryUpdateAccess; } public boolean isProjectActive() diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java new file mode 100644 index 0000000000..0d44375f24 --- /dev/null +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/presenter/GlossaryDetailsPresenterTest.java @@ -0,0 +1,224 @@ +/* + * Copyright 2012, Red Hat, Inc. and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.zanata.webtrans.client.presenter; + +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.expectLastCall; +import net.customware.gwt.presenter.client.EventBus; + +import org.easymock.Capture; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.zanata.webtrans.client.presenter.GlossaryDetailsPresenter.Display; +import org.zanata.webtrans.client.resources.UiMessages; +import org.zanata.webtrans.client.rpc.CachingDispatchAsync; +import org.zanata.webtrans.shared.model.UserWorkspaceContext; + +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.HasChangeHandlers; +import com.google.gwt.event.dom.client.HasClickHandlers; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.ui.HasText; + +/** + * + * @author Alex Eng aeng@redhat.com + * + */ +@Test(groups = { "unit-tests" }) +public class GlossaryDetailsPresenterTest extends PresenterTest +{ + // object under test + private GlossaryDetailsPresenter glossaryDetailsPresenter; + + private Display mockDisplay; + private EventBus mockEventBus; + private CachingDispatchAsync mockDispatcher; + private UiMessages mockMessages; + private UserWorkspaceContext mockUserWorkspaceContext; + + private HasText mockTargetCommentText; + + HasClickHandlers mockDismissButton; + HasClickHandlers mockSaveButton; + HasClickHandlers mockAddNewCommentButton; + + HasChangeHandlers mockEntryListBox; + + private Capture capturedDismissButtonClickHandler; + private Capture capturedSaveButtonClickHandler; + private Capture capturedAddNewCommentButtonClickHandler; + + private Capture capturedEntryListBoxChangeHandler; + + @BeforeClass + public void createMocks() + { + mockDisplay = createAndAddMock(GlossaryDetailsPresenter.Display.class); + mockEventBus = createAndAddMock(EventBus.class); + mockDispatcher = createAndAddMock(CachingDispatchAsync.class); + mockMessages = createAndAddMock(UiMessages.class); + mockUserWorkspaceContext = createAndAddMock(UserWorkspaceContext.class); + + mockTargetCommentText = createAndAddMock(HasText.class); + + mockDismissButton = createAndAddMock(HasClickHandlers.class); + mockSaveButton = createAndAddMock(HasClickHandlers.class); + mockAddNewCommentButton = createAndAddMock(HasClickHandlers.class); + + mockEntryListBox = createAndAddMock(HasChangeHandlers.class); + + capturedDismissButtonClickHandler = addCapture(new Capture()); + capturedSaveButtonClickHandler = addCapture(new Capture()); + capturedAddNewCommentButtonClickHandler = addCapture(new Capture()); + + capturedEntryListBoxChangeHandler = addCapture(new Capture()); + } + + @BeforeMethod + public void beforeMethod() + { + resetAll(); + } + + @Test + public void canBind() + { + expect(mockUserWorkspaceContext.hasGlossaryUpdateAccess()).andReturn(true).once(); + + mockDisplay.setHasUpdateAccess(true); + expectLastCall().once(); + + replayAllMocks(); + glossaryDetailsPresenter = new GlossaryDetailsPresenter(mockDisplay, mockEventBus, mockMessages, mockDispatcher, mockUserWorkspaceContext); + glossaryDetailsPresenter.bind(); + + verifyAllMocks(); + } + + @Test + public void testAddNewCommentWithUpdateAccess() + { + int rowNum = 1; + String newComment = "new comment"; + boolean hasAccess = true; + + expect(mockUserWorkspaceContext.hasGlossaryUpdateAccess()).andReturn(hasAccess).once(); + + mockDisplay.setHasUpdateAccess(hasAccess); + expectLastCall().once(); + + expect(mockDisplay.getNewCommentText()).andReturn(mockTargetCommentText).times(3); + expect(mockTargetCommentText.getText()).andReturn(newComment).times(2); + + expect(mockUserWorkspaceContext.hasGlossaryUpdateAccess()).andReturn(true).once(); + + expect(mockDisplay.getTargetCommentRowCount()).andReturn(rowNum); + + mockDisplay.addRowIntoTargetComment(rowNum, newComment); + expectLastCall().once(); + + mockTargetCommentText.setText(""); + expectLastCall().once(); + + replayAllMocks(); + + glossaryDetailsPresenter = new GlossaryDetailsPresenter(mockDisplay, mockEventBus, mockMessages, mockDispatcher, mockUserWorkspaceContext); + glossaryDetailsPresenter.bind(); + + ClickEvent clickEvent = createMock(ClickEvent.class); + capturedAddNewCommentButtonClickHandler.getValue().onClick(clickEvent); + + verifyAllMocks(); + } + + @Test + public void testAddNewCommentWithNoUpdateAccess() + { + String newComment = "new comment"; + boolean hasAccess = false; + + expect(mockUserWorkspaceContext.hasGlossaryUpdateAccess()).andReturn(hasAccess).times(2); + + mockDisplay.setHasUpdateAccess(hasAccess); + expectLastCall().once(); + + expect(mockDisplay.getNewCommentText()).andReturn(mockTargetCommentText).once(); + expect(mockTargetCommentText.getText()).andReturn(newComment).once(); + + replayAllMocks(); + + glossaryDetailsPresenter = new GlossaryDetailsPresenter(mockDisplay, mockEventBus, mockMessages, mockDispatcher, mockUserWorkspaceContext); + glossaryDetailsPresenter.bind(); + + ClickEvent clickEvent = createMock(ClickEvent.class); + capturedAddNewCommentButtonClickHandler.getValue().onClick(clickEvent); + + verifyAllMocks(); + } + + @Test + public void testAddNewCommentWithEmptyString() + { + String newComment = ""; + boolean hasAccess = false; + + expect(mockUserWorkspaceContext.hasGlossaryUpdateAccess()).andReturn(hasAccess).once(); + + mockDisplay.setHasUpdateAccess(hasAccess); + expectLastCall().once(); + + expect(mockDisplay.getNewCommentText()).andReturn(mockTargetCommentText).once(); + expect(mockTargetCommentText.getText()).andReturn(newComment).once(); + + replayAllMocks(); + + glossaryDetailsPresenter = new GlossaryDetailsPresenter(mockDisplay, mockEventBus, mockMessages, mockDispatcher, mockUserWorkspaceContext); + glossaryDetailsPresenter.bind(); + + ClickEvent clickEvent = createMock(ClickEvent.class); + capturedAddNewCommentButtonClickHandler.getValue().onClick(clickEvent); + + verifyAllMocks(); + } + + @Override + protected void setDefaultBindExpectations() + { + expect(mockDisplay.getDismissButton()).andReturn(mockDismissButton).once(); + expect(mockDismissButton.addClickHandler(capture(capturedDismissButtonClickHandler))).andReturn(createMock(HandlerRegistration.class)).once(); + + expect(mockDisplay.getSaveButton()).andReturn(mockSaveButton).once(); + expect(mockSaveButton.addClickHandler(capture(capturedSaveButtonClickHandler))).andReturn(createMock(HandlerRegistration.class)).once(); + + expect(mockDisplay.getAddNewCommentButton()).andReturn(mockAddNewCommentButton).anyTimes(); + expect(mockAddNewCommentButton.addClickHandler(capture(capturedAddNewCommentButtonClickHandler))).andReturn(createMock(HandlerRegistration.class)).once(); + + expect(mockDisplay.getEntryListBox()).andReturn(mockEntryListBox).once(); + expect(mockEntryListBox.addChangeHandler(capture(capturedEntryListBoxChangeHandler))).andReturn(createMock(HandlerRegistration.class)).once(); + } + +} diff --git a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyActivateWorkspaceCommand.java b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyActivateWorkspaceCommand.java index 333f626d21..4a4742f4de 100644 --- a/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyActivateWorkspaceCommand.java +++ b/zanata-war/src/test/java/org/zanata/webtrans/client/rpc/DummyActivateWorkspaceCommand.java @@ -33,7 +33,7 @@ public void execute() { Log.info("ENTER DummyActivateWorkspaceCommand.execute()"); WorkspaceContext context = new WorkspaceContext(action.getWorkspaceId(), "Dummy Workspace", "Mock Sweedish"); - UserWorkspaceContext userWorkspaceContext = new UserWorkspaceContext(context, true, true); + UserWorkspaceContext userWorkspaceContext = new UserWorkspaceContext(context, true, true, true); userWorkspaceContext.setSelectedDoc(new DocumentInfo(new DocumentId(1), "Dummy doc", "Dummy path", LocaleId.EN_US, null)); Identity identity = new Identity(new EditorClientId("123456", 1), new Person(new PersonId("bob"), "Bob The Builder", "http://www.gravatar.com/avatar/bob@zanata.org?d=mm&s=16"));