net.scran24.staff.client.StaffPage.java Source code

Java tutorial

Introduction

Here is the source code for net.scran24.staff.client.StaffPage.java

Source

/*
This file is part of Intake24.
    
 Crown copyright, 2012, 2013, 2014.
    
This software is licensed under the Open Government Licence 3.0:
    
http://www.nationalarchives.gov.uk/doc/open-government-licence/
*/

package net.scran24.staff.client;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import net.scran24.common.client.EmbeddedData;
import net.scran24.common.client.NavigationBar;
import net.scran24.common.client.UserInfoUpload;
import net.scran24.common.client.WidgetFactory;
import net.scran24.datastore.shared.SurveyParameters;
import net.scran24.datastore.shared.SurveyState;

import org.workcraft.gwt.shared.client.Callback1;
import org.workcraft.gwt.shared.client.Option;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.datepicker.client.DatePicker;

public class StaffPage implements EntryPoint {

    // private final PromptMessages messages = GWT.create(PromptMessages.class);

    private FlowPanel content;
    private RootPanel links;
    private SurveyControlServiceAsync surveyControl = SurveyControlServiceAsync.Util
            .getInstance(EmbeddedData.surveyId());
    private final String surveyId = EmbeddedData.surveyId();
    private SurveyParameters parameters;

