View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.enduser.pages;
20  
21  import java.util.Collections;
22  import java.util.Iterator;
23  import java.util.stream.Collectors;
24  import org.apache.commons.lang3.StringUtils;
25  import org.apache.syncope.client.enduser.SyncopeEnduserSession;
26  import org.apache.syncope.client.enduser.markup.html.form.BpmnProcessesAjaxPanel;
27  import org.apache.syncope.client.enduser.panels.UserRequestDetails;
28  import org.apache.syncope.client.enduser.rest.BpmnProcessRestClient;
29  import org.apache.syncope.client.enduser.rest.UserRequestRestClient;
30  import org.apache.syncope.client.ui.commons.Constants;
31  import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
32  import org.apache.syncope.client.ui.commons.annotations.ExtPage;
33  import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
34  import org.apache.syncope.common.lib.to.BpmnProcess;
35  import org.apache.syncope.common.lib.to.UserRequest;
36  import org.apache.wicket.ajax.AjaxRequestTarget;
37  import org.apache.wicket.ajax.markup.html.AjaxLink;
38  import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
39  import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
40  import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
41  import org.apache.wicket.extensions.markup.html.tabs.ITab;
42  import org.apache.wicket.markup.html.WebMarkupContainer;
43  import org.apache.wicket.markup.repeater.Item;
44  import org.apache.wicket.markup.repeater.data.DataView;
45  import org.apache.wicket.markup.repeater.data.IDataProvider;
46  import org.apache.wicket.model.IModel;
47  import org.apache.wicket.model.Model;
48  import org.apache.wicket.model.StringResourceModel;
49  import org.apache.wicket.request.mapper.parameter.PageParameters;
50  import org.apache.wicket.spring.injection.annot.SpringBean;
51  
52  @ExtPage(label = "User Requests", icon = "fa fa-briefcase", listEntitlement = "")
53  public class Flowable extends BaseExtPage {
54  
55      private static final long serialVersionUID = -8781434495150074529L;
56  
57      protected static final String USER_REQUESTS = "page.userRequests";
58  
59      protected static final int ROWS_PER_PAGE = 5;
60  
61      @SpringBean
62      protected UserRequestRestClient userRequestRestClient;
63  
64      @SpringBean
65      protected BpmnProcessRestClient bpmnProcessRestClient;
66  
67      protected final Model<String> bpmnProcessModel = new Model<>();
68  
69      protected final WebMarkupContainer container;
70  
71      protected final DataView<UserRequest> urDataView;
72  
73      public Flowable(final PageParameters parameters) {
74          super(parameters, USER_REQUESTS);
75  
76          container = new WebMarkupContainer("content");
77          container.setOutputMarkupId(true);
78  
79          // list of accordions containing request form (if any) and delete button
80          urDataView = new DataView<>("userRequests", new URDataProvider(ROWS_PER_PAGE, "bpmnProcess")) {
81  
82              private static final long serialVersionUID = -5002600396458362774L;
83  
84              @Override
85              protected void populateItem(final Item<UserRequest> item) {
86                  final UserRequest userRequest = item.getModelObject();
87                  item.add(new Accordion("userRequestDetails", Collections.<ITab>singletonList(new AbstractTab(
88                          new StringResourceModel("user.requests.accordion", container, Model.of(userRequest))) {
89  
90                      private static final long serialVersionUID = 1037272333056449378L;
91  
92                      @Override
93                      public WebMarkupContainer getPanel(final String panelId) {
94                          // find the form associated to the current request, if any
95                          return new UserRequestDetails(panelId, userRequest, container, notificationPanel);
96                      }
97                  }), Model.of(-1)).setOutputMarkupId(true));
98              }
99          };
100 
101         urDataView.setItemsPerPage(ROWS_PER_PAGE);
102         urDataView.setOutputMarkupId(true);
103         container.add(urDataView);
104         container.add(new AjaxPagingNavigator("navigator", urDataView));
105 
106         AjaxLink<Void> startButton = new AjaxLink<>("start") {
107 
108             private static final long serialVersionUID = 3669569969172391336L;
109 
110             @Override
111             public void onClick(final AjaxRequestTarget target) {
112                 if (StringUtils.isNotBlank(bpmnProcessModel.getObject())) {
113                     try {
114                         userRequestRestClient.startRequest(bpmnProcessModel.getObject(), null);
115                     } catch (Exception e) {
116                         LOG.error("Unable to start bpmnProcess [{}]", bpmnProcessModel.getObject(), e);
117                         SyncopeEnduserSession.get()
118                                 .error(String.format("Unable to start bpmnProcess [%s]", e.getMessage()));
119                         notificationPanel.refresh(target);
120                     }
121                     target.add(container);
122                 }
123             }
124         };
125 
126         startButton.setEnabled(false);
127         container.add(startButton);
128 
129         // autocomplete select with bpmnProcesses
130         BpmnProcessesAjaxPanel bpmnProcesses = new BpmnProcessesAjaxPanel("bpmnProcesses", "bpmnProcesses",
131                 bpmnProcessModel, new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
132 
133             private static final long serialVersionUID = -1107858522700306810L;
134 
135             @Override
136             protected void onUpdate(final AjaxRequestTarget target) {
137                 if (StringUtils.isNotBlank(bpmnProcessModel.getObject())) {
138                     startButton.setEnabled(true);
139                 } else {
140                     startButton.setEnabled(false);
141                 }
142                 target.add(container);
143             }
144         });
145         bpmnProcesses.setChoices(bpmnProcessRestClient.getDefinitions().stream()
146                 .filter(definition -> !definition.isUserWorkflow())
147                 .map(BpmnProcess::getKey).collect(Collectors.toList()));
148         container.add(bpmnProcesses);
149 
150         contentWrapper.add(container);
151     }
152 
153     protected class URDataProvider implements IDataProvider<UserRequest> {
154 
155         private static final long serialVersionUID = 1169386589403139714L;
156 
157         protected final int paginatorRows;
158 
159         protected final String sortParam;
160 
161         public URDataProvider(final int paginatorRows, final String sortParam) {
162             this.paginatorRows = paginatorRows;
163             this.sortParam = sortParam;
164         }
165 
166         @Override
167         public Iterator<UserRequest> iterator(final long first, final long count) {
168             int page = ((int) first / paginatorRows);
169             return userRequestRestClient.listRequests((page < 0 ? 0 : page) + 1,
170                     paginatorRows,
171                     SyncopeEnduserSession.get().getSelfTO().getUsername(),
172                     new SortParam<>(sortParam, true)).iterator();
173         }
174 
175         @Override
176         public long size() {
177             return userRequestRestClient.countRequests();
178         }
179 
180         @Override
181         public IModel<UserRequest> model(final UserRequest ur) {
182             return Model.of(ur);
183         }
184     }
185 }