diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java b/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java index d43bb6968d..c78d650e5e 100644 --- a/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java +++ b/src/main/java/se/su/dsv/scipro/admin/pages/AbstractAdminSettingsPage.java @@ -10,9 +10,10 @@ import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPage; import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPerProjectClassPage; import se.su.dsv.scipro.admin.pages.settings.AdminGeneralSettingsPage; import se.su.dsv.scipro.admin.pages.settings.AdminPeerSettingsPage; +import se.su.dsv.scipro.admin.pages.settings.AdminProjectClassSettingsPage; import se.su.dsv.scipro.admin.pages.settings.AdminServerEnvironmentSettingsPage; + import se.su.dsv.scipro.components.AbstractMenuPanel; -import se.su.dsv.scipro.icons.ImageIcon; import se.su.dsv.scipro.security.auth.Authorization; import se.su.dsv.scipro.security.auth.roles.Roles; @@ -32,8 +33,10 @@ public abstract class AbstractAdminSettingsPage extends AbstractAdminPage { items.add(new MenuItem("General settings", AdminGeneralSettingsPage.class)); items.add(new MenuItem("Server Environment", AdminServerEnvironmentSettingsPage.class)); items.add(new MenuItem("Final seminar general settings", AdminFinalSeminarSettingsPage.class)); - items.add(new MenuItem("Final seminar project level settings", AdminFinalSeminarSettingsPerProjectClassPage.class)); - items.add(new MenuItem("Peer settings", AdminPeerSettingsPage.class /*,ImageIcon.ICON_SETTINGS */)); + items.add(new MenuItem("Final seminar project level settings", AdminFinalSeminarSettingsPerProjectClassPage.class)); + items.add(new MenuItem("Level settings", AdminPeerSettingsPage.class)); + items.add(new MenuItem("Edit levels", AdminProjectClassSettingsPage.class)); + return items; } diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.html b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.html new file mode 100644 index 0000000000..9e85a06391 --- /dev/null +++ b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html + xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> +<body> + <wicket:extend> + + <!-- Edit/add dialog --> + <div wicket:id="dialog"> + <div wicket:id="dialogContent"></div> + </div> + + <a href=# wicket:id="createLink"><img src="images/icons/add_16x16.png" alt=""/> Create new level</a> + <div class="span-15 last"> + <h3 class="section">Active</h3> + </div> + <table class="rounded-table-top"> + <tr> + <th>Code</th> + <th>Name</th> + <th>Description</th> + <th>Edit</th> + </tr> + <tr> + </tr> + <tbody wicket:id="activeProjectClassContainer"> + <tr wicket:id="projectClassList"> + <td wicket:id="code"></td> + <td wicket:id="name"></td> + <td wicket:id="desc"></td> + <td><a href=# wicket:id="editLink"><img src="images/icons/edit_16x16.png" " alt="Edit" title="Edit"/></a> + </td> + </tr> + </tbody> + </table> + + <div class="span-15 last"> + <h3 class="section">Inactive</h3> + </div> + <table class="rounded-table-top"> + <tr> + <th>Code</th> + <th>Name</th> + <th>Description</th> + <th>Edit</th> + </tr> + <tr> + </tr> + <tbody wicket:id="deletedProjectClassContainer"> + <tr wicket:id="projectClassListDel"> + <td wicket:id="codeDel"></td> + <td wicket:id="nameDel"></td> + <td wicket:id="descDel"></td> + <td><a href=# wicket:id="undeleteLink">Activate</a> + </td> + </tr> + </tbody> + </table> + </wicket:extend> +</body> +</html> \ No newline at end of file diff --git a/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.java b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.java new file mode 100644 index 0000000000..fc5ad666cc --- /dev/null +++ b/src/main/java/se/su/dsv/scipro/admin/pages/settings/AdminProjectClassSettingsPage.java @@ -0,0 +1,154 @@ +package se.su.dsv.scipro.admin.pages.settings; + +import java.util.List; + +import org.apache.wicket.PageParameters; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.basic.MultiLineLabel; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.EmptyPanel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.odlabs.wiquery.ui.dialog.Dialog; + +import se.su.dsv.scipro.admin.pages.AbstractAdminSettingsPage; +import se.su.dsv.scipro.admin.panels.AdminProjectClassPanel; +import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; +import se.su.dsv.scipro.data.dataobjects.ProjectClass; + +public class AdminProjectClassSettingsPage extends AbstractAdminSettingsPage { + + @SpringBean + ProjectClassDao projectClassDao; + + public AdminProjectClassSettingsPage(PageParameters pp) { + super(pp); + + String msg = ""; + if((msg = pp.getString("info")) != null) + info(msg); + else if((msg = pp.getString("error")) != null) + error(msg); + + final Dialog dialog = new Dialog("dialog"); + dialog.setModal(true); + dialog.setAutoOpen(false); + dialog.add(new EmptyPanel("dialogContent")); + + dialog.setWidth(500); + dialog.setHeight(360); + add(dialog); + + IModel<List<ProjectClass>> activeProjectClass = new LoadableDetachableModel<List<ProjectClass>>() { + + private static final long serialVersionUID = 1L; + + @Override + protected List<ProjectClass> load() { + return projectClassDao.findAll(); + } + }; + + final WebMarkupContainer activeWmc = new WebMarkupContainer("activeProjectClassContainer"); + activeWmc.setOutputMarkupId(true); + add(activeWmc); + + final ListView<ProjectClass> listView = new ListView<ProjectClass>("projectClassList", activeProjectClass){ + + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem<ProjectClass> item) { + final IModel<ProjectClass> model = item.getModel(); + + item.add(new Label("code", model.getObject().getCode())); + item.add(new Label("name", model.getObject().getName())); + item.add(new MultiLineLabel("desc", model.getObject().getDescription())); + + AjaxLink<Void> editLink = new AjaxLink<Void>("editLink"){ + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + dialog.replace(new AdminProjectClassPanel("dialogContent", model)); + target.addComponent(dialog); + dialog.setTitle("Edit"); + dialog.open(target); + } + }; + item.add(editLink); + } + + }; + activeWmc.add(listView); + + /* + * Begin - list of deleted project classes + */ + + final IModel<List<ProjectClass>> deletedProjectClass = new LoadableDetachableModel<List<ProjectClass>>() { + + private static final long serialVersionUID = 1L; + + @Override + protected List<ProjectClass> load() { + return projectClassDao.findAllDeleted(); + } + }; + + final WebMarkupContainer deletedWmc = new WebMarkupContainer("deletedProjectClassContainer"); + deletedWmc.setOutputMarkupId(true); + add(deletedWmc); + + final ListView<ProjectClass> listViewDeleted = new ListView<ProjectClass>("projectClassListDel", deletedProjectClass){ + + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem<ProjectClass> item) { + final IModel<ProjectClass> model = item.getModel(); + + item.add(new Label("codeDel", model.getObject().getCode())); + item.add(new Label("nameDel", model.getObject().getName())); + item.add(new MultiLineLabel("descDel", model.getObject().getDescription())); + + AjaxLink<Void> undeleteLink = new AjaxLink<Void>("undeleteLink"){ + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + model.getObject().setDeleted(false); + model.setObject(projectClassDao.save(model.getObject())); + deletedProjectClass.detach(); + target.addComponent(activeWmc); + target.addComponent(deletedWmc); + info("Level activated"); + } + }; + item.add(undeleteLink); + } + + }; + deletedWmc.add(listViewDeleted); + + AjaxLink<Void> createLink = new AjaxLink<Void>("createLink"){ + private static final long serialVersionUID = 1L; + + @Override + public void onClick(AjaxRequestTarget target) { + dialog.replace(new AdminProjectClassPanel("dialogContent")); + target.addComponent(dialog); + dialog.setTitle("Add new..."); + dialog.open(target); + } + }; + add(createLink); + + } + +} diff --git a/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.html b/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.html new file mode 100644 index 0000000000..9f38ffb0e8 --- /dev/null +++ b/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html + xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> +<body> + <wicket:panel> + <form wicket:id="projectClassForm"> + + <!-- Fix max lengths --> + <table> + <tr> + <td>Code: <input wicket:id="code" type="text" maxlength="50" /> + </td> + </tr> + <tr> + <td>Name: <input wicket:id="name" type="text" maxlength="50" /> + </td> + </tr> + <tr> + <td>Description:</td> + </tr> + <tr> + <td><textarea wicket:id="description" cols="60" rows="5"></textarea> + </td> + </tr> + <tr> + <td><input wicket:id="createButton" type="submit" value="Save" /> + </td> + <td><input wicket:id="deleteButton" type="submit" + value="Inactivate" /> + </td> + </tr> + </table> + </form> + + </wicket:panel> +</body> +</html> \ No newline at end of file diff --git a/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.java b/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.java new file mode 100644 index 0000000000..c083732e8b --- /dev/null +++ b/src/main/java/se/su/dsv/scipro/admin/panels/AdminProjectClassPanel.java @@ -0,0 +1,98 @@ +package se.su.dsv.scipro.admin.panels; + +import org.apache.wicket.PageParameters; +import org.apache.wicket.markup.html.form.Button; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.TextArea; +import org.apache.wicket.markup.html.form.TextField; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +import se.su.dsv.scipro.admin.pages.settings.AdminProjectClassSettingsPage; +import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; +import se.su.dsv.scipro.data.dataobjects.ProjectClass; + +public class AdminProjectClassPanel extends Panel { + + @SpringBean + ProjectClassDao projectClassDao; + + private static final long serialVersionUID = 1L; + + public AdminProjectClassPanel(final String id) { + super(id); + + Model<ProjectClass> model = new Model<ProjectClass>(new ProjectClass()); + add(new ProjectClassSettingsForm("projectClassForm", model, false)); + } + + public AdminProjectClassPanel(String id, IModel<ProjectClass> model) { + super(id); + + add(new ProjectClassSettingsForm("projectClassForm", model, true)); + } + + private class ProjectClassSettingsForm extends Form<Void>{ + + private static final long serialVersionUID = 1L; + + IModel<ProjectClass> projectClassModel; + + public ProjectClassSettingsForm(String id, final IModel<ProjectClass> model, final boolean editMode) { + super(id); + + final PageParameters pp = new PageParameters(); + setRedirect(true); + + projectClassModel = model; + + add(new TextField<ProjectClass>("code", new PropertyModel<ProjectClass>(projectClassModel, "code"))); + add(new TextField<ProjectClass>("name", new PropertyModel<ProjectClass>(projectClassModel, "name"))); + add(new TextArea<ProjectClass>("description", new PropertyModel<ProjectClass>(projectClassModel, "description"))); + + Button createButton = new Button("createButton"){ + private static final long serialVersionUID = 1L; + @Override + public void onSubmit(){ + + if (editMode) { + pp.add("info", "Level edited"); + ProjectClass pc = projectClassDao.save(projectClassModel.getObject()); + projectClassModel.setObject(pc); + setResponsePage(AdminProjectClassSettingsPage.class, pp); + } else { + ProjectClass duplicateCheck = projectClassDao.getProjectClass(projectClassModel.getObject().getCode()); + if (duplicateCheck != null){ + String msg = "Level already exists"; + pp.add("error", msg); + setResponsePage(AdminProjectClassSettingsPage.class, pp); + return; + } + ProjectClass pc = projectClassDao.save(projectClassModel.getObject()); + projectClassModel.setObject(pc); + pp.add("info", "New level created"); + setResponsePage(AdminProjectClassSettingsPage.class, pp); + } + } + }; + add(createButton); + + Button deleteButton = new Button("deleteButton"){ + private static final long serialVersionUID = 1L; + @Override + public void onSubmit(){ + projectClassModel.getObject().setDeleted(true); + projectClassDao.save(projectClassModel.getObject()); + pp.add("info", "Level inactivated"); + setResponsePage(AdminProjectClassSettingsPage.class, pp); + } + }; + add(deleteButton); + deleteButton.setEnabled(editMode); + } + } + +} diff --git a/src/main/java/se/su/dsv/scipro/data/dao/interfaces/ProjectClassDao.java b/src/main/java/se/su/dsv/scipro/data/dao/interfaces/ProjectClassDao.java index c8eb98a5a4..f0bcf31b93 100644 --- a/src/main/java/se/su/dsv/scipro/data/dao/interfaces/ProjectClassDao.java +++ b/src/main/java/se/su/dsv/scipro/data/dao/interfaces/ProjectClassDao.java @@ -1,9 +1,13 @@ package se.su.dsv.scipro.data.dao.interfaces; +import java.util.List; + import se.su.dsv.scipro.data.dataobjects.ProjectClass; public interface ProjectClassDao extends Dao<ProjectClass>{ - ProjectClass getProjectClass(String projectCode); + ProjectClass getProjectClass(String projectCode); + + List<ProjectClass> findAllDeleted(); } diff --git a/src/main/java/se/su/dsv/scipro/data/dao/jpa/ProjectClassDaoJPAImp.java b/src/main/java/se/su/dsv/scipro/data/dao/jpa/ProjectClassDaoJPAImp.java index 76db26d20d..f0b8bf5c38 100644 --- a/src/main/java/se/su/dsv/scipro/data/dao/jpa/ProjectClassDaoJPAImp.java +++ b/src/main/java/se/su/dsv/scipro/data/dao/jpa/ProjectClassDaoJPAImp.java @@ -1,9 +1,13 @@ package se.su.dsv.scipro.data.dao.jpa; +import java.util.List; + import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceException; import javax.persistence.TypedQuery; + +import org.hibernate.ejb.QueryHints; import org.springframework.orm.jpa.JpaCallback; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -38,6 +42,16 @@ public class ProjectClassDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<ProjectCl }); } + @Transactional( readOnly=true ) + public List<ProjectClass> findAllDeleted() { + return getJpaTemplate().execute(new JpaCallback<List<ProjectClass>>() { + public List<ProjectClass> doInJpa(EntityManager em) throws PersistenceException { + TypedQuery<ProjectClass> query = em.createQuery("SELECT x FROM ProjectClass x WHERE x.deleted = 1", ProjectClass.class); + return query.getResultList(); + } + }); + } + @Override @Transactional public ProjectClass save(ProjectClass projectClass){ diff --git a/src/main/java/se/su/dsv/scipro/data/dataobjects/ProjectClass.java b/src/main/java/se/su/dsv/scipro/data/dataobjects/ProjectClass.java index 04863505ec..d8fd980fe4 100644 --- a/src/main/java/se/su/dsv/scipro/data/dataobjects/ProjectClass.java +++ b/src/main/java/se/su/dsv/scipro/data/dataobjects/ProjectClass.java @@ -9,7 +9,6 @@ import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.OneToOne; -import javax.persistence.PostLoad; import javax.persistence.Table; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy;