View Javadoc

1   package org.appfuse.webapp.pages.admin;
2   
3   import de.agilecoders.wicket.core.markup.html.bootstrap.button.*;
4   import de.agilecoders.wicket.core.markup.html.bootstrap.image.GlyphIconType;
5   import org.apache.wicket.Page;
6   import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
7   import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable;
8   import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
9   import org.apache.wicket.markup.html.basic.Label;
10  import org.apache.wicket.markup.html.form.Form;
11  import org.apache.wicket.markup.html.form.TextField;
12  import org.apache.wicket.markup.html.link.Link;
13  import org.apache.wicket.markup.html.panel.Panel;
14  import org.apache.wicket.markup.repeater.Item;
15  import org.apache.wicket.model.*;
16  import org.appfuse.Constants;
17  import org.appfuse.model.Role;
18  import org.appfuse.model.User;
19  import org.appfuse.service.UserManager;
20  import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
21  import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
22  import org.apache.wicket.spring.injection.annot.SpringBean;
23  import org.appfuse.webapp.pages.AbstractWebPage;
24  import org.appfuse.webapp.pages.FromListUserEdit;
25  import org.appfuse.webapp.pages.Home;
26  import org.appfuse.webapp.pages.components.PlaceholderBehavior;
27  import org.wicketstuff.annotation.mount.MountPath;
28  
29  import java.util.*;
30  
31  /**
32   * Page displaying a user list.
33   *
34   * @author Marcin ZajÄ…czkowski, 2010-09-11
35   */
36  @MountPath("admin/userList")
37  @AuthorizeInstantiation("ROLE_ADMIN")
38  public class UserList extends AbstractWebPage {
39  
40      private static final int ROWS_PER_PAGE = 25;
41  
42      @SpringBean(name = "userManager")
43      private UserManager userManager;
44      private TextField<String> searchQuery;
45      private UserDataProvider userDataProvider;
46  
47      @Override
48      protected void onInitialize() {
49          super.onInitialize();
50  
51          add(createPageTitleTag("userList.title"));
52          add(createFeedbackPanel());
53          add(createPageHeading("userList.heading"));
54          add(createSearchForm());
55          add(createAddButton());
56          add(createDoneButton());
57  
58          add(createUserListTable());
59      }
60  
61      private Form createSearchForm() {
62          Form<Void> searchForm = new Form<Void>("searchForm") {
63              @Override
64              protected void onSubmit() {
65                  //TODO: MZA: Could be done without refreshing the whole page?
66                  userDataProvider.setSearchFilter(searchQuery.getModelObject());
67              }
68          };
69          searchQuery = new TextField<String>("searchQuery", Model.of(""));
70          searchQuery.add(new PlaceholderBehavior(getString("search.enterTerms")));
71          searchForm.add(searchQuery);
72          return searchForm;
73      }
74  
75      private BootstrapLink<Page> createDoneButton() {
76          return new BootstrapLink<Page>("doneButton", Model.<Page>of(this), Buttons.Type.Default) {
77              @Override
78              public void onClick() {
79                  setResponsePage(Home.class);
80              }
81          }.setIconType(GlyphIconType.ok).setLabel(new ResourceModel("button.done"));
82      }
83  
84      private BootstrapLink<Page> createAddButton() {
85          return new BootstrapLink<Page>("addButton", Model.<Page>of(this), Buttons.Type.Primary) {
86              @Override
87              public void onClick() {
88                  log.info("addButton submitted");
89                  User user = new User();
90                  user.addRole(new Role(Constants.USER_ROLE));
91                  //TODO: MZA: Is it the best way to create this model here?
92                  setResponsePage(new FromListUserEdit(getPage(), new Model<User>(user)));
93              }
94          }.setIconType(GlyphIconType.plus).setLabel(new ResourceModel("button.add"));
95      }
96  
97      private AjaxFallbackDefaultDataTable<User, String> createUserListTable() {
98          userDataProvider = new UserDataProvider(userManager);
99          return new AjaxFallbackDefaultDataTable<User, String>(
100                 "userListTable", createColumns(), userDataProvider, ROWS_PER_PAGE);
101     }
102 
103     private List<IColumn<User, String>> createColumns() {
104         List<IColumn<User, String>> userListColumns = new ArrayList<IColumn<User, String>>();
105         userListColumns.add(createLinkableColumn("user.username", "username", "username"));
106         userListColumns.add(createColumn("activeUsers.fullName", "fullName", "fullName"));
107         userListColumns.add(createColumn("user.email", "email", "email"));
108         //TODO: MZA: Is there a "boolean" column? Check version from PhoneBook
109         userListColumns.add(createColumn("user.enabled", "enabled", "enabled"));
110         return userListColumns;
111     }
112 
113     private IColumn<User, String> createLinkableColumn(String key, String sortProperty, String propertyExpression) {
114         return new PropertyColumn<User, String>(new ResourceModel(key), sortProperty, propertyExpression) {
115             @Override
116             public void populateItem(Item<ICellPopulator<User>> iCellPopulatorItem, String componentId,
117                                      IModel<User> rowModel) {
118                 iCellPopulatorItem.add(new UsernamePanel(componentId, rowModel));
119             }
120         };
121     }
122 
123     private PropertyColumn<User, String> createColumn(String key, String sortProperty, String propertyExpression) {
124         return new PropertyColumn<User, String>(new ResourceModel(key), sortProperty, propertyExpression);
125     }
126 
127     //TODO: MZA: Change to LinkPanel make more generic
128     private class UsernamePanel extends Panel {
129 
130         private UsernamePanel(String id, IModel<User> userModel) {
131             super(id, userModel);
132 
133             //TODO: MZA: The whole row should be clickable
134             //TODO: MZA: A cursor isn't changed when on link
135             final Link<User> editLink = new Link<User>("editLink", userModel) {
136                 @Override
137                 public void onClick() {
138                     User clickedUser = getModelObject();
139                     log.info("clicked {}", clickedUser.getUsername());
140 
141                     setResponsePage(new FromListUserEdit(getPage(), getModel()));
142                 }
143             };
144             add(editLink);
145 
146             editLink.add(new Label("editLabel", new Model<String>(userModel.getObject().getUsername())));
147         }
148     }
149 }