    private void initStage1(final FlowPanel div) {
        div.add(new HTMLPanel("h2", "1. Set the start and end dates"));

        HorizontalPanel hpanel = new HorizontalPanel();

        hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
        hpanel.setSpacing(10);

        final DatePicker dateFrom = new DatePicker();
        final DatePicker dateTo = new DatePicker();

        hpanel.add(new Label("Start date:"));
        hpanel.add(dateFrom);
        hpanel.add(new Label("End date:"));
        hpanel.add(dateTo);

        final Button cont = WidgetFactory.createButton("Continue", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final long twelveHours = 12 * 60 * 60 * 1000;
                long timeFrom = dateFrom.getValue().getTime() - twelveHours;
                long timeTo = dateTo.getValue().getTime() + twelveHours;

                initStage2(timeFrom, timeTo, div);
            }
        });

        cont.setEnabled(false);
        cont.getElement().addClassName("scran24-admin-button");

        dateFrom.addValueChangeHandler(new ValueChangeHandler<Date>() {
            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                if (event.getValue() != null && dateTo.getValue() != null) {
                    cont.setEnabled(true);
                }
            }
        });

        dateTo.addValueChangeHandler(new ValueChangeHandler<Date>() {
            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                if (event.getValue() != null && dateFrom.getValue() != null) {
                    cont.setEnabled(true);
                }
            }
        });

        div.add(hpanel);
        div.add(cont);
    }

    private void initStage2(final long startDate, final long endDate, FlowPanel div) {
        div.clear();
        div.add(new HTMLPanel("h2", "2. Upload the respondent accounts"));

        final FlowPanel messageDiv = new FlowPanel();

        final Button start = WidgetFactory.createButton("Activate survey", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                surveyControl.getParameters(new AsyncCallback<SurveyParameters>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        messageDiv.clear();
                        messageDiv.getElement().getStyle().setColor("#d00");
                        messageDiv.add(new HTMLPanel(
                                SafeHtmlUtils.fromString("Survey could not be started: " + caught.getMessage())));
                    }

                    @Override
                    public void onSuccess(SurveyParameters result) {
                        surveyControl.setParameters(
                                result.withDates(startDate, endDate).withState(SurveyState.ACTIVE),
                                new AsyncCallback<Void>() {
                                    @Override
                                    public void onSuccess(Void result) {
                                        Location.reload();
                                    }

                                    @Override
                                    public void onFailure(Throwable caught) {
                                        messageDiv.clear();
                                        messageDiv.getElement().getStyle().setColor("#d00");
                                        messageDiv.add(new HTMLPanel(SafeHtmlUtils.fromString(
                                                "Survey could not be started: " + caught.getMessage())));
                                    }
                                });
                    }
                });

            }
        });

        start.getElement().addClassName("intake24-admin-button");
        start.setEnabled(false);

        List<String> permissions = Arrays.asList(new String[] { "processSurvey:" + surveyId });

        final UserInfoUpload userUpload = new UserInfoUpload(surveyId, "respondent", permissions,
                new Callback1<Option<String>>() {
                    @Override
                    public void call(Option<String> res) {
                        res.accept(new Option.SideEffectVisitor<String>() {
                            @Override
                            public void visitSome(String error) {
                                messageDiv.clear();
                                messageDiv.getElement().getStyle().setColor("#d00");
                                messageDiv.add(new HTMLPanel(SafeHtmlUtils.fromString(error)));
                                start.setEnabled(false);
                            }

                            @Override
                            public void visitNone() {
                                messageDiv.clear();
                                messageDiv.getElement().getStyle().setColor("#0d0");
                                messageDiv.add(new HTMLPanel(
                                        SafeHtmlUtils.fromString("Respondent accounts uploaded successfully")));
                                start.setEnabled(true);
                            }
                        });
                    }
                });

        div.add(userUpload);
        div.add(messageDiv);
        div.add(start);
    }

    private void showSurveyStatus() {
        content.clear();

        switch (parameters.state) {
        case SUSPENDED:
            content.add(new HTMLPanel("<h1>Survey is suspended</h1>"));
            content.add(new HTMLPanel(
                    "<h2>Reason</h2><p>" + SafeHtmlUtils.htmlEscape(parameters.suspensionReason) + "</p>"));

            Button resumeButton = WidgetFactory.createButton("Resume", new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    surveyControl.setParameters(parameters.withState(SurveyState.ACTIVE).withSuspensionReason(""),
                            new AsyncCallback<Void>() {
                                @Override
                                public void onFailure(Throwable caught) {
                                    content.clear();
                                    content.add(new HTMLPanel("<p>Server error: </p>" + caught.getMessage()));
                                }

                                @Override
                                public void onSuccess(Void result) {
                                    Location.reload();
                                }
                            });
                }
            });

            resumeButton.getElement().addClassName("scran24-admin-button");

            content.add(resumeButton);
            break;
        case NOT_INITIALISED:
            content.add(new HTMLPanel("<h1>Survey has not yet been activated</h1>"));
            content.add(new HTMLPanel("<p>Follow the instructions below to activate the survey."));

            FlowPanel initDiv = new FlowPanel();
            content.add(initDiv);

            initStage1(initDiv);
            break;
        case ACTIVE:
            Date now = new Date();

            boolean showSuspend = true;

            if (now.getTime() < parameters.startDate)
                content.add(new HTMLPanel("<h1>Survey is active, but not yet started</h1>"));
            else if (now.getTime() > parameters.endDate) {
                content.add(new HTMLPanel("<h1>Survey is finished</h1>"));
                showSuspend = false;
            } else
                content.add(new HTMLPanel("<h1>Survey is running</h1>"));

            content.add(new HTMLPanel("<h2>Start date (inclusive)</h2>"));
            content.add(new HTMLPanel(
                    "<p>" + DateTimeFormat.getFormat("EEE, MMMM d, yyyy").format(new Date(parameters.startDate))
                            + "</p>"));

            content.add(new HTMLPanel("<h2>End date (exclusive)</h2>"));
            content.add(new HTMLPanel("<p>"
                    + DateTimeFormat.getFormat("EEE, MMMM d, yyyy").format(new Date(parameters.endDate)) + "</p>"));

            if (showSuspend) {

                content.add(new HTMLPanel(SafeHtmlUtils.fromSafeConstant("<h3>Suspend survey</h3>")));
                content.add(new HTMLPanel(SafeHtmlUtils.fromSafeConstant("<p>Reason for suspension:</p>")));
                final TextBox reason = new TextBox();
                reason.getElement().getStyle().setWidth(600, Unit.PX);

                Button suspend = WidgetFactory.createButton("Suspend", new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        if (reason.getText().isEmpty()) {
                            Window.alert("Please give a reason for suspension.");
                        } else {
                            surveyControl.setParameters(parameters.withSuspensionReason(reason.getText())
                                    .withState(SurveyState.SUSPENDED), new AsyncCallback<Void>() {
                                        @Override
                                        public void onSuccess(Void result) {
                                            Location.reload();
                                        }

                                        @Override
                                        public void onFailure(Throwable caught) {
                                            Window.alert("Server error: " + caught.getMessage());
                                        }
                                    });
                        }
                    }
                });

                suspend.getElement().addClassName("scran24-admin-button");

                content.add(reason);
                content.add(new HTMLPanel("<p></p>"));
                content.add(suspend);
            }
            break;
        }
    }

    private void downloadData() {
        content.clear();
        content.add(new HTMLPanel("<h1>Download data</h1>"));
        final DownloadData download = new DownloadData();

        switch (parameters.state) {
        case SUSPENDED:
        case ACTIVE:
            download.dateFrom.setValue(new Date(parameters.startDate), true);
            download.dateTo.setValue(new Date(parameters.endDate), true);
            break;
        case NOT_INITIALISED:
            break;
        }
        content.add(download);
    }

    private void updateUsers() {
        content.clear();
        content.add(new HTMLPanel("<h2>Upload participant accounts from CSV</h2>"));
        content.add(new HTMLPanel(
                "<p><strong>Note:</strong> participant records from CSV files you upload using this page will be appended to the existing user list, which means that you can only add new accounts or update the passwords and custom fields for existing participants.</p><p>You <strong>cannot delete</strong> participant accounts from this page; if you need to delete existing participants please contact support.</p>"));

        final FlowPanel messageDiv = new FlowPanel();

        List<String> permissions = Arrays.asList(new String[] { "processSurvey:" + surveyId });

        final UserInfoUpload userUpload = new UserInfoUpload(surveyId, "respondent", permissions,
                new Callback1<Option<String>>() {
                    @Override
                    public void call(Option<String> res) {
                        res.accept(new Option.SideEffectVisitor<String>() {
                            @Override
                            public void visitSome(String error) {
                                messageDiv.clear();
                                messageDiv.getElement().getStyle().setColor("#d00");
                                messageDiv.add(new HTMLPanel(SafeHtmlUtils.fromString(error)));
                            }

                            @Override
                            public void visitNone() {
                                messageDiv.clear();
                                messageDiv.getElement().getStyle().setColor("#0d0");
                                messageDiv.add(new HTMLPanel(
                                        SafeHtmlUtils.fromString("Respondent accounts uploaded successfully")));
                            }
                        });
                    }
                });

        content.add(messageDiv);
        content.add(userUpload);
    }

    private void updateSchedule() {
        content.clear();
        content.add(new HTMLPanel("<h1>Update schedule</h1>"));
        HorizontalPanel hpanel = new HorizontalPanel();

        hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
        hpanel.setSpacing(10);

        final DatePicker dateFrom = new DatePicker();
        final DatePicker dateTo = new DatePicker();

        final Button update = WidgetFactory.createButton("Update", new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final long twelveHours = 12 * 60 * 60 * 1000;
                final long timeFrom = dateFrom.getValue().getTime() - twelveHours;
                final long timeTo = dateTo.getValue().getTime() + twelveHours;

                surveyControl.getParameters(new AsyncCallback<SurveyParameters>() {
                    @Override
                    public void onFailure(Throwable caught) {
                        content.clear();
                        content.add(new HTMLPanel("<p>Server error: </p>" + caught.getMessage()));
                    }

                    @Override
                    public void onSuccess(SurveyParameters result) {
                        surveyControl.setParameters(result.withDates(timeFrom, timeTo), new AsyncCallback<Void>() {
                            @Override
                            public void onFailure(Throwable caught) {
                                content.clear();
                                content.add(new HTMLPanel("<p>Server error: </p>" + caught.getMessage()));
                            }

                            @Override
                            public void onSuccess(Void result) {
                                Location.reload();
                            }
                        });
                    }
                });
            }
        });

        update.getElement().addClassName("scran24-admin-button");

        dateFrom.addValueChangeHandler(new ValueChangeHandler<Date>() {
            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                if (event.getValue() != null && dateTo.getValue() != null) {
                    update.setEnabled(true);
                }
            }
        });

        dateTo.addValueChangeHandler(new ValueChangeHandler<Date>() {
            @Override
            public void onValueChange(ValueChangeEvent<Date> event) {
                if (event.getValue() != null && dateFrom.getValue() != null) {
                    update.setEnabled(true);
                }
            }
        });

        update.setEnabled(false);

        switch (parameters.state) {
        case SUSPENDED:
        case ACTIVE:
            dateFrom.setValue(new Date(parameters.startDate), true);
            dateTo.setValue(new Date(parameters.endDate), true);
            break;
        case NOT_INITIALISED:
            break;
        }

        hpanel.add(new Label("Start date:"));
        hpanel.add(dateFrom);
        hpanel.add(new Label("End date:"));
        hpanel.add(dateTo);

        content.add(hpanel);
        content.add(update);
    }

    @Override
    public void onModuleLoad() {
        final Element loading = Document.get().getElementById("loading");
        links = RootPanel.get("navigation-bar");

        RootPanel contentDiv = RootPanel.get("main-content");
        content = new FlowPanel();
        content.addStyleName("intake24-staff-ui-container");
        contentDiv.add(content);

        surveyControl.getParameters(new AsyncCallback<SurveyParameters>() {
            @Override
            public void onSuccess(SurveyParameters result) {
                parameters = result;

                final Anchor downloadData = new Anchor("Download data");
                downloadData.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        downloadData();
                    }
                });

                final Anchor surveyCtl = new Anchor("Survey control");
                surveyCtl.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        showSurveyStatus();
                    }
                });

                final Anchor updateUsers = new Anchor("Create participant accounts");
                updateUsers.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        updateUsers();
                    }
                });

                final Anchor updateSchedule = new Anchor("Update schedule");
                updateSchedule.addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        updateSchedule();
                    }
                });

                links.clear();
                links.add(new NavigationBar(downloadData, surveyCtl, updateUsers, updateSchedule,
                        new Anchor("Log out", "../../../common/logout" + Location.getQueryString())));

                showSurveyStatus();
                loading.removeFromParent();
            }

            @Override
            public void onFailure(Throwable caught) {
                content.clear();
                content.add(new HTMLPanel("<p>Server error</p?" + caught.getMessage()));
                loading.removeFromParent();
            }
        });
    }
}