Merge branch 'm3_first_meeting' into develop

This commit is contained in:
Emil Siverhall 2012-08-02 16:04:51 +02:00
commit 9931d13305
22 changed files with 609 additions and 39 deletions

@ -1,2 +1,12 @@
alter table `general_system_settings` drop column matchAlgorithmMatchesAreForceAccepted;
alter table `general_system_settings` drop column supervisorsCanAcceptDeclinePIs;
alter table `general_system_settings` drop column supervisorsCanAcceptDeclinePIs;
CREATE TABLE `first_meeting` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`firstMeetingDate` datetime NOT NULL,
`description` varchar(1024) NOT NULL,
`supervisoridea_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK2E9F13AC8DE85053` (`supervisoridea_id`),
CONSTRAINT `FK2E9F13AC8DE85053` FOREIGN KEY (`supervisoridea_id`) REFERENCES `supervisoridea` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;

@ -204,7 +204,8 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
mountBookmarkablePage("supervisor/project/files", SupervisorFilePage.class);
mountBookmarkablePage("supervisor/interest", SupervisorInterestPage.class);
mountBookmarkablePage("supervisor/projectideas", SupervisorProjectIdeaStartPage.class);
mountBookmarkablePage("supervisor/projectideas/myideas", SupervisorMyProjectIdeasPage.class);
mountBookmarkablePage("supervisor/projectideas/mystudentideas", SupervisorMyProjectIdeasPage.class);
mountBookmarkablePage("supervisor/projectideas/myideas", SupervisorMySupervisorIdeasPage.class);
/*
* Peer pages
*/

@ -0,0 +1,3 @@
<wicket:panel>
<img wicket:id="icon"/>
</wicket:panel>

@ -0,0 +1,49 @@
package se.su.dsv.scipro.datatables;
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.IModel;
import se.su.dsv.scipro.icons.ImageObject;
/**
* Column that displays different icons depending on a boolean value defined in abstract method booleanValue()
*
* @author emil-siv
*
*/
public abstract class BooleanIconColumn<T> extends AbstractColumn<T> {
private static final long serialVersionUID = -9034393574179345237L;
private final String yesIconString;
private final String noIconString;
public BooleanIconColumn(IModel<String> displayModel, String yesIconString, String noIconString) {
super(displayModel, null);
this.yesIconString = yesIconString;
this.noIconString = noIconString;
}
public void populateItem(Item<ICellPopulator<T>> cellItem,
String componentId, IModel<T> rowModel) {
cellItem.add(new IconPanel(componentId, rowModel));
}
private class IconPanel extends Panel {
private static final long serialVersionUID = 5301911716927261302L;
public IconPanel(String id, IModel<T> rowModel) {
super(id);
if(booleanValue(rowModel))
add(new ImageObject("icon", ImageObject.SIXTEEN + yesIconString));
else
add(new ImageObject("icon", ImageObject.SIXTEEN + noIconString));
}
}
protected abstract boolean booleanValue(IModel<T> rowModel);
}

@ -0,0 +1,76 @@
package se.su.dsv.scipro.match.dataobject;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.apache.wicket.IClusterable;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Table(name = "first_meeting")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class FirstMeeting implements IClusterable {
private static final long serialVersionUID = 1659431236791209714L;
@Id
@GeneratedValue
private Long id;
@Basic(optional=false)
private Date firstMeetingDate;
@Column(nullable = false, length = 1024)
private String description;
@OneToOne(optional=false)
private SupervisorIdea supervisorIdea;
public FirstMeeting(){
}
public FirstMeeting(Date firstMeetingDate, String description, SupervisorIdea supervisorIdea) {
this.firstMeetingDate = firstMeetingDate;
this.description = description;
this.supervisorIdea = supervisorIdea;
}
public Date getFirstMeetingDate() {
return firstMeetingDate;
}
public void setFirstMeetingDate(Date firstMeetingDate) {
this.firstMeetingDate = firstMeetingDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setSupervisorIdea(SupervisorIdea supervisorIdea) {
this.supervisorIdea = supervisorIdea;
}
public SupervisorIdea getSupervisorIdea() {
return supervisorIdea;
}
}

@ -85,5 +85,8 @@ public class IdeaParticipation implements Serializable {
return (getPk()!=null?getPk().hashCode() : 0);
}
@Override
public String toString() {
return getStudent().getNameAsString();
}
}

