2 * Copyright 2011 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
35 package gr.grnet.pithos.web.client;
37 import gr.grnet.pithos.web.client.foldertree.Resource;
38 import gr.grnet.pithos.web.client.rest.PostRequest;
40 import com.google.gwt.core.client.GWT;
41 import com.google.gwt.core.client.Scheduler;
42 import com.google.gwt.dom.client.NativeEvent;
43 import com.google.gwt.event.dom.client.ClickEvent;
44 import com.google.gwt.event.dom.client.ClickHandler;
45 import com.google.gwt.event.dom.client.KeyCodes;
46 import com.google.gwt.http.client.Response;
47 import com.google.gwt.user.client.Event.NativePreviewEvent;
48 import com.google.gwt.user.client.ui.Anchor;
49 import com.google.gwt.user.client.ui.Button;
50 import com.google.gwt.user.client.ui.DialogBox;
51 import com.google.gwt.user.client.ui.FlexTable;
52 import com.google.gwt.user.client.ui.HTML;
53 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
54 import com.google.gwt.user.client.ui.HorizontalPanel;
55 import com.google.gwt.user.client.ui.Image;
56 import com.google.gwt.user.client.ui.TextBox;
57 import com.google.gwt.user.client.ui.VerticalPanel;
58 import com.google.gwt.user.client.ui.Widget;
62 * A dialog box that displays info about invitations
64 public class InvitationsDialog extends DialogBox {
65 private static final int INV_PER_PAGE = 5;
68 VerticalPanel messagesPanel;
70 FlexTable sentInvitationsTable;
72 * The current displayed page of sent invitations
75 HorizontalPanel pagerPanel;
77 * The widget constructor.
79 public InvitationsDialog(Pithos _app, final Invitations inv) {
81 Anchor close = new Anchor();
82 close.addStyleName("close");
83 close.addClickHandler(new ClickHandler() {
86 public void onClick(ClickEvent event) {
90 // Set the dialog's caption.
91 setText("Invite friends");
92 setAnimationEnabled(true);
93 setGlassEnabled(true);
94 setStyleName("pithos-DialogBox");
95 VerticalPanel outer = new VerticalPanel();
96 outer.addStyleName("outer");
97 outer.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
99 VerticalPanel inner = new VerticalPanel();
100 inner.addStyleName("inner");
101 // Create the text and set a style name so we can style it with CSS.
102 HTML text = new HTML("You have <span class='pithos-leftInvitationsNumber'>" + inv.getInvitationsLeft() + "</span> invitations left");
103 text.addStyleName("pithos-invitationsLeft");
106 HorizontalPanel split = new HorizontalPanel();
107 split.addStyleName("pithos-invitationsSplitPanel");
109 VerticalPanel left = new VerticalPanel();
110 left.addStyleName("pithos-sendInvitationsPanel");
111 left.setVisible(inv.getInvitationsLeft() > 0);
113 HorizontalPanel sendLabelPanel = new HorizontalPanel();
114 HTML sendLabel = new HTML("Send new invitations");
115 sendLabel.addStyleName("pithos-sendInvitationsTitle");
116 sendLabelPanel.add(sendLabel);
117 Image plus = new Image("images/plus.png");
118 plus.addStyleName("pithos-addInvitationImg");
119 sendLabelPanel.add(plus);
120 left.add(sendLabelPanel);
122 messagesPanel = new VerticalPanel();
123 messagesPanel.setSpacing(5);
124 left.add(messagesPanel);
126 final FlexTable table = new FlexTable();
127 table.setCellSpacing(0);
128 if (inv.getInvitationsLeft() > 0) {
129 table.setHTML(0, 0, "Name <span class='eg'>e.g. John Smith</span>");
130 table.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
131 table.setText(0, 1, "Email");
132 table.getFlexCellFormatter().setStyleName(0, 1, "props-labels");
137 plus.addClickHandler(new ClickHandler() {
140 public void onClick(ClickEvent event) {
142 table.setHTML(0, 0, "Name <span class='eg'>e.g. John Smith</span>");
143 table.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
144 table.setText(0, 1, "Email");
145 table.getFlexCellFormatter().setStyleName(0, 1, "props-labels");
152 Button send = new Button("send invitations", new ClickHandler() {
154 public void onClick(ClickEvent event) {
155 int rowCount = table.getRowCount();
157 for (int i = 1; i<rowCount; i++) {
158 String name = ((TextBox) table.getWidget(i, 0)).getText().trim();
159 String email = ((TextBox) table.getWidget(i, 1)).getText().trim();
160 sendInvitation(email, name);
164 send.addStyleName("pithos-sendInvitationButton");
165 send.setVisible(inv.getInvitationsLeft() > 0);
169 split.setCellWidth(left, "50%");
171 VerticalPanel right = new VerticalPanel();
172 right.addStyleName("pithos-sentInvitationsPanel");
174 HTML sentLabel = new HTML("Invitations sent");
175 sentLabel.addStyleName("pithos-sentInvitationsTitle");
176 right.add(sentLabel);
178 sentInvitationsTable = new FlexTable();
179 sentInvitationsTable.setCellSpacing(0);
180 sentInvitationsTable.addStyleName("pithos-sentInvitationsTable");
181 fillSentInvitationsTable(inv);
182 right.add(sentInvitationsTable);
184 pagerPanel = new HorizontalPanel();
185 pagerPanel.setSpacing(5);
186 Button prev = new Button("Prev");
187 prev.addStyleName("pithos-pagerButton");
188 prev.addClickHandler(new ClickHandler() {
191 public void onClick(ClickEvent event) {
192 if (currentPage > 0) {
193 pagerPanel.getWidget(currentPage + 1).removeStyleName("pithos-pagerButtonCurrent");
195 fillSentInvitationsTable(inv);
196 pagerPanel.getWidget(currentPage + 1).addStyleName("pithos-pagerButtonCurrent");
200 pagerPanel.add(prev);
201 Button next = new Button("Next");
202 next.addStyleName("pithos-pagerButton");
203 next.addClickHandler(new ClickHandler() {
206 public void onClick(ClickEvent event) {
207 int numOfInvs = inv.getSentInvitations().size();
208 int numOfPages = numOfInvs / INV_PER_PAGE + (numOfInvs % INV_PER_PAGE == 0 ? 0 : 1);
209 if (currentPage < numOfPages - 1) {
210 pagerPanel.getWidget(currentPage + 1).removeStyleName("pithos-pagerButtonCurrent");
212 pagerPanel.getWidget(currentPage + 1).addStyleName("pithos-pagerButtonCurrent");
213 fillSentInvitationsTable(inv);
217 pagerPanel.add(next);
218 right.add(pagerPanel);
219 updatePagerPanel(inv);
227 outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
231 private void addFormLine(final FlexTable table) {
232 table.setWidget(rows, 0, new TextBox());
233 table.getFlexCellFormatter().setStyleName(1, 0, "props-values");
235 table.setWidget(rows, 1, new TextBox());
236 table.getFlexCellFormatter().setStyleName(1, 1, "props-values");
238 Image delete = new Image("images/delete.png");
239 delete.addStyleName("pithos-invitationDeleteImg");
240 delete.addClickHandler(new ClickHandler() {
243 public void onClick(ClickEvent event) {
244 int rowIndex = table.getCellForEvent(event).getRowIndex();
245 table.removeRow(rowIndex);
246 if (rowIndex == 1 && table.getRowCount() > 1) {
247 table.getCellFormatter().removeStyleName(rowIndex, 0, "pithos-invitationFormRow");
248 table.getCellFormatter().removeStyleName(rowIndex, 1, "pithos-invitationFormRow");
249 table.getCellFormatter().removeStyleName(rowIndex, 2, "pithos-invitationFormRow");
254 table.setWidget(rows, 2, delete);
257 table.getCellFormatter().addStyleName(rows, 0, "pithos-invitationFormRow");
258 table.getCellFormatter().addStyleName(rows, 1, "pithos-invitationFormRow");
259 table.getCellFormatter().addStyleName(rows, 2, "pithos-invitationFormRow");
264 void sendInvitation(String email, final String realname) {
265 if (realname == null || realname.length() == 0) {
266 HTML msg = new HTML("Name cannot be empty");
267 msg.addStyleName("pithos-invitationResponseError");
268 messagesPanel.add(msg);
270 else if (email == null || email.length() == 0 || !email.contains("@") ||
271 email.substring(email.indexOf("@")).length() < 4 || !email.substring(email.indexOf("@") + 2).contains(".")) {
272 HTML msg = new HTML("Invalid email");
273 msg.addStyleName("pithos-invitationResponseError");
274 messagesPanel.add(msg);
277 PostRequest sendInvitation = new PostRequest("/im/", "", "invite", "uniq=" + email + "&realname=" + realname) {
280 protected void onUnauthorized(Response response) {
281 app.sessionExpired();
285 public void onSuccess(Resource result) {
286 HTML msg = new HTML("Invitation to <span class='user'>" + realname + "</span> was sent.");
287 msg.addStyleName("pithos-invitationResponse");
288 messagesPanel.add(msg);
292 public void onError(Throwable t) {
296 sendInvitation.setHeader("X-Auth-Token", app.getToken());
297 Scheduler.get().scheduleDeferred(sendInvitation);
301 void fillSentInvitationsTable(Invitations inv) {
302 sentInvitationsTable.removeAllRows();
304 for (int j=currentPage * INV_PER_PAGE + 0; j<inv.getSentInvitations().size() && j<(currentPage + 1)* INV_PER_PAGE; j++) {
305 final Invitation i = inv.getSentInvitations().get(j);
306 sentInvitationsTable.setText(row, 0, i.getRealname());
308 sentInvitationsTable.setWidget(row, 1, new Image("images/invitation_accepted.png"));
310 Image img = new Image("images/resend.png");
311 img.addStyleName("pithos-resendInvitation");
312 img.addClickHandler(new ClickHandler() {
315 public void onClick(ClickEvent event) {
316 sendInvitation(i.getEmail(), i.getRealname());
319 sentInvitationsTable.setWidget(row, 1, img);
321 sentInvitationsTable.getFlexCellFormatter().setRowSpan(row, 1, 2);
322 sentInvitationsTable.getFlexCellFormatter().setHorizontalAlignment(row, 1, HasHorizontalAlignment.ALIGN_RIGHT);
323 if (j < inv.getSentInvitations().size() - 1 && j < (currentPage + 1)* INV_PER_PAGE - 1)
324 sentInvitationsTable.getFlexCellFormatter().addStyleName(row, 1, "pithos-invitedEmailBorder");
326 sentInvitationsTable.setText(row, 0, i.getEmail());
327 sentInvitationsTable.getFlexCellFormatter().addStyleName(row, 0, "pithos-invitedEmail");
328 if (j < inv.getSentInvitations().size() - 1 && j < (currentPage + 1)* INV_PER_PAGE - 1)
329 sentInvitationsTable.getFlexCellFormatter().addStyleName(row, 0, "pithos-invitedEmailBorder");
334 void updatePagerPanel(final Invitations inv) {
335 int numOfInvitations = inv.getSentInvitations().size();
336 int numOfPages = numOfInvitations / INV_PER_PAGE + (numOfInvitations % INV_PER_PAGE == 0 ? 0 : 1);
337 for (int i=0; i<numOfPages; i++) {
338 final Button page = new Button(String.valueOf(i + 1));
339 page.addStyleName("pithos-pagerButton");
340 if (i == currentPage)
341 page.addStyleName("pithos-pagerButtonCurrent");
344 page.addClickHandler(new ClickHandler() {
347 public void onClick(ClickEvent event) {
348 pagerPanel.getWidget(currentPage + 1).removeStyleName("pithos-pagerButtonCurrent");
350 fillSentInvitationsTable(inv);
351 page.addStyleName("pithos-pagerButtonCurrent");
354 pagerPanel.insert(page, i + 1);