You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2016/03/31 17:28:58 UTC
[04/10] syncope git commit: [SYNCOPE-765] TODO -> Approval
[SYNCOPE-765] TODO -> Approval
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/ef80e015
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/ef80e015
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/ef80e015
Branch: refs/heads/master
Commit: ef80e01536b131ea818d84df9d8bd6b4a41824ed
Parents: e29d78c
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Mar 31 14:09:50 2016 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Mar 31 14:09:50 2016 +0200
----------------------------------------------------------------------
.../client/console/approvals/Approval.java | 206 ++++++++++++++
.../console/approvals/ApprovalDetails.java | 48 ++++
.../client/console/approvals/ApprovalModal.java | 83 ++++++
.../approvals/ApprovalSearchResultPanel.java | 215 ++++++++++++++
.../syncope/client/console/pages/Approvals.java | 41 +++
.../syncope/client/console/pages/BasePage.java | 8 +-
.../syncope/client/console/pages/TODOs.java | 41 ---
.../syncope/client/console/todos/Approval.java | 206 --------------
.../client/console/todos/ApprovalDetails.java | 48 ----
.../client/console/todos/ApprovalModal.java | 83 ------
.../console/todos/TODOSearchResultPanel.java | 215 --------------
.../client/console/widgets/ApprovalsWidget.java | 284 +++++++++++++++++++
.../client/console/widgets/TODOsWidget.java | 283 ------------------
.../SyncopeConsoleApplication.properties | 1 -
.../SyncopeConsoleApplication_it.properties | 1 -
.../SyncopeConsoleApplication_pt_BR.properties | 1 -
.../client/console/approvals/Approval.html | 34 +++
.../console/approvals/Approval.properties | 17 ++
.../console/approvals/ApprovalDetails.html | 26 ++
.../client/console/approvals/ApprovalModal.html | 26 ++
.../console/approvals/ApprovalModal.properties | 17 ++
.../console/approvals/Approval_it.properties | 17 ++
.../console/approvals/Approval_pt_BR.properties | 17 ++
.../syncope/client/console/pages/Approvals.html | 35 +++
.../client/console/pages/Approvals.properties | 32 +++
.../console/pages/Approvals_it.properties | 32 +++
.../console/pages/Approvals_pt_BR.properties | 32 +++
.../syncope/client/console/pages/BasePage.html | 2 +-
.../syncope/client/console/pages/TODOs.html | 35 ---
.../client/console/pages/TODOs.properties | 32 ---
.../client/console/pages/TODOs_it.properties | 32 ---
.../client/console/pages/TODOs_pt_BR.properties | 32 ---
.../syncope/client/console/todos/Approval.html | 34 ---
.../client/console/todos/Approval.properties | 17 --
.../client/console/todos/ApprovalDetails.html | 26 --
.../client/console/todos/ApprovalModal.html | 26 --
.../console/todos/ApprovalModal.properties | 17 --
.../client/console/todos/Approval_it.properties | 17 --
.../console/todos/Approval_pt_BR.properties | 17 --
.../client/console/widgets/ApprovalsWidget.html | 45 +++
.../console/widgets/ApprovalsWidget.properties | 21 ++
.../widgets/ApprovalsWidget_it.properties | 21 ++
.../widgets/ApprovalsWidget_pt_BR.properties | 21 ++
.../client/console/widgets/TODOsWidget.html | 48 ----
.../console/widgets/TODOsWidget.properties | 21 --
.../console/widgets/TODOsWidget_it.properties | 21 --
.../widgets/TODOsWidget_pt_BR.properties | 21 --
.../syncope/fit/console/AnyObjectsITCase.java | 7 +-
.../syncope/fit/console/BulkActionITCase.java | 1 -
.../syncope/fit/console/GroupsITCase.java | 5 +-
.../apache/syncope/fit/console/LogsITCase.java | 2 -
.../syncope/fit/console/ParametersITCase.java | 2 -
.../apache/syncope/fit/console/RolesITCase.java | 2 -
.../fit/console/SecurityQuestionsITCase.java | 3 -
.../apache/syncope/fit/console/UsersITCase.java | 5 +-
55 files changed, 1282 insertions(+), 1300 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
new file mode 100644
index 0000000..b084d48
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/Approval.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.approvals;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.syncope.client.console.commons.MapChoiceRenderer;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.DateTimeFieldPanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class Approval extends Panel {
+
+ private static final long serialVersionUID = -8847854414429745216L;
+
+ protected static final Logger LOG = LoggerFactory.getLogger(Approval.class);
+
+ public Approval(final PageReference pageRef, final WorkflowFormTO formTO) {
+ super(MultilevelPanel.FIRST_LEVEL_ID);
+
+ IModel<List<WorkflowFormPropertyTO>> formProps = new LoadableDetachableModel<List<WorkflowFormPropertyTO>>() {
+
+ private static final long serialVersionUID = 3169142472626817508L;
+
+ @Override
+ protected List<WorkflowFormPropertyTO> load() {
+ return formTO.getProperties();
+ }
+ };
+
+ final ListView<WorkflowFormPropertyTO> propView = new ListView<WorkflowFormPropertyTO>("propView", formProps) {
+
+ private static final long serialVersionUID = 9101744072914090143L;
+
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected void populateItem(final ListItem<WorkflowFormPropertyTO> item) {
+ final WorkflowFormPropertyTO prop = item.getModelObject();
+
+ String label = StringUtils.isBlank(prop.getName()) ? prop.getId() : prop.getName();
+
+ FieldPanel field;
+ switch (prop.getType()) {
+ case Boolean:
+ field = new AjaxDropDownChoicePanel("value", label, new PropertyModel<String>(prop, "value") {
+
+ private static final long serialVersionUID = -3743432456095828573L;
+
+ @Override
+ public String getObject() {
+ return StringUtils.isBlank(prop.getValue())
+ ? null
+ : prop.getValue().equals("true") ? "Yes" : "No";
+ }
+
+ @Override
+ public void setObject(final String object) {
+ prop.setValue(String.valueOf(object.equalsIgnoreCase("yes")));
+ }
+
+ }, false).setChoices(Arrays.asList(new String[] { "Yes", "No" }));
+ break;
+
+ case Date:
+ final FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
+ field = new DateTimeFieldPanel("value", label, new PropertyModel<Date>(prop, "value") {
+
+ private static final long serialVersionUID = -3743432456095828573L;
+
+ @Override
+ public Date getObject() {
+ try {
+ if (StringUtils.isBlank(prop.getValue())) {
+ return null;
+ } else {
+ return formatter.parse(prop.getValue());
+ }
+ } catch (ParseException e) {
+ LOG.error("Unparsable date: {}", prop.getValue(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public void setObject(final Date object) {
+ prop.setValue(formatter.format(object));
+ }
+
+ }, prop.getDatePattern());
+ break;
+
+ case Enum:
+ MapChoiceRenderer<String, String> enumCR = new MapChoiceRenderer<>(prop.getEnumValues());
+ final Map<String, String> map = MapUtils.invertMap(prop.getEnumValues());
+
+ field = new AjaxDropDownChoicePanel(
+ "value", label, new PropertyModel<String>(prop, "value"), false).
+ setChoiceRenderer(enumCR).setChoices(new Model<ArrayList<String>>() {
+
+ private static final long serialVersionUID = -858521070366432018L;
+
+ @Override
+ public ArrayList<String> getObject() {
+ return new ArrayList<>(prop.getEnumValues().keySet());
+ }
+ });
+ break;
+
+ case Long:
+ field = new AjaxSpinnerFieldPanel.Builder<Long>().build(
+ "value",
+ label,
+ Long.class,
+ new PropertyModel<Long>(prop, "value") {
+
+ private static final long serialVersionUID = -7688359318035249200L;
+
+ @Override
+ public Long getObject() {
+ return StringUtils.isBlank(prop.getValue())
+ ? null
+ : NumberUtils.toLong(prop.getValue());
+ }
+
+ @Override
+ public void setObject(final Long object) {
+ prop.setValue(String.valueOf(object));
+ }
+ });
+ break;
+
+ case String:
+ default:
+ field = new AjaxTextFieldPanel("value", label, new PropertyModel<String>(prop, "value"), false);
+ break;
+ }
+
+ field.setReadOnly(!prop.isWritable());
+ if (prop.isRequired()) {
+ field.addRequiredLabel();
+ }
+
+ item.add(field);
+ }
+ };
+
+ final AjaxLink<String> userDetails = new AjaxLink<String>("userDetails") {
+
+ private static final long serialVersionUID = -4804368561204623354L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ viewDetails(formTO, target);
+ }
+ };
+ MetaDataRoleAuthorizationStrategy.authorize(userDetails, ENABLE, StandardEntitlement.USER_READ);
+
+ add(propView);
+ add(userDetails);
+ }
+
+ protected abstract void viewDetails(final WorkflowFormTO formTO, final AjaxRequestTarget target);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java
new file mode 100644
index 0000000..ec8cbcf
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDetails.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.approvals;
+
+import java.util.List;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
+import org.apache.syncope.client.console.rest.UserRestClient;
+import org.apache.syncope.client.console.wizards.AjaxWizard;
+import org.apache.syncope.client.console.wizards.any.AnyHandler;
+import org.apache.syncope.client.console.wizards.any.UserWizardBuilder;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.wicket.PageReference;
+
+public class ApprovalDetails extends MultilevelPanel.SecondLevel {
+
+ private static final long serialVersionUID = -8847854414429745216L;
+
+ public ApprovalDetails(final PageReference pageRef, final WorkflowFormTO formTO) {
+ super(MultilevelPanel.SECOND_LEVEL_ID);
+
+ final UserTO userTO = new UserRestClient().read(formTO.getUserKey());
+ final List<String> anyTypeClasses = new AnyTypeRestClient().get(AnyTypeKind.USER.name()).getClasses();
+
+ final AjaxWizard<AnyHandler<UserTO>> wizard
+ = new UserWizardBuilder("wizard", userTO, anyTypeClasses, pageRef).build(AjaxWizard.Mode.READONLY);
+
+ add(wizard);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
new file mode 100644
index 0000000..f5367cf
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalModal.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.approvals;
+
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.panels.ModalPanel;
+import org.apache.syncope.client.console.panels.MultilevelPanel;
+import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
+import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Panel;
+
+public class ApprovalModal extends Panel implements ModalPanel<WorkflowFormTO> {
+
+ private static final long serialVersionUID = -8847854414429745216L;
+
+ private final BaseModal<?> modal;
+
+ private final WorkflowFormTO formTO;
+
+ public ApprovalModal(final BaseModal<?> modal, final PageReference pageRef, final WorkflowFormTO formTO) {
+ super(BaseModal.CONTENT_ID);
+ this.modal = modal;
+ this.formTO = formTO;
+
+ final MultilevelPanel mlp = new MultilevelPanel("approval");
+ add(mlp);
+
+ mlp.setFirstLevel(new Approval(pageRef, formTO) {
+
+ private static final long serialVersionUID = -2195387360323687302L;
+
+ @Override
+ protected void viewDetails(final WorkflowFormTO formTO, final AjaxRequestTarget target) {
+ mlp.next(getString("approval.details"), new ApprovalDetails(pageRef, formTO), target);
+ }
+ });
+ }
+
+ @Override
+ public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
+ try {
+ new UserWorkflowRestClient().submitForm(formTO);
+ this.modal.show(false);
+ this.modal.close(target);
+ SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (SyncopeClientException e) {
+ SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
+ }
+ SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+ }
+
+ @Override
+ public void onError(final AjaxRequestTarget target, final Form<?> form) {
+ SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+ }
+
+ @Override
+ public WorkflowFormTO getItem() {
+ return this.formTO;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
new file mode 100644
index 0000000..2d97bf0
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalSearchResultPanel.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.approvals;
+
+import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.commons.Constants;
+import org.apache.syncope.client.console.commons.SearchableDataProvider;
+import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
+import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
+import org.apache.syncope.client.console.approvals.ApprovalSearchResultPanel.ApprovalProvider;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
+import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
+import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
+import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
+import org.apache.wicket.model.AbstractReadOnlyModel;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.model.ResourceModel;
+
+public class ApprovalSearchResultPanel
+ extends AbstractSearchResultPanel<WorkflowFormTO, WorkflowFormTO, ApprovalProvider, UserWorkflowRestClient> {
+
+ private static final long serialVersionUID = -7122136682275797903L;
+
+ public ApprovalSearchResultPanel(final String id, final PageReference pageReference) {
+ super(id, pageReference, false);
+ disableCheckBoxes();
+
+ setFooterVisibility(true);
+ modal.addSumbitButton();
+ modal.size(Modal.Size.Large);
+
+ restClient = new UserWorkflowRestClient();
+
+ initResultTable();
+
+ MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
+ }
+
+ @Override
+ protected List<IColumn<WorkflowFormTO, String>> getColumns() {
+
+ List<IColumn<WorkflowFormTO, String>> columns = new ArrayList<>();
+ columns.add(new PropertyColumn<WorkflowFormTO, String>(
+ new ResourceModel("taskId"), "taskId", "taskId"));
+ columns.add(new PropertyColumn<WorkflowFormTO, String>(
+ new ResourceModel("key"), "key", "key"));
+ columns.add(new PropertyColumn<WorkflowFormTO, String>(
+ new ResourceModel("description"), "description", "description"));
+ columns.add(new DatePropertyColumn<WorkflowFormTO>(
+ new ResourceModel("createTime"), "createTime", "createTime"));
+ columns.add(new DatePropertyColumn<WorkflowFormTO>(
+ new ResourceModel("dueDate"), "dueDate", "dueDate"));
+ columns.add(new PropertyColumn<WorkflowFormTO, String>(new ResourceModel("owner"), "owner", "owner"));
+ columns.add(new ActionColumn<WorkflowFormTO, String>(new ResourceModel("actions")) {
+
+ private static final long serialVersionUID = -3503023501954863133L;
+
+ @Override
+ public ActionLinksPanel<WorkflowFormTO> getActions(
+ final String componentId, final IModel<WorkflowFormTO> model) {
+ final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
+
+ panel.add(new ActionLink<WorkflowFormTO>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+ try {
+ restClient.claimForm(model.getObject().getTaskId());
+ info(getString(Constants.OPERATION_SUCCEEDED));
+ } catch (SyncopeClientException scee) {
+ error(getString(Constants.ERROR) + ": " + scee.getMessage());
+ }
+ SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
+ target.add(container);
+ }
+ }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
+
+ panel.add(new ActionLink<WorkflowFormTO>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+ final IModel<WorkflowFormTO> formModel = new CompoundPropertyModel<>(model.getObject());
+ modal.setFormModel(formModel);
+
+ target.add(modal.setContent(new ApprovalModal(modal, pageRef, model.getObject())));
+ modal.header(new Model<>(getString("approval.edit", new Model<>(model.getObject()))));
+
+ modal.show(true);
+ }
+
+ @Override
+ protected boolean statusCondition(final WorkflowFormTO modelObject) {
+ return SyncopeConsoleSession.get().getSelfTO().getUsername().
+ equals(model.getObject().getOwner());
+ }
+
+ }, ActionLink.ActionType.EDIT, StandardEntitlement.WORKFLOW_FORM_READ);
+
+ return panel.build(componentId);
+ }
+
+ @Override
+ public ActionLinksPanel<WorkflowFormTO> getHeader(final String componentId) {
+ final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
+
+ return panel.add(new ActionLink<WorkflowFormTO>() {
+
+ private static final long serialVersionUID = -7978723352517770644L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
+ if (target != null) {
+ target.add(container);
+ }
+ }
+ }, ActionLink.ActionType.RELOAD, StandardEntitlement.WORKFLOW_FORM_LIST).build(componentId);
+ }
+ });
+
+ return columns;
+ }
+
+ @Override
+ protected ApprovalProvider dataProvider() {
+ return new ApprovalProvider(rows);
+ }
+
+ @Override
+ protected String paginatorRowsKey() {
+ return Constants.PREF_WORKFLOW_FORM_PAGINATOR_ROWS;
+ }
+
+ public static class ApprovalProvider extends SearchableDataProvider<WorkflowFormTO> {
+
+ private static final long serialVersionUID = -2311716167583335852L;
+
+ private final SortableDataProviderComparator<WorkflowFormTO> comparator;
+
+ private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
+
+ public ApprovalProvider(final int paginatorRows) {
+ super(paginatorRows);
+ setSort("createTime", SortOrder.DESCENDING);
+ this.comparator = new SortableDataProviderComparator<>(this);
+ }
+
+ @Override
+ public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
+ final List<WorkflowFormTO> list = restClient.getForms();
+ Collections.sort(list, comparator);
+ return list.subList((int) first, (int) first + (int) count).iterator();
+ }
+
+ @Override
+ public long size() {
+ return restClient.getForms().size();
+ }
+
+ @Override
+ public IModel<WorkflowFormTO> model(final WorkflowFormTO configuration) {
+ return new AbstractReadOnlyModel<WorkflowFormTO>() {
+
+ private static final long serialVersionUID = -2566070996511906708L;
+
+ @Override
+ public WorkflowFormTO getObject() {
+ return configuration;
+ }
+ };
+ }
+ }
+
+ @Override
+ protected Collection<ActionLink.ActionType> getBulkActions() {
+ return Collections.<ActionLink.ActionType>emptyList();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
new file mode 100644
index 0000000..a93d7c3
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Approvals.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.pages;
+
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.approvals.ApprovalSearchResultPanel;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public class Approvals extends BasePage {
+
+ private static final long serialVersionUID = -1100228004207271271L;
+
+ public Approvals(final PageParameters parameters) {
+ super(parameters);
+
+ body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
+
+ WebMarkupContainer content = new WebMarkupContainer("content");
+ content.setOutputMarkupId(true);
+ body.add(content);
+
+ content.add(new ApprovalSearchResultPanel("wfPanel", getPageReference()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
index 44fc786..334b095 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/BasePage.java
@@ -30,7 +30,7 @@ import org.apache.syncope.client.console.panels.NotificationPanel;
import org.apache.syncope.client.console.topology.Topology;
import org.apache.syncope.client.console.wicket.markup.head.MetaHeaderItem;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.client.console.widgets.TODOsWidget;
+import org.apache.syncope.client.console.widgets.ApprovalsWidget;
import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
@@ -96,7 +96,7 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
body.add(new Label("version", SyncopeConsoleApplication.get().getVersion()));
body.add(new Label("username", SyncopeConsoleSession.get().getSelfTO().getUsername()));
- body.add(new TODOsWidget("todosWidget", getPageReference()).setRenderBodyOnly(true));
+ body.add(new ApprovalsWidget("approvalsWidget", getPageReference()).setRenderBodyOnly(true));
// menu
WebMarkupContainer liContainer = new WebMarkupContainer(getLIContainerId("dashboard"));
@@ -239,8 +239,8 @@ public class BasePage extends WebPage implements IAjaxIndicatorAware {
}
// Extensions
- ClassPathScanImplementationLookup classPathScanImplementationLookup
- = (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
+ ClassPathScanImplementationLookup classPathScanImplementationLookup =
+ (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
List<Class<? extends BaseExtPage>> extPageClasses = classPathScanImplementationLookup.getExtPageClasses();
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/pages/TODOs.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/TODOs.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/TODOs.java
deleted file mode 100644
index ac51ba0..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/pages/TODOs.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.pages;
-
-import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.todos.TODOSearchResultPanel;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-
-public class TODOs extends BasePage {
-
- private static final long serialVersionUID = -1100228004207271271L;
-
- public TODOs(final PageParameters parameters) {
- super(parameters);
-
- body.add(BookmarkablePageLinkBuilder.build("dashboard", "dashboardBr", Dashboard.class));
-
- WebMarkupContainer content = new WebMarkupContainer("content");
- content.setOutputMarkupId(true);
- body.add(content);
-
- content.add(new TODOSearchResultPanel("wfPanel", getPageReference()));
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/todos/Approval.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/todos/Approval.java b/client/console/src/main/java/org/apache/syncope/client/console/todos/Approval.java
deleted file mode 100644
index 9e5e3ac..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/todos/Approval.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.todos;
-
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.apache.commons.lang3.time.FastDateFormat;
-import org.apache.syncope.client.console.commons.MapChoiceRenderer;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxSpinnerFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.DateTimeFieldPanel;
-import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
-import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.PropertyModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class Approval extends Panel {
-
- private static final long serialVersionUID = -8847854414429745216L;
-
- protected static final Logger LOG = LoggerFactory.getLogger(Approval.class);
-
- public Approval(final PageReference pageRef, final WorkflowFormTO formTO) {
- super(MultilevelPanel.FIRST_LEVEL_ID);
-
- IModel<List<WorkflowFormPropertyTO>> formProps = new LoadableDetachableModel<List<WorkflowFormPropertyTO>>() {
-
- private static final long serialVersionUID = 3169142472626817508L;
-
- @Override
- protected List<WorkflowFormPropertyTO> load() {
- return formTO.getProperties();
- }
- };
-
- final ListView<WorkflowFormPropertyTO> propView = new ListView<WorkflowFormPropertyTO>("propView", formProps) {
-
- private static final long serialVersionUID = 9101744072914090143L;
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected void populateItem(final ListItem<WorkflowFormPropertyTO> item) {
- final WorkflowFormPropertyTO prop = item.getModelObject();
-
- String label = StringUtils.isBlank(prop.getName()) ? prop.getId() : prop.getName();
-
- FieldPanel field;
- switch (prop.getType()) {
- case Boolean:
- field = new AjaxDropDownChoicePanel("value", label, new PropertyModel<String>(prop, "value") {
-
- private static final long serialVersionUID = -3743432456095828573L;
-
- @Override
- public String getObject() {
- return StringUtils.isBlank(prop.getValue())
- ? null
- : prop.getValue().equals("true") ? "Yes" : "No";
- }
-
- @Override
- public void setObject(final String object) {
- prop.setValue(String.valueOf(object.equalsIgnoreCase("yes")));
- }
-
- }, false).setChoices(Arrays.asList(new String[] { "Yes", "No" }));
- break;
-
- case Date:
- final FastDateFormat formatter = FastDateFormat.getInstance(prop.getDatePattern());
- field = new DateTimeFieldPanel("value", label, new PropertyModel<Date>(prop, "value") {
-
- private static final long serialVersionUID = -3743432456095828573L;
-
- @Override
- public Date getObject() {
- try {
- if (StringUtils.isBlank(prop.getValue())) {
- return null;
- } else {
- return formatter.parse(prop.getValue());
- }
- } catch (ParseException e) {
- LOG.error("Unparsable date: {}", prop.getValue(), e);
- return null;
- }
- }
-
- @Override
- public void setObject(final Date object) {
- prop.setValue(formatter.format(object));
- }
-
- }, prop.getDatePattern());
- break;
-
- case Enum:
- MapChoiceRenderer<String, String> enumCR = new MapChoiceRenderer<>(prop.getEnumValues());
- final Map<String, String> map = MapUtils.invertMap(prop.getEnumValues());
-
- field = new AjaxDropDownChoicePanel(
- "value", label, new PropertyModel<String>(prop, "value"), false).
- setChoiceRenderer(enumCR).setChoices(new Model<ArrayList<String>>() {
-
- private static final long serialVersionUID = -858521070366432018L;
-
- @Override
- public ArrayList<String> getObject() {
- return new ArrayList<>(prop.getEnumValues().keySet());
- }
- });
- break;
-
- case Long:
- field = new AjaxSpinnerFieldPanel.Builder<Long>().build(
- "value",
- label,
- Long.class,
- new PropertyModel<Long>(prop, "value") {
-
- private static final long serialVersionUID = -7688359318035249200L;
-
- @Override
- public Long getObject() {
- return StringUtils.isBlank(prop.getValue())
- ? null
- : NumberUtils.toLong(prop.getValue());
- }
-
- @Override
- public void setObject(final Long object) {
- prop.setValue(String.valueOf(object));
- }
- });
- break;
-
- case String:
- default:
- field = new AjaxTextFieldPanel("value", label, new PropertyModel<String>(prop, "value"), false);
- break;
- }
-
- field.setReadOnly(!prop.isWritable());
- if (prop.isRequired()) {
- field.addRequiredLabel();
- }
-
- item.add(field);
- }
- };
-
- final AjaxLink<String> userDetails = new AjaxLink<String>("userDetails") {
-
- private static final long serialVersionUID = -4804368561204623354L;
-
- @Override
- public void onClick(final AjaxRequestTarget target) {
- viewDetails(formTO, target);
- }
- };
- MetaDataRoleAuthorizationStrategy.authorize(userDetails, ENABLE, StandardEntitlement.USER_READ);
-
- add(propView);
- add(userDetails);
- }
-
- protected abstract void viewDetails(final WorkflowFormTO formTO, final AjaxRequestTarget target);
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalDetails.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalDetails.java
deleted file mode 100644
index 20613d9..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalDetails.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.todos;
-
-import java.util.List;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.rest.AnyTypeRestClient;
-import org.apache.syncope.client.console.rest.UserRestClient;
-import org.apache.syncope.client.console.wizards.AjaxWizard;
-import org.apache.syncope.client.console.wizards.any.AnyHandler;
-import org.apache.syncope.client.console.wizards.any.UserWizardBuilder;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.wicket.PageReference;
-
-public class ApprovalDetails extends MultilevelPanel.SecondLevel {
-
- private static final long serialVersionUID = -8847854414429745216L;
-
- public ApprovalDetails(final PageReference pageRef, final WorkflowFormTO formTO) {
- super(MultilevelPanel.SECOND_LEVEL_ID);
-
- final UserTO userTO = new UserRestClient().read(formTO.getUserKey());
- final List<String> anyTypeClasses = new AnyTypeRestClient().get(AnyTypeKind.USER.name()).getClasses();
-
- final AjaxWizard<AnyHandler<UserTO>> wizard
- = new UserWizardBuilder("wizard", userTO, anyTypeClasses, pageRef).build(AjaxWizard.Mode.READONLY);
-
- add(wizard);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalModal.java b/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalModal.java
deleted file mode 100644
index a4fa1b5..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/todos/ApprovalModal.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.todos;
-
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.panels.ModalPanel;
-import org.apache.syncope.client.console.panels.MultilevelPanel;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.markup.html.panel.Panel;
-
-public class ApprovalModal extends Panel implements ModalPanel<WorkflowFormTO> {
-
- private static final long serialVersionUID = -8847854414429745216L;
-
- private final BaseModal<?> modal;
-
- private final WorkflowFormTO formTO;
-
- public ApprovalModal(final BaseModal<?> modal, final PageReference pageRef, final WorkflowFormTO formTO) {
- super(BaseModal.CONTENT_ID);
- this.modal = modal;
- this.formTO = formTO;
-
- final MultilevelPanel mlp = new MultilevelPanel("approval");
- add(mlp);
-
- mlp.setFirstLevel(new Approval(pageRef, formTO) {
-
- private static final long serialVersionUID = -2195387360323687302L;
-
- @Override
- protected void viewDetails(final WorkflowFormTO formTO, final AjaxRequestTarget target) {
- mlp.next(getString("approval.details"), new ApprovalDetails(pageRef, formTO), target);
- }
- });
- }
-
- @Override
- public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
- try {
- new UserWorkflowRestClient().submitForm(formTO);
- this.modal.show(false);
- this.modal.close(target);
- SyncopeConsoleSession.get().info(getString(Constants.OPERATION_SUCCEEDED));
- } catch (SyncopeClientException e) {
- SyncopeConsoleSession.get().error(getString(Constants.ERROR) + ": " + e.getMessage());
- }
- SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
- }
-
- @Override
- public void onError(final AjaxRequestTarget target, final Form<?> form) {
- SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
- }
-
- @Override
- public WorkflowFormTO getItem() {
- return this.formTO;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/todos/TODOSearchResultPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/todos/TODOSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/todos/TODOSearchResultPanel.java
deleted file mode 100644
index ff789b4..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/todos/TODOSearchResultPanel.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.todos;
-
-import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.commons.Constants;
-import org.apache.syncope.client.console.commons.SearchableDataProvider;
-import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
-import org.apache.syncope.client.console.panels.AbstractSearchResultPanel;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.client.console.todos.TODOSearchResultPanel.ApprovalProvider;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn;
-import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
-import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel;
-import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
-import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
-import org.apache.wicket.model.AbstractReadOnlyModel;
-import org.apache.wicket.model.CompoundPropertyModel;
-import org.apache.wicket.model.IModel;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.model.ResourceModel;
-
-public class TODOSearchResultPanel
- extends AbstractSearchResultPanel<WorkflowFormTO, WorkflowFormTO, ApprovalProvider, UserWorkflowRestClient> {
-
- private static final long serialVersionUID = -7122136682275797903L;
-
- public TODOSearchResultPanel(final String id, final PageReference pageReference) {
- super(id, pageReference, false);
- disableCheckBoxes();
-
- setFooterVisibility(true);
- modal.addSumbitButton();
- modal.size(Modal.Size.Large);
-
- restClient = new UserWorkflowRestClient();
-
- initResultTable();
-
- MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, ENABLE, StandardEntitlement.WORKFLOW_FORM_SUBMIT);
- }
-
- @Override
- protected List<IColumn<WorkflowFormTO, String>> getColumns() {
-
- List<IColumn<WorkflowFormTO, String>> columns = new ArrayList<>();
- columns.add(new PropertyColumn<WorkflowFormTO, String>(
- new ResourceModel("taskId"), "taskId", "taskId"));
- columns.add(new PropertyColumn<WorkflowFormTO, String>(
- new ResourceModel("key"), "key", "key"));
- columns.add(new PropertyColumn<WorkflowFormTO, String>(
- new ResourceModel("description"), "description", "description"));
- columns.add(new DatePropertyColumn<WorkflowFormTO>(
- new ResourceModel("createTime"), "createTime", "createTime"));
- columns.add(new DatePropertyColumn<WorkflowFormTO>(
- new ResourceModel("dueDate"), "dueDate", "dueDate"));
- columns.add(new PropertyColumn<WorkflowFormTO, String>(new ResourceModel("owner"), "owner", "owner"));
- columns.add(new ActionColumn<WorkflowFormTO, String>(new ResourceModel("actions")) {
-
- private static final long serialVersionUID = -3503023501954863133L;
-
- @Override
- public ActionLinksPanel<WorkflowFormTO> getActions(
- final String componentId, final IModel<WorkflowFormTO> model) {
- final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
-
- panel.add(new ActionLink<WorkflowFormTO>() {
-
- private static final long serialVersionUID = -3722207913631435501L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
- try {
- restClient.claimForm(model.getObject().getTaskId());
- info(getString(Constants.OPERATION_SUCCEEDED));
- } catch (SyncopeClientException scee) {
- error(getString(Constants.ERROR) + ": " + scee.getMessage());
- }
- SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
- target.add(container);
- }
- }, ActionLink.ActionType.CLAIM, StandardEntitlement.WORKFLOW_FORM_CLAIM);
-
- panel.add(new ActionLink<WorkflowFormTO>() {
-
- private static final long serialVersionUID = -3722207913631435501L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
- final IModel<WorkflowFormTO> formModel = new CompoundPropertyModel<>(model.getObject());
- modal.setFormModel(formModel);
-
- target.add(modal.setContent(new ApprovalModal(modal, pageRef, model.getObject())));
- modal.header(new Model<>(getString("approval.edit", new Model<>(model.getObject()))));
-
- modal.show(true);
- }
-
- @Override
- protected boolean statusCondition(final WorkflowFormTO modelObject) {
- return SyncopeConsoleSession.get().getSelfTO().getUsername().
- equals(model.getObject().getOwner());
- }
-
- }, ActionLink.ActionType.EDIT, StandardEntitlement.WORKFLOW_FORM_READ);
-
- return panel.build(componentId);
- }
-
- @Override
- public ActionLinksPanel<WorkflowFormTO> getHeader(final String componentId) {
- final ActionLinksPanel.Builder<WorkflowFormTO> panel = ActionLinksPanel.builder();
-
- return panel.add(new ActionLink<WorkflowFormTO>() {
-
- private static final long serialVersionUID = -7978723352517770644L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final WorkflowFormTO ignore) {
- if (target != null) {
- target.add(container);
- }
- }
- }, ActionLink.ActionType.RELOAD, StandardEntitlement.WORKFLOW_FORM_LIST).build(componentId);
- }
- });
-
- return columns;
- }
-
- @Override
- protected ApprovalProvider dataProvider() {
- return new ApprovalProvider(rows);
- }
-
- @Override
- protected String paginatorRowsKey() {
- return Constants.PREF_WORKFLOW_FORM_PAGINATOR_ROWS;
- }
-
- public static class ApprovalProvider extends SearchableDataProvider<WorkflowFormTO> {
-
- private static final long serialVersionUID = -2311716167583335852L;
-
- private final SortableDataProviderComparator<WorkflowFormTO> comparator;
-
- private final UserWorkflowRestClient restClient = new UserWorkflowRestClient();
-
- public ApprovalProvider(final int paginatorRows) {
- super(paginatorRows);
- setSort("createTime", SortOrder.DESCENDING);
- this.comparator = new SortableDataProviderComparator<>(this);
- }
-
- @Override
- public Iterator<WorkflowFormTO> iterator(final long first, final long count) {
- final List<WorkflowFormTO> list = restClient.getForms();
- Collections.sort(list, comparator);
- return list.subList((int) first, (int) first + (int) count).iterator();
- }
-
- @Override
- public long size() {
- return restClient.getForms().size();
- }
-
- @Override
- public IModel<WorkflowFormTO> model(final WorkflowFormTO configuration) {
- return new AbstractReadOnlyModel<WorkflowFormTO>() {
-
- private static final long serialVersionUID = -2566070996511906708L;
-
- @Override
- public WorkflowFormTO getObject() {
- return configuration;
- }
- };
- }
- }
-
- @Override
- protected Collection<ActionLink.ActionType> getBulkActions() {
- return Collections.<ActionLink.ActionType>emptyList();
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
new file mode 100644
index 0000000..fd19e97
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/widgets/ApprovalsWidget.java
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.widgets;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.pages.Approvals;
+import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.StandardEntitlement;
+import org.apache.wicket.Application;
+import org.apache.wicket.PageReference;
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.BookmarkablePageLink;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.LoadableDetachableModel;
+import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
+import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ApprovalsWidget extends Panel {
+
+ private static final long serialVersionUID = 7667120094526529934L;
+
+ private static final Logger LOG = LoggerFactory.getLogger(ApprovalsWidget.class);
+
+ private static final int UPDATE_PERIOD = 30;
+
+ private final Label linkApprovalsNumber;
+
+ private final Label headerApprovalsNumber;
+
+ private final WebMarkupContainer lastApprovalsList;
+
+ private final ListView<WorkflowFormTO> lastFive;
+
+ private final List<WorkflowFormTO> lastApprovals;
+
+ public ApprovalsWidget(final String id, final PageReference pageRef) {
+ super(id);
+ setOutputMarkupId(true);
+
+ LoadableDetachableModel<List<WorkflowFormTO>> model = new LoadableDetachableModel<List<WorkflowFormTO>>() {
+
+ private static final long serialVersionUID = 7474274077691068779L;
+
+ @Override
+ protected List<WorkflowFormTO> load() {
+ return ApprovalsWidget.this.lastApprovals.subList(0, ApprovalsWidget.this.lastApprovals.size() < 6
+ ? ApprovalsWidget.this.lastApprovals.size() : 5);
+ }
+ };
+
+ lastApprovals = getLastApprovals();
+ Collections.sort(lastApprovals, new WorkflowFormComparator());
+
+ linkApprovalsNumber = new Label("approvals", lastApprovals.size()) {
+
+ private static final long serialVersionUID = 4755868673082976208L;
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ if (Integer.valueOf(getDefaultModelObject().toString()) > 0) {
+ tag.put("class", "label label-danger");
+ } else {
+ tag.put("class", "label label-info");
+ }
+ }
+
+ };
+ add(linkApprovalsNumber.setOutputMarkupId(true));
+
+ headerApprovalsNumber = new Label("number", lastApprovals.size());
+ headerApprovalsNumber.setOutputMarkupId(true);
+ add(headerApprovalsNumber);
+
+ lastApprovalsList = new WebMarkupContainer("lastApprovalsList");
+ lastApprovalsList.setOutputMarkupId(true);
+ add(lastApprovalsList);
+
+ lastFive = new ListView<WorkflowFormTO>("lastApprovals", model) {
+
+ private static final long serialVersionUID = 4949588177564901031L;
+
+ @Override
+ protected void populateItem(final ListItem<WorkflowFormTO> item) {
+ final WorkflowFormTO modelObject = item.getModelObject();
+
+ final AjaxLink<String> approval = new AjaxLink<String>("approval") {
+
+ private static final long serialVersionUID = 7021195294339489084L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target) {
+ // do nothing
+ }
+
+ @Override
+ protected void onComponentTag(final ComponentTag tag) {
+ super.onComponentTag(tag);
+ if (StringUtils.isNotBlank(modelObject.getDescription())) {
+ tag.put("title", modelObject.getDescription().trim());
+ }
+ }
+ };
+
+ item.add(approval);
+
+ approval.add(new Label("key", new ResourceModel(modelObject.getKey(), modelObject.getKey())).
+ setRenderBodyOnly(true));
+
+ approval.add(new Label("owner", modelObject.getOwner()));
+
+ approval.add(new Label("createTime",
+ SyncopeConsoleSession.get().getDateFormat().format(modelObject.getCreateTime())).
+ setRenderBodyOnly(true));
+
+ WebMarkupContainer dueDateContainer = new WebMarkupContainer("dueDateContainer");
+ dueDateContainer.setOutputMarkupId(true);
+ approval.add(dueDateContainer);
+
+ if (modelObject.getDueDate() == null) {
+ dueDateContainer.add(new Label("dueDate"));
+ dueDateContainer.setVisible(false);
+ } else {
+ dueDateContainer.add(new Label("dueDate",
+ SyncopeConsoleSession.get().getDateFormat().format(modelObject.getDueDate())).
+ setRenderBodyOnly(true));
+ }
+
+ }
+ };
+ lastApprovalsList.add(lastFive.setReuseItems(false).setOutputMarkupId(true));
+
+ BookmarkablePageLink<Object> approvals = BookmarkablePageLinkBuilder.build("approvalsLink", Approvals.class);
+ add(approvals);
+ MetaDataRoleAuthorizationStrategy.authorize(approvals, WebPage.ENABLE, StandardEntitlement.WORKFLOW_FORM_LIST);
+
+ add(new WebSocketBehavior() {
+
+ private static final long serialVersionUID = 7944352891541344021L;
+
+ @Override
+ protected void onConnect(final ConnectedMessage message) {
+ super.onConnect(message);
+ SyncopeConsoleSession.get().scheduleAtFixedRate(
+ new ApprovalInfoUpdater(message), 0, UPDATE_PERIOD, TimeUnit.SECONDS);
+ }
+ });
+ }
+
+ private List<WorkflowFormTO> getLastApprovals() {
+ if (SyncopeConsoleSession.get().owns(StandardEntitlement.WORKFLOW_FORM_LIST)) {
+ return new UserWorkflowRestClient().getForms();
+ } else {
+ return Collections.<WorkflowFormTO>emptyList();
+ }
+ }
+
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ if (event.getPayload() instanceof WebSocketPushPayload) {
+ WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
+ if (wsEvent.getMessage() instanceof UpdateMessage) {
+
+ ApprovalsWidget.this.linkApprovalsNumber.
+ setDefaultModelObject(ApprovalsWidget.this.lastApprovals.size());
+ wsEvent.getHandler().add(ApprovalsWidget.this.linkApprovalsNumber);
+
+ ApprovalsWidget.this.headerApprovalsNumber.
+ setDefaultModelObject(ApprovalsWidget.this.lastApprovals.size());
+ wsEvent.getHandler().add(ApprovalsWidget.this.headerApprovalsNumber);
+
+ ApprovalsWidget.this.lastFive.removeAll();
+ wsEvent.getHandler().add(ApprovalsWidget.this.lastApprovalsList);
+ }
+ } else {
+ super.onEvent(event);
+ }
+ }
+
+ protected final class ApprovalInfoUpdater implements Runnable {
+
+ private final Application application;
+
+ private final SyncopeConsoleSession session;
+
+ private final IKey key;
+
+ public ApprovalInfoUpdater(final ConnectedMessage message) {
+ this.application = message.getApplication();
+ this.session = SyncopeConsoleSession.get();
+ this.key = message.getKey();
+ }
+
+ @Override
+ public void run() {
+ try {
+ ThreadContext.setApplication(application);
+ ThreadContext.setSession(session);
+
+ final List<WorkflowFormTO> actual = getLastApprovals();
+ Collections.sort(actual, new WorkflowFormComparator());
+
+ if (!actual.equals(lastApprovals)) {
+ LOG.debug("Update approvals");
+
+ lastApprovals.clear();
+ lastApprovals.addAll(actual);
+
+ WebSocketSettings settings = WebSocketSettings.Holder.get(application);
+ WebSocketPushBroadcaster broadcaster =
+ new WebSocketPushBroadcaster(settings.getConnectionRegistry());
+ broadcaster.broadcast(new ConnectedMessage(application, session.getId(), key), new UpdateMessage());
+ }
+ } catch (Throwable t) {
+ LOG.error("Unexpected error while checking for updated approval info", t);
+ } finally {
+ ThreadContext.detach();
+ }
+ }
+ }
+
+ private static class UpdateMessage implements IWebSocketPushMessage, Serializable {
+
+ private static final long serialVersionUID = -824793424112532838L;
+
+ }
+
+ private class WorkflowFormComparator implements Comparator<WorkflowFormTO> {
+
+ @Override
+ public int compare(final WorkflowFormTO o1, final WorkflowFormTO o2) {
+ if (o1 == null) {
+ return o2 == null ? 0 : 1;
+ } else if (o2 == null) {
+ return -1;
+ } else {
+ // inverse
+ return o2.getCreateTime().compareTo(o1.getCreateTime());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/ef80e015/client/console/src/main/java/org/apache/syncope/client/console/widgets/TODOsWidget.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/widgets/TODOsWidget.java b/client/console/src/main/java/org/apache/syncope/client/console/widgets/TODOsWidget.java
deleted file mode 100644
index 8b50826..0000000
--- a/client/console/src/main/java/org/apache/syncope/client/console/widgets/TODOsWidget.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.widgets;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
-import org.apache.syncope.client.console.SyncopeConsoleSession;
-import org.apache.syncope.client.console.pages.TODOs;
-import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
-import org.apache.syncope.common.lib.to.WorkflowFormTO;
-import org.apache.syncope.common.lib.types.StandardEntitlement;
-import org.apache.wicket.Application;
-import org.apache.wicket.PageReference;
-import org.apache.wicket.ThreadContext;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.ajax.markup.html.AjaxLink;
-import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
-import org.apache.wicket.event.IEvent;
-import org.apache.wicket.markup.ComponentTag;
-import org.apache.wicket.markup.html.WebMarkupContainer;
-import org.apache.wicket.markup.html.WebPage;
-import org.apache.wicket.markup.html.basic.Label;
-import org.apache.wicket.markup.html.link.BookmarkablePageLink;
-import org.apache.wicket.markup.html.list.ListItem;
-import org.apache.wicket.markup.html.list.ListView;
-import org.apache.wicket.markup.html.panel.Panel;
-import org.apache.wicket.model.LoadableDetachableModel;
-import org.apache.wicket.model.ResourceModel;
-import org.apache.wicket.protocol.ws.WebSocketSettings;
-import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
-import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
-import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
-import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
-import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
-import org.apache.wicket.protocol.ws.api.registry.IKey;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class TODOsWidget extends Panel {
-
- private static final long serialVersionUID = 7667120094526529934L;
-
- private static final Logger LOG = LoggerFactory.getLogger(TODOsWidget.class);
-
- private static final int UPDATE_PERIOD = 30;
-
- private final Label linkTODOsNumber;
-
- private final Label headerTODOsNumber;
-
- private final WebMarkupContainer lastTODOsList;
-
- private final ListView<WorkflowFormTO> lastFive;
-
- private List<WorkflowFormTO> lastTODOs;
-
- public TODOsWidget(final String id, final PageReference pageRef) {
- super(id);
- setOutputMarkupId(true);
-
- LoadableDetachableModel<List<WorkflowFormTO>> model = new LoadableDetachableModel<List<WorkflowFormTO>>() {
-
- private static final long serialVersionUID = 7474274077691068779L;
-
- @Override
- protected List<WorkflowFormTO> load() {
- return TODOsWidget.this.lastTODOs.subList(
- 0, TODOsWidget.this.lastTODOs.size() < 6 ? TODOsWidget.this.lastTODOs.size() : 5);
- }
- };
-
- lastTODOs = getLastTODOs();
- Collections.sort(lastTODOs, new WorkflowFormComparator());
-
- linkTODOsNumber = new Label("todos", lastTODOs.size()) {
-
- private static final long serialVersionUID = 4755868673082976208L;
-
- @Override
- protected void onComponentTag(final ComponentTag tag) {
- super.onComponentTag(tag);
- if (Integer.valueOf(getDefaultModelObject().toString()) > 0) {
- tag.put("class", "label label-danger");
- } else {
- tag.put("class", "label label-info");
- }
- }
-
- };
- add(linkTODOsNumber.setOutputMarkupId(true));
-
- headerTODOsNumber = new Label("number", lastTODOs.size());
- headerTODOsNumber.setOutputMarkupId(true);
- add(headerTODOsNumber);
-
- lastTODOsList = new WebMarkupContainer("lastTODOsList");
- lastTODOsList.setOutputMarkupId(true);
- add(lastTODOsList);
-
- lastFive = new ListView<WorkflowFormTO>("lastTODOs", model) {
-
- private static final long serialVersionUID = 4949588177564901031L;
-
- @Override
- protected void populateItem(final ListItem<WorkflowFormTO> item) {
- final WorkflowFormTO modelObject = item.getModelObject();
-
- final AjaxLink<String> todo = new AjaxLink<String>("todo") {
-
- private static final long serialVersionUID = 7021195294339489084L;
-
- @Override
- public void onClick(final AjaxRequestTarget target) {
- // do nothing
- }
-
- @Override
- protected void onComponentTag(final ComponentTag tag) {
- super.onComponentTag(tag);
- if (StringUtils.isNotBlank(modelObject.getDescription())) {
- tag.put("title", modelObject.getDescription().trim());
- }
- }
- };
-
- item.add(todo);
-
- todo.add(new Label("key", new ResourceModel(modelObject.getKey(), modelObject.getKey())).
- setRenderBodyOnly(true));
-
- todo.add(new Label("owner", modelObject.getOwner()));
-
- todo.add(new Label("createTime",
- SyncopeConsoleSession.get().getDateFormat().format(modelObject.getCreateTime())).
- setRenderBodyOnly(true));
-
- WebMarkupContainer dueDateContainer = new WebMarkupContainer("dueDateContainer");
- dueDateContainer.setOutputMarkupId(true);
- todo.add(dueDateContainer);
-
- if (modelObject.getDueDate() == null) {
- dueDateContainer.add(new Label("dueDate"));
- dueDateContainer.setVisible(false);
- } else {
- dueDateContainer.add(new Label("dueDate",
- SyncopeConsoleSession.get().getDateFormat().format(modelObject.getDueDate())).
- setRenderBodyOnly(true));
- }
-
- }
- };
- lastTODOsList.add(lastFive.setReuseItems(false).setOutputMarkupId(true));
-
- final BookmarkablePageLink<Object> todos = BookmarkablePageLinkBuilder.build("todosLink", TODOs.class);
- add(todos);
-
- MetaDataRoleAuthorizationStrategy.authorize(todos, WebPage.ENABLE, StandardEntitlement.WORKFLOW_FORM_LIST);
-
- add(new WebSocketBehavior() {
-
- private static final long serialVersionUID = 7944352891541344021L;
-
- @Override
- protected void onConnect(final ConnectedMessage message) {
- super.onConnect(message);
- SyncopeConsoleSession.get().scheduleAtFixedRate(
- new TODOInfoUpdater(message), 0, UPDATE_PERIOD, TimeUnit.SECONDS);
- }
- });
- }
-
- private List<WorkflowFormTO> getLastTODOs() {
- if (SyncopeConsoleSession.get().owns(StandardEntitlement.WORKFLOW_FORM_LIST)) {
- return new UserWorkflowRestClient().getForms();
- } else {
- return Collections.<WorkflowFormTO>emptyList();
- }
- }
-
- @Override
- public void onEvent(final IEvent<?> event) {
- if (event.getPayload() instanceof WebSocketPushPayload) {
- WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
- if (wsEvent.getMessage() instanceof UpdateMessage) {
-
- TODOsWidget.this.linkTODOsNumber.setDefaultModelObject(TODOsWidget.this.lastTODOs.size());
- wsEvent.getHandler().add(TODOsWidget.this.linkTODOsNumber);
-
- TODOsWidget.this.headerTODOsNumber.setDefaultModelObject(TODOsWidget.this.lastTODOs.size());
- wsEvent.getHandler().add(TODOsWidget.this.headerTODOsNumber);
-
- TODOsWidget.this.lastFive.removeAll();
- wsEvent.getHandler().add(TODOsWidget.this.lastTODOsList);
- }
- } else {
- super.onEvent(event);
- }
- }
-
- protected final class TODOInfoUpdater implements Runnable {
-
- private final Application application;
-
- private final SyncopeConsoleSession session;
-
- private final IKey key;
-
- public TODOInfoUpdater(final ConnectedMessage message) {
- this.application = message.getApplication();
- this.session = SyncopeConsoleSession.get();
- this.key = message.getKey();
- }
-
- @Override
- public void run() {
- try {
- ThreadContext.setApplication(application);
- ThreadContext.setSession(session);
-
- final List<WorkflowFormTO> actual = getLastTODOs();
- Collections.sort(actual, new WorkflowFormComparator());
-
- if (!actual.equals(lastTODOs)) {
- LOG.debug("Update TODOs");
-
- lastTODOs.clear();
- lastTODOs = actual;
-
- WebSocketSettings settings = WebSocketSettings.Holder.get(application);
- WebSocketPushBroadcaster broadcaster
- = new WebSocketPushBroadcaster(settings.getConnectionRegistry());
- broadcaster.broadcast(new ConnectedMessage(application, session.getId(), key), new UpdateMessage());
- }
- } catch (Throwable t) {
- LOG.error("Unexpected error while checking for updated Job info", t);
- } finally {
- ThreadContext.detach();
- }
- }
- }
-
- private static class UpdateMessage implements IWebSocketPushMessage, Serializable {
-
- private static final long serialVersionUID = -824793424112532838L;
-
- }
-
- private class WorkflowFormComparator implements Comparator<WorkflowFormTO> {
-
- @Override
- public int compare(final WorkflowFormTO o1, final WorkflowFormTO o2) {
- if (o1 == null) {
- return o2 == null ? 0 : 1;
- } else if (o2 == null) {
- return -1;
- } else {
- // inverse
- return o2.getCreateTime().compareTo(o1.getCreateTime());
- }
- }
- }
-}