@ -2,11 +2,11 @@ package se.su.dsv.scipro.match.dataobject;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
@ -34,6 +34,9 @@ public class SupervisorIdea extends Idea {
@Column(nullable = false, length = 1024)
private String requirements;
@OneToOne(mappedBy="supervisorIdea", orphanRemoval = true, optional = true)
private FirstMeeting firstMeeting;
@Override
public Long getId() {
return id;
@ -109,4 +112,12 @@ public class SupervisorIdea extends Idea {
return false;
return true;
}
public void setFirstMeeting(FirstMeeting firstMeeting) {
this.firstMeeting = firstMeeting;
}
public FirstMeeting getFirstMeeting() {
return firstMeeting;
}
}

@ -0,0 +1,12 @@
package se.su.dsv.scipro.springdata.repos;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
@Transactional(readOnly = true)
public interface FirstMeetingRepo extends JpaRepository<FirstMeeting, Long>, QueryDslPredicateExecutor<FirstMeeting> {
}

@ -0,0 +1,42 @@
package se.su.dsv.scipro.springdata.serviceimpls;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mysema.query.types.expr.BooleanExpression;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.QFirstMeeting;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.repos.FirstMeetingRepo;
import se.su.dsv.scipro.springdata.services.FirstMeetingService;
@Service ( "firstMeetingService" )
@Transactional ( readOnly = true )
public class FirstMeetingServiceImpl extends AbstractQueryService<FirstMeeting, Long> implements FirstMeetingService {
@Resource
private FirstMeetingRepo firstMeetingRepo;
@Autowired
public FirstMeetingServiceImpl(
@Qualifier("firstMeetingRepo")
FirstMeetingRepo firstMeetingRepo) {
super(firstMeetingRepo, firstMeetingRepo);
System.out.println("FirstMeetingServiceImpl instantiating...");
}
@Override
public FirstMeeting getMeetingByIdea(SupervisorIdea idea) {
return firstMeetingRepo.findOne(byIdea(idea));
}
public BooleanExpression byIdea(SupervisorIdea idea) {
return QFirstMeeting.firstMeeting.supervisorIdea.eq(idea);
}
}

@ -19,6 +19,7 @@ import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.QSupervisorIdea;
@ -27,6 +28,7 @@ import se.su.dsv.scipro.match.dataobject.Watson;
import se.su.dsv.scipro.peer.data.dao.controllers.Pair;
import se.su.dsv.scipro.springdata.repos.SupervisorIdeaRepo;
import se.su.dsv.scipro.springdata.services.ApplicationPeriodService;
import se.su.dsv.scipro.springdata.services.FirstMeetingService;
import se.su.dsv.scipro.springdata.services.StudentService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorService;
@ -47,6 +49,9 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
private SupervisorService supervisorService;
@Resource
private ApplicationPeriodService applicationPeriodService;
@Resource
private FirstMeetingService firstMeetingService;
private transient Logger logger = Logger.getLogger(SupervisorIdeaService.class);
private int MAX_PARTNERS = 1;
@ -190,6 +195,10 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
Student s = ip.getStudent();
s.removeIdeaParticipation(ip);
}
//Remove first meeting info if existing
if(reloadedIdea.getFirstMeeting()!=null)
firstMeetingService.delete(reloadedIdea.getFirstMeeting().getId());
reloadedIdea.setFirstMeeting(null);
//Erase watson boxes
reloadedIdea.setWatson(new Watson());
//Remove application period association
@ -212,6 +221,21 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
reloadedIdea.getWatson().setPracticalHow(idea.getWatson().getPracticalHow());
}
@Override
@Transactional ( readOnly = false)
public SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (reloadedIdea.getFirstMeeting()!=null) {
reloadedIdea.getFirstMeeting().setFirstMeetingDate(date);
reloadedIdea.getFirstMeeting().setDescription(desc);
} else {
FirstMeeting meeting = new FirstMeeting(date, desc, reloadedIdea);
meeting = firstMeetingService.save(meeting);
reloadedIdea.setFirstMeeting(meeting);
}
return reloadedIdea;
}
@Override
@Transactional
public boolean hasTakenIdeas(User authorUser, boolean confirmed) {
@ -248,7 +272,7 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
@Override
public Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(levelFilter(params.getLevels())), pageable);
return supervisorIdeaRepo.findAll(byStatus(status).and(predicateFromParams(params)), pageable);
}
@Override
@ -284,6 +308,16 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
return supervisorIdeaRepo.countIdeasByAuthorAndStatus(author, status);
}
@Override
public Long count(FilterParams params) {
return supervisorIdeaRepo.count(predicateFromParams(params));
}
@Override
public Long countByStatusAndParams(IdeaStatus status, FilterParams params) {
return supervisorIdeaRepo.count(byStatus(status).and(predicateFromParams(params)));
}
@Override
public boolean authorParticipatingOnIdea(User user) {
Student author = studentService.findByUser(user);

@ -0,0 +1,10 @@
package se.su.dsv.scipro.springdata.services;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
public interface FirstMeetingService extends GenericService<FirstMeeting, Long>, QueryService<FirstMeeting, Long> {
FirstMeeting getMeetingByIdea(SupervisorIdea idea);
}

@ -2,6 +2,7 @@ package se.su.dsv.scipro.springdata.services;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
@ -28,6 +29,8 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
Long countByAuthorAndStatus(Student author, IdeaStatus status);
Long countByStatus(IdeaStatus status);
Long countIdeas(IdeaStatus status, Employee supervisor, ProjectClass pc);
Long count(FilterParams params);
Long countByStatusAndParams(IdeaStatus status, FilterParams params);
void saveSupervisorCreatedIdea(SupervisorIdea idea, Employee creator, SortedSet<Student> students);
void acceptIdea(SupervisorIdea idea, User mainAuthor, SortedSet<Student> sortedSet);
@ -35,6 +38,7 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
void partnerAcceptIdea(SupervisorIdea idea, User loggedInUser);
void declineIdea(SupervisorIdea idea);
void updateIdea(SupervisorIdea idea);
SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc);
boolean hasTakenIdeas(User authorUser, boolean confirmed);
boolean isIdeaEditable(SupervisorIdea idea, User currentUser);

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div wicket:id="feedback"></div>
<div wicket:id="availabilityPanel" class="append-bottom"></div>
<div class="prepend-top" wicket:id="ideaPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,25 @@
package se.su.dsv.scipro.supervisor.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.supervisor.panels.SupervisorAvailabilityPanel;
import se.su.dsv.scipro.supervisor.panels.SupervisorMatchedSupervisorIdeasPanel;
@Authorization(authorizedRoles={Roles.SYSADMIN})
public class SupervisorMySupervisorIdeasPage extends AbstractSupervisorProjectIdeaPage {
private FeedbackPanel feedbackPanel;
public SupervisorMySupervisorIdeasPage(PageParameters pp) {
super(pp);
add(feedbackPanel = new FeedbackPanel("feedback"));
feedbackPanel.setOutputMarkupId(true);
add(new SupervisorAvailabilityPanel("availabilityPanel", getUser()));
add(new SupervisorMatchedSupervisorIdeasPanel("ideaPanel", getUser()));
}
}

