diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java index 0d796f05b2e90acf6b5bac5f4108710fcd30d5ec..bc8d28a3bc7e23abc1b7cd544d369c5fdde32c3c 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java @@ -6,9 +6,10 @@ import unipotsdam.gf.modules.annotation.controller.AnnotationController; import unipotsdam.gf.modules.assessment.controller.service.AssessmentDBCommunication; import unipotsdam.gf.modules.assessment.controller.service.PeerAssessment; import unipotsdam.gf.modules.communication.service.CommunicationDummyService; -import unipotsdam.gf.modules.group.DummyGroupfinding; import unipotsdam.gf.modules.group.DummyProjectCreationService; import unipotsdam.gf.modules.group.GroupDAO; +import unipotsdam.gf.modules.group.GroupfindingImpl; +import unipotsdam.gf.modules.journal.service.IJournalImpl; import unipotsdam.gf.modules.project.Management; import unipotsdam.gf.modules.project.ManagementImpl; import unipotsdam.gf.modules.project.ProjectConfigurationDAO; @@ -34,12 +35,12 @@ public class GFApplicationBinder extends AbstractBinder { protected void configure() { bind(CommunicationDummyService.class).to(ICommunication.class); bind(ManagementImpl.class).to(Management.class); - bind(PeerAssessment.class).to(IPeerAssessment.class); bind(PhasesImpl.class).to(IPhases.class); bind(ManagementImpl.class).to(Management.class); bind(DummyResearchReportManagement.class).to(ResearchReportManagement.class); - bind(DummyGroupfinding.class).to(IGroupFinding.class); + bind(IJournalImpl.class).to(IJournal.class); + bind(GroupfindingImpl.class).to(IGroupFinding.class); bind(AssessmentDBCommunication.class).to(AssessmentDBCommunication.class); bind(GFContexts.class).to(GFContexts.class); bind(ProjectCreationProcess.class).to(ProjectCreationProcess.class); diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java index 977056d194b92c84f552223b13ceae3e64933c25..a618c43f01312c2ac788665c6d34debe5ce72d0b 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java @@ -11,9 +11,5 @@ public interface IPhases { */ void endPhase(Phase phase, Project project); - /** - * the dependency to feedback should be settable externally for test reasons - * @param feedback the feedback that is send - */ - void setFeedback(Feedback feedback); + } diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/group/DummyGroupfinding.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/group/DummyGroupfinding.java deleted file mode 100644 index b1fd4dc7c149e6d9f86f22aab8ff259d4a989f31..0000000000000000000000000000000000000000 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/group/DummyGroupfinding.java +++ /dev/null @@ -1,46 +0,0 @@ -package unipotsdam.gf.modules.group; - -import unipotsdam.gf.modules.project.Project; -import unipotsdam.gf.assignments.Assignee; -import unipotsdam.gf.assignments.NotImplementedLogger; -import unipotsdam.gf.interfaces.IGroupFinding; -import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier; - -import java.util.ArrayList; -import java.util.List; - -public class DummyGroupfinding implements IGroupFinding { - @Override - public void selectGroupfindingCriteria( - GroupfindingCriteria groupfindingCriteria, Project project) { - NotImplementedLogger.logAssignment(Assignee.MIRJAM, IGroupFinding.class); - } - - @Override - public void persistGroups( - List<Group> groupComposition, Project project){ - NotImplementedLogger.logAssignment(Assignee.MIRJAM, IGroupFinding.class); - } - - @Override - public List<Group> getGroups(Project project) { - NotImplementedLogger.logAssignment(Assignee.MIRJAM, IGroupFinding.class); - return new ArrayList<>(); - } - - @Override - public void formGroups(GroupFormationMechanism groupFindingMechanism) { - NotImplementedLogger.logAssignment(Assignee.MIRJAM, IGroupFinding.class); - } - - @Override - public ArrayList<String> getStudentsInSameGroup( - StudentIdentifier student) { - return null; - } - - @Override - public int getMinNumberOfStudentsNeeded(Project project) { - return 2; - } -} diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/project/ProjectView.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/project/ProjectView.java index e801d77eb55ff415695dfa04d68572e74ecae027..ab8525d346360372a68f0e3ef601f96bd5327f8a 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/project/ProjectView.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/project/ProjectView.java @@ -29,9 +29,6 @@ public class ProjectView { @Inject private Management iManagement; - @Inject - private TaskDAO taskDao; - @Inject private ProjectCreationProcess projectCreationProcess; diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java index ef4d12609009fb1343d73161235c38d7c591766b..7574532bd0534d49af1a66037d3924cbab128f6b 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/submission/controller/SubmissionController.java @@ -2,6 +2,8 @@ package unipotsdam.gf.modules.submission.controller; import com.google.common.base.Strings; import org.slf4j.LoggerFactory; +import unipotsdam.gf.modules.group.GroupDAO; +import unipotsdam.gf.modules.group.GroupFormationMechanism; import unipotsdam.gf.modules.project.Project; import unipotsdam.gf.modules.project.ProjectDAO; import unipotsdam.gf.modules.submission.view.SubmissionRenderData; @@ -22,6 +24,7 @@ import unipotsdam.gf.process.phases.Phase; import unipotsdam.gf.process.progress.HasProgress; import unipotsdam.gf.process.progress.ProgressData; import unipotsdam.gf.process.tasks.FeedbackTaskData; +import unipotsdam.gf.process.tasks.ParticipantsCount; import javax.inject.Inject; import java.util.ArrayList; @@ -41,7 +44,10 @@ public class SubmissionController implements ISubmission, HasProgress { private UserDAO userDAO; @Inject - private ConstraintsImpl constraints; + private GroupDAO groupDAO; + + @Inject + private ProjectDAO projectDAO; private static final org.slf4j.Logger log = LoggerFactory.getLogger(SubmissionController.class); @@ -570,8 +576,8 @@ public class SubmissionController implements ISubmission, HasProgress { */ public void markAsFinal(FullSubmission fullSubmission) { connection.connect(); - String query = "update fullsubmission set finalized = ? where id = ?"; - connection.issueUpdateStatement(query, true, fullSubmission.getId()); + String query = "update fullsubmissions set finalized = ? where id = ?"; + connection.issueUpdateStatement(query, 1, fullSubmission.getId()); connection.close(); } @@ -616,7 +622,7 @@ public class SubmissionController implements ISubmission, HasProgress { Integer count = null; String query = "SELECT COUNT(*) from fullsubmissions where projectName = ? and finalized = ?"; - VereinfachtesResultSet vereinfachtesResultSet = connection.issueSelectStatement(query); + VereinfachtesResultSet vereinfachtesResultSet = connection.issueSelectStatement(query, project.getName(), true); vereinfachtesResultSet.next(); count = vereinfachtesResultSet.getInt(1); connection.close(); @@ -633,13 +639,58 @@ public class SubmissionController implements ISubmission, HasProgress { progressData.setNumberOfCompletion(getFinalizedDossiersCount(project)); // the number of dossiers needed relativ to the group or user count - progressData.setNumberNeeded(constraints.dossiersNeeded(project)); - List<User> strugglersWithSubmission = constraints.getStrugglersWithSubmission(project); + progressData.setNumberNeeded(dossiersNeeded(project)); + List<User> strugglersWithSubmission = getStrugglersWithSubmission(project); progressData.setUsersMissing(strugglersWithSubmission); progressData.setAlmostComplete((progressData.getNumberNeeded()/progressData.getNumberOfCompletion()) <= (1/10)); return progressData; } + /** + * get how many dossiers are needed + * + * @param project + * @return + */ + public int dossiersNeeded(Project project) { + GroupFormationMechanism groupFormationMechanism = groupDAO.getGroupFormationMechanism(project); + Integer result = 0; + switch (groupFormationMechanism) { + case SingleUser: + ParticipantsCount participantCount = projectDAO.getParticipantCount(project); + result = participantCount.getParticipants(); + break; + case LearningGoalStrategy: + case UserProfilStrategy: + case Manual: + int groupCount = groupDAO.getGroupsByProjectName(project.getName()).size(); + result = groupCount; + break; + } + return result; + } + + + public List<User> getStrugglersWithSubmission(Project project) { + ArrayList<User> struggles = new ArrayList<>(); + GroupFormationMechanism groupFormationMechanism = groupDAO.getGroupFormationMechanism(project); + switch (groupFormationMechanism) { + case SingleUser: + List<User> usersInProject = userDAO.getUsersByProjectName(project.getName()); + List<User> usersHavingGivenFeedback = getAllUsersWithFeedbackGiven(project); + for (User user : usersInProject) { + if (!usersHavingGivenFeedback.contains(user)) { + struggles.add(user); + } + } + break; + case LearningGoalStrategy: + case Manual: + case UserProfilStrategy: + } + return struggles; + } + public List<User> getAllUsersWithFeedbackGiven(Project project) { List<User> result = new ArrayList<>(); connection.connect(); diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/ProjectCreationProcess.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/ProjectCreationProcess.java index 4eb53bd199224307b91b2e994b026c6693b57150..6549b063b6ba49b1cb2b4d450e06f0894111e243 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/ProjectCreationProcess.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/ProjectCreationProcess.java @@ -35,8 +35,6 @@ public class ProjectCreationProcess { @Inject private GroupDAO groupDAO; - @Inject - private IPhases phases; /** * STEP 1 diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/constraints/ConstraintsImpl.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/constraints/ConstraintsImpl.java index 04edebe8d34edfc19296e6e768d122b91873d971..7948515f03de3c89904bbcfe0739146b6bde5e24 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/constraints/ConstraintsImpl.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/constraints/ConstraintsImpl.java @@ -73,50 +73,7 @@ public class ConstraintsImpl { return result; } - /** - * get how many dossiers are needed - * - * @param project - * @return - */ - public int dossiersNeeded(Project project) { - GroupFormationMechanism groupFormationMechanism = groupDAO.getGroupFormationMechanism(project); - Integer result = 0; - switch (groupFormationMechanism) { - case SingleUser: - ParticipantsCount participantCount = projectDAO.getParticipantCount(project); - result = participantCount.getParticipants(); - break; - case LearningGoalStrategy: - case UserProfilStrategy: - case Manual: - int groupCount = groupDAO.getGroupsByProjectName(project.getName()).size(); - result = groupCount; - break; - } - return result; - } - public List<User> getStrugglersWithSubmission(Project project) { - ArrayList<User> struggles = new ArrayList<>(); - GroupFormationMechanism groupFormationMechanism = groupDAO.getGroupFormationMechanism(project); - switch (groupFormationMechanism) { - case SingleUser: - List<User> usersInProject = userDAO.getUsersByProjectName(project.getName()); - List<User> usersHavingGivenFeedback = submissionController.getAllUsersWithFeedbackGiven(project); - for (User user : usersInProject) { - if (!usersHavingGivenFeedback.contains(user)) { - struggles.add(user); - } - } - break; - case LearningGoalStrategy: - case Manual: - case UserProfilStrategy: - } - return struggles; - } - } diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/phases/PhasesImpl.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/phases/PhasesImpl.java index e6cf044bc273faaad34edb25a43bf43cef8cac36..891d6f8560f54b83e76898a347e19f9ea61eaa5c 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/process/phases/PhasesImpl.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/process/phases/PhasesImpl.java @@ -35,9 +35,6 @@ public class PhasesImpl implements IPhases { @Inject private IPeerAssessment iPeerAssessment; - @Inject - private Feedback feedback; - @Inject private ICommunication iCommunication; @@ -47,8 +44,7 @@ public class PhasesImpl implements IPhases { @Inject private DossierCreationProcess dossierCreationProcess; - @Inject - private ConstraintsImpl constraints; + public PhasesImpl() { @@ -152,7 +148,5 @@ public class PhasesImpl implements IPhases { } - public void setFeedback(Feedback feedback) { - this.feedback = feedback; - } + } diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/taglibs/OmniDependencies.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/taglibs/OmniDependencies.java index 567d1c06632be56ed86d527c9855120b2733aa92..695dfb171f63823a7bdc2019ca809eea078a2fe9 100644 --- a/gemeinsamforschen/src/main/java/unipotsdam/gf/taglibs/OmniDependencies.java +++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/taglibs/OmniDependencies.java @@ -29,7 +29,7 @@ public class OmniDependencies extends SimpleTagSupport { " <link rel=\"stylesheet\" href=\"" + hierarchyToString(hierarchyLevel) + "project/css/style.css\" type=\"text/css\">" + " <link rel=\"stylesheet\" href=\"" + hierarchyToString(hierarchyLevel) + "libs/tagsinput/jquery.tagsinput.min.css\">\n" + " <script src=\"" + hierarchyToString(hierarchyLevel) + "libs/tagsinput/jquery.tagsinput.min.js\"></script>\n" + - " <script type=\"text/javascript\" src=\"http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.js\"></script>"+ + " <script type=\"text/javascript\" src=\"" + hierarchyToString(hierarchyLevel) + "libs/jquery/jqueryTemplate.js\"></script>"+ " <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.1.0/css/all.css\"\n" + " integrity=\"sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt\" crossorigin=\"anonymous\">"); } diff --git a/gemeinsamforschen/src/main/webapp/annotation/create-unstructured-annotation.jsp b/gemeinsamforschen/src/main/webapp/annotation/create-unstructured-annotation.jsp index 38e1e30796f0eccea62b0de4c9f1f3f589c34aba..ab27a239b3bdfa56f0fe995fbeac4007c5ede6d9 100644 --- a/gemeinsamforschen/src/main/webapp/annotation/create-unstructured-annotation.jsp +++ b/gemeinsamforschen/src/main/webapp/annotation/create-unstructured-annotation.jsp @@ -2,6 +2,7 @@ <%@ taglib uri="../taglibs/gemeinsamForschen.tld" prefix="menu" %> <%@ taglib uri="../taglibs/gemeinsamForschen.tld" prefix="headLine" %> <%@ taglib uri="../taglibs/gemeinsamForschen.tld" prefix="omniDependencies" %> +<%@ taglib uri="../taglibs/gemeinsamForschen.tld" prefix="footer" %> <!DOCTYPE html> <html> @@ -37,75 +38,37 @@ <body> <menu:menu hierarchy="1"/> -<div id="wrapper"> - <div class="page-content-wrapper full-height"> - <div class="container-fluid full-height"> - <div class="container-fluid-content"> - <div class="flex"> - <headLine:headLine/> - </div> - <div class="content-mainpage"> - <div class="leftcolumn"> - <div class="leftcontent"> - <div class="leftcontent-text context-menu-one" id="documentText"></div> - <div class="leftcontent-buttons"> - <div class="leftcontent-buttons-save"> - <button id="btnSave" type="button" class="btn btn-secondary">Speichern</button> - </div> - </div> - </div> - </div> - <div class="rightcolumn"> - <div class="rightcontent"> - <ol id="annotations"> - <li class="spacing"> - <div id="titel" class="category-card not-added"> - <p>Titel</p> - </div> - </li> - <li class="spacing"> - <div id="recherche" class="category-card not-added"> - <p>Recherche</p> - </div> - </li> - <li class="spacing"> - <div id="literaturverzeichnis" class="category-card not-added"> - <p>Literaturverzeichnis</p> - </div> - </li> - <li class="spacing"> - <div id="forschungsfrage" class="category-card not-added"> - <p>Forschungsfrage</p> - </div> - </li> - <li class="spacing"> - <div id="untersuchungskonzept" class="category-card not-added"> - <p>Untersuchungskonzept</p> - </div> - </li> - <li class="spacing"> - <div id="methodik" class="category-card not-added"> - <p>Methodik</p> - </div> - </li> - <li class="spacing"> - <div id="durchfuehrung" class="category-card not-added"> - <p>Durchführung</p> - </div> - </li> - <li> - <div id="auswertung" class="category-card not-added"> - <p>Auswertung</p> - </div> - </li> - </ol> - </div> +<div class="col span_l_of_2"> <!-- col right--> + <headLine:headLine/> + <div class="content-mainpage"> + <div class="leftcolumn"> + <div class="leftcontent"> + <div class="leftcontent-text context-menu-one" id="documentText"></div> + <div class="leftcontent-buttons"> + <div class="leftcontent-buttons-save"> + <button id="btnSave" type="button" class="btn btn-secondary">Speichern</button> </div> </div> </div> </div> + <div class="rightcolumn"> + <div id="missingAnnotation" class="alert alert-warning"></div> + <div class="rightcontent"> + <ol id="annotations"> + + </ol> + <script id="annotationTemplate" type="text/x-jQuery-tmpl"> + <li class="spacing"> + <div id="${annotationType}" class="category-card not-added"> + <p>${annotationType}</p> + </div> + </li> + </script> + </div> + </div> </div> </div> +<footer:footer/> </body> </html> diff --git a/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredAnnotation.js b/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredAnnotation.js index e4d1849ad362d85025b15fe0fcd2256ab9fe9d9c..4964685f40f85957c657686a3162f5fe5b7a7ee3 100644 --- a/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredAnnotation.js +++ b/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredAnnotation.js @@ -2,14 +2,15 @@ * This function will fire when the DOM is ready */ $(document).ready(function () { - + $('#missingAnnotation').hide(); + buildAnnotationList(); // fetch the document text of the given id - getFullSubmission(getSubmissionIdFromUrl(), function (response) { + getFullSubmission(getQueryVariable("submissionId"), function (response) { // set text in div $('#documentText').text(response.text); // get submissions parts from database - getAllSubmissionParts(getSubmissionIdFromUrl(), function (response) { + getAllSubmissionParts(getQueryVariable("submissionId"), function (response) { // iterate over response for (let i = 0; i < response.length; i++) { @@ -67,22 +68,6 @@ $(document).ready(function () { }); -/** - * Get the id of a full submission from url - * - * @returns The id of the full submission - */ -function getSubmissionIdFromUrl() { - var parts = window.location.search.substr(1).split("&"); - var $_GET = {}; - for (var i = 0; i < parts.length; i++) { - var temp = parts[i].split("="); - $_GET[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]); - } - return $_GET['submissionId']; - -} - /** * Handel the category selection * @@ -141,17 +126,17 @@ function getSelectedText() { */ function addHighlightedText(startCharacter, endCharacter, category, offset) { - var documentText = $('#documentText').text(); - var documentHtml = $('#documentText').html(); + let documentText = $('#documentText').text(); + let documentHtml = $('#documentText').html(); // create <span> tag with the annotated text - var replacement = $('<span></span>').attr('class', category).html(documentText.slice(startCharacter, endCharacter)); + let replacement = $('<span></span>').attr('class', category).html(documentText.slice(startCharacter, endCharacter)); // wrap an <p> tag around the replacement, get its parent (the <p>) and ask for the html - var replacementHtml = replacement.wrap('<p/>').parent().html(); + let replacementHtml = replacement.wrap('<p/>').parent().html(); // insert the replacementHtml - var newDocument = documentHtml.slice(0, startCharacter + offset) + replacementHtml + documentHtml.slice(endCharacter + offset); + let newDocument = documentHtml.slice(0, startCharacter + offset) + replacementHtml + documentHtml.slice(endCharacter + offset); // set new document text $('#documentText').html(newDocument); @@ -249,6 +234,7 @@ function saveButtonHandler() { if (window.confirm("Möchten Sie wirklich ihre Annotationen speichern?")) { // declare array of promises let promises = []; + let categoriesSent = []; $('#annotations').find('.category-card').each(function () { let array = $(this).data('array'); if (array != null) { @@ -257,7 +243,7 @@ function saveButtonHandler() { let category = $(this).attr('id').toUpperCase(); let submissionPartPostRequest = { userEmail: getUserEmail(), - fullSubmissionId: getSubmissionIdFromUrl(), + fullSubmissionId: getQueryVariable("submissionId"), category: category, body: [] }; @@ -280,13 +266,20 @@ function saveButtonHandler() { promises.push(createSubmissionPart(submissionPartPostRequest, function (response) { console.log("send " + response.category + "'s post request to back-end") })); - + categoriesSent.push(category); } }); $.when.apply($, promises).then(function () { - // redirect user to project page after saving - finalizeDossier(getSubmissionIdFromUrl()); + let categories = ["TITEL", "RECHERCHE", "LITERATURVERZEICHNIS", "FORSCHUNGSFRAGE", "UNTERSUCHUNGSKONZEPT", + "METHODIK", "DURCHFUEHRUNG", "AUSWERTUNG"]; + if (categoriesSent.length === categories.length){ + finalizeDossier(getQueryVariable("submissionId")); + }else{ + let missingAnnotation = $('#missingAnnotation'); + missingAnnotation.show(); + missingAnnotation.text("Sie haben noch nicht alle Kategorien markiert"); + } }); // redirect user to project page after saving @@ -299,7 +292,7 @@ function saveButtonHandler() { * */ function finalizeDossier(submissionId) { - let requestObj = new RequestObj(1,"/submissions","/id/?/finalize", [submissionId]) + let requestObj = new RequestObj(1,"/submissions","/id/?/projects/?/finalize", [submissionId, $('#projectName').text().trim()]); serverSide(requestObj, "POST", function (response) { location.href = "../project/tasks-student.jsp?projectName=" + getQueryVariable('projectName'); }) @@ -328,5 +321,13 @@ function handleCategoryClick(key) { handleCategorySelection(key, startCharacter, endCharacter); } } +} +function buildAnnotationList(){ + let categories = ["TITEL", "RECHERCHE", "LITERATURVERZEICHNIS", "FORSCHUNGSFRAGE", "UNTERSUCHUNGSKONZEPT", + "METHODIK", "DURCHFUEHRUNG", "AUSWERTUNG"]; + for (let i in categories){ + let tmplObject = {annotationType: categories[i].toLowerCase()}; + $('#annotationTemplate').tmpl(tmplObject).appendTo('#annotations'); + } } diff --git a/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredRest.js b/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredRest.js index f3c37746cc684e31d7539d48ea217b9214aa79b8..34215f44d033f43911233860ef5aff78df34c64c 100644 --- a/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredRest.js +++ b/gemeinsamforschen/src/main/webapp/annotation/js/unstructuredRest.js @@ -27,7 +27,7 @@ function createFullSubmission(fullSubmissionPostRequest, responseHandler) { * @param errorHandler The error handler */ function getFullSubmission(id, responseHandler, errorHandler) { - var url = "../rest/submissions/full/" + id; + let url = "../rest/submissions/full/" + id; $.ajax({ url: url, type: "GET", @@ -51,8 +51,8 @@ function getFullSubmission(id, responseHandler, errorHandler) { * @returns A promise object */ function createSubmissionPart(submissionPartPostRequest, responseHandler) { - var url = "../rest/submissions/part/"; - var json = JSON.stringify(submissionPartPostRequest); + let url = "../rest/submissions/part/"; + let json = JSON.stringify(submissionPartPostRequest); return $.ajax({ url: url, type: "POST", @@ -77,7 +77,7 @@ function createSubmissionPart(submissionPartPostRequest, responseHandler) { * @param errorHandler The error handler */ function getSubmissionPart(id, category, responseHandler, errorHandler) { - var url = "../rest/submissions/full/" + id + "/category/" + category; + let url = "../rest/submissions/full/" + id + "/category/" + category; $.ajax({ url: url, type: "GET", @@ -100,7 +100,7 @@ function getSubmissionPart(id, category, responseHandler, errorHandler) { * @param responseHandler The response handler */ function getAllSubmissionParts(id, responseHandler) { - var url = "../rest/submissions/full/" + id + "/parts"; + let url = "../rest/submissions/full/" + id + "/parts"; $.ajax({ url: url, type: "GET", diff --git a/gemeinsamforschen/src/main/webapp/libs/jquery/jqueryTemplate.js b/gemeinsamforschen/src/main/webapp/libs/jquery/jqueryTemplate.js new file mode 100644 index 0000000000000000000000000000000000000000..f4cd4f3034ebee34c39400e584bf874272178998 --- /dev/null +++ b/gemeinsamforschen/src/main/webapp/libs/jquery/jqueryTemplate.js @@ -0,0 +1,486 @@ +/* + * jQuery Templating Plugin + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + */ +(function( jQuery, undefined ){ + var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /, + newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = []; + + function newTmplItem( options, parentItem, fn, data ) { + // Returns a template item data structure for a new rendered instance of a template (a 'template item'). + // The content field is a hierarchical array of strings and nested items (to be + // removed and replaced by nodes field of dom elements, once inserted in DOM). + var newItem = { + data: data || (parentItem ? parentItem.data : {}), + _wrap: parentItem ? parentItem._wrap : null, + tmpl: null, + parent: parentItem || null, + nodes: [], + calls: tiCalls, + nest: tiNest, + wrap: tiWrap, + html: tiHtml, + update: tiUpdate + }; + if ( options ) { + jQuery.extend( newItem, options, { nodes: [], parent: parentItem } ); + } + if ( fn ) { + // Build the hierarchical content to be used during insertion into DOM + newItem.tmpl = fn; + newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem ); + newItem.key = ++itemKey; + // Keep track of new template item, until it is stored as jQuery Data on DOM element + (stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem; + } + return newItem; + } + + // Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core). + jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" + }, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems, + parent = this.length === 1 && this[0].parentNode; + + appendToTmplItems = newTmplItems || {}; + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) { + insert[ original ]( this[0] ); + ret = this; + } else { + for ( i = 0, l = insert.length; i < l; i++ ) { + cloneIndex = i; + elems = (i > 0 ? this.clone(true) : this).get(); + jQuery.fn[ original ].apply( jQuery(insert[i]), elems ); + ret = ret.concat( elems ); + } + cloneIndex = 0; + ret = this.pushStack( ret, name, insert.selector ); + } + tmplItems = appendToTmplItems; + appendToTmplItems = null; + jQuery.tmpl.complete( tmplItems ); + return ret; + }; + }); + + jQuery.fn.extend({ + // Use first wrapped element as template markup. + // Return wrapped set of template items, obtained by rendering template against data. + tmpl: function( data, options, parentItem ) { + return jQuery.tmpl( this[0], data, options, parentItem ); + }, + + // Find which rendered template item the first wrapped DOM element belongs to + tmplItem: function() { + return jQuery.tmplItem( this[0] ); + }, + + // Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template. + template: function( name ) { + return jQuery.template( name, this[0] ); + }, + + domManip: function( args, table, callback, options ) { + // This appears to be a bug in the appendTo, etc. implementation + // it should be doing .call() instead of .apply(). See #6227 + if ( args[0] && args[0].nodeType ) { + var dmArgs = jQuery.makeArray( arguments ), argsLength = args.length, i = 0, tmplItem; + while ( i < argsLength && !(tmplItem = jQuery.data( args[i++], "tmplItem" ))) {} + if ( argsLength > 1 ) { + dmArgs[0] = [jQuery.makeArray( args )]; + } + if ( tmplItem && cloneIndex ) { + dmArgs[2] = function( fragClone ) { + // Handler called by oldManip when rendered template has been inserted into DOM. + jQuery.tmpl.afterManip( this, fragClone, callback ); + }; + } + oldManip.apply( this, dmArgs ); + } else { + oldManip.apply( this, arguments ); + } + cloneIndex = 0; + if ( !appendToTmplItems ) { + jQuery.tmpl.complete( newTmplItems ); + } + return this; + } + }); + + jQuery.extend({ + // Return wrapped set of template items, obtained by rendering template against data. + tmpl: function( tmpl, data, options, parentItem ) { + var ret, topLevel = !parentItem; + if ( topLevel ) { + // This is a top-level tmpl call (not from a nested template using {{tmpl}}) + parentItem = topTmplItem; + tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl ); + wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level + } else if ( !tmpl ) { + // The template item is already associated with DOM - this is a refresh. + // Re-evaluate rendered template for the parentItem + tmpl = parentItem.tmpl; + newTmplItems[parentItem.key] = parentItem; + parentItem.nodes = []; + if ( parentItem.wrapped ) { + updateWrapped( parentItem, parentItem.wrapped ); + } + // Rebuild, without creating a new template item + return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) )); + } + if ( !tmpl ) { + return []; // Could throw... + } + if ( typeof data === "function" ) { + data = data.call( parentItem || {} ); + } + if ( options && options.wrapped ) { + updateWrapped( options, options.wrapped ); + } + ret = jQuery.isArray( data ) ? + jQuery.map( data, function( dataItem ) { + return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null; + }) : + [ newTmplItem( options, parentItem, tmpl, data ) ]; + return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret; + }, + + // Return rendered template item for an element. + tmplItem: function( elem ) { + var tmplItem; + if ( elem instanceof jQuery ) { + elem = elem[0]; + } + while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {} + return tmplItem || topTmplItem; + }, + + // Set: + // Use $.template( name, tmpl ) to cache a named template, + // where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc. + // Use $( "selector" ).template( name ) to provide access by name to a script block template declaration. + + // Get: + // Use $.template( name ) to access a cached template. + // Also $( selectorToScriptBlock ).template(), or $.template( null, templateString ) + // will return the compiled template, without adding a name reference. + // If templateString includes at least one HTML tag, $.template( templateString ) is equivalent + // to $.template( null, templateString ) + template: function( name, tmpl ) { + if (tmpl) { + // Compile template and associate with name + if ( typeof tmpl === "string" ) { + // This is an HTML string being passed directly in. + tmpl = buildTmplFn( tmpl ) + } else if ( tmpl instanceof jQuery ) { + tmpl = tmpl[0] || {}; + } + if ( tmpl.nodeType ) { + // If this is a template block, use cached copy, or generate tmpl function and cache. + tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML )); + } + return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl; + } + // Return named compiled template + return name ? (typeof name !== "string" ? jQuery.template( null, name ): + (jQuery.template[name] || + // If not in map, treat as a selector. (If integrated with core, use quickExpr.exec) + jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null; + }, + + encode: function( text ) { + // Do HTML encoding replacing < > & and ' and " by corresponding entities. + return ("" + text).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'"); + } + }); + + jQuery.extend( jQuery.tmpl, { + tag: { + "tmpl": { + _default: { $2: "null" }, + open: "if($notnull_1){_=_.concat($item.nest($1,$2));}" + // tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions) + // This means that {{tmpl foo}} treats foo as a template (which IS a function). + // Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}. + }, + "wrap": { + _default: { $2: "null" }, + open: "$item.calls(_,$1,$2);_=[];", + close: "call=$item.calls();_=call._.concat($item.wrap(call,_));" + }, + "each": { + _default: { $2: "$index, $value" }, + open: "if($notnull_1){$.each($1a,function($2){with(this){", + close: "}});}" + }, + "if": { + open: "if(($notnull_1) && $1a){", + close: "}" + }, + "else": { + _default: { $1: "true" }, + open: "}else if(($notnull_1) && $1a){" + }, + "html": { + // Unecoded expression evaluation. + open: "if($notnull_1){_.push($1a);}" + }, + "=": { + // Encoded expression evaluation. Abbreviated form is ${}. + _default: { $1: "$data" }, + open: "if($notnull_1){_.push($.encode($1a));}" + }, + "!": { + // Comment tag. Skipped by parser + open: "" + } + }, + + // This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events + complete: function( items ) { + newTmplItems = {}; + }, + + // Call this from code which overrides domManip, or equivalent + // Manage cloning/storing template items etc. + afterManip: function afterManip( elem, fragClone, callback ) { + // Provides cloned fragment ready for fixup prior to and after insertion into DOM + var content = fragClone.nodeType === 11 ? + jQuery.makeArray(fragClone.childNodes) : + fragClone.nodeType === 1 ? [fragClone] : []; + + // Return fragment to original caller (e.g. append) for DOM insertion + callback.call( elem, fragClone ); + + // Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data. + storeTmplItems( content ); + cloneIndex++; + } + }); + + //========================== Private helper functions, used by code above ========================== + + function build( tmplItem, nested, content ) { + // Convert hierarchical content into flat string array + // and finally return array of fragments ready for DOM insertion + var frag, ret = content ? jQuery.map( content, function( item ) { + return (typeof item === "string") ? + // Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM. + (tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) : + // This is a child template item. Build nested template. + build( item, tmplItem, item._ctnt ); + }) : + // If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}. + tmplItem; + if ( nested ) { + return ret; + } + + // top-level template + ret = ret.join(""); + + // Support templates which have initial or final text nodes, or consist only of text + // Also support HTML entities within the HTML markup. + ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) { + frag = jQuery( middle ).get(); + + storeTmplItems( frag ); + if ( before ) { + frag = unencode( before ).concat(frag); + } + if ( after ) { + frag = frag.concat(unencode( after )); + } + }); + return frag ? frag : unencode( ret ); + } + + function unencode( text ) { + // Use createElement, since createTextNode will not render HTML entities correctly + var el = document.createElement( "div" ); + el.innerHTML = text; + return jQuery.makeArray(el.childNodes); + } + + // Generate a reusable function that will serve to render a template against data + function buildTmplFn( markup ) { + return new Function("jQuery","$item", + "var $=jQuery,call,_=[],$data=$item.data;" + + + // Introduce the data as local variables using with(){} + "with($data){_.push('" + + + // Convert the template into pure JavaScript + jQuery.trim(markup) + .replace( /([\\'])/g, "\\$1" ) + .replace( /[\r\t\n]/g, " " ) + .replace( /\$\{([^\}]*)\}/g, "{{= $1}}" ) + .replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g, + function( all, slash, type, fnargs, target, parens, args ) { + var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect; + if ( !tag ) { + throw "Template command not found: " + type; + } + def = tag._default || []; + if ( parens && !/\w$/.test(target)) { + target += parens; + parens = ""; + } + if ( target ) { + target = unescape( target ); + args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : ""); + // Support for target being things like a.toLowerCase(); + // In that case don't call with template item as 'this' pointer. Just evaluate... + expr = parens ? (target.indexOf(".") > -1 ? target + parens : ("(" + target + ").call($item" + args)) : target; + exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))"; + } else { + exprAutoFnDetect = expr = def.$1 || "null"; + } + fnargs = unescape( fnargs ); + return "');" + + tag[ slash ? "close" : "open" ] + .split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" ) + .split( "$1a" ).join( exprAutoFnDetect ) + .split( "$1" ).join( expr ) + .split( "$2" ).join( fnargs ? + fnargs.replace( /\s*([^\(]+)\s*(\((.*?)\))?/g, function( all, name, parens, params ) { + params = params ? ("," + params + ")") : (parens ? ")" : ""); + return params ? ("(" + name + ").call($item" + params) : all; + }) + : (def.$2||"") + ) + + "_.push('"; + }) + + "');}return _;" + ); + } + function updateWrapped( options, wrapped ) { + // Build the wrapped content. + options._wrap = build( options, true, + // Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string. + jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()] + ).join(""); + } + + function unescape( args ) { + return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null; + } + function outerHtml( elem ) { + var div = document.createElement("div"); + div.appendChild( elem.cloneNode(true) ); + return div.innerHTML; + } + + // Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance. + function storeTmplItems( content ) { + var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m; + for ( i = 0, l = content.length; i < l; i++ ) { + if ( (elem = content[i]).nodeType !== 1 ) { + continue; + } + elems = elem.getElementsByTagName("*"); + for ( m = elems.length - 1; m >= 0; m-- ) { + processItemKey( elems[m] ); + } + processItemKey( elem ); + } + function processItemKey( el ) { + var pntKey, pntNode = el, pntItem, tmplItem, key; + // Ensure that each rendered template inserted into the DOM has its own template item, + if ( (key = el.getAttribute( tmplItmAtt ))) { + while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { } + if ( pntKey !== key ) { + // The next ancestor with a _tmplitem expando is on a different key than this one. + // So this is a top-level element within this template item + // Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment. + pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0; + if ( !(tmplItem = newTmplItems[key]) ) { + // The item is for wrapped content, and was copied from the temporary parent wrappedItem. + tmplItem = wrappedItems[key]; + tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode], null, true ); + tmplItem.key = ++itemKey; + newTmplItems[itemKey] = tmplItem; + } + if ( cloneIndex ) { + cloneTmplItem( key ); + } + } + el.removeAttribute( tmplItmAtt ); + } else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) { + // This was a rendered element, cloned during append or appendTo etc. + // TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem. + cloneTmplItem( tmplItem.key ); + newTmplItems[tmplItem.key] = tmplItem; + pntNode = jQuery.data( el.parentNode, "tmplItem" ); + pntNode = pntNode ? pntNode.key : 0; + } + if ( tmplItem ) { + pntItem = tmplItem; + // Find the template item of the parent element. + // (Using !=, not !==, since pntItem.key is number, and pntNode may be a string) + while ( pntItem && pntItem.key != pntNode ) { + // Add this element as a top-level node for this rendered template item, as well as for any + // ancestor items between this item and the item of its parent element + pntItem.nodes.push( el ); + pntItem = pntItem.parent; + } + // Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering... + delete tmplItem._ctnt; + delete tmplItem._wrap; + // Store template item as jQuery data on the element + jQuery.data( el, "tmplItem", tmplItem ); + } + function cloneTmplItem( key ) { + key = key + keySuffix; + tmplItem = newClonedItems[key] = + (newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent, null, true )); + } + } + } + + //---- Helper functions for template item ---- + + function tiCalls( content, tmpl, data, options ) { + if ( !content ) { + return stack.pop(); + } + stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options }); + } + + function tiNest( tmpl, data, options ) { + // nested template, using {{tmpl}} tag + return jQuery.tmpl( jQuery.template( tmpl ), data, options, this ); + } + + function tiWrap( call, wrapped ) { + // nested template, using {{wrap}} tag + var options = call.options || {}; + options.wrapped = wrapped; + // Apply the template, which may incorporate wrapped content, + return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item ); + } + + function tiHtml( filter, textOnly ) { + var wrapped = this._wrap; + return jQuery.map( + jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ), + function(e) { + return textOnly ? + e.innerText || e.textContent : + e.outerHTML || outerHtml(e); + }); + } + + function tiUpdate() { + var coll = this.nodes; + jQuery.tmpl( null, null, null, this).insertBefore( coll[0] ); + jQuery( coll ).remove(); + } +})( jQuery ); \ No newline at end of file diff --git a/gemeinsamforschen/src/main/webapp/taglibs/js/utility.js b/gemeinsamforschen/src/main/webapp/taglibs/js/utility.js index da64cdc7b76764bc3228797672274e747695d636..7a174d902942ed373983f14fc0334e2bcb99b97d 100644 --- a/gemeinsamforschen/src/main/webapp/taglibs/js/utility.js +++ b/gemeinsamforschen/src/main/webapp/taglibs/js/utility.js @@ -88,8 +88,7 @@ function getQueryVariable(variable) { * @param methodPath i.e. /create/{id} in this case /create/?/another/? * @param pathParams what is filling in for the ? * @param queryParams i.e. &projectName=something&submissionId=anotherthing - * @param requestEntity the json obj to send in put - * @param callback the callback to call after success + * @param entity the json obj to send in put * @constructor */ function RequestObj(hierachyLevel, modulePath, methodPath, pathParams, queryParams, entity) { @@ -115,7 +114,7 @@ function serverSide(requestObj, method, callback) { methodPath = methodPath.replace("?", e); }); - let localurl = relativPath + "gemeinsamforschen/rest" + requestObj.modulePath + methodPath ; + let localurl = relativPath + "rest" + requestObj.modulePath + methodPath ; if (requestObj.queryParams) { localurl = localurl + requestObj.queryParams; diff --git a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ActivityFlowTest.java b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ActivityFlowTest.java index 42d9626173cfd78e290a8ad053d4804200a99fe1..93e94f69d61b1349896f4c5123b8936f6fb44a86 100644 --- a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ActivityFlowTest.java +++ b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ActivityFlowTest.java @@ -100,7 +100,7 @@ public class ActivityFlowTest { // TODO @Julian: Find out more elegant way of doing this researchReportManagement.setFeedback(feedback); - phases.setFeedback(feedback); +// phases.setFeedback(feedback); }