@ -7,7 +7,27 @@
<body>
<wicket:panel>
<form wicket:id="form">
<div wicket:id="ideaDetails"></div>
<div class="append-bottom" wicket:id="ideaDetails"></div>
<div class="prepend-top" wicket:id="meetingEnclosure">
<div class="span-8 append-bottom info-box rounded-box last">
<p>
The students won't see who is the supervisor until the
application period course start date.
</p>
A time and date for the first meeting must be selected and
saved at least X days before application period course start date.
</div>
<div class="span-6">
<div class="span-8" wicket:id="feedback"></div>
<b>First meeting:</b><br />
<input wicket:id="dateField"/><br />
<b>Place:</b><br />
<textarea wicket:id="descriptionField"></textarea>
<input type="button" wicket:id="saveButton" value="Save meeting details"/>
</div>
</div>
</form>
</wicket:panel>
</body>

@ -1,19 +1,36 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.Date;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.extensions.yui.calendar.DatePicker;
import org.apache.wicket.markup.html.basic.EnclosureContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.project.panels.ProjectIdeaDetailsPanel;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
public class SupervisorIdeaDetailsPanel extends Panel {
public abstract class SupervisorIdeaDetailsPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
public SupervisorIdeaDetailsPanel(String id, IModel<SupervisorIdea> model) {
super(id, model);
add(new SupervisorIdeaDetailsForm("form", model));
}
public abstract void updateTarget(AjaxRequestTarget target, SupervisorIdea idea);
private static final long serialVersionUID = 29731924490786784L;
private class SupervisorIdeaDetailsForm extends Form<SupervisorIdea> {
@ -23,6 +40,56 @@ public class SupervisorIdeaDetailsPanel extends Panel {
public SupervisorIdeaDetailsForm(String id, final IModel<SupervisorIdea> model) {
super(id, model);
add(new ProjectIdeaDetailsPanel("ideaDetails", model, true, true));
addFirstMeetingEnclosure(model, true);
}
private void addFirstMeetingEnclosure(final IModel<SupervisorIdea> model, boolean visibility) {
final FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
Date firstMeetingDate;
Model<String> descModel;
if (model.getObject().getFirstMeeting()!=null){
firstMeetingDate = model.getObject().getFirstMeeting().getFirstMeetingDate();
descModel = Model.of(model.getObject().getFirstMeeting().getDescription());
}
else {
firstMeetingDate = new Date();
descModel = new Model<String>();
}
final DateTextField dateField = new DateTextField("dateField", new Model<Date>(firstMeetingDate), "yyyy-MM-dd");
DatePicker datePicker = new DatePicker();
datePicker.setShowOnFieldClick(true);
dateField.add(datePicker);
final TextArea<String> meetingDescriptionField = new TextArea<String>("descriptionField", descModel);
AjaxSubmitLink saveLink = new AjaxSubmitLink("saveButton") {
private static final long serialVersionUID = -4841491128764249358L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if(meetingDescriptionField.getModelObject()==null){
error("You need to specify a place for the meeting");
} else {
SupervisorIdea idea = ideaService.saveMeeting(model.getObject(), dateField.getModelObject(), meetingDescriptionField.getModelObject());
updateTarget(target, idea);
}
target.addComponent(feedback);
}
};
//Date field controls visibility of entire container.
dateField.setVisible(visibility);
EnclosureContainer firstMeetingEnclosure = new EnclosureContainer("meetingEnclosure", dateField);
firstMeetingEnclosure.add(feedback);
firstMeetingEnclosure.add(dateField);
firstMeetingEnclosure.add(meetingDescriptionField);
firstMeetingEnclosure.add(saveLink);
add(firstMeetingEnclosure);
}

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
</head>
<body>
<wicket:panel>
<div wicket:id="dialog">
<div wicket:id="dialogPanel"></div>
</div>
<div wicket:id="feedback"></div>
<form wicket:id="form">
<div class="span-5" wicket:id="levelFilter"></div>
</form>
<div class="span-24 prepend-top" wicket:id="dataPanel"></div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,164 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.Iterator;
import org.apache.wicket.ajax.AjaxRequestTarget;
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.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.dialog.Dialog;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.datatables.BooleanIconColumn;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
import se.su.dsv.scipro.icons.ImageObject;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.panel.FilterFormProjectClass;
import se.su.dsv.scipro.reusable.SafeLongToIntService;
import se.su.dsv.scipro.springdata.services.GenericService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorService;
public class SupervisorMatchedSupervisorIdeasPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
@SpringBean
private SupervisorService supervisorService;
private GenericDataPanel<SupervisorIdea> genericDataPanel;
private SupervisorIdeaService.FilterParams params;
private Dialog dialog;
private static final long serialVersionUID = -9010467449322120267L;
public SupervisorMatchedSupervisorIdeasPanel(String id, final User supervisor) {
super(id);
FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
add(feedback);
addDialog();
addDataTable(supervisor, feedback);
add(new FilterForm("form", supervisor));
}
private void addDialog() {
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(450);
dialog.setHeight(600);
dialog.add(new EmptyPanel("dialogPanel"));
add(dialog);
}
private void addDataTable(final User supervisor, final FeedbackPanel feedback) {
add(genericDataPanel = new GenericDataPanel<SupervisorIdea>("dataPanel") {
@Override
public int getSize() {
return SafeLongToIntService.safeLongToInt(ideaService.countByStatusAndParams(IdeaStatus.TAKEN, params));
}
private static final long serialVersionUID = -4539188306454725307L;
@Override
public Iterator<SupervisorIdea> getIterator() {
return ideaService.findByStatusAndParams(IdeaStatus.TAKEN, params, new PageRequest(getTable().getCurrentPage(), getTable().getRowsPerPage(), getSort())).iterator();
}
@Override
public GenericService<SupervisorIdea, Long> getService() {
return ideaService;
}
@Override
public String getSortString() {
return "dateCreated";
}
@Override
public IColumn[] getColumns() {
IColumn[] columns = new IColumn[5];
columns[0] = new PropertyColumn<SupervisorIdea>(Model.of("Date"), "dateCreated", "dateCreated");
columns[1] = new PropertyColumn<SupervisorIdea>(Model.of("Level"), "projectClass", "projectClass");
columns[2] = new ClickableTitleColumn<SupervisorIdea>(Model.of("Title"), "title", "title") {
private static final long serialVersionUID = 4667741924987868274L;
@Override
protected void onClick(final IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget target) {
dialog.replace(new SupervisorIdeaDetailsPanel("dialogPanel", ideaModel){
private static final long serialVersionUID = -1970068053928444580L;
@Override
public void updateTarget(AjaxRequestTarget target, SupervisorIdea idea) {
dialog.close(target);
info("Meeting details saved");
ideaModel.setObject(idea);
target.addComponent(feedback);
target.addComponent(getWMC());
}
});
dialog.setTitle("Selected supervisor project idea");
target.addComponent(dialog);
dialog.open(target);
}
};
columns[3] = new PropertyColumn<SupervisorIdea>(Model.of("Author(s)"), "ideaParticipations");
columns[4] = new BooleanIconColumn<SupervisorIdea>(Model.of("First meeting added?"), ImageObject.CHECK, ImageObject.DELETE){
private static final long serialVersionUID = -6759283830735306302L;
@Override
protected boolean booleanValue(IModel<SupervisorIdea> ideaModel) {
return ideaModel.getObject().getFirstMeeting()!=null;
}
};
return columns;
}
});
}
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 6581597176580961782L;
public FilterForm(String id, User user) {
super(id);
params = new SupervisorIdeaService.FilterParams();
//FILTERING ON PROJECT CLASS:
final FilterFormProjectClass levelFilter = new FilterFormProjectClass("levelFilter", null) {
private static final long serialVersionUID = -7758850229259608443L;
@Override
public void ajaxUpdate(AjaxRequestTarget target) {
if(!getProjectClasses().isEmpty()){
params.setLevels(getProjectClasses());
}
target.addComponent(genericDataPanel.getWMC());
}
};
params.setLevels(levelFilter.getProjectClasses());
Employee supervisor = supervisorService.findByUser(user);
params.setSupervisor(supervisor);
add(levelFilter);
}
}
}

@ -5,9 +5,7 @@
</head>
<body>
<wicket:panel>
<div wicket:id="dialog">
<div wicket:id="dialogPanel"></div>
</div>
<div wicket:id="feedback"></div>
<form wicket:id="form">
<div class="span-5" wicket:id="levelFilter"></div>
<div class="span-5">

@ -8,22 +8,21 @@ import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
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.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.dialog.Dialog;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.datatables.ClickableIconColumn;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
import se.su.dsv.scipro.icons.ImageIcon;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.panel.FilterFormProjectClass;
import se.su.dsv.scipro.reusable.SafeLongToIntService;
import se.su.dsv.scipro.springdata.services.GenericService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorService;
@ -37,28 +36,19 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
private SupervisorService supervisorService;
private GenericDataPanel<SupervisorIdea> genericDataPanel;
private SupervisorIdeaService.FilterParams params;
private Dialog dialog;
private static final long serialVersionUID = -9010467449322120267L;
public SupervisorProjectIdeaOverviewPanel(String id, final User supervisor) {
super(id);
addDialog();
addDataTable(supervisor);
FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
add(feedback);
addDataTable(supervisor, feedback);
add(new FilterForm("form", supervisor));
}
private void addDialog() {
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(500);
dialog.setHeight(600);
dialog.add(new EmptyPanel("dialogPanel"));
add(dialog);
}
private void addDataTable(final User supervisor) {
private void addDataTable(final User supervisor, final FeedbackPanel feedback) {
add(genericDataPanel = new GenericDataPanel<SupervisorIdea>("dataPanel") {
private static final long serialVersionUID = -4539188306454725307L;
@ -68,6 +58,11 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
return ideaService.findAll(params, new PageRequest(getTable().getCurrentPage(), getTable().getRowsPerPage(), getSort())).iterator();
}
@Override
public int getSize(){
return SafeLongToIntService.safeLongToInt(ideaService.count(params));
}
@Override
public GenericService<SupervisorIdea, Long> getService() {
return ideaService;
@ -83,18 +78,7 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
IColumn[] columns = new IColumn[7];
columns[0] = new PropertyColumn<SupervisorIdea>(Model.of("Date"), "dateCreated", "dateCreated");
columns[1] = new PropertyColumn<SupervisorIdea>(Model.of("Level"), "projectClass", "projectClass");
columns[2] = new ClickableTitleColumn<SupervisorIdea>(Model.of("Title"), "title", "title") {
private static final long serialVersionUID = 4667741924987868274L;
@Override
protected void onClick(IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget target) {
dialog.replace(new SupervisorIdeaDetailsPanel("dialogPanel", ideaModel));
dialog.setTitle("Selected supervisor project idea");
target.addComponent(dialog);
dialog.open(target);
}
};
columns[2] = new PropertyColumn<SupervisorIdea>(Model.of("Title"), "title", "title");
columns[3] = new PropertyColumn<SupervisorIdea>(Model.of("Creator"), "creator.user.lastName", "creator");
columns[4] = new PropertyColumn<SupervisorIdea>(Model.of("Status"), "ideaStatus", "ideaStatus");
columns[5] = new ClickableIconColumn<SupervisorIdea>(Model.of("Edit"), null, ImageIcon.ICON_EDIT) {

@ -10,6 +10,7 @@ import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorProje
import se.su.dsv.scipro.supervisor.pages.AbstractSupervisorProjectIdeaPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorInterestPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorMyProjectIdeasPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorMySupervisorIdeasPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorProjectIdeaStartPage;
public class SupervisorProjectIdeaTabMenuPanel extends AbstractMenuPanel{
@ -24,6 +25,7 @@ public class SupervisorProjectIdeaTabMenuPanel extends AbstractMenuPanel{
protected List<MenuItem> getItemList() {
List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Supervisor project ideas", SupervisorProjectIdeaStartPage.class, MenuHighlightSupervisorProjectIdea.class));
items.add(new MenuItem("My matched supervisor project ideas", SupervisorMySupervisorIdeasPage.class));
items.add(new MenuItem("Unmatched student project ideas", SupervisorInterestPage.class));
items.add(new MenuItem("My matched student project ideas", SupervisorMyProjectIdeasPage.class));
return items;

@ -1,10 +1,14 @@
package se.su.dsv.scipro.springdata;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@ -29,6 +33,7 @@ import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.Keyword;
@ -70,6 +75,7 @@ public class TestSupervisorIdea {
private SupervisorIdea waitingBachelorIdea, waitingMasterIdea, takenBachelorIdea, completedMasterIdea, waitingBachelor2, waitingMaster2, waitingBachelor3;
private ApplicationPeriod bachelorPeriod, masterPeriod;
private Keyword keyword1, keyword2;
private SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
@Before
public void startTransaction() throws Exception {
@ -410,6 +416,18 @@ public class TestSupervisorIdea {
Assert.assertNotNull(idea.getApplicationPeriod());
}
@Test
@Transactional
@Rollback
public void testCreateFirstMeeting() {
Date firstMeetingDate = date("2012-08-01");
FirstMeeting firstMeeting = new FirstMeeting(firstMeetingDate, "First meeting description", takenBachelorIdea);
takenBachelorIdea.setFirstMeeting(firstMeeting);
Assert.assertEquals(firstMeetingDate, takenBachelorIdea.getFirstMeeting().getFirstMeetingDate());
Assert.assertEquals("First meeting description", takenBachelorIdea.getFirstMeeting().getDescription());
Assert.assertEquals(takenBachelorIdea, takenBachelorIdea.getFirstMeeting().getSupervisorIdea());
}
// HELPER METHODS
private SupervisorIdea newIdea(ProjectClass pc, ApplicationPeriod ap, Employee supervisor, IdeaStatus ideaStatus) {
SupervisorIdea idea = new SupervisorIdea();
@ -455,4 +473,12 @@ public class TestSupervisorIdea {
}
return list;
}
private Date date(String dateString) {
try {
return date.parse(dateString